Hola @enery88 creo que estás pisando un filtro con el otro. Con el código que tienes gestiona ahí las dos condiciones, comprueba los dos parámetros (podrías comprobar con ! empty
y así compruebas que esté definido el parámetro $_GET
y también que no esté vacío, ni 0, ni null ni false).
Después de comprobar ambos valores (año y mes), según las condiciones recibidas construyes el query adecuado y te funcionará.
En resumen, gestiona ambas condiciones en la misma acción y en el mismo filtro.
Iniciador del debate
Enery88
(@enery88)
Muchas gracias @carloslongarela, otra pregunta relacionado con esto. Crees que para hacer la consulta podré realizar la sentencia en mysql directamente con la función get_results() ? o debería hacerlo con el objeto WP_Query? con el objeto wp_query me refiero a la estructura de argumentos que se suele pasar a get_posts(), por ejemplo, no al objeto como tal, porque se que no hay otra forma de sacar los datos sino es a través de wp-query objeto.
Muchas gracias!!
-
Esta respuesta fue modificada hace 6 años, 4 meses por Enery88.
Hola @enery88 puedes realizar la sentencia perfectamente con get_results()
preferiblemente utiliza $wpdb->prepare por ejemplo:
$values = $wpdb->get_col( $wpdb->prepare(
'SELECT DISTINCT meta_value FROM ' . $wpdb->prefix . 'postmeta WHERE meta_key = %s',
$meta_key_name
) );
En este caso he utilizado get_col() en vez de get_results()
ya que sólo estás devolviendo una columna y no un resultset completo (y get_var()
si es un solo valor en vez de una columna)
Iniciador del debate
Enery88
(@enery88)
Muchísimas gracias @carloslongarela !! 🙂
Iniciador del debate
Enery88
(@enery88)
Hola, @carloslongarela, tengo una duda acerca de la sentencia a la base de datos que tengo que hacer en el código que enseño arriba. Debo abrir nuevo debate o en este puedo hacer la consulta?
Al tratarse de la misma consulta podrías ponerla aquí sin problema.
Iniciador del debate
Enery88
(@enery88)
Gracias @carloslongarela.
Al final he optado por realizar una condicional para hacer una consulta en función de los filtros. Me explico, finalmente he unido los dos selects en la misma función, y las sentencias a la bbdd las he metido juntas en una función así que en vez de tener 4 funciones, ahora tengo dos. Por una parte tengo la función que muestra los selects y por otra parte la que hace las consultas.
La duda que me surge ahora es la consulta a la bbdd de wp cuando me llegan ambos campos year y month. Resulta que en la bbdd directamente si me funciona pero cuando en wp empleo ambos filter, no le gusta demasiado la consulta.
function cpt_posts_filters( $query ){
global $wpdb;
global $pagenow;
$type = 'post';
if(isset($_GET['post_type'])) {
$type = $_GET['post_type'];
}
if( $type == 'cpt' && is_admin() && $pagenow=='edit.php'){
if( (isset($_GET['admin_filter_year']) && $_GET['admin_filter_year'] != '') && (isset($_GET['admin_filter_month']) && $_GET['admin_filter_month'] != '') ){
$query->get_result('SELECT * FROM '.$wpdb->prefix.'posts WHERE EXISTS
(SELECT meta_key FROM '.$wpdb->prefix.'postmeta WHERE '.$wpdb->prefix.'postmeta.post_id='.$wpdb->prefix.'posts.ID AND meta_value='.$_GET['admin_filter_month'].')
AND EXISTS
(SELECT meta_key FROM '.$wpdb->prefix.'postmeta WHERE '.$wpdb->prefix.'postmeta.post_id='.$wpdb->prefix.'posts.ID AND meta_value='.$_GET['admin_filter_year'].')');
}
else if( isset($_GET['admin_filter_year']) && $_GET['admin_filter_year'] != '' ) {
$query->query_vars['meta_key'] = '_year_field';
$query->query_vars['meta_value'] = $_GET['admin_filter_year'];
}
else if( isset($_GET['admin_filter_month']) && $_GET['admin_filter_month'] != '' ){
$query->query_vars['meta_key'] = '_month_field';
$query->query_vars['meta_value'] = $_GET['admin_filter_month'];
}
}
}
add_filter( 'parse_query', 'cpt_posts_filters' );
¿Por qué puede ser?
Hola @enery88 en primer lugar deberías reescribir el código para simplificarlo lo máximo posible y hacerlo compatible con los estándares de WordPress, nunca utilices else if
sino elseif
comprueba el tipo de las variables ===
en lugar de ==
para las sentencias de la BD usa prepare
, escapa/sanitiza las posibles entradas de usuario, utiliza nonces en los datos enviados…
La consulta SQL tiene get_result en lugar de get_results
, además, ¿no puedes simplificar la consulta SQL en una consulta simple sin subconsultas? ¿no la puedes sustituir por un SELECT con LEFT JOIN a postmeta con WHERE meta_value = %s OR meta_value = %? prueba a simplificar la consulta y después depurar mostrando el SQL resultante.
Te pongo tu código con el get_results
y conforme a los estándares de WP aunque sin verificación de nonce ya que los debes crear antes del envío:
function cpt_posts_filters( $query ) {
global $wpdb;
global $pagenow;
$type = 'post';
if ( ! empty( $_GET['post_type'] ) ) {
$type = esc_html( $_GET['post_type'] );
}
if ( 'cpt' === $type && is_admin() && 'edit.php' === $pagenow ) {
if ( ( ! empty( $_GET['admin_filter_year'] ) ) && ( ! empty( $_GET['admin_filter_month'] ) ) ) {
$query->get_results( $wpdb->prepare(
'SELECT * FROM ' . $wpdb->prefix . 'posts
WHERE EXISTS
( SELECT meta_key FROM ' . $wpdb->prefix . 'postmeta
WHERE ' . $wpdb->prefix . 'postmeta.post_id = ' . $wpdb->prefix . 'posts.ID
AND meta_value = %s )
AND EXISTS
( SELECT meta_key FROM ' . $wpdb->prefix . 'postmeta
WHERE ' . $wpdb->prefix . 'postmeta.post_id = ' . $wpdb->prefix . 'posts.ID
AND meta_value = %s )',
array(
$_GET['admin_filter_month'],
$_GET['admin_filter_year'],
)
) );
} elseif ( ! empty ( $_GET['admin_filter_year'] ) ) {
$query->query_vars['meta_key'] = '_year_field';
$query->query_vars['meta_value'] = esc_html( $_GET['admin_filter_year'] );
} elseif ( ! empty ( $_GET['admin_filter_month'] ) ) {
$query->query_vars['meta_key'] = '_month_field';
$query->query_vars['meta_value'] = esc_html( $_GET['admin_filter_month'] );
}
}
}
add_filter( 'parse_query', 'cpt_posts_filters' );
Iniciador del debate
Enery88
(@enery88)
Hola @carloslongarela!!
Al final estue mirandoloque me has comentado y tratando de hacer una query menos compleja pero me ha sido dificil y aun asi no me he funcionado, apesar de todos los consejos que me has dado. asi que he pensado. ¿Crees que podría recoger los resultados de una consulta y dentro de esa condicional introducir una consulta sobre los resultados de la consulta anterior? No se si me explico bien, me refiero a guardar los resultados de busqueda de por ejemplo el filtro year y dentro de esa condicional preguntar por el otro campo que es month, y realizar una consulta con los datos de month sobre los resultados que nos da la consulta sobre el campo year.
Iniciador del debate
Enery88
(@enery88)
Esta es la solución final a la pregunta de la query con dos postmeta en una sola consulta para filtros.
$query->set( 'orderby', 'date' );
$query->set( 'order', 'DESC' );
$meta_query[]= array(
array(
'key' => '_year_field',
'value' => sanitize_text_field( $_GET['admin_filter_year'] ),
'compare' => '='
),
array(
'key' => '_month_field',
'value' => sanitize_text_field( $_GET['admin_filter_month'] ),
'compare' => '='
) );
$query->set( 'meta_query', $meta_query );