✅ Noticias, temas, complementos de WEB y WordPress. Aquí compartimos consejos y las mejores soluciones para sitios web.

Consultas de WordPress con cláusulas IN (¿Quién sabía)?

23

Hace poco más de un año, escribí una publicación sobre cómo usar WP_Meta_Query siempre que tenga un conjunto de claves que quiera usar para ayudar a recuperar información de la base de datos.

Sin embargo, ¿qué pasa con el caso, cuando tiene varias claves diferentes que darían como resultado la creación de una matriz realmente larga para la clase WP_Meta_Query? Por ejemplo, ¿qué pasaría si tuviera que recorrer una colección de datos incluso antes de configurar la consulta?

En algún nivel, podría parecer que lo más natural sería:

  1. iterar a través de la colección de claves,
  2. construir dinámicamente los resultados,
  3. combinarlos en un único conjunto de resultados,
  4. luego trabaja con lo que te den.

¿Pero no suena un poco engorroso (y mucho menos lento)?

Cuando se trata de usar la API de WordPress, hago lo que puedo para ceñirme a ella antes de hablar, por ejemplo, directamente con la base de datos, pero también hay momentos en los que tiene sentido escribir una consulta sin formato que escribir algún tipo de código inteligente simplemente para que la API de WordPress funcione.

Antes de entrar en la justificación de por qué hice las cosas que hice, quiero explicar el problema y el enfoque. Es probable que esto evite que alguien salte a los comentarios prematuramente.

Esta captura de pantalla no tiene nada que ver con la consulta. Solo una foto del IDE por diversión.

Así que aquí va:

  • Tengo una matriz estándar de valores que eventualmente se usan para ayudar a tomar metadatos y crear un tipo de publicación personalizado a partir de ellos (porque se han importado de una fuente de terceros).
  • Soy un gran defensor de la parametrización de consultas (y, por lo tanto, del uso de la preparación) para asegurarme de que los datos se consultan correctamente en la base de datos. Desafortunadamente, esto no sucedía al intentar ejecutar esta consulta. Explicaré por qué más adelante en este post.
  • Por lo tanto, tomar la matriz y convertirla en una cadena es útil, pero aún no resuelve el problema de por qué la  función de preparación estándar no funcionaba.

Dicho esto, voy a explicar algunas cosas:

  1. por qué opté por usar una matriz para almacenar valores de metadatos,
  2. por qué he usado  la implosión para convertirlos en una cadena,
  3. por qué no estoy usando preparar para manejar la consulta.

Sobre valores de metadatos

La razón para mantener los metadatos en una matriz como una propiedad de la clase es que esta matriz puede cambiar con el tiempo.

Es decir, es posible que necesitemos importar datos de terceros adicionales, eliminar datos de terceros o hacer algunas modificaciones a lo que esté presente.

Cuando estos datos se guardan en un solo lugar, es mucho más fácil administrarlos para futuras versiones del código.

implosión de la matriz

Cada vez que ejecuta una consulta en la base de datos y tiene que trabajar con una matriz de datos, puede usar WP_Meta_Query y usar cada clave como parte de la matriz de argumentos.

Pero si tiene un conjunto de datos relativamente grande, primero debe recorrerlos todos, luego debe crear la consulta y luego debe procesarla.

Y una vez que haya hecho todo eso, no estoy convencido de que el código que se escribió no haya sido a expensas del rendimiento. Es por eso que, a veces, opto por usar wpdb.

No usar preparar

Ahora, cuando interactúo directamente con la base de datos, trato de asegurarme de que:

  1. Tengo una buena razón para hacerlo,
  2. Estoy usando consultas parametrizadas.

Pero he estado trabajando con este conjunto específico de datos por un tiempo tratando de usar cada permutación del desarrollo de WordPress que conozco (incluyendo hablar con varios compañeros al respecto) para tratar de hacer que esto funcione de la mejor manera posible.

Sin embargo, no estaba sucediendo. Y fue entonces cuando me topé con la siguiente página en el Codex :

En el 99% de los casos, puede usar $wpdb->prepare() en su lugar, y ese es el método recomendado. Esta función solo se usa en aquellos casos excepcionales en los que no puede usar fácilmente $wpdb->prepare(). Un ejemplo es preparar una matriz para usarla en una cláusula IN.

Y eso es exactamente lo que estaba tratando de hacer: estaba buscando buscar en la tabla de metadatos de la publicación donde los valores clave de la metadatos estaban contenidos en una matriz.

Así que así es como resolví todo esto.

Primero, creé una matriz para contener las diversas claves meta que sé que eventualmente necesitaré mapear (aunque el valor de las claves no importa para el propósito de esta publicación):

<?php

// This is used to maintain a map of data should we need to add more.
$data_types = [
    'data_item_one',
    'data_item_two',
    '...'
    'data_item_ten,
];

Luego los convertí a una cadena lista para MySQL. Por supuesto, esto no es una entrada del usuario y se está usando en una  cláusula IN, por lo que no se puede usar en una  declaración de preparación :

<?php

/**
 * Converts the incoming array into a comma-delimited string with
 * quotes wrapped around each key.
 *
 * @access private
 *
 * @param  array $arr The array to convert to a string.
 * @return string     The string representation of the array delimited by quotes and commas.
 */
private function convert_to_sql_ready_string( $arr) {
  return '"'. implode( $arr, '","' ). '"';
}

Finalmente, creé la consulta y recuperé los resultados:

<?php

public function get_data_values() {

  global $wpdb;
  $query = "
    SELECT post_id, meta_key, meta_value 
    FROM $wpdb->postmeta WHERE
    meta_key in ($this->data_types) AND 
    meta_value <> '';
  ";

  $results = $wpdb->get_results( $query );

  return $results;
}

Y así es como terminé trabajando con las matrices, la propiedad de clase y configurando mi consulta.

¿Es esta la mejor manera de trabajar con consultas de WordPress con cláusulas IN? No estoy seguro, pero dada mi experiencia, lo que he leído y cómo funciona, estoy contento con el resultado final.

Fuente de grabación: tommcfarlin.com

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More