Consultar pedidos de WooCommerce donde los metadatos no existen
Estoy intentando obtener todos mis pedidos de WooCommerce donde algunos metadatos adicionales no están vacíos.
$orders = wc_get_orders( array(
'orderby' => 'date',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'var_rate',
'compare' => 'NOT EXISTS',
)
)
));
Así que si var_rate está vacío o no existe, no devolver ese registro. Actualmente se devuelven todos los pedidos usando estos argumentos.
Ejemplo de registro vacío -
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
}
}
El argumento meta_query (que puedes usar en una WP_Query) no está habilitado por defecto cuando se usa una WC_Order_Query a través de la función wc_get_orders() de WooCommerce.
Pero puedes usar los Custom Field Parameters no documentados (igual que en un WP_Query):
meta_keymeta_valuemeta_value_nummeta_compare
Así que en tu caso puedes usar lo siguiente:
$orders = wc_get_orders( array(
'limit' => -1, // Consultar todos los pedidos
'orderby' => 'date',
'order' => 'DESC',
'meta_key' => 'var_rate', // El campo meta_key
'meta_compare' => 'NOT EXISTS', // El argumento de comparación
));
Esta vez funciona correctamente (Probado en WooCommerce 3.5.8 y 3.6.2).
Al parecer, WooCommerce está ignorando el parámetro meta_query, por eso estás obteniendo todos los pedidos.
Puedes usar este código para hacer que el parámetro meta_query funcione con las consultas de WooCommerce (pedidos):
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 );
Pero como mencioné en mi comentario, para consultar todos los pedidos donde el metadato var_rate no esté vacío, establece el compare en !=:
'meta_query' => array(
array(
'key' => 'var_rate',
'compare' => '!=',
'value' => '',
),
),
Y en tu caso, donde estás consultando con un solo meta query, podrías simplemente usar el parámetro meta_key junto con meta_compare y meta_value, sin necesidad de usar el parámetro meta_query:
'meta_key' => 'var_rate',
'meta_compare' => '!=',
'meta_value' => '',
De esa manera, no tienes que usar el código anterior que "habilita" el parámetro meta_query.
ACTUALIZACIÓN
Creo que no estaba prestando suficiente atención al título de la pregunta... y pensé que debería agregar esto:
En el título de la pregunta, tienes "donde los metadatos no existen", y para eso, necesitarías 'compare' => 'NOT EXISTS' o 'meta_compare' => 'NOT EXISTS'.
Pero en el cuerpo de la pregunta, dijiste "donde algunos metadatos adicionales son iguales a no vacío" y también "si el var_rate está vacío o no existe, entonces no devolver ese registro", y para eso, necesitarías 'compare' => '!=' o 'meta_compare' => '!='.
Porque cuando compare o meta_compare está configurado como !=, y value o meta_value está configurado como '' (el valor predeterminado, si no se especifica explícitamente), entonces significa "encontrar registros donde el meta exista en la base de datos y el valor no esté vacío (no sea '' o no sea NULL)".
Espero que eso ayude. :)