web-dev-qa-db-fra.com

Tri et limitation avec pre_get_posts

C’est ma troisième question concernant les WP requêtes et les pre_get_posts (désolé), mais je ne peux pas abandonner une étape avant le succès complet :)

Donc, l’histoire - ma requête limite les articles de première page à ceux qui ont des images en vedette. Jusqu'ici tout va bien. Mon dernier objectif est de trier ces publications par champ personnalisé, de les classer dans l’ordre ASC et d’afficher uniquement les publications pour lesquelles la date du champ personnalisé/métakey est dans 30 jours. Jusqu’à présent, c’est mon code et mes tentatives, mais il me semble que je ne suis même pas proche ...

Le tri en cours est chaotique. Pour la deuxième partie, qui ne montre que les publications dans les 30 prochains jours, je souhaite définir une variable contenant la date du jour + 30 jours, une version avec une date de champ personnalisée et la vérification est la première plus grande mais la peut obtenir le champ personnalisé dans cette fonction et où mettre ceci si cocher? Probablement ces questions sont simples mais je me bats. Merci pour votre temps et pour le partage des connaissances.

add_action( 'pre_get_posts', function ( $q ) 
{

    if (     $q->is_home() // Target the home page only
          && $q->is_main_query() // Target only the main query
          || $q->is_category()
    ) {
        $meta_query = array(
            array(
                'key' => '_thumbnail_id',
            )
        );
        $q->set( 'meta_query', $meta_query );
        $q->set('orderby','meta_value_num');
$q->set('meta_key', 'event_date');
$q->set('order', 'ASC');
    }
});
1
tslid

Avant de coder et d'entrer dans les détails, examinons le problème actuel.

  • Tout d’abord, tout format de date valide est valide dans un champ personnalisé si vous n'allez pas l'utiliser pour des comparaisons et des tris

  • Lorsque vous allez trier par date ou faire des comparaisons par date dans un champ personnalisé, la première puce doit être ignorée. Il n'y a que deux formats utilisables qui fonctionneront si vous souhaitez trier par date de champ personnalisé. Elles sont:

    • Horodatage Unix (que je préfère par opinion personnelle) qui est une valeur entière et correspond au nombre de secondes écoulées depuis le 1er janvier 1970. Enregistrer une date dans ce format est le plus précis à mon avis, et tout horodatage peut être facilement converti dans n'importe quel format en utilisant la classe DateTime . Remarque: seules les dates comprises entre le 1er janvier 1970 et le 19 janvier 2038 sont actuellement prises en charge.

    • Y-m-d H:i:s ou Y-m-d ou H:i:s. Tout autre format ne fonctionnera pas. Le paramètre orderby trie littéralement. Ainsi, le premier nombre des chaînes données est comparé et trié par ordre croissant ou décroissant en fonction du paramètre order. S'ils correspondent, le deuxième nombre est comparé, etc. jusqu'à ce que des nombres non correspondants soient trouvés et l'ordre de tri. est retourné. Il est recommandé de définir la valeur correcte du paramètre type dans votre meta_query en fonction de votre format spécifique. Ces valeurs de paramètre type sont DATE, DATETIME et TIME qui gèreront votre format exact lors de l'interrogation de ces champs particuliers

Ce qui précède est très important. Par conséquent, avant de continuer, assurez-vous de bien comprendre cette partie et que vos valeurs sont au format correct. Dans le cas contraire, la section suivante ne fonctionnera pas.

Maintenant que le format est trié, nous devons écrire en anglais clair ce dont nous avons besoin. J'ai tendance à utiliser cette méthode si quelque chose devient difficile ou trop complexe. Cela aide beaucoup. Donc, en clair, voici ce que votre requête devrait faire

Tous les messages avec des vignettes doivent être affichés. Cette option est enregistrée dans un champ personnalisé, _thumbnail_id. En outre, ces postes devraient également avoir des dates dans le futur, pour être exact, dans les trente prochains jours. Ceci est également conforme à un champ personnalisé. Ces publications doivent également être triées en fonction des dates dans le champ personnalisé

Génial, cela signifie donc que, dans notre meta_query, nos messages devraient avoir une vignette ET ( ce sera notre relation entre les champs personnalisés ) et doit avoir une valeur de date de champ personnalisée ENTRE l'heure actuelle et 30 jours à compter de l'heure actuelle

Mettons cela dans le code: ( Note: Avertissement: Ceci n'est pas testé et nécessite au moins PHP 5.3 pour fonctionner à cause de l'utilisation de DateInterval. De plus, ceci est configuré avec la date Y-m-d H:i:s format dans votre champ personnalisé. Gardez vos formats de date uniformément, sinon cela ne fonctionnera pas )

add_action( 'pre_get_posts', function( $q )
{
    if (     $q->is_home() // Target the home page only
          && $q->is_main_query() // Target only the main query
          || $q->is_category() // NO IDEA WHY YOU ADDED THIS! ARE YOU TARGETING CATEGORY PAGES AS WELL?
    ) {

        $current_time = new DateTime(); // Get the current date and time
            $current_time_format = $current_time->format( 'Y-m-d H:i:s' ); // This is the current date and time

        $after_thirty_days = new DateTime(); // Create the date after 30 days
            $after_thirty_days->add( new DateInterval( 'P30D' ) ); // Adds 30 days to the current date and time
            $date_after_thirty_days = $after_thirty_days->format( 'Y-m-d H:i:s' );

        $meta_query = array(
            //Default relation is AND, no need to set it. So posts should match both conditions set in the two sets of arrays
            array( // Our first array of conditions set to get posts with a thumbnail
                'key' => '_thumbnail_id'
            ),
            array( // Our second array of conditions. Posts should also have these conditions in addition to the first array of conditions
                'key' => 'event_date',
                'value' => array( $current_time_format, $date_after_thirty_days ), // Add todays date and date after 30 days as an array
                'compare' => 'BETWEEN', // Will look for valid values between the array of dates given in the value parameter
                'type' => 'DATETIME' // We will use the date and time format to compare our dates
            ),
        );
        $q->set( 'meta_query', $meta_query );
        $q->set( 'orderby', 'meta_value_num' );
        $q->set( 'meta_key', 'event_date' );
        $q->set( 'order', 'ASC' );
    }
});

Quelques dernières remarques:

  • Comme je l’ai déjà noté, cela n’a pas été testé, il est donc possible que cela ne fonctionne pas immédiatement. Il faudra peut-être quelques ajustements.

  • J'ai utilisé le format Y-m-d H:i:s ici. Vous pouvez simplement utiliser Y-m-d ici aussi. Il suffit d’ajuster la requête et les dates en conséquence. Si vous allez utiliser des horodatages, n'oubliez pas de convertir vos dates de comparaison en horodatages.

  • Comme vous utilisez le défilement infini, vous devrez vous rappeler d’ajuster cette fonction en conséquence, sinon la page 2 et les versions ultérieures afficheront des publications erronées.

MODIFIER

Le code ci-dessus est maintenant testé et fonctionne comme prévu avec les formats de date Y-m-d H:i:s et Y-m-d. Je devais corriger un ou deux petits bugs. J'espère que ça aide

3
Pieter Goosen