Los plugins WordPress que se limpian a sí mismos son oro puro. Si estás desarrollando un plugin que añada algún tipo de dato a la base de datos de WordPress es importante que el plugin elimine cualquier dato sin uso o indeseado cuando se desinstale el plugin.
Esta guía explica técnicas útiles para hacerlo usando el potencial del archivo uninstall.php
.
Índice de contenidos
Cómo funciona uninstall.php
Básicamente es añadir un archivo llamado uninstall.php
al directorio principal (raíz) del plugin.
Por ejemplo, digamos que tienes un plugin llamado «Optimizar WordPress±, y que el directori principal es /optimizar-wordpress/
. Dentro de ese directorio es donde añadiremos el archivo uninstall.php
tal que así:
/optimizar-wordpress/ /optimizar-wordpress.php /index.php /uninstall.php <--- aquí está /readme.txt
A partir de ahora, cuando el plugin se desinstale (elimine) desde la pantalla de plugins del área de administración de WordPress, WordPress encontrará y ejecutará el archivo uninstall.php
.
Este archivo es el que hará posible que el desarrollador del plugin (tú) limpie cualquier dato innecesario o indeseado de la base de datos.
En resumen así es como funciona. Los detalles completos están en el Codex de WordPress.
Qué hay dentro del archivo uninstall.php
El archivo uninstall.php
puede incluir cualquier código que sea necesario para gestionar la limpieza correcta y rutinas de desinstalación del plugin.
Al principio del mismo hay que incluir siempre la protección frente a accesos indeseados. Se hace así:
<?php if (!defined('WP_UNINSTALL_PLUGIN')) exit; // exit si no existe la constante uninstall
Esas líneas deben estar al principio del archivo uninstall.php
, antes de cualquier otro código.
Este código comprueba la constante WP_UNINSTALL_PLUGIN
, que está definida por WordPress justo antes de cargar uninstall.php
. Así que si algo que no sea WordPress trata de acceder al archivo el script se finalizará de inmediato.
Para que te hagas una idea más clara, aquí tienes un ejemplo de archivo uninstall.php
que elimina varios tipos de datos. Observa que la mayoría del código no está, para que lo veas más claro.
<?php if (!defined('WP_UNINSTALL_PLUGIN')) exit; // exit si no está definida la constante uninstall // eliminar opciones del plugin // eliminar transients del plugin // eliminar eventos cron del plugin // ..etc., basado en lo que haya que eliminar
Por tanto, las técnicas de código que se añadan al archivo uninstall dependerá de los datos que haya que eliminar o modificar.
Variarán según el plugin, así que tendrás que saber exactamente qué datos tienen que eliminarse antes de añadir la técnica adecuada. En las siguientes secciones de esta guía veremos técnicas para quitar todo tipo de datos de la base de datos de WordPress
Importante: Añade únicamente las técnicas que sean necesarias, no todas. Tienes que ser cuidadoso y aplicar solo lo imprescindible
Borrar las opciones del plugin
Probablemente, la técnica de desinstalación más común es la de borrar las opciones del plugin, usando la función de WordPress delete_option(). Por ejemplo, para borrar la opción llamda miplugin_options
, añade esto a uninstall.php
:
// borrar opciones del plugin delete_option('miplugin_options');
Si hay que borrar varias opciones lo haremos con un array:
// borrar varias opciones $options = array( 'miplugin_option_1', 'miplugin_option_2', 'miplugin_option_3', ); foreach ($options as $option) { if (get_option($option)) delete_option($option); }
Para usar este código, lógicamente, renombra los elementos del array (p.ej., miplugin_option_1
) con los nombres de las opciones de tu plugin que quieras borrar.
Truco Pro: Si estás usando las opciones del plugin para cualquier otra técnica de desinstalación NO borres las opciones hasta que hayas terminado de usarlas.
Borrar transients del plugin
Otra técnica habitual es eliminar los datos transitorios (transients) del plugin de la base de datos. Para hacerlo usaremos la función delete_transient():
// borrar transient del plugin delete_transient('miplugin_transient');
De nuevo, si tenemos varios transients, tiramos de array:
// borrar varios transients $transients = array( 'miplugin_transient_1', 'miplugin_transient_2', 'miplugin_transient_3', ); foreach ($transients as $transient) { delete_transient($transient); }
Acuérdate de que el código es un ejemplo, tienes que poner los nombres de tus transients.
Borrar eventos Cron
La siguiente técnica es para cuando tengas que borrar eventos cron, y usaremos la función wp_unschedule_event(). Aquí el ejemplo:
// borrar evento cron $timestamp = wp_next_scheduled('miplugin_cron_event'); wp_unschedule_event($timestamp, 'miplugin_cron_event');
El truco está en usar wp_next_scheduled() para obtener el valor correcto del $timestamp
del transient que quieras borrar.
Borrar tablas de la base de datos
Este es fundamental. Tienes que ser precavido con esta técnica. Asegúrate de que el nombre de la tabla sea el correcto. Aquí tienes un ejemplo en el que borraremos la tabla miplugin_table
:
// borrar tabla de la base de datos global $wpdb; $table_name = $wpdb->prefix .'miplugin_table'; $wpdb->query("DROP TABLE IF EXISTS {$table_name}");
Esta técnica utiliza la clase wpdb para definir la $table_name
y luego borrar (drop) la tabla, si existe.
Más que nunca, es importante que recuerdes que el ejemplo usa nombres de ejemplo, en este caso miplugin_table
, que deberás sustituir por el nombre de tu tabla. Siento ser tan pesado pero es vital.
Borrar entradas y páginas
Para borrar entradas y páginas que hayamos creado desde nuestro plugin usaremos wp_trash_post(). Por ejemplo, para borrar un contenido con el ID 67
:
// borrar post con id 67 wp_trash_post(67);
El truco de esta técnica es determinar el ID correcto de la entrada/página.
Hay varias maneras de hacerlo, y probablemente la más fácil es grabar el ID de cualquier entrada o página creada por tu plugin.
Por ejemplo, si tu plugin añade 3 páginas cuando se activa por primera vez, podrías añadir los IDs de esas páginas a la base de datos como una opción.
De este modo puedes revisar las opciones para obtener los IDs correctos que tienes que borrar. Se haría así:
// borrar páginas $miplugin_pages = get_option('miplugin_pages'); if (is_array($miplugin_pages) && !empty($miplugin_pages)) { foreach ($miplugin_pages as $miplugin_page) { wp_trash_post($miplugin_page); } }
Como ves, hemos usado get_option()
para obtener el array de los IDs de las páginas. Luego vamos al array y usamos wp_trash_post()
para borrarlas.
Se puede usar la misma técnica para borrar entradas o páginas.
Importante: Solo debes borrar entradas y páginas si estás totalmente seguro de que el usuario no las querrá. Un modo de controlar esto es mediante una opción en los ajustes del plugin, en la que preguntarás al usuario qué entradas y/o páginas quiere borrar si desinstala el plugin.
Borrar tipos de contenido personalizados (CPTs)
Con esto me refiero a borrar ciertas entradas definidas como CPT, no a borrar en sí el CPT, que quede claro.
Para hacerlo usaremos la función wp_delete_post(). Y este sería un ejemplo de cómo borraríamos todas las entradas del CPT miplugin_cpt
.
// borrar entradas del cpt $miplugin_cpt_args = array('post_type' => 'miplugin_cpt', 'posts_per_page' => -1); $miplugin_cpt_posts = get_posts($miplugin_cpt_args); foreach ($miplugin_cpt_posts as $post) { wp_delete_post($post->ID, false); }
Como ves, hemos usado get_posts() para obtener las entradas del CPT miplugin_cpt
. Luego hacemos loop en los resultados y usamos wp_delete_post()
para borrar las entradas del CPT.
Lo único que tienes que cambiar es el nombre (slug) del CPT, en el ejemplo miplugin_cpt
.
Y, de nuevo, recuerda asegurarte de que el usuario realmente quiera que se borren las entradas del CPT. Nunca está de más preguntar en una opción de los ajustes del plugin.
Nota: La técnica anterior usawp_delete_post()
para borrar las entradas del CPT. Entiende que esta función también borra todo lo que esté asociado a las entradas: comentarios, campos meta, términos, etc.
Nota: El segundo parámetro de la funciónwp_delete_post()
está establecido afalse
. Eso le dice a WordPress que envíe las entradas a la papelera, donde el usuario podrá más tarde borrarlas (o restaurarlas). Si prefieres borrarlas del todo cambia el parámetro atrue
.
Borrar user meta
Para borrar los metadatos de usuario vamos a utilizar la función delete_user_meta(). En el ejemplo vamos a borrar todos los metadatos de usuario de miplugin_user_meta
, sería así:
// borrar user meta $users = get_users(); foreach ($users as $user) { delete_user_meta($user->ID, 'miplugin_user_meta'); }
Como ves, usamos get_users() para obtener el array de todos los usuarios. Luego vamos al array y usamos delete_user_meta
para borrar todos los metadatos de miplugin_user_meta
. Soy muy pesado, lo sé, pero recuerda cambiar el nombre miplugin_user_meta
por los metadatos que TÚ quieras borrar.
Nota: La técnica anterior borra los metadatos de todos los usuarios. Si solo quieres seleccionar una serie de usuarios puedes hacerlo pasando un array array de argumentos aget_users()
. Tienes toda la información en WP_User_Query::prepare_query().
Borrar post meta
Si tu plugin añade algún metadato a las entradas puedes eliminarlo usando delete_post_meta(). Este sería un ejemplo de cómo eliminar los post meta llamados miplugin_post_meta
.
// borrar post meta $miplugin_post_args = array('posts_per_page' => -1); $miplugin_posts = get_posts($miplugin_post_args); foreach ($miplugin_posts as $post) { delete_post_meta($post->ID, 'miplugin_post_meta'); }
De nuevo, usamos get_posts() para obtener todas las entradas. Luego vamos a las entradas y borramos todos los datos meta llamados miplugin_post_meta
. ¿Te he dicho ya que siempre cambies los nombres de los ejemplos por los tuyos? ¿ah sí?, pues entonces no te lo digo más veces (creo).
Limitar el borrado de metas a un CPT
Un truco adicional para eliminar post meta, si quieres borrarlos solo de un CPT concreto, es reemplazar el valor de $miplugin_post_args
en el código anterior por lo siguiente:
array('post_type' => 'miplugin_cpt', 'posts_per_page' => -1);
Así, añadimos el parámetro post_type
para get_posts()
. Recuerda, cambia el nombre … ah, perdona, ya lo sabes.
Método alternativo usando delete_metadata()
Un modo alternativo, y equivalente, de eliminar todos los meta es usar la función delete_metadata(). Lo más chulo de este método oes que esta función se puede usar para borrar todos los meta de comentarios, entradas, términos o usuarios.
El ejemplo de rigor, borrando todos los post meta llamados miplugin_meta_key
:
// borrar post meta delete_metadata('post', 0, 'miplugin_meta_key', '', true);
Esta técnica usa varios parámetros. Son cinco:
- $meta_type — Tipo de objeto (entrada, comentario, término o usuario)
- $object_id — ID del objeto o
0
para todos - $meta_key — Nombre de los meta datos
- $meta_value — Valor de los meta datos
- $delete_all — Borrar todos los meta datos
Por tanto, para la técnica de arriba, pasaremos los siguientes argumentos de estos cinco parámetros:
- post — Queremos seleccionar objetos de entradas
- 0 — Usamos cero para seleccionar todas las entradas
- miplugin_meta_key — El nombre de nuestros metadatos
- (empty) — Déjar en blanco para seleccionar tod
- true — Importante establecer a true para borrar todos los resultados
Como puedes imaginar, delete_metadata()
es flexible y potente, y permite el borrado de cualquier metadato que exista en la base de datos de WordPress.
Archivo uninstall.php de ejemplo completo
Bueno, ya está casi completo. Este código a continuación incluye la mayoría de los ejemplos que hemos visto en la guía. No incluye todos, solo un fragmento de cada técnica. Las técnicas avanzadas o alternativas no están incluidas.
<?php /* Archivo uninstall.php de ejemplo */ // salir si la constante uninstall no está definida if (!defined('WP_UNINSTALL_PLUGIN')) exit; // borrar opciones del plugin delete_option('miplugin_options'); // borrar transient del plugin delete_transient('miplugin_transient'); // borrar evento cron $timestamp = wp_next_scheduled('miplugin_cron_event'); wp_unschedule_event($timestamp, 'miplugin_cron_event'); // borrar tabla de la base de datos global $wpdb; $table_name = $wpdb->prefix .'miplugin_table'; $wpdb->query("DROP TABLE IF EXISTS {$table_name}"); // borrar páginas $miplugin_pages = get_option('miplugin_pages'); if (is_array($miplugin_pages) && !empty($miplugin_pages)) { foreach ($miplugin_pages as $miplugin_page) { wp_trash_post($miplugin_page); } } // borrar entradas de cpt $miplugin_cpt_args = array('post_type' => 'miplugin_cpt', 'posts_per_page' => -1); $miplugin_cpt_posts = get_posts($miplugin_cpt_args); foreach ($miplugin_cpt_posts as $post) { wp_delete_post($post->ID, false); } // borrar user meta $users = get_users(); foreach ($users as $user) { delete_user_meta($user->ID, 'miplugin_user_meta'); } // borrar post meta $miplugin_post_args = array('posts_per_page' => -1); $miplugin_posts = get_posts($miplugin_post_args); foreach ($miplugin_posts as $post) { delete_post_meta($post->ID, 'miplugin_post_meta'); }
Solo tendrías que añadir este código a tu archivo uninstall.php
vacío, por supuesto cambiando todos los nombres por los de tu plugin, y solo las técnicas que necesites
Advertencias finales
Siendo tan útil como es un archivo uninstall.php
, es importante ser muy precavido a la hora de borrar cualquier dato de la base de datos.
Por ejemplo, en al gunos casos, los usuarios pueden desinstalar accidentalmente o temporalmente un plugin. Con lo que todo lo que el usuario haya configurado del plugin se perdería.
Para ayudar a evitar este tipo de accidentes puede ser una buena idea ofrecer la opción y preguntar a los usuarios qué quieren eliminar cuando se desinstale el plugin.
Un buen ejemplo sería una casilla obligatoria en el archivo uninstall.php
, antes de que se elimine ningún dato. Sería algo tan simple como añadir esta línea:
if (!get_option('plugin_do_uninstall', false)) exit;
De ese modo puedes comprobar si el usuario realmente quiere eliminar los datos cuando se desinstale el plugin.
Conclusión: Es tú responsabilidad como desarrollador de plugins asegurarte de que se eliminen y/o restauren los datos adecuados cuando se desinstale tu plugin. Un archivo
uninstall.php
es un modo sencillo y fiable de conseguirlo.
¿Te gustó este artículo? ¡Ni te imaginas lo que te estás perdiendo en YouTube!
Felicitaciones Fernando por el articulo super completo y muy bien explicado. gracias
Muchas gracias