ワードプレスで古い日付を選択できません


13

投稿の年を1899年より下に設定できません。年を1899年未満に設定すると、現在の年に自動的に設定されます。

スクリーンショット

タイムラインテーマを購入し、サポートフォーラムで質問しました。彼らは答えた:

これは、ホスティングプロバイダーによって作成された制限のようです。テーマには、指定した日付を妨げるものは何もありません。ご覧のとおり、デモには1400年代の日付を使用した投稿があります。ホスティングプロバイダーに連絡して、その解決方法についての洞察があるかどうかを確認してください。


2
そして、あなたの質問は正確に何ですか?そこには何千ものテーマがあります-あなたが買ったテーマを誰もが知っていると仮定するのはロングショットです。少なくとも関連するコードを提供する必要があります。
ヨハネスポール

1
私はそれがホスティング事業者のせいだとは思わない。これは、データベースに保存された値に関するものだと思います。WP_DEBUGエラーメッセージをオンにして、質問に編集します。私はそれをそのように思わせたかもしれませんが、問題のテーマの作業バージョンへのリンクも実際にはあまり役に立ちません。
ヨハネスポール

1
これは合法的な質問です。テーマとは関係ありません。この問題を再現できます。このアニメーションのスクリーンショットをご覧ください。
FUXIA

1
1900と1901で同じ問題がありますが、1902は動作します;-)
birgire

1
Unixタイムスタンプ範囲(2038)を超える問題もあるため、これを再現できます。Win7x64上のPHP 5.4
13

回答:


10

これは実際には答えではなく、この問題の特定のコンテキストを見つけるための試みにすぎません。次のプラグインをサイトにインストールし、3つの日付を設定して、<pre>下の表の2番目の日付に結果を追加してください。

/* Plugin Name: WPSE Sysinfo */
add_action( 'admin_footer', 'wpse_sysinfo' );
function wpse_sysinfo() {

    $bit         = 4 === PHP_INT_SIZE ? 32 : 64; // PHP version, not OS!
    $php_version = PHP_VERSION;
    $db_version  = $GLOBALS['wpdb']->db_version();

    print "<pre>$bit | $php_version | $db_version</pre>";
}

プラグインの要点はこちらで確認できます

OS | OSビット| PHP | PHPビット| MySQL | 999 | 1899 | 2020 | 2039 | ユーザー
WIN7 | 64 | 5.4.4 | ?| 5.5.25 | ✘| ✘| ✔| ✘| トスコ
Linux | ?| 5.3.18-nmm1 | ?| 5.1.70 | ✔| ✔| ✔| ✔| トスコ
CentOS 6 | 64 | 5.5.4 | ?| 5.0.95 | ✔| ✔| ✔| ✔| トスコ
WIN7 | 64 | 5.4.15 | 32 | 5.5.31 | ✘| ✘| ✔| ✘| 最悪
Ubuntu 12.04 | 64 | 5.3.10-1 | 64 | 5.5.32 | ✔| ✔| ✔| ✔| ピレ
CloudLinux | 64 | 5.2.17 | 64 | 5.0.96 | ✔| ✔| ✔| ✔| ピレ
Ubuntu 12.10 | 64 | 5.4.6 | 64 | 5.5.32 | ✔| ✔| ✔| ✔| マイケル・エクランド
CENTOS 5.9 | 32 | 5.3.27 | 32 | 5.5.32 | ✘| ✘| ✔| ✘| マイケル・エクランド
WIN7 | 64 | 5.4.7 | 64 | 5.5.27 | ✘| ✘| ✔| ✘| カイザー
OSX 10.7.5 | 64 | 5.3.6 | 64 | 5.5.9 | ✔| ✔| ✔| ✔| ゴーストトースト
Centos 6.4 | 64 | 5.4.17 | 32 | 5.1.59 | ✘| ✘| ✔| ✘| 処女
Debian 6 | 64 | 5.4.19 | 64 | 5.1.66 | ✘| ✘| ✔| ✘| 処女
WIN7 | 64 | 5.5.0 | 64 | 5.5.22 | ✘| ✘| ✔| ✘| GM
OSX 10.7.4 | 64 | 5.3.6 | 64 | 5.5.9 | ✔| ✔| ✔| ✔| ブラソフィロ
CentOS 5 | 64 | 5.3.22 | 64 | 5.1.68 | ✔| ✔| ✔| ✔| ブラソフィロ
Mac 10.8.5 | 64 | 5.3.26 | 64 | 5.5.25 | ✔| ✔| ✔| ✔| フレティーニ
WIN7 | 64 | 5.3.27 | 64 | 5.5.31 | ✔| ✔| ✔| ✔| サシャ・クラウス
Win7SP1 | 64 | 5.3.8 | 64 | 5.5.28 | ✔| ✔| ✔| ✔| マヌエル・シコールド
  1. 新しい投稿を作成します。それを保存。
  2. 日付を1月1日に設定し0999、[ 更新 ]をクリックします。現在の日付に保存または変更されていますか?
  3. 18992020およびの日付設定について繰り返します2039
  4. 管理フッターのプラグイン出力から情報を取得し、テーブルを更新します。

