¿Cómo hacer una meta query usando REST-API en WordPress 4.7+?
Estoy tratando de filtrar mediante una meta query pero sin importar lo que intente no puedo hacer que funcione.
Básicamente quiero esta consulta a través de la REST API:
wp-json/wp/v2/books?meta_query[relation]=OR&meta_query[0][key]=arkivera&meta_query[0][value]=1&meta_query[0][compare]==
He probado varios campos personalizados pero siempre devuelve todos los objetos de publicación.
En mi archivo functions he añadido:
function api_allow_meta_query( $valid_vars ) {
$valid_vars = array_merge( $valid_vars, array( 'meta_query') );
return $valid_vars;
}
add_filter( 'rest_query_vars', 'api_allow_meta_query' );
Intenté buscar documentación sobre esto pero no pude encontrar, además la mayoría de las preguntas similares no son para wordpress 4.7 ya que filter[xxx] fue eliminado.

Utiliza el filtro rest_{CUSTOM_POST_TYPE}_query para agregar soporte de meta post en la API REST de WP para cualquier tipo de publicación.
Revisa el Gist buscar publicación por meta post con API REST.
¿Cómo usarlo?
http://example.org/wp-json/wp/v2/post?meta_key=<my_meta_key>&meta_value=<my_meta_value>
Ejemplo
Obtener publicaciones cuyo meta post already-visited
tenga el valor true
.
http://example.org/wp-json/wp/v2/post?meta_key=already-visited&meta_value=true
SÓLO lista las publicaciones cuyo meta post clave already-visited
tenga el valor true
.
Para referencia Buscar publicación por meta post con API REST.
Filtros Disponibles
- rest_post_query
- rest_page_query
- rest_attachment_query

¿Qué pasa con las cadenas si queremos un campo con valor (no nulo)? Puedo recuperar campos de latitud mayores que un valor filter[meta_key]=latitude&filter[meta_compare]=%3C&filter[meta_value]=34.7 pero necesito otro campo de cadena, así que quiero tener los que tienen valor

Puedes escribir tu propio manejador REST para consultas personalizadas si lo deseas. En tu caso, la consulta se puede realizar de la siguiente manera:
// Registrar una ruta REST
add_action( 'rest_api_init', function () {
// Ruta para la consulta de metadatos
register_rest_route( 'tchernitchenko/v2', '/my_meta_query/', array(
'methods' => 'GET',
'callback' => 'custom_meta_query'
) );
});
// Realizar la consulta y devolver los datos
function custom_meta_query(){
if(isset($_GET['meta_query'])) {
$query = $_GET['meta_query'];
// Establecer los argumentos basados en nuestros parámetros GET
$args = array (
'relation' => $query[0]['relation'],
array(
'key' => $query[0]['key'],
'value' => $query[0]['value'],
'compare' => '=',
),
);
// Ejecutar una consulta personalizada
$meta_query = new WP_Query($args);
if($meta_query->have_posts()) {
// Definir un array vacío
$data = array();
// Almacenar el título de cada post en el array
while($meta_query->have_posts()) {
$meta_query->the_post();
$data[] = get_the_title();
}
// Devolver los datos
return $data;
} else {
// Si no hay posts
return 'No hay posts para mostrar';
}
}
}
Ahora, todo lo que tienes que hacer es acceder a:
wp-json/tchernitchenko/v2/my_meta_query?meta_query[relation]=OR&meta_query[0][key]=arkivera&meta_query[0][value]=1&meta_query[0][compare]==

El siguiente código debería añadir la capacidad de múltiples consultas meta a todos tus tipos de publicación. Soporta CPT (Custom Post Type) y ACF (Advanced Custom Field). El código fuente también está disponible en Github.
Añádelo a tu function.php
add_action( 'rest_api_init', 'wp_rest_filter_add_filters' );
/**
* Añade los filtros necesarios a cada tipo de publicación
**/
function wp_rest_filter_add_filters() {
foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
add_filter( 'rest_' . $post_type->name . '_query', 'wp_rest_filter_add_filter_param', 10, 2 );
}
}
/**
* Añade el parámetro de filtro
*
* @param array $args Los argumentos de la consulta.
* @param WP_REST_Request $request Detalles completos sobre la solicitud.
* @return array $args.
**/
function wp_rest_filter_add_filter_param( $args, $request ) {
// Salir si no se establece el parámetro de filtro.
if ( empty( $request['filter'] ) || ! is_array( $request['filter'] ) ) {
return $args;
}
$filter = $request['filter'];
if ( isset( $filter['posts_per_page'] ) && ( (int) $filter['posts_per_page'] >= 1 && (int) $filter['posts_per_page'] <= 100 ) ) {
$args['posts_per_page'] = $filter['posts_per_page'];
}
global $wp;
$vars = apply_filters( 'rest_query_vars', $wp->public_query_vars );
function allow_meta_query( $valid_vars )
{
$valid_vars = array_merge( $valid_vars, array( 'meta_query', 'meta_key', 'meta_value', 'meta_compare' ) );
return $valid_vars;
}
$vars = allow_meta_query( $vars );
foreach ( $vars as $var ) {
if ( isset( $filter[ $var ] ) ) {
$args[ $var ] = $filter[ $var ];
}
}
return $args;
}
En mi opinión, una mejor forma sería incluir la función adicional como un plugin separado. Así, incluso si el usuario cambia de tema, tus llamadas API no se verán afectadas.
Por eso he desarrollado un plugin para consultas meta en WordPress. ¡Y aún mejor, también soporta ACF!
Después de la instalación, simplemente haz una solicitud GET con el siguiente formato.
https://dominio.com/wp-json/acf/v3/customposttype?filter[meta_key]=acfkey&filter[meta_value]=acfvalue
Revisa el código fuente del plugin en Github.

¡Buen plugin, pero el ordenamiento por fecha no funciona para campos de fecha de ACF!

Hola Tanckom. Gracias por tu mensaje. ¿Podrías ampliar tu problema? ¿Qué has intentado? Por favor, envía tu problema a https://wordpress.org/support/plugin/wp-rest-filter. Nuestro equipo de soporte te responderá allí. Gracias.

Hola Jack, Descubrí que la URL correcta para obtener la fecha del campo ACF y ordenarla ascendente o descendente es la siguiente: https://domain.com/wp-json/wp/v2/events?filter[meta_key].acf=evt_date&per_page=100&filter[order]=asc

Una sola pregunta, ¿cómo podría filtrar fechas en este formato "2018-09-25 19:30:00 GMT+02:00"? El selector de fecha y hora para ACF no permite formato ISO :( Intenté esto pero sin éxito domain.com/wp-json/wp/v2/events?filter[meta_key].acf=date&[meta_value]=2018-09-25

Convertir a hora GMT, yyyy-mm-dd'T'HH:mm:ss , luego domain.com/wp-json/wp/v2/events?filter[meta_key]=date&[meta_value]=2018-09-25T23:59:59. Creo que ACF guarda los datos en formato IOS en MySQL, así que debería funcionar.

Desafortunadamente, es imposible obtener la Fecha y Hora sin espacios con el plugin Add-on para ACF "Date and Time Picker" :/ Por eso tuve que hacerlo de esta manera.
