Consultar pedidos de WooCommerce donde los metadatos no existen

14 may 2019, 15:02:25
Vistas: 18.5K
Votos: 5

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
  }
}
2
Comentarios

Tu código está consultando todos los pedidos que no tienen el metadato var_rate. Entonces, si eso devuelve todos los pedidos, ¿estás segura de que realmente hay pedidos que tienen ese metadato? ¿Estás segura de que el nombre es var_rate? Y para incluir solo los pedidos donde ese metadato no esté vacío, deberías usar 'compare' => '!=' y opcionalmente añadir 'value' => '' al array.

Sally CJ Sally CJ
14 may 2019 16:20:17

@SallyCJ gracias por tu respuesta, revisando mis datos un valor vacío es NULL. Intenté como sugeriste e incluí lo siguiente 'value' => NULL pero aún obtengo ambos pedidos. Gracias.

SamXronn SamXronn
14 may 2019 16:51:34
Todas las respuestas a la pregunta 2
0
15

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_key
  • meta_value
  • meta_value_num
  • meta_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).

14 may 2019 21:10:06
0

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. :)

14 may 2019 18:29:34