web-dev-qa-db-fra.com

ACF Custom Field WP_Query, mais doit obtenir tous les articles, si ce champ n'existe pas

J'ai un champ ACF personnalisé défini sur tous les articles, appelé event_date. J'aimerais saisir tous les articles d'une variable category donnée, mais les articles dont le nom event_date est défini sont placés en premier dans l'ordre DESC de event_date. La args que j'utilise pour query_posts est la suivante:

$args = array(
    'posts_per_page' => -1,
    'cat' => $category_id,
    'meta_query' => array(
        array(
            'key' => 'event_date',
            'value' => date("Ymd", time()),
            'compare' => $type == 'upcoming' ? '>=' : '<'
        )
    ),
    'orderby' => 'meta_value',
    'order' => 'DESC',
    'meta_key' => 'event_date'
);

Mais le problème que je rencontre est que le champ ACF a été créé pour les types d'article, une fois que tous les articles ont été créés. Par conséquent, beaucoup de ces articles n'ont pas event_date même défini pour la méta_key (qui omet automatiquement ces articles de la requête lorsque vous utilisez query_posts($args). Il y a trop de publications pour pouvoir les parcourir toutes et les enregistrer toutes manuellement, cela prendrait une éternité.

Fondamentalement, si le meta_key d’une publication n’a pas event_date, il me faut utiliser la date de la publication elle-même (au moment de sa publication) pour passer commande. J'ai besoin de toutes les publications avec event_date affichées en premier dans l'ordre DESC de event_date. Toutes les publications n'ayant pas défini event_date doivent ensuite être affichées en utilisant la date de publication de la publication dans l'ordre DESC. Comment puis-je faire ceci? De préférence, tout en 1 appel query_posts?

Merci :)

1
Solomon Closson

Vous pouvez obtenir les deux avec une ORmeta_query qui vérifie également si la clé n'existe pas:

'meta_query' => array(
    'relation' => 'OR',
    array(
        'key' => 'event_date',
        'compare' => 'NOT EXISTS',
    ),
    array(
        'key' => 'event_date',
        'value' => date("Ymd", time()),
        'compare' => '>',
    ),
),
'orderby' => array(
    'meta_value_num' => 'DESC',
    'date' => 'ASC',
),
4
Milo

L'itinéraire le plus probable que je vais emprunter avec ceci consiste à exécuter un script qui ajouterait le champ personnalisé souhaité aux publications auxquelles aucun champ personnalisé n'a été attribué.

Vous pouvez essayer ce qui suit: ( NOTE: Ceci n’a pas été testé )

add_action( 'wp', function ()
{
    $args = [
        'post_type'        => 'post', // Set according to needs
        'posts_per_page'   => -1, // Set to execute smaller chucks per page load if necessary
        'suppress_filters' => true,
        'fields'           => 'ids',
        'meta_query'       => [
            [
                'key'      => 'event_date',
                'compare'  => 'NOT EXISTS'
            ]
        ]
    ];
    $q = get_posts( $args );
    foreach ( $q as $post_id ) {
        add_post_meta( 
            $post_id, // Post ID
            'event_date', // Custom field name
            get_the_date( 'Ymd', $post_id )
        );  
     }
});

Vous pouvez l'exécuter en chargeant simplement n'importe quelle page après quoi vous pouvez la supprimer. Si vous définissez des tronçons plus petits, tels que posts_per_page=100, vous actualiserez la page jusqu'à ce que toutes les publications soient terminées. Notez qu’il s’agit d’un script coûteux en ressources intensives qui peut entraîner une erreur fatale de dépassement du délai d’attente. Par conséquent, si vous avez un nombre considérable de publications, vous pouvez en exécuter moins par chargement de page.

Après cela, vous pouvez exécuter votre requête comme d'habitude selon la question. Juste un conseil cependant, n'utilisez jamais query_posts, utilisez WP_Query pour exécuter votre requête personnalisée ( ou utilisez get_posts alternativement )

0
Pieter Goosen