7

質問と期待

この質問の文字通りの形式は文脈(1899年)で実用的ですが、理論的な意味では少しあいまいです。何歳ですか?過去までどのくらい行きたいですか?未来はどうですか?

WordPressはブログエンジンとして開始されたため、その文脈の意味で、次の期間を処理するように進化しました。

  • WPが存在した日付(明らかにそれを使用できるように)
  • 可能な履歴投稿の範囲(暗黙的にインターネットが存在する限り)
  • 特別な努力をせずに可能な限り未来まで(壊れるまで働く)

WordPressの使用が非ブログアプリケーションに進化するにつれて、このようなプロジェクト(一般に、レポートで見たような歴史と芸術)は、この範囲外の日付でさまざまな問題に突き当たり始めました。

私の研究の目的のために、次の質問を策定しました。

  1. WordPressの投稿日でネイティブかつ確実に使用できる、最も早い2つの完全な暦年とは何ですか?
  2. ネイティブ範囲を超えて利用可能なスパンを拡張するための低垂れ下がった果物(ある場合)とは何ですか?

プラットフォームの制限

WordPressはPHPアプリケーションであり、データストレージにMySQLを使用しているため、制限があります。

MySQL

WordPress はMySQL post_dateDATETIMEタイプの列に投稿日を保存します。

ドキュメントによると、このタイプは1000〜9999年をサポートしています。

このDATETIMEタイプは、日付と時刻の両方の部分を含む値に使用されます。MySQLはDATETIME'YYYY-MM-DD HH:MM:SS'形式で値を取得して表示します。サポート範囲がある'1000-01-01 00:00:00''9999-12-31 23:59:59'

ただし、以前の値機能する可能性もあり、後の値については言及されていません

以下のためにDATE and DATETIME範囲の説明、以前の値が働くかもしれませんが、保証はありませんことを意味し、「サポート」。

経験的に、動作範囲外の値を観察しましたが、これは逸話であり、信頼性条件から外れています。

PHP

PHPプログラミングでは、日付のUnixタイムスタンプ表現が広く使用されています。私たちの目的(PHP 5.2+および一般的な32ビット環境)のドキュメントによると、1902年から2037年(完全)をサポートしています。

タイムスタンプの有効範囲は、典型的にはFri, 13 Dec 1901 20:45:54 UTCしますTue, 19 Jan 2038 03:14:07 UTC。(これらは32ビット符号付き整数の最小値と最大値に対応する日付です。)さらに、すべてのプラットフォームが負のタイムスタンプをサポートしているわけではないため、日付範囲はUnixエポック以前に制限される場合があります。これは、たとえばJan 1, 1970、Windows、一部のLinuxディストリビューション、および他のいくつかのオペレーティングシステムでは前の日付が機能しないことを意味します。ただし、PHP 5.1.0以降のバージョンはこの制限を克服しています。

それ以外の新しいDate/Timeベースの処理は64ビットで、およそ-292億年から2,920億年の範囲で、おそらく現時点で人類のニーズを超えています。

WordPressの制限

WordPressは、コードベースにいくつかの追加の制限を導入し、継承します。

データフロー

基本的なユーザーワークフローの観点から、日付に関連する2つの処理があります。

  • 編集後のフォームで入力された日付は、データベースで正しく処理および保存する必要があります
  • データベースに保存された日付は、正しく読み取られ、インターフェースに表示される必要があります

これらは技術的に完全に異なる独立したプロセスであることに注意してください。さらに説明したように、それらの範囲は重複せず、正しい日付を保存することは、WordPress環境でそれを正しく読み取る能力と等しくありません。

