web-dev-qa-db-ja.com

ACFカスタムフィールドWP_Query。ただし、フィールドが存在しない場合はすべての投稿を取得する必要があります。

すべての投稿にカスタムACFフィールドを設定し、event_dateと呼びます。与えられたcategory内のすべての投稿を取得したいのですが、event_dateが定義されている投稿をevent_dateのDESC順に配置します。 query_postsに使用しているargsは次のとおりです。

$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'
);

しかし、私が直面している問題は、すべての投稿が作成された後でACFフィールドが投稿タイプ用に作成されたため、meta_keyにevent_dateが定義されていないことです。 query_posts($args)。すべての投稿をまとめて手動で保存するには、投稿が多すぎます。

基本的に、投稿のmeta_keyevent_dateがない場合は、実際の投稿自体のdateを使用して注文する必要があります。 event_dateが定義されていないすべての投稿を、それ以降にDESCの順序で投稿の公開日を使用して表示する必要があるのに対し、event_dateを含む投稿はすべてevent_dateのDESC順序で最初に表示される必要があります。これどうやってするの?できれば、1つのquery_posts呼び出しで全部?

ありがとう:)

1
Solomon Closson

キーが存在しないかどうかもチェックするORmeta_queryで両方を取得できます。

'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

私がこれを採用する最も可能性の高いルートは、カスタムフィールドが割り当てられていない投稿に目的のカスタムフィールドを追加するスクリプトを実行することです。

次のことを試すことができます。(注:これはテストされていません

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 )
        );  
     }
});

これを実行するには、単にページをロードしてから削除します。 posts_per_page=100のように、より小さなまとまりを設定した場合は、すべての投稿が完了するまでページを更新します。これは非常に高価なリソース集約型スクリプトであり、タイムアウト致命的エラーにつながる可能性があるため、大量の投稿がある場合は、ページのロードあたり実行する投稿を少なくすることができます。

この後は、質問と同じようにクエリを実行できます。ただし、単なるヒントです。決してquery_postsを使用しないでください。カスタムクエリを実行するためにWP_Queryを使用してください(または代わりにget_postsを使用する

0
Pieter Goosen