Recetas de consultas de eventos
Cómo consultar eventos correctamente, reproduciendo lo que hacen los propios listados del plugin.
La regla
Consulta sobre event_start_date y event_end_date. Son valores Y-m-d normalizados que se escriben al guardar, precisamente para que puedan compararse y ordenarse.
Los valores de fecha y hora son para mostrar. Compararlos en una consulta da resultados poco fiables.
Próximos eventos, en orden
Esto es lo que hace el formulario de búsqueda:
$query = new WP_Query( array(
'post_type' => 'event',
'post_status' => 'publish',
'posts_per_page' => 12,
'orderby' => 'event_start_date',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'event_end_date',
'value' => date( 'Y-m-d' ),
'compare' => '>=',
'type' => 'DATE',
),
),
) );
Ten en cuenta que la comparación se hace sobre la fecha de fin: un evento que ha empezado pero no ha terminado sigue contando como próximo.
Eventos pasados
'meta_query' => array(
array(
'key' => 'event_end_date',
'value' => date( 'Y-m-d' ),
'compare' => '<',
'type' => 'DATE',
),
),
'orderby' => 'event_start_date',
'order' => 'DESC',
Los más recientes primero, que es lo que conviene en un listado de eventos pasados.
Eventos que se celebran en una fecha concreta
La lógica del selector de fechas — eventos que empezaron en la fecha o antes y terminan en ella o después, de modo que un evento de varios días se encuentra en cada uno de sus días:
'meta_query' => array(
array(
'key' => 'event_start_date',
'value' => $date,
'compare' => '<=',
'type' => 'DATE',
),
array(
'key' => 'event_end_date',
'value' => $date,
'compare' => '>=',
'type' => 'DATE',
),
),
Eventos de un mes
'meta_query' => array(
array(
'key' => 'event_start_date',
'value' => "$year-$month-01",
'compare' => '>=',
'type' => 'DATE',
),
array(
'key' => 'event_end_date',
'value' => date( 'Y-m-t', strtotime( "$year-$month-01" ) ),
'compare' => '<=',
'type' => 'DATE',
),
),
Filtrar por taxonomía
'tax_query' => array(
array(
'taxonomy' => 'event_category',
'field' => 'slug',
'terms' => array( 'concerts' ),
'include_children' => true,
),
),
Ambas taxonomías de eventos son jerárquicas, así que incluye las subcategorías a menos que quieras deliberadamente solo la categoría principal.
Eventos con plazas disponibles
No existe un valor «restante» almacenado; se deriva del aforo y de las inscripciones. Calcúlalo:
$meta = get_post_meta( $event_id, 'pom', true );
$capacity = (int) ( $meta['available_space'] ?? 0 );
$assistants = get_post_meta( $event_id, 'event_assistants', true ) ?: array();
$unlimited = 0 === $capacity;
$remaining = $unlimited ? null : max( 0, $capacity - count( $assistants ) );
Un aforo de cero significa ilimitado. No intentes expresar «tiene plazas» como una consulta de metadatos.
Eventos en los que está inscrito un usuario
$events = get_user_meta( $user_id, 'attended_events', true ) ?: array();
O, desde el lado del evento, inspecciona su mapa event_assistants, que está indexado por el ID de usuario.
Rendimiento
- No uses
posts_per_page => -1en una página pública. Ambos listados paginan por un motivo. - Las consultas de fechas por metadatos son comparaciones de cadenas sobre valores normalizados, y por eso existen las claves derivadas.
- Contar las inscripciones implica cargar el mapa. Para un listado que muestra la disponibilidad en muchos eventos, espera una lectura de metadatos por evento y guarda el resultado en caché.
Protege siempre el tipo de contenido
if ( ! post_type_exists( 'event' ) ) {
return; // Not the POM theme, or too early.
}