Cómo personalizar la clase wpdb y agregar nuevos métodos
Publicado: 2018-07-10La capa de abstracción de la base de datos de WordPress, más conocida como wpdb, es una clase basada en ezSQL responsable de interactuar con la base de datos. La clase wpdb también es un complemento: una parte del código principal de WP que se puede reemplazar fácilmente por otra pieza de código con una funcionalidad similar (una lista actualizada de complementos está disponible en WP Code Reference).
Modificar la clase #wpdb predeterminada no es complicado. Puede agregar, eliminar o modificar fácilmente solo algunos métodos. No es necesario reemplazar toda la clase. #wordpress
HAGA CLIC PARA TUITARAquí es donde entra en juego un gran error. Las personas perciben "reemplazado" como "escribir mi propia clase de base de datos completa". Afortunadamente, no tiene que escribir toda la clase de la base de datos. Puede tomar la clase existente y agregar, eliminar o modificar solo las funciones que necesita. Y eso es lo que vamos a hacer.
¿Por qué modificar la clase wpdb?
¡Seguramente, wpdb tiene todo lo que necesitas!? Todo el WP está construido sobre él. Técnicamente eso es correcto. Usando el $wpdb->query()
puede ejecutar cualquier comando SQL. Pero con esa lógica aplicada, nunca tendríamos ni necesitaríamos métodos como $wpdb->insert()
o $wpdb->get_var()
. Pero lo hacemos, porque ahorran tiempo, reducen los errores y evitan las consultas incorrectas. Entonces, ¿qué funciones faltan? Eso depende del proyecto en el que estés trabajando. Necesitábamos soporte para estas dos consultas:
INSERT IGNORE INTO tbl_name ...
INSERT INTO tbl_name ... ON DUPLICATE KEY UPDATE ...
Paso #1 - Crea el drop-in
El proceso de creación de una base de datos es simple y el resultado final se integra a la perfección en WP.
Cree un archivo llamado db.php
y colóquelo en la carpeta /wp-content/
. Asigne al archivo un encabezado de complemento estándar y cree una clase que amplíe wpdb. Algo como esto:
<?php /* Plugin Name: Extended wpdb Description: A few extra functions for wpdb Version: 1.0 Author: WebFactory Ltd */ class wpdb_extended extends wpdb { public function __construct(){ parent::__construct( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST ); } public function test() { echo 'Extended wpdb is running.'; } } global $wpdb; $wpdb = new wpdb_extended();
El encabezado es bastante autoexplicativo. El método de construcción se asegura de que creemos una nueva conexión de base de datos una vez que se construye un objeto y utiliza el constructor wpdb original para eso. Esas constantes DB se definen en wp-config.php
. Como dijimos al principio, solo estamos agregando algunas funciones y reutilizando todo lo demás. El segundo método test()
es puramente para ver si todo funciona correctamente.
Las dos últimas líneas son cruciales. Dado que esta es una clase personalizada, WP no creará el objeto $wpdb
automáticamente. Tenemos que hacerlo nosotros mismos. Recuerde usar la palabra clave global
porque, de lo contrario, creará una variable local.
Paso n.º 2: pruebe antes de profundizar más
Abra su panel de WP y diríjase a Complementos. Además de las pestañas habituales Todos, Activos e Inactivos (complementos), verá una pestaña Drop-ins y, por arte de magia, nuestra clase de base de datos personalizada.
Dado que el administrador funciona correctamente, sabemos que hicimos un buen trabajo. Nuestra nueva clase ampliada y personalizada ya está aquí y nada ha cambiado. ¡Estupendo! Pero, solo por si acaso, coloque estas tres líneas de código en functions.php
del tema (o en algún lugar dentro de un complemento donde se ejecutará de inmediato):
global $wpdb; $wpdb->test(); die;
Ejecute cualquier página de administrador o de front-end y ¿qué ve? “ Se está ejecutando wpdb extendido. " Perfecto. Ahora para nuestras funciones del mundo real.
Paso #3 – Crear, modificar o reemplazar funciones
La consulta INSERT IGNORE
parece bastante fácil de hacer. Ya tenemos $wpdb->insert() así que solo nos falta una palabra. Desafortunadamente, debido a la falta de filtros en los lugares correctos, no serán dos líneas de código.
Si abre wp-db.php y se dirige al método insert()
en la línea #2100, verá que usa el método _insert_replace_helper()
de la línea #2151. Y esa función no tiene un solo filtro o acción. Tampoco podemos envolver la función porque devuelve inmediatamente el resultado de la consulta y no la consulta en sí misma que podríamos modificar. Gorrón. Tendremos que anular los métodos insert()
y _insert_replace_helper()
. Agregaremos un parámetro adicional: $ignore
. Un valor booleano con el valor predeterminado de false
.
public function insert( $table, $data, $format = null, $ignore = false ) { return $this->_insert_replace_helper( $table, $data, $format, 'INSERT', $ignore = false ); }
En cualquier otra circunstancia, una función que tenga cinco parámetros sería un buen candidato para convertirlos en una matriz asociativa. Pero queremos compatibilidad con versiones anteriores, así que no lo haremos. Los cambios en la otra función también son menores:
function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT', $ignore = false ) { $this->insert_id = 0; if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) { return false; } $data = $this->process_fields( $table, $data, $format ); if ( false === $data ) { return false; } $formats = $values = array(); foreach ( $data as $value ) { if ( is_null( $value['value'] ) ) { $formats[] = 'NULL'; continue; } $formats[] = $value['format']; $values[] = $value['value']; } $fields = '`' . implode( '`, `', array_keys( $data ) ) . '`'; $formats = implode( ', ', $formats ); // modification for IGNORE keyword if (true == $ignore && 'INSERT' == $type) { $type = 'INSERT IGNORE'; } $sql = "$type INTO `$table` ($fields) VALUES ($formats)"; $this->check_current_query = false; return $this->query( $this->prepare( $sql, $values ) ); }
¿Por qué los desarrolladores no hacen esto con más frecuencia?
Si necesita una consulta personalizada solo unas pocas veces, puede usar fácilmente $wpdb->query()
. No hay necesidad de reemplazar la clase predeterminada. También puede escribir una clase personalizada que amplíe la predeterminada pero que no anule el objeto wpdb. En ese caso, usaría $mycustomclass->method()
pero ese no es el fin del mundo.
Además del factor de frescura obvio, extender la clase wpdb predeterminada es algo que debe hacerse en WP y no es un truco, así que siéntase libre de jugar con él. Ten en cuenta dos cosas:
- cuando envíe su proyecto a alguien, no olvide incluir el archivo
db.php
; no va a estar en ninguna carpeta de temas o complementos - Esté atento a los cambios en
wp-db.php
, ya que podrían afectar su clase personalizada (aunque eso es muy poco probable)