Tidak dapat memilih tanggal lama di wordpress

13

Saya tidak dapat menetapkan tahun di bawah 1899 untuk sebuah pos. Jika saya mengatur tahun di bawah 1899 itu diatur ke tahun berjalan secara otomatis.

tangkapan layar

Saya telah membeli tema Timeline dan bertanya di forum dukungan mereka. Mereka menjawab:

Ini terdengar seperti batasan yang dibuat oleh penyedia hosting Anda. Tidak ada dalam tema yang mencegah tanggal yang Anda tetapkan - seperti yang Anda lihat, demo memiliki posting menggunakan tanggal di tahun 1400-an. Coba hubungi penyedia hosting Anda dan lihat apakah mereka memiliki wawasan tentang cara mengatasinya.

Spartan
sumber
2
Dan pertanyaan Anda adalah apa sebenarnya? Ada ribuan tema di luar sana - sangat sulit untuk berasumsi siapa pun akan tahu tema yang Anda beli. Setidaknya Anda harus memberikan kode yang relevan.
Johannes Pille
1
Saya ragu itu adalah kesalahan hoster. Ini tentang nilai yang disimpan ke database, saya kira. Aktifkan WP_DEBUGdan edit pesan kesalahan ke pertanyaan Anda. Saya mungkin telah membuatnya tampak seperti itu, tetapi tautan ke versi tema yang berfungsi benar-benar tidak banyak membantu.
Johannes Pille
1
Ini pertanyaan yang sah. Itu tidak terkait dengan tema. Saya bisa mereproduksi masalah ini. Lihat tangkapan layar animasi ini .
fuxia
1
Masalah yang sama dengan 1900 dan 1901 tetapi 1902 bekerja ;-)
birgire
1
Saya dapat mereproduksi ini, dengan cara ada masalah di atas rentang cap waktu Unix (2038) juga. PHP 5.4 pada Win7x64
Rarst

Jawaban:

10

Ini sebenarnya bukan jawaban, hanya upaya untuk menemukan konteks spesifik untuk masalah ini. Silakan instal plugin berikut di situs Anda, cobalah untuk mengatur tiga tanggal dan menambahkan hasil Anda ke yang kedua <pre>pada tabel di bawah ini.

/* 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>";
}

Intisari dari Plugin dapat diperiksa di sini .

OS | OS bit | PHP | PHP Bit | MySQL | 999 | 1899 | 2020 | 2039 | pengguna
WIN7 | 64 | 5.4.4 | ?? | 5.5.25 | ✘ | ✘ | ✔ | ✘ | toscho
Linux | ?? | 5.3.18-nmm1 | ?? | 5.1.70 | ✔ | ✔ | ✔ | ✔ | toscho
CentOS 6 | 64 | 5.5.4 | ?? | 5.0.95 | ✔ | ✔ | ✔ | ✔ | toscho
WIN7 | 64 | 5.4.15 | 32 | 5.5.31 | ✘ | ✘ | ✔ | ✘ | jarang
Ubuntu 12.04 | 64 | 5.3.10-1 | 64 | 5.5.32 | ✔ | ✔ | ✔ | ✔ | Pille
CloudLinux | 64 | 5.2.17 | 64 | 5.0.96 | ✔ | ✔ | ✔ | ✔ | Pille
Ubuntu 12.10 | 64 | 5.4.6 | 64 | 5.5.32 | ✔ | ✔ | ✔ | ✔ | Michael Ecklund
CENTOS 5.9 | 32 | 5.3.27 | 32 | 5.5.32 | ✘ | ✘ | ✔ | ✘ | Michael Ecklund
WIN7 | 64 | 5.4.7 | 64 | 5.5.27 | ✘ | ✘ | ✔ | ✘ | kaisar
OSX 10.7.5 | 64 | 5.3.6 | 64 | 5.5.9 | ✔ | ✔ | ✔ | ✔ | GhostToast
Centos 6.4 | 64 | 5.4.17 | 32 | 5.1.59 | ✘ | ✘ | ✔ | ✘ | birgire
Debian 6 | 64 | 5.4.19 | 64 | 5.1.66 | ✘ | ✘ | ✔ | ✘ | birgire
WIN7 | 64 | 5.5.0 | 64 | 5.5.22 | ✘ | ✘ | ✔ | ✘ | GM
OSX 10.7.4 | 64 | 5.3.6 | 64 | 5.5.9 | ✔ | ✔ | ✔ | ✔ | brasofilo
CentOS 5 | 64 | 5.3.22 | 64 | 5.1.68 | ✔ | ✔ | ✔ | ✔ | brasofilo
Mac 10.8.5 | 64 | 5.3.26 | 64 | 5.5.25 | ✔ | ✔ | ✔ | ✔ | flentini
WIN7 | 64 | 5.3.27 | 64 | 5.5.31 | ✔ | ✔ | ✔ | ✔ | Sascha Krause
Win7SP1 | 64 | 5.3.8 | 64 | 5.5.28 | ✔ | ✔ | ✔ | ✔ | Manuel Sychold
  1. Buat posting baru. Simpan itu.
  2. Setel tanggal ke 1 Januari 0999,, klik Perbarui . Apakah disimpan atau diubah ke tanggal saat ini?
  3. Ulangi untuk pengaturan tanggal untuk 1899, 2020dan 2039.
  4. Ambil informasi dari output plugin di footer admin Anda, dan perbarui tabel.
toscho
sumber
7

Pertanyaan dan harapan

Sementara bentuk literal dari pertanyaan ini praktis dalam konteksnya (tahun 1899), ia agak kabur dalam pengertian teoretis. Berapa umur? Seberapa jauh ke masa lalu kita mungkin ingin pergi? Bagaimana dengan masa depan?

Sejak WordPress dimulai sebagai mesin blogging, dalam hal itu arti kontekstual itu berkembang untuk menangani rentang waktu berikut:

  • tanggal WP ada (jelas untuk dapat menggunakannya)
  • berbagai kemungkinan posting historis (secara implisit sejauh Internet ada)
  • sejauh mungkin di masa depan tanpa usaha khusus (bekerja sampai rusak)

Ketika penggunaan WordPress berevolusi menjadi aplikasi non-blogging, proyek-proyek tersebut (biasanya sejarah dan seni seperti yang saya lihat dari laporan) mulai mengalami berbagai masalah dengan tanggal di luar rentang ini.

Untuk tujuan penelitian saya, saya telah merumuskan pertanyaan-pertanyaan berikut:

  1. Apa dua tahun kalender penuh paling awal dan terbaru, yang dapat digunakan dengan tanggal posting WordPress secara asli dan andal?
  2. Apa itu buah gantung rendah (jika ada) untuk memperpanjang rentang yang tersedia di luar rentang asli?

Keterbatasan platform

Karena WordPress adalah aplikasi PHP dan menggunakan MySQL untuk penyimpanan data, itu tunduk pada batasan mereka.

MySQL

WordPress menyimpan tanggal posting dalam post_datekolom DATETIMEtipe di MySQL.

Menurut dokumentasi , tipe ini mendukung tahun 1000 hingga 9999 :

The DATETIMEjenis digunakan untuk nilai-nilai yang mengandung kedua tanggal dan bagian waktu. MySQL mengambil dan menampilkan DATETIMEnilai dalam 'YYYY-MM-DD HH:MM:SS'format. Kisaran yang didukung adalah '1000-01-01 00:00:00'untuk '9999-12-31 23:59:59'.

Namun ia juga mengatakan bahwa nilai sebelumnya mungkin berfungsi, tidak menyebutkan nilai selanjutnya:

Untuk DATE and DATETIMEdeskripsi rentang, "didukung" berarti bahwa meskipun nilai sebelumnya mungkin berfungsi, tidak ada jaminan.

Sementara secara empiris saya telah mengamati nilai-nilai di luar jangkauan kerja, ini adalah anekdotal dan jatuh dari kondisi keandalan kami.

PHP

Dalam pemrograman PHP, representasi timestamp tanggal Unix banyak digunakan. Menurut dokumentasi untuk tujuan kami (PHP 5.2+ dan lingkungan 32 bit umum) mendukung tahun (secara penuh) 1902 hingga 2037 :

Rentang cap waktu yang valid biasanya dari Fri, 13 Dec 1901 20:45:54 UTChingga Tue, 19 Jan 2038 03:14:07 UTC. (Ini adalah tanggal yang sesuai dengan nilai minimum dan maksimum untuk integer bertanda 32-bit.) Selain itu, tidak semua platform mendukung cap waktu negatif, oleh karena itu rentang tanggal Anda mungkin dibatasi tidak lebih awal dari zaman Unix. Ini berarti bahwa misalnya tanggal sebelum Jan 1, 1970tidak akan berfungsi pada Windows, beberapa distribusi Linux, dan beberapa sistem operasi lainnya. PHP 5.1.0 dan versi yang lebih baru mengatasi batasan ini.

Selain itu Date/Timepenanganan berbasis yang lebih baru adalah 64 bit dan memiliki kisaran sekitar -292 miliar hingga 292 miliar tahun , yang mungkin melebihi kebutuhan manusia saat ini.

Keterbatasan WordPress

WordPress memperkenalkan dan mewarisi beberapa batasan tambahan dalam basis kodenya.

Aliran data

Dari sudut pandang alur kerja pengguna dasar ada dua yang diproses terkait dengan tanggal:

  • input tanggal dalam bentuk postingan harus diproses dengan benar dan disimpan dalam database
  • tanggal yang disimpan dalam database harus dibaca dan ditampilkan dengan benar di antarmuka

Perhatikan bahwa ini adalah proses yang sepenuhnya berbeda dan independen secara teknis. Seperti dijelaskan lebih lanjut rentang mereka tidak tumpang tindih dan menyimpan tanggal yang benar tidak sama dengan kemampuan untuk membacanya dengan benar di lingkungan WordPress.

Batas eksplisit

  • Editor posting WordPress di admin memungkinkan rentang tahun, yang dapat dikirimkan sebagai tanggal posting, 100 hingga 9999
  • _wp_translate_postdata() memproses tahun (diajukan sebagai nomor berbeda dari formulir) dan:
    • membersihkannya menjadi non-negatif > 0
    • memvalidasi penggunaannya wp_checkdate(), yang memanggil PHP asli checkdate(), yang memberlakukan batas 1 hingga 32767

Batas implisit

  • strtotime()Fungsi PHP digunakan beberapa kali dan tunduk pada cap waktu Unix yang disebutkan di atas, pada level terendah mysql2date()yang memengaruhi semua pembacaan tanggal dari basis data, rentang 1902 hingga 2037 yang diwarisi
  • WordPress kembali ke ekspresi reguler untuk parsing tanggal get_gmt_from_date(), yang diperkirakan tahun ([0-9]{1,4}), membatasi 1 hingga 9999 , kemungkinan kuat pemrosesan serupa di fungsi lain yang akan memerlukan audit kode yang lebih teliti untuk dihitung

Kemungkinan solusi

  • wp_checkdate()memiliki wp_checkdatefilter, yang memungkinkan untuk mengganti pemeriksaan validasi ini
  • output yang ditujukan untuk pengguna akhir date_i18n()yang memiliki date_i18nfilter, secara teoritis memungkinkan untuk sepenuhnya mencegat dan memproses kembali output dari tanggal ke antarmuka namun menantang jika fungsi dilewatkan sudah di luar jangkauan ( false) input timestamp

Kesimpulan

Untuk tujuan praktis dan portabilitas data, kisaran tanggal posting WordPress tampaknya sama dengan 32 bit cap waktu Unix dan terdiri dari tahun 1902 hingga 2037 secara inklusif .

Untuk setiap operasi tanggal posting keluar dari lingkungan jangkauan ini harus diaudit (kisaran 64 bit cap waktu Unix, de-facto berfungsi MySQL atau penyimpanan database alternatif untuk nilai-nilai). Untuk rentang lebih jauh (di bawah 1000, di atas 9999 ) sejumlah besar kode kustom mungkin diperlukan.

Untuk setiap implementasi tanggal sewenang-wenang, masuk akal untuk:

  • menyimpannya dalam format MySQL tidak tunduk pada batasan basis data
  • proses dalam PHP menggunakan Date/Timekode berbasis kustom sepenuhnya dan / atau fungsi WordPress diaudit untuk tidak terpengaruh oleh batas cap waktu Unix

Tempat uji kode

Kode dan set tahun pilihan tangan berikut telah digunakan untuk penelitian di atas dan pengujian kesimpulan:

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,
        ) );
    }
}
Jarang
sumber
+1 Hanya tersisa pertanyaan: Apa itu r()?
kaiser
1
@kaiser php-ref , ganti dengan fungsi dump pilihan :)
Rarst