Impossible de sélectionner une ancienne date dans wordpress


13

Je ne peux pas définir l'année en dessous de 1899 pour un poste. Si je règle l'année en dessous de 1899, elle est automatiquement définie sur l'année en cours.

capture d'écran

J'ai acheté le thème Timeline et demandé dans leur forum de support. Ils ont répondu:

Cela ressemble à une limitation créée par votre hébergeur. Rien dans le thème n'empêche la date que vous attribuez - comme vous pouvez le voir, la démo a des publications utilisant des dates dans les années 1400. Essayez de contacter votre hébergeur et voyez s'il a des informations sur la façon de résoudre ce problème.


2
Et votre question est quoi exactement? Il y a des milliers de thèmes - c'est loin de supposer que quiconque connaîtrait le thème que vous avez acheté. Vous devrez au moins fournir le code pertinent.
Johannes Pille

1
Je doute que ce soit la faute de l'hébergeur. Il s'agit d'une valeur enregistrée dans la base de données, je suppose. Activez WP_DEBUGet modifiez un message d'erreur dans votre question. J'aurais pu le faire croire, mais un lien vers une version de travail du thème en question n'est vraiment pas très utile non plus.
Johannes Pille

1
C'est une question légitime. Ce n'est pas lié au thème. Je peux reproduire ce problème. Voir cette capture d'écran animée .
fuxia

1
Même problème avec 1900 et 1901 mais 1902 fonctionne ;-)
birgire

1
Je peux reproduire cela, en raison de la présence de problèmes au-dessus de la plage d'horodatage Unix (2038). PHP 5.4 sur Win7x64
Rarst le

Réponses:


10

Ce n'est pas vraiment une réponse, juste une tentative de trouver le contexte spécifique de ce problème. Veuillez installer le plugin suivant sur votre site, essayez de définir les trois dates et ajoutez votre résultat à la seconde <pre>dans le tableau ci-dessous.

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

L'essentiel du plugin peut être vérifié ici .

OS | Bit OS | PHP | Bit PHP | MySQL | 999 | 1899 | 2020 | 2039 | utilisateur
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 | ✘ | ✘ | ✔ | ✘ | rare
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 | ✘ | ✘ | ✔ | ✘ | kaiser
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. Créez un nouveau message. Sauvegarde le.
  2. Définissez la date au 1er janvier 0999, cliquez sur Mettre à jour . Est-il enregistré ou modifié à la date actuelle?
  3. Répétez l'opération pour les paramètres de date pour 1899, 2020et 2039.
  4. Prenez les informations de la sortie du plugin dans votre pied de page d'administration et mettez à jour le tableau.

7

Question et attentes

Bien que la forme littérale de cette question soit pratique dans son contexte (année 1899), elle est un peu vague au sens théorique. Quel âge a vieux? Jusqu'où peut-on vouloir aller dans le passé ? Qu'en est-il du futur?