明示的な制限

  • 管理者のWordPress投稿エディターでは、100年から9999年の投稿日として送信できる年の範囲を許可しています。
  • _wp_translate_postdata() 年を処理し(フォームとは異なる番号として送信されます)、および:
    • 0以外の値に無害化する
    • 検証には、使用してwp_checkdate()ネイティブPHP呼び出す、checkdate()課しが限度、1〜32767を

暗黙の制限

  • strtotime()PHP関数は複数回使用され、上記のUnixタイムスタンプのmysql2date()影響を受けます。これは、データベースからの日付のすべての読み取りに影響し、1902〜2037の範囲が継承されます。
  • WordPressは、日付の解析で正規表現にフォールバックしますget_gmt_from_date()。これは([0-9]{1,4})1年から9999年までを想定し、より徹底したコード監査を列挙する必要のある他の機能で同様の処理を行う可能性が高い

回避策の可能性

  • wp_checkdate()持っているwp_checkdateこの検証チェックを無効にすることを可能にするフィルタを、
  • エンドユーザー向けの出力date_i18n()date_i18nフィルターを通過し、理論的には日付の出力を完全にインターセプトし、インターフェイスに再処理することができますが、関数が既に範囲外に渡された場合は困難です(false)タイムスタンプ入力

結論

データの実用的な目的と移植性のために、WordPressの投稿日付範囲は32ビットUnixタイムスタンプの日付範囲と等しく、1902から2037年までを包括するように思われます。

この範囲外の投稿日操作については、環境を監査する必要があります(64ビット範囲のUnixタイムスタンプ、事実上機能するMySQL、または値の代替データベースストレージ)。それ以上の範囲(1000未満、9999以上では、かなりの量のカスタムコードが必要になる可能性があります。

任意の日付の実装では、次のことを意味します。

  • データベースの制限を受けない形式でMySQLに保存する
  • Date/TimeUnixタイムスタンプ制限の影響を受けないように監査された完全にカスタムベースのコードおよび/またはWordPress関数を使用したPHPでの処理

コードテストベッド

次のコードと厳選された一連の年は、上記の調査と結論のテストに使用されています。

require ABSPATH . '/wp-admin/includes/post.php';

$timestamp_size_info = array(
    'PHP_INT_SIZE'   => PHP_INT_SIZE,
    'PHP_INT_MAX'    => number_format( PHP_INT_MAX ),
    'min timestamp'  => date( DATE_ISO8601, - PHP_INT_MAX ),
    'zero timestamp' => date( DATE_ISO8601, 0 ),
    'max timestamp'  => date( DATE_ISO8601, PHP_INT_MAX ),
);

r( $timestamp_size_info );

// hand picked set of years to test for assorted limits
$years = array(
    'negative'           => - 1,
    'zero'               => 0,
    'one'                => 1,
    'wp min'             => 100,
    'mysql first'        => 1000,
    'before unix'        => 1899,
    'unix first'         => 1902,
    'current'            => 2013,
    'unix last'          => 2037,
    'after unix'         => 2039,
    'mysql last, wp max' => 9999,
    'after checkdate'    => 33000,
);

// simulates form submission data
$post = array(
    'post_type' => 'post', // shut notice
    'edit_date' => 1,
    'aa'        => 1,
    'mm'        => '01',
    'jj'        => '01',
    'hh'        => '00',
    'mn'        => '00',
    'ss'        => '00',
);

// add_filter( 'wp_checkdate', '__return_true' );

foreach ( $years as $name => $year ) {

    $post['aa'] = $year;
    $translated = _wp_translate_postdata( false, $post );

    if ( is_wp_error( $translated ) ) { // wp_checkdate() failed
        r( array( 'year' => $year . " ({$name})", 'translated valid' => false ) );
    }
    else {

        $post_date        = $translated['post_date'];
        $post_date_gmt    = $translated['post_date_gmt'];
        $translated_valid = (string) $year == substr( $post_date, 0, strpos( $post_date, '-' ) );
        $mysql2date       = mysql2date( DATE_ISO8601, $post_date );
        $mysql2date_valid = (string) $year == substr( $mysql2date, 0, strpos( $mysql2date, '-' ) );

        r( array(
            'year'             => $year . " ({$name})",
            'post_date'        => $post_date,
            'translated valid' => $translated_valid,
            'post_date_gmt'    => $post_date_gmt,
            'mysql2date'       => $mysql2date,
            'from sql valid'   => $mysql2date_valid,
        ) );
    }
}

+1残りの質問のみ:何r()ですか?
カイザー

1
@kaiser php-ref、選択したダンプ関数に置き換えてください:)
Rarst
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.