Запрос заказов WooCommerce, где метаданные не существуют

14 мая 2019 г., 15:02:25
Просмотры: 18.5K
Голосов: 5

Я пытаюсь получить все мои заказы WooCommerce, где дополнительные метаданные не пустые.

$orders = wc_get_orders( array(
    'orderby'   => 'date', // Сортировка по дате
    'order'     => 'DESC', // По убыванию
    'meta_query' => array(
        array(
            'key' => 'var_rate', // Ключ метаполя
            'compare' => 'NOT EXISTS', // Условие "не существует"
        )
    )
));

Таким образом, если var_rate пуст или не существует, то не возвращать эту запись. В настоящее время возвращаются все заказы при использовании этих аргументов.

Пример пустой записи -

object(WC_Meta_Data)#2344 (2) {
  ["current_data":protected]=> // Текущие данные
  array(3) {
    ["id"]=>
    int(6471)
    ["key"]=>
    string(15) "var_rate" // Ключ метаполя
    ["value"]=>
    NULL // Пустое значение
  }
  ["data":protected]=> // Основные данные
  array(3) {
    ["id"]=>
    int(6471)
    ["key"]=>
    string(15) "var_rate"
    ["value"]=>
    NULL
  }
}
2
Комментарии

Ваш код запрашивает все заказы, у которых нет метаданных var_rate. Если возвращаются все заказы, уверены ли вы, что существуют заказы с такими метаданными? Уверены ли вы, что имя метаданных именно var_rate? Чтобы включить только заказы, где эти метаданные не пустые, следует использовать 'compare' => '!=' и, опционально, добавить 'value' => '' в массив.

Sally CJ Sally CJ
14 мая 2019 г. 16:20:17

@SallyCJ спасибо за ваш ответ. Проверив свои данные, я обнаружил, что пустое значение - это NULL. Я попробовал, как вы предложили, и добавил 'value' => NULL, но всё равно получаю оба заказа. Спасибо.

SamXronn SamXronn
14 мая 2019 г. 16:51:34
Все ответы на вопрос 2
0
15

Аргумент meta_query (который можно использовать в WP_Query) по умолчанию не включен при использовании WC_Order_Query через функцию WooCommerce wc_get_orders().

Но вы можете использовать недокументированные Параметры пользовательских полей (точно так же, как в WP_Query):

  • meta_key
  • meta_value
  • meta_value_num
  • meta_compare

Таким образом, в вашем случае можно использовать следующее:

$orders = wc_get_orders( array(
    'limit'        => -1, // Запросить все заказы
    'orderby'      => 'date',
    'order'        => 'DESC',
    'meta_key'     => 'var_rate', // Ключ поля postmeta
    'meta_compare' => 'NOT EXISTS', // Аргумент сравнения
));

В этот раз всё работает отлично (Протестировано на WooCommerce 3.5.8 и 3.6.2).

14 мая 2019 г. 21:10:06
0

Похоже, WooCommerce игнорирует параметр meta_query, поэтому вы получаете все заказы.

Вы можете использовать этот код, чтобы параметр meta_query работал с запросами WooCommerce (заказы):

add_filter( 'woocommerce_get_wp_query_args', function( $wp_query_args, $query_vars ){
    if ( isset( $query_vars['meta_query'] ) ) {
        $meta_query = isset( $wp_query_args['meta_query'] ) ? $wp_query_args['meta_query'] : [];
        $wp_query_args['meta_query'] = array_merge( $meta_query, $query_vars['meta_query'] );
    }
    return $wp_query_args;
}, 10, 2 );

Но, как я уже отмечал в своем комментарии, чтобы запросить все заказы, где метаданные var_rate не пустые, установите compare в !=:

'meta_query' => array(
    array(
        'key'     => 'var_rate',
        'compare' => '!=',
        'value'   => '',
    ),
),

И в вашем случае, когда вы делаете запрос с одним мета-запросом, вы можете просто использовать параметр meta_key вместе с meta_compare и meta_value, без необходимости использовать параметр meta_query:

'meta_key'     => 'var_rate',
'meta_compare' => '!=',
'meta_value'   => '',

Таким образом, вам не нужно использовать код выше, который "включает" параметр meta_query.

ОБНОВЛЕНИЕ

Думаю, я не совсем внимательно прочитал заголовок вопроса.. и решил добавить следующее:

В заголовке вопроса у вас написано "где метаданные не существуют", и для этого вам понадобится 'compare' => 'NOT EXISTS' или 'meta_compare' => 'NOT EXISTS'.

Но в теле вопроса вы сказали "где некоторые дополнительные метаданные не пустые" и также "если var_rate пустой или не существует, то не возвращать эту запись", и для этого вам понадобится 'compare' => '!=' или 'meta_compare' => '!='.

Потому что, когда compare или meta_compare установлен в !=, а value или meta_value установлен в '' (значение по умолчанию, если не указано явно), это означает "найти записи, где мета существует в базе данных и значение не пустое (не '' или не NULL)".

Надеюсь, это поможет. :)

14 мая 2019 г. 18:29:34