Tablas de base de datos personalizadas Exportación de datos

Como se mencionó en el primer artículo de esta serie, uno de los principales problemas con las tablas de bases de datos personalizadas es el hecho de que no están controladas por los controladores de importación y exportación existentes. Este artículo pretende abordar ese problema, pero debe tenerse en cuenta que actualmente no existe una solución completamente satisfactoria..

Consideremos dos escenarios:

  1. La tabla personalizada hace referencia a una tabla nativa de WordPress
  2. La tabla personalizada es completamente independiente de las tablas nativas.

El escenario del "peor caso" es el primero. Tomemos el ejemplo de una tabla personalizada que mantiene registros de la actividad del usuario. Hace referencia al ID de usuario, al ID de objeto y al tipo de objeto, todos los cuales se refieren a datos almacenados en tablas nativas de WordPress. Ahora imagine a alguien que quiera importar todos los datos de su sitio de WordPress a un segundo. Es totalmente posible que al importar una publicación, por ejemplo, WordPress tenga que asignarle una nueva ID, ya que puede que ya exista una publicación con esa ID en el segundo sitio..

En esta situación, sería necesario realizar un seguimiento de dichos cambios y actualizar los ID a los que se hace referencia en nuestra tabla. Esto no es en sí tan difícil.. Desafortunadamente, El complemento de WordPress Importer que maneja la importación de datos de otro sitio de WordPress carece de los ganchos necesarios para hacer esto posible. Como se sugiere en este comentario, una solución alternativa potencial es almacenar los datos en el metadatos posterior. Desafortunadamente, esto se traduce en datos duplicados y se opone a la normalización de la base de datos, por lo general no es una buena idea. Finalmente, solo es realmente viable en una minoría de casos de uso..

El segundo caso evita esta complejidad pero aún requiere controladores personalizados de importación y exportación. Es este caso que vamos a demostrar en los próximos dos artículos. Sin embargo, para mantener la coherencia con el resto de la serie, mantendremos la tabla de registros de actividad aunque sea un ejemplo de caso (1).


Decidir el formato

Primero debemos decidir el formato que debe tomar nuestro archivo de exportación. El mejor formato depende de la naturaleza (o la "estructura") de los datos y de cómo se usará. En mi opinión, XML es generalmente mejor, ya que maneja relaciones de uno a muchos. Sin embargo, a veces, si los datos son tabulares, CSV puede ser preferible, en particular por su facilidad de integración con las aplicaciones de hoja de cálculo. En este ejemplo usaremos XML.


El mark-up

El siguiente paso es crear una página de administración para permitir a los usuarios exportar los datos en la tabla de registro. Crearemos una clase que agregará una página debajo del elemento de menú 'Herramientas'. Esta página contendrá poco más que un botón, y le pedirá al usuario que descargue el archivo de exportación. La clase también agregará un controlador para escuchar el envío del formulario y activar la descarga del archivo.

Primero echemos un vistazo a la estructura de la clase, antes de completar los detalles de sus métodos..

 class WPTuts_Log_Export_Admin_Page / ** * El sufijo de enlace de página * / static $ hook_suffix = "; function static load () add_action ('admin_menu', array (__ CLASS __, 'add_submenu')); add_action ('admin_init', array (__ CLASS__ , 'maybe_download')); función estática add_submenu ()  función estática maybe_download ()  pantalla de función estática ()  WPTuts_Log_Export_Admin_Page :: load ();

los WPTuts_Log_Export_Admin_Page :: load () inicializa la clase y enlaza las devoluciones de llamada a las acciones apropiadas:

  • add_submenu - El método responsable de agregar la página en el menú Herramientas..
  • maybe_download - Este método escuchará si se ha enviado una solicitud de descarga. Esto también verificará permisos y nonces.

Se debe llamar al oyente de exportación desde el principio y antes de que se envíen los encabezados, ya que los estableceremos nosotros mismos. Podríamos engancharlo en en eso, pero como solo permitiremos que el archivo de exportación se descargue en el administrador, admin_init es mas apropiado aqui.

Agregar una página al menú es muy simple. Para agregar una página en Herramientas solo necesitamos llamar add_management_page ().

 función estática add_submenu () self :: $ hook_suffix = add_management_page (__ ('Export Logs', 'wptuts-log'), __ ('Export Logs', 'wptuts-log'), 'manage_options', 'wptuts-export ', array (__ CLASS __,' display ')); 

los $ hook_suffix Aquí está el sufijo usado para varios ganchos específicos de pantalla, discutido aquí. No lo usamos aquí, pero si lo hace, es una buena idea almacenar su valor en una variable, en lugar de codificarla..

En lo anterior hemos establecido el método. monitor() Para ser el callback de nuestra página, definimos esto a continuación:

 pantalla de función estática () echo '
'; screen_icon (); eco '

'. __ ('Exportar registros de actividad', 'wptuts-log'). '

'; ?>

Finalmente, queremos escuchar cuando se envía el formulario anterior y activar la descarga del archivo de exportación.

 función estática maybe_download () / * Escuchar el envío del formulario * / if (empty ($ _ POST ['action']) || 'export-logs'! == $ _POST ['action']) return; / * Compruebe permisos y permisos * / if (! Current_user_can ('manage_options')) wp_die ("); check_admin_referer ('wptuts-export-logs', '_ wplnonce'); / * Trigger download * / wptuts_export_logs ();

Todo lo que queda es crear la función. wptuts_export_logs () que crea y devuelve nuestro archivo .xml.


Creando el archivo de exportación

Lo primero que queremos es que nuestra función sea recuperar los registros. Si hay alguno, tendremos que configurar los encabezados adecuados e imprimirlos en formato XML. Como queremos que el usuario descargue un archivo XML, estableceremos el Tipo de contenido en texto / xml y Contenido-Descripción a Transferencia de archivos. También generaremos un nombre adecuado para el archivo de descarga. Finalmente, incluiremos algunos comentarios: estos son totalmente opcionales, pero pueden ser útiles para instruir al usuario sobre qué hacer con el archivo descargado..

Ya que en la parte anterior de esta serie creamos una API para nuestra tabla, nuestro controlador de exportación no necesita tocar la base de datos directamente, ni tampoco debemos sanear la $ args matriz, ya que esto es manejado por el wptuts_get_logs ().

 función wptuts_export_logs ($ args = array ()) / * Registros de consultas * / $ logs = wptuts_get_logs ($ args); / * Si no hay registros - abortar * / if (! $ Logs) devolver falso; / * Crear un nombre de archivo * / $ sitename = sanitize_key (get_bloginfo ('name')); if (! empty ($ sitename)) $ sitename. = '.'; $ filename = $ nombre de sitio. 'wptuts-logs'. . fecha ('Y-m-d'). '.xml'; / * Imprimir encabezado * / encabezado ('Descripción del contenido: Transferencia de archivos'); header ('Contenido-Disposición: archivo adjunto; nombre_archivo = ". $ filename); header (" Contenido-Tipo: text / xml; charset = ". get_option (" blog_charset'), verdadero); / * Imprimir comentarios * / echo "\ n "; eco"\ n "; eco"\ n "; / * Imprimir los registros * /

Notará que hemos pasado la matriz de consulta real como un argumento para el wptuts_export_logs () función. Podríamos haber codificado esto, pero tiene sentido no hacerlo. Aunque la intención aquí es sólo exportar. todo en la tabla, pasar la consulta como un argumento nos permite agregar más tarde la opción de exportar registros en un determinado período de tiempo, o para un usuario en particular.

Al crear el archivo XML, debemos asegurarnos de que ningún valor impreso entre las etiquetas contenga los caracteres Y, < o >. Para asegurar esto, para las identificaciones desinfectamos los datos con absint, y los tipos de objetos y actividades con sanitize_key (ya que esperamos que solo contengan números alfa en minúsculas, guiones bajos y guiones).

 / * Imprimir los registros en el archivo * / echo ''; foreach ($ registra como $ log) ?>  log_id); ?> fecha_actividad, falso); ?> user_id); ?> object_id); ?> tipo de objeto); ?> actividad); ?>  ';

De manera más general, puede desinfectar los valores que se imprimen envolviéndolos CDATA etiqueta usando la siguiente función:

 / ** * Envuelve la cadena pasada en una etiqueta CDATA XML. * * @param string $ string Cadena para envolver en una etiqueta CDATA XML. * @return string * / function wptuts_wrap_cdata ($ string) if (looks_utf8 ($ string) == falso) $ string = utf8_encode ($ string); regreso '',']]]]>', $ string). ']]>'; 

Finalmente nosotros salida() Para evitar cualquier procesamiento posterior:

 / * Terminado - ahora sale * / exit ();

Navegando a nuestra página de exportación, haga clic en 'Descargar registros de actividad' para solicitar la descarga de un archivo XML.


Resumen

En este tutorial hemos analizado la exportación de datos de nuestra tabla personalizada. Desafortunadamente, donde los datos hacen referencia a tablas nativas de WordPress, esto es, en el mejor de los casos, problemático. El método descrito anteriormente solo es útil para los casos en que los datos no hacen esto. El ejemplo utilizado (nuestros registros de actividad) obviamente no se incluye en esta categoría, sino que se usa simplemente para mantener la coherencia con el resto de esta serie..

Cuando los datos hace Para hacer referencia a las tablas nativas, obviamente es necesario importarlo junto con las tablas nativas y, al hacerlo, realizar un seguimiento de los cambios en los ID que se producen durante la importación. Actualmente, eso no es posible con los controladores de importación y exportación existentes, por lo que la única opción viable es crear la suya propia. En casos más simples en los que los datos personalizados solo hacen referencia a un solo tipo de publicación, es posible diseñar sus controladores de importación y exportación para manejar ese tipo de publicación, así como sus datos personalizados e informar al usuario que no use el exportador nativo para ese tipo de publicación.

En la siguiente parte de esta serie, crearemos un controlador de importación simple para el archivo .xml exportado..