Tablas de bases de datos personalizadas en WordPress: Parte 2
Publicado: 2022-08-01En la primera parte de nuestra serie sobre tablas de base de datos personalizadas en WordPress, vimos cómo puede crear una tabla de base de datos personalizada desde su propio complemento personalizado. En la Parte 2, lo guiaremos a través de cómo puede modificar una tabla personalizada de WordPress, incluida la forma de eliminar la tabla de la base de datos personalizada al eliminar el complemento. Además, explicaremos cómo puede agregar elementos de menú para el complemento en el área de administración, con opciones para ver o agregar entradas en su tabla de datos personalizada.
Cómo eliminar su tabla personalizada al eliminar el complemento
Para eliminar la tabla cuando se elimina el complemento, debemos usar la función register_uninstall_hook()
que proporciona WordPress para configurar el gancho de desinstalación para un complemento.
function uninstall_students_plugin(){ global $wpdb; $table_name = $wpdb->prefix . 'students'; $wpdb->query("DROP TABLE IF EXISTS $table_name"); } register_uninstall_hook(__FILE__,'uninstall_students_plugin');
Si desactiva y elimina el complemento ahora, debería ver que la tabla de "estudiantes" en la base de datos se ha eliminado correctamente.
Elementos y página del menú de administración de la tabla personalizada
En esta sección, le mostraremos cómo agregar una página de administración, junto con sus elementos de menú, para la tabla personalizada "estudiantes".
Elementos del menú de administración
Aquí está el fragmento de código que puede probar: añádalo al archivo PHP del complemento actual:
function students_custom_table_admin_menu() { add_menu_page(__('Students', 'students_custom_table'), __('Students', 'students_custom_table'), 'activate_plugins', 'students', 'students_custom_table_page_handler', 'dashicons-welcome-learn-more', '5'); add_submenu_page('students', __('Students', 'students_custom_table'), __('Students', 'students_custom_table'), 'activate_plugins', 'students', 'students_custom_table_page_handler'); add_submenu_page('students', __('Add new', 'students_custom_table'), __('Add new', 'students_custom_table'), 'activate_plugins', 'students_form', 'students_custom_table_page_handler_add_form'); } add_action('admin_menu', 'students_custom_table_admin_menu');
Ahora, en el área de administración, debería ver algo como esto.
Como era de esperar, verá que no se muestra nada cuando hace clic en cualquiera de los iconos. Definiremos el contenido de la página en la siguiente sección, pero primero, examinemos las líneas de código anteriores para comprender cómo funcionan.
Como queremos crear un elemento de menú de nivel superior y dos subelementos, usamos la función add_menu_page() y add_submenu_page() que proporciona WordPress. Estas funciones aceptan los siguientes argumentos:
add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position )
- Se requiere definir
$page_title
y es básicamente la primera parte de las etiquetas de título de la página a la que es redirigido al seleccionar este elemento del menú. En nuestro caso,students_custom_table
. - El
$menu_title
-también obligatorio- es el texto que se utilizará para el menú. Elegimos “Estudiantes” como texto. -
$capability
es la capacidad requerida para que el usuario muestre este menú. En nuestro caso, elegimos el permisoactivate_plugins
. De forma predeterminada, se otorga solo a los superusuarios y administradores. Si desea comprender qué rol o capacidad se ajusta a sus necesidades, puede consultar la documentación oficial relacionada. - El
$menu_slug
es la cadena de nuestrosstudents
que viene justo después del permiso. También es obligatorio y debe ser único. Solo utiliza caracteres alfanuméricos en minúsculas, guiones y guiones bajos que son compatibles con sanitize_key(). -
$icon_url
es un argumento opcional y es la URL que enlaza con el archivo de icono que se usará para el elemento del menú. Elegimos uno de la biblioteca de WordPress de dashicons. - $posición es donde opcionalmente establece la posición en el orden del menú en el que debe aparecer este elemento.
add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position )
Además de los parámetros que tiene en común con add_menu_page
, también vemos
- El parámetro
$parent_slug
es la cadena requerida para el menú principal, en nuestro caso,students
. - El argumento
$function
es donde define la función de devolución de llamada que creará el contenido de la página de configuración. En nuestro caso, esstudents_custom_table_page_handler()
, para la tabla de visualización de estudiantes, ystudents_custom_table_page_handler_add_form()
, para el formulario que usaremos para agregar estudiantes.
Todavía no hemos declarado estas funciones, pero lo haremos en un tiempo.
Visualización de registros de tablas personalizadas
Comencemos agregando el código que mostrará la tabla de estudiantes en el elemento de menú "Estudiantes".
Para mostrar los datos de las tablas de administración, WordPress amplía la clase integrada WP_List_Table
. La clase WP_List_Table
se presenta como una clase privada en el archivo wp-admin/includes/class-wp-list-table.php. Las clases privadas se denominan privadas porque solo están destinadas a otras clases y funciones principales y no a los desarrolladores.
Sin embargo, WordPress te ofrece la posibilidad de redefinir esta clase ampliándola. Entonces, lo que haremos será crear una clase personalizada, donde redefiniremos las propiedades y métodos de la clase WP_List_Table
, para poder llenar la tabla de administración con los datos que queremos. Llamamos a la clase “Students_Custom_Table_List_Table” y las líneas de código que necesitamos son las siguientes.
if (!class_exists('WP_List_Table')) { require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php'); } class Students_Custom_Table_List_Table extends WP_List_Table { function __construct() { global $status, $page; parent::__construct(array( 'singular' => 'person', 'plural' => 'persons', )); } function column_default($item, $column_name) { return $item[$column_name]; } function column_age($item) { return '<em>' . $item['age'] . '</em>'; } function column_ip($item) { return '<em>' . $item['ip_address'] . '</em>'; } function column_name($item) { $actions = array( 'edit' => sprintf('<a href="?page=students_form&id=%s">%s</a>', $item['id'], __('Edit', 'students_custom_table')), 'delete' => sprintf('<a href="?page=%s&action=delete&id=%s">%s</a>', $_REQUEST['page'], $item['id'], __('Delete', 'students_custom_table')), ); return sprintf('%s %s', $item['name'], $this->row_actions($actions) ); } function column_cb($item) { return sprintf( '<input type="checkbox" name="id[]" value="%s" />', $item['id'] ); } function get_columns() { $columns = array( 'cb' => '<input type="checkbox" />', //Render a checkbox instead of text 'name' => __('Name', 'students_custom_table'), 'email' => __('E-Mail', 'students_custom_table'), 'age' => __('Age', 'students_custom_table'), 'ip_address' => __('IP address', 'students_custom_table'), ); return $columns; } function get_sortable_columns() { $sortable_columns = array( 'name' => array('name', true), 'email' => array('email', false), 'age' => array('age', false), 'ip_address' => array('ip_address', false), ); return $sortable_columns; } function get_bulk_actions() { $actions = array( 'delete' => 'Delete' ); return $actions; } function process_bulk_action() { global $wpdb; $table_name = $wpdb->prefix . 'students'; // do not forget about tables prefix if ('delete' === $this->current_action()) { $ids = isset($_REQUEST['id']) ? $_REQUEST['id'] : array(); if (is_array($ids)) $ids = implode(',', $ids); if (!empty($ids)) { $wpdb->query("DELETE FROM $table_name WHERE id IN($ids)"); } } } function prepare_items() { global $wpdb; $table_name = $wpdb->prefix . 'students'; $per_page = 5; $columns = $this->get_columns(); $hidden = array(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array($columns, $hidden, $sortable); $this->process_bulk_action(); $total_items = $wpdb->get_var("SELECT COUNT(id) FROM $table_name"); $paged = isset($_REQUEST['paged']) ? ($per_page * max(0, intval($_REQUEST['paged']) - 1)) : 0; $orderby = (isset($_REQUEST['orderby']) && in_array($_REQUEST['orderby'], array_keys($this->get_sortable_columns()))) ? $_REQUEST['orderby'] : 'name'; $order = (isset($_REQUEST['order']) && in_array($_REQUEST['order'], array('asc', 'desc'))) ? $_REQUEST['order'] : 'asc'; $this->items = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name ORDER BY $orderby $order LIMIT %d OFFSET %d", $per_page, $paged), ARRAY_A); $this->set_pagination_args(array( 'total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil($total_items / $per_page) )); } }
Si examina el código detenidamente, notará cómo se definen las columnas 'edad' y 'ip_address'. Ahora podemos continuar y también definir la función que finalmente nos dará el contenido de la pantalla de administración "Estudiantes".
function students_custom_table_page_handler() { global $wpdb; $table = new Students_Custom_Table_List_Table(); $table->prepare_items(); $message = ''; if ('delete' === $table->current_action()) { $message = '<div class="updated below-h2"><p>' . sprintf(__('Items deleted: %d', 'students_custom_table'), count($_REQUEST['id'])) . '</p></div>'; } ?> <div class="wrap"> <div class="icon32 icon32-posts-post"><br></div> <h2><?php _e('Students', 'students_custom_table')?> <a class="add-new-h2" href="<?php echo get_admin_url(get_current_blog_id(), 'admin.php?page=students_form');?>"><?php _e('Add new', 'students_custom_table')?></a> </h2> <?php echo $message; ?> <form method="GET"> <input type="hidden" name="page" value="<?php echo $_REQUEST['page'] ?>"/> <?php $table->display() ?> </form> </div> <?php }
En resumen, primero creamos una instancia de la clase personalizada Students_Custom_Table_List_Table
y luego los elementos html que incluirán los datos de la tabla de los estudiantes. Debería poder ver la tabla que se muestra ahora, pero tenga en cuenta que estará vacía.
Ahora que hemos hecho esto, ¡agreguemos algunos estudiantes!
Crear el formulario para agregar nuestros datos personalizados
Como mencionamos anteriormente, la función encargada de agregar estudiantes será students_custom_table_page_handler_add_form()
.
function students_custom_table_page_handler_add_form() { global $wpdb; $table_name = $wpdb->prefix . 'students'; $message = ''; $notice = ''; $default = array( 'id' => 0, 'name' => '', 'email' => '', 'age' => null, 'ip_address' => null, ); if (wp_verify_nonce($_REQUEST['nonce'], basename(__FILE__))) { $item = shortcode_atts($default, $_REQUEST); $result = $wpdb->insert($table_name, $item); $item['id'] = $wpdb->insert_id; if ($result) { $message = __('Item was successfully saved', 'students_custom_table'); } else { $notice = __('There was an error while saving item', 'students_custom_table'); } } add_meta_box('students_form_meta_box', 'Student data', 'students_custom_table_students_form_meta_box_handler', 'student', 'normal', 'default'); ?> <div class="wrap"> <div class="icon32 icon32-posts-post"><br></div> <h2><?php _e('Student', 'students_custom_table')?> <a class="add-new-h2" href="<?php echo get_admin_url(get_current_blog_id(), 'admin.php?page=students');?>"><?php _e('back to list', 'students_custom_table')?></a> </h2> <?php if (!empty($notice)): ?> <div class="error"><p><?php echo $notice ?></p></div> <?php endif;?> <?php if (!empty($message)): ?> <div class="updated"><p><?php echo $message ?></p></div> <?php endif;?> <form method="POST"> <input type="hidden" name="nonce" value="<?php echo wp_create_nonce(basename(__FILE__))?>"/> <input type="hidden" name="id" value="<?php echo $item['id'] ?>"/> <div class="metabox-holder"> <div> <div> <?php do_meta_boxes('student', 'normal', $item); ?> <input type="submit" value="<?php _e('Save', 'students_custom_table')?>" class="button-primary" name="submit"> </div> </div> </div> </form> </div> <?php }
Como puede ver en el código, primero establecemos una matriz $default
que se usará para nuestros nuevos registros.
Luego, después de verificar que la solicitud se haya publicado y tengamos el nonce correcto, usamos shortcode_atts(). Esta es una función incorporada de WordPress muy útil que combina los parámetros proporcionados y completa los valores predeterminados cuando es necesario.
Y finalmente, agregamos nuestro meta box personalizado e insertamos los datos en la tabla personalizada, recibiendo un mensaje que nos informa que el proceso fue exitoso.
A los efectos de este tutorial, omitimos algunos elementos que, si se usan en el mundo real, le gustaría agregar. Estos incluyen la validación de la información agregada a la base de datos haciendo cosas como definir qué sucede si se agrega un nombre o correo electrónico duplicado.
Por último, pero no menos importante, debemos agregar un controlador para nuestro metabox personalizado:
function students_custom_table_students_form_meta_box_handler($item) { ?> <table cellspacing="2" cellpadding="5" class="form-table"> <tbody> <tr class="form-field"> <th valign="top" scope="row"> <label for="name"><?php _e('Name', 'students_custom_table')?></label> </th> <td> <input name="name" type="text" value="<?php echo esc_attr($item['name'])?>" size="50" class="code" placeholder="<?php _e('Your name', 'students_custom_table')?>" required> </td> </tr> <tr class="form-field"> <th valign="top" scope="row"> <label for="email"><?php _e('E-Mail', 'students_custom_table')?></label> </th> <td> <input name="email" type="email" value="<?php echo esc_attr($item['email'])?>" size="50" class="code" placeholder="<?php _e('Your E-Mail', 'students_custom_table')?>" required> </td> </tr> <tr class="form-field"> <th valign="top" scope="row"> <label for="age"><?php _e('Age', 'students_custom_table')?></label> </th> <td> <input name="age" type="number" value="<?php echo esc_attr($item['age'])?>" size="50" class="code" placeholder="<?php _e('Your age', 'students_custom_table')?>" required> </td> </tr> <tr class="form-field"> <th valign="top" scope="row"> <label for="ip_address"><?php _e('IP', 'students_custom_table')?></label> </th> <td> <input name="ip_address" type="number" value="<?php echo esc_attr($item['ip_address'])?>" size="50" class="code" placeholder="<?php _e('Your IP address', 'students_custom_table')?>" required> </td> </tr> </tbody> </table> <?php }
Y eso es. ¡Ahora tenemos un complemento personalizado que nos permite agregar estudiantes, ver la lista de estudiantes o eliminar a un estudiante, y almacenar los datos en una tabla de base de datos personalizada!