Depuis que WordPress avait commencé comme moteur de blog, dans ce sens contextuel , il a évolué pour gérer la période de temps suivante:

  • dates d'existence de WP (évidemment pour pouvoir l'utiliser)
  • gamme de publications historiques possibles (implicitement aussi loin qu'Internet existait)
  • aussi loin dans le futur que possible sans effort particulier (travailler jusqu'à la rupture)

Au fur et à mesure que l'utilisation de WordPress a évolué vers des applications non liées aux blogs, ces projets (généralement l'histoire et l'art comme je l'ai vu dans les rapports) ont commencé à rencontrer des problèmes divers avec des dates en dehors de cette période.

Aux fins de mes recherches, j'avais formulé les questions suivantes:

  1. Quelles sont les deux premières et dernières années civiles complètes, qui peuvent être utilisées avec les dates de publication WordPress de manière native et fiable?
  2. Quels sont les fruits à suspension basse (le cas échéant) pour étendre la portée disponible au-delà de l'aire de répartition native?

Limitations de la plateforme

Étant donné que WordPress est une application PHP et utilise MySQL pour le stockage de données, il est soumis à leurs limites.

MySQL

WordPress stocke les dates de publication dans une post_datecolonne de DATETIMEtype dans MySQL.

Selon la documentation, ce type prend en charge les années 1000 à 9999 :

Le DATETIMEtype est utilisé pour les valeurs qui contiennent des parties de date et d'heure. MySQL récupère et affiche les DATETIMEvaleurs au 'YYYY-MM-DD HH:MM:SS'format. La plage prise en charge est '1000-01-01 00:00:00'de '9999-12-31 23:59:59'.

Cependant, il indique également que des valeurs antérieures peuvent fonctionner, aucune mention de valeurs ultérieures:

Pour les DATE and DATETIMEdescriptions de plage, «pris en charge» signifie que bien que des valeurs antérieures puissent fonctionner, il n'y a aucune garantie.

Bien qu'empiriquement, j'ai observé des valeurs hors plage de travail, cela est anecdotique et tombe hors de notre condition de fiabilité.

PHP

En programmation PHP, la représentation d'horodatage Unix de la date est largement utilisée. Selon la documentation à nos fins (PHP 5.2+ et environnement générique 32 bits), il prend en charge les années (en entier) 1902 à 2037 :

La plage valide d'un horodatage est généralement de Fri, 13 Dec 1901 20:45:54 UTCà Tue, 19 Jan 2038 03:14:07 UTC. (Ce sont les dates qui correspondent aux valeurs minimale et maximale pour un entier signé 32 bits.) De plus, toutes les plates-formes ne prennent pas en charge les horodatages négatifs, par conséquent, votre plage de dates peut être limitée au plus tôt à l'époque Unix. Cela signifie par exemple que les dates antérieures à Jan 1, 1970ne fonctionneront pas sur Windows, certaines distributions Linux et quelques autres systèmes d'exploitation. PHP 5.1.0 et les versions plus récentes surmontent cependant cette limitation.

En dehors de cette nouvelle Date/Timegestion basée sur 64 bits, la plage varie entre -292 et 292 milliards d'années , ce qui dépasse probablement les besoins de l'humanité à l'heure actuelle.

Limitations de WordPress

WordPress introduit et hérite de certaines limitations supplémentaires dans sa base de code.

Flux de données

Du point de vue du flux de travail utilisateur de base, deux processus sont liés à la date:

  • la date saisie dans le formulaire de post-édition doit être correctement traitée et enregistrée dans la base de données
  • la date enregistrée dans la base de données doit être correctement lue et affichée dans l'interface

Notez que ce sont des processus techniquement complètement différents et indépendants. Comme expliqué plus en détail, leurs plages ne se chevauchent pas et la sauvegarde de la date correcte n'équivaut pas à la capacité de la lire correctement dans l'environnement WordPress.

Limites explicites

  • L'éditeur de publication WordPress dans admin permet une plage d'années, qui peut être soumise comme date de publication, de 100 à 9999
  • _wp_translate_postdata() traite l'année (soumise en tant que numéro distinct du formulaire) et:
    • le désinfecte à non négatif > 0
    • le valide en utilisant wp_checkdate(), qui appelle PHP natif checkdate(), qui impose une limite de 1 à 32767

Limites implicites

  • strtotime()La fonction PHP est utilisée plusieurs fois et est sujette à l'horodatage Unix mentionné ci-dessus, au niveau le plus bas mysql2date()qui affecte toutes les lectures de dates de la base de données, plage de 1902 à 2037 héritée
  • WordPress revient à l'expression régulière pour l'analyse de la date get_gmt_from_date(), qui s'attend à ce que l'année soit ([0-9]{1,4}), en la limitant de 1 à 9999 , une forte possibilité de traitement similaire dans d'autres fonctions qui nécessiteront un audit de code plus approfondi pour être énuméré

Possibilité de contournements

  • wp_checkdate()a un wp_checkdatefiltre qui permet de passer outre ce contrôle de validation
  • sortie destinée à l' utilisateur final passe par date_i18n()qui présente date_i18nfiltre, permet théoriquement d'intercepter et complètement re-sortie processus de dates à l' interface contester si la fonction est passé déjà hors de portée ( false) entrée d'horodatage

Conclusions

Pour des raisons pratiques et de portabilité des données, la plage de dates de publication WordPress semble être égale à celle de l'horodatage Unix 32 bits et comprend les années 1902 à 2037 inclusivement .

Pour toute opération post-date hors de cette plage, l'environnement doit être audité (plage de 64 bits d'horodatages Unix, MySQL fonctionnant de facto ou stockage de base de données alternatif pour les valeurs). Pour des plages plus éloignées ( inférieures à 1 000, supérieures à 9 999 ), des quantités considérables de code personnalisé seront probablement nécessaires.

Pour toute implémentation de dates arbitraires, il est logique de:

  • les stocker dans MySQL dans un format non soumis aux limitations de la base de données
  • processus en PHP utilisant du Date/Timecode entièrement personnalisé et / ou des fonctions WordPress audités pour ne pas être affecté par les limites d'horodatage Unix

Banc d'essai de code

Le code suivant et un ensemble d'années sélectionnées à la main ont été utilisés pour la recherche ci-dessus et pour tester les conclusions:

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 Seule question restante: Qu'est-ce que c'est r()?
kaiser

1
@kaiser php-ref , remplacez par la fonction de vidage de votre choix :)
Rarst le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.