WordPress'te eski bir tarih seçilemiyor


13

Bir yayın için yılı 1899'un altına ayarlayamıyorum. Yılı 1899'un altına ayarlarsam, otomatik olarak geçerli yıla ayarlanır.

ekran görüntüsü

Zaman Çizelgesi temasını satın aldım ve destek forumlarında sordum. Cevap verdiler:

Bu, barındırma sağlayıcınız tarafından oluşturulan bir sınırlama gibi görünüyor. Temadaki hiçbir şey atadığınız tarihi engellemiyor - gördüğünüz gibi, demoda 1400'lerde tarihleri ​​kullanan yayınlar yok. Barındırma sağlayıcınızla iletişim kurmayı deneyin ve bunun nasıl ele alınacağına dair herhangi bir fikirleri olup olmadığını görün.


2
Ve sorunuz tam olarak nedir? Dışarıda binlerce tema var - satın aldığınız temayı kimsenin bileceğini varsaymak uzun bir atış. En azından ilgili kodu girmeniz gerekecek.
Johannes Pille

1
Kuşkucunun suçu olduğundan şüpheliyim. Bu veritabanına kaydedilen bir değer hakkında, sanırım. Sorunuzda WP_DEBUGbir hata mesajı açın ve düzenleyin. Öyle görünebilirdim, ancak söz konusu temanın çalışan bir sürümüne bir bağlantı da çok fazla yardımcı olmuyor.
Johannes Pille

1
Bu yasal bir soru. Tema ile ilgili değil. Bu sorunu yeniden oluşturabilirim. Bu animasyonlu ekran görüntüsüne bakın .
fuxia

1
1900 ve 1901 ile aynı sorun ama 1902 çalışır ;-)
birgire

1
Bu arada, Unix zaman damgası aralığının (2038) üzerinde de sorunlar var. Win7x64 PHP 5.4
Rarst

Yanıtlar:


10

Bu gerçekten bir cevap değil, sadece bu problem için belirli bir bağlam bulma çabasıdır. Lütfen sitenize aşağıdaki eklentiyi yükleyin, üç tarihi ayarlamayı deneyin ve sonucunuzu <pre>aşağıdaki tabloda ikincisine ekleyin .

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

Eklentinin özeti buradan kontrol edilebilir .

İşletim Sistemi | İşletim Sistemi bit | PHP | PHP Bit | MySQL | 999 | 1899 | 2020 | 2039 | kullanıcı
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 | ✘ | ✘ | ✔ | ✘ | rarst
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 | ✘ | ✘ | ✔ | ✘ | Kayser
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. Yeni bir yayın oluşturun. Kaydet.
  2. Tarihi 1 Ocak olarak ayarlayın, Güncelle'yi0999 tıklayın . Kayıtlı mı yoksa geçerli tarihe mi değiştirildi?
  3. Tarih ayarları için tekrarlayın 1899, 2020ve 2039.
  4. Yönetici altbilginizdeki eklenti çıktısından bilgileri alın ve tabloyu güncelleyin.

7

Soru ve beklentiler

Bu sorunun gerçek formu bağlamda pratik olsa da (yıl 1899) teorik anlamda biraz belirsizdir. Kaç yaşında Geçmişe ne kadar gitmek isteyebiliriz ? Gelecek hakkında ne düşünüyorsun?

WordPress, bloglama motoru olarak başladığından beri, bu bağlamsal olarak, aşağıdaki zaman aralığını ele almak için gelişti:

  • WP'nin var olduğu tarihler (açıkça kullanabilmek için)
  • olası tarihsel yayınların aralığı (dolaylı olarak internet var olduğu kadar)
  • özel çaba sarf etmeden mümkün olduğunca geleceğe kadar (kırılana kadar çalışın)

WordPress kullanımı, blog oluşturmayan uygulamalara dönüştükçe, bu tür projeler (genellikle raporlardan gördüğüm tarih ve sanat), bu aralığın dışındaki tarihlerle çeşitli sorunları vurmaya başladı.

Araştırmamın amacı için aşağıdaki soruları formüle etmiştim:

  1. WordPress posta tarihleriyle doğal ve güvenilir bir şekilde kullanılabilecek en eski ve en yeni iki takvim yılı nedir?
  2. Mevcut aralığın doğal aralığın ötesine genişletilmesi için düşük asılı meyveler (varsa) nelerdir?

Platform sınırlamaları

WordPress PHP uygulaması olduğundan ve veri depolama için MySQL kullandığından sınırlamalarına tabidir.

MySQL

WordPress yazı tarihlerini MySQL'de tür post_datesütununda saklar DATETIME.

Belgelere göre bu tip 1000 ila 9999 yıllarını destekler :

DATETIMETip tarih ve saat parçaları her ikisini de içerir değerler için kullanılır. MySQL DATETIMEdeğerleri alır ve 'YYYY-MM-DD HH:MM:SS'formatta görüntüler . Desteklenen aralığı '1000-01-01 00:00:00'için '9999-12-31 23:59:59'.

Bununla birlikte, önceki değerlerin işe yarayabileceğini söylüyor, daha sonraki değerlerden bahsedilmiyor:

İçin DATE and DATETIMEaralık açıklamaları, önceki değerler çalışabilir, ancak hiçbir garantisi olmadığı anlamına gelir “desteklenen”.

Ampirik olarak aralık dışı çalışma değerlerini gözlemledim, ancak bu anekdot ve güvenilirlik durumumuzdan düşüyor.

PHP

PHP programlamasında Unix zaman damgası tarih gösterimi yaygın olarak kullanılmaktadır. Amaçlarımız için olan belgelere göre (PHP 5.2+ ve genel 32 bit ortam) 1902 ila 2037 yıllarını (tam olarak) destekler :

Zaman damgasının geçerli aralığı genellikle Fri, 13 Dec 1901 20:45:54 UTCila arasındadır Tue, 19 Jan 2038 03:14:07 UTC. (Bunlar, 32 bit işaretli tam sayı için minimum ve maksimum değerlere karşılık gelen tarihlerdir.) Ayrıca, tüm platformlar negatif zaman damgalarını desteklemez, bu nedenle tarih aralığınız Unix döneminden daha erken olamaz. Bu, örneğin önceki tarihlerin Jan 1, 1970Windows, bazı Linux dağıtımları ve diğer birkaç işletim sisteminde çalışmayacağı anlamına gelir . PHP 5.1.0 ve daha yeni sürümleri bu sınırlamanın üstesinden gelir.

Bunun dışında yeni Date/Timetabanlı işlem 64 bit ve kabaca -292 milyar ila 292 milyar yıl arasındadır , bu da muhtemelen insanlık ihtiyaçlarını şu anda aşmaktadır.

WordPress sınırlamaları

WordPress, kod tabanına bazı ek sınırlamalar getirir ve devralır.

Veri akışı

Temel kullanıcı iş akışı bakış açısından, tarihle ilgili olarak işlenmiş iki tane vardır:

  • düzenleme sonrası formdaki tarih girişi doğru şekilde işlenmeli ve veritabanına kaydedilmelidir
  • veritabanına kaydedilen tarih doğru okunmalı ve arayüzde gösterilmelidir

Bunların teknik olarak tamamen farklı ve bağımsız süreçler olduğunu unutmayın. Daha fazla açıklandığı gibi, aralıkları üst üste gelmez ve doğru tarihin kaydedilmesi, WordPress ortamında doğru okuma yeteneği ile eşit değildir.

Açık limitler

  • Yönetici içinde WordPress yazı editörü, 100 ila 9999 arası yayın tarihi olarak gönderilebilen yıl aralığına izin verir
  • _wp_translate_postdata() süreç yılı (formdan ayrı sayı olarak gönderilir) ve:
    • negatif olmayan > 0 olarak dezenfekte eder
    • 1 ile 32767 arasında sınır uygulayan wp_checkdate()PHP yerli adını kullanan doğrularcheckdate()

Örtük sınırlar

  • strtotime()PHP işlevi birden çok kez kullanılır ve yukarıda belirtilen Unix zaman damgasına tabidir, en düşük düzeyde mysql2date()veritabanından tüm tarih okumalarını etkiler, 1902'den 2037'ye devralınan aralık
  • WordPress, tarih ayrıştırma için düzenli ifadeye geri döner get_gmt_from_date(), bu da yılı bekler ([0-9]{1,4}), 1 ile 9999 arasında sınırlar, daha kapsamlı kod denetiminin numaralandırılmasını gerektiren diğer işlevlerde benzer işleme olasılığı

Geçici çözüm olasılığı

  • wp_checkdate()wp_checkdatebu doğrulama kontrolünü geçersiz kılmaya izin veren bir filtreye sahip
  • yoluyla, son kullanıcı yönelik çıkış gider date_i18n()sahip olan date_i18nhareket aralığı (zaten üzerinden geçirilir filtre, teorik olarak tamamen tarihleri kesişme ve yeniden işlem çıkış zorlu ancak arayüz sağlar false) zaman damgası girişi

Sonuçlar

Verilerin pratik amaçları ve taşınabilirliği için WordPress yazı tarihi aralığı 32 bit Unix zaman damgasınınkine eşit gibi gözükmektedir ve 1902-2037 yıllarını kapsamaktadır .

Bu aralık dışındaki herhangi bir son tarih işlemi için ortam denetlenmelidir (64 bit Unix zaman damgaları, fiili çalışan MySQL veya alternatif veritabanı depolama değerleri). Daha uzak aralıklar için ( 1000'in altında, 9999'un üzerinde ) önemli miktarda özel kod gerekli olabilir.

Keyfi tarihlerin herhangi bir uygulaması için:

  • bunları MySQL'de veritabanı sınırlamalarına tabi olmayan bir biçimde saklar
  • tamamen özel Date/Timetabanlı kod ve / veya Unix zaman damgası sınırlarından etkilenmeyecek şekilde denetlenmiş WordPress işlevleri kullanılarak PHP'de işlem

Kod test yatağı

Aşağıdaki kod ve elle seçilmiş yıllar kümesi, yukarıdaki araştırmalar ve sonuçların test edilmesi için kullanılmıştır:

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 Yalnızca kalan soru: Nedir r()?
kaiser

1
@kaiser php-ref , seçim döküm fonksiyonu ile değiştirin :)
Rarst
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.