Comme mentionné dans le tout premier article de cette série, l'un des principaux problèmes des tables de base de données personnalisées est le fait qu'elles ne sont pas gérées par les gestionnaires d'importation et d'exportation existants. Cet article vise à résoudre ce problème - mais il convient de noter qu’il n’existe actuellement aucune solution totalement satisfaisante..
Considérons deux scénarios:
Le "pire des cas" est le premier. Prenons l'exemple d'un tableau personnalisé conservant les journaux de l'activité de l'utilisateur. Il fait référence à l'ID utilisateur, à l'ID d'objet et au type d'objet, qui font tous référence aux données stockées dans des tables WordPress natives. Maintenant, imaginons que quelqu'un veuille importer toutes les données de son site WordPress dans un second. Par exemple, il est tout à fait possible que lors de l’importation d’une publication, WordPress lui attribue un nouvel identifiant, puisqu’il existe peut-être déjà une publication portant cet identifiant sur le deuxième site..
Dans ce cas, il serait nécessaire de suivre ces modifications et de mettre à jour les identifiants référencés dans notre tableau. Ce n'est pas si difficile. Malheureusement, le plug-in WordPress Importer, qui gère l'importation de données depuis d'autres sites WordPress, ne dispose pas des points d'ancrage nécessaires pour rendre cela possible. Comme suggéré dans ce commentaire, une solution potentielle consiste à stocker les données également dans post-méta. Malheureusement, cela entraîne des données en double et nuit à la normalisation de la base de données - ce n’est généralement pas une bonne idée. Enfin, il n’est vraiment utilisable que dans une minorité d’utilisations.
Le second cas évite cette complexité mais nécessite toujours des gestionnaires d'importation et d'exportation personnalisés. C'est ce cas que nous allons démontrer dans les deux prochains articles. Cependant, par souci de cohérence avec le reste de la série, nous nous en tiendrons au tableau des journaux d'activité, même s'il s'agit d'un exemple de cas (1)..
Nous devons d’abord décider du format de notre fichier d’exportation. Le meilleur format dépend de la nature (ou de la «structure») des données et de la manière dont elles doivent être utilisées. À mon avis, XML est généralement préférable, car il gère les relations un à plusieurs. Cependant, parfois, si les données sont tabulaires, le format CSV peut être préférable, en particulier pour sa facilité d'intégration avec les applications de tableur. Dans cet exemple, nous utiliserons XML.
L'étape suivante consiste à créer une page d'administration pour permettre aux utilisateurs d'exporter les données de la table de journal. Nous allons créer une classe qui ajoutera une page sous l'élément de menu "Outils". Cette page contiendra un peu plus qu'un bouton, invitant l'utilisateur à télécharger le fichier d'exportation. La classe ajoutera également un gestionnaire pour écouter la soumission du formulaire et déclencher le téléchargement du fichier..
Jetons d'abord un coup d'œil à la structure de la classe, avant de détailler ses méthodes.
class WPTuts_Log_Export_Admin_Page / ** * Le suffixe de crochet de page * / static $ hook_suffix = "; fonction statique load () add_action ('admin_menu', array (__ CLASS __, 'add_submenu'));; add_action ('admin_init', array (__ CLASS__ , 'Maybe_download')); Fonction statique add_submenu () fonction statique Maybe_download () fonction statique display () WPTuts_Log_Export_Admin_Page :: load ();
le WPTuts_Log_Export_Admin_Page :: load ()
initialise la classe et raccroche les rappels aux actions appropriées:
add_submenu
- La méthode responsable de l'ajout de la page dans le menu Outils.peut-être_download
- Cette méthode écoutera pour vérifier si une demande de téléchargement a été soumise. Cela permettra également de vérifier les autorisations et nonces. L'auditeur à l'exportation doit être appelé à un stade précoce et avant l'envoi des en-têtes, car nous les définirons nous-mêmes. Nous pourrions l'accrocher à init
, mais puisque nous autoriserons uniquement le téléchargement du fichier d'exportation dans l'admin, admin_init
est plus approprié ici.
Ajouter une page au menu est très simple. Pour ajouter une page sous Outils, il suffit d'appeler add_management_page ()
.
fonction statique add_submenu () self :: $ hook_suffix = add_management_page (__ ('Export Logs', 'wptuts-log'), __ ('Export Logs', 'wptuts-log'), 'manage_options', 'wptuts-export ', tableau (__ CLASS __,' display '));
le $ hook_suffix
voici le suffixe utilisé pour divers crochets spécifiques à l’écran, discuté ici. Nous ne l'utilisons pas ici - mais si vous le faites, c'est une bonne idée de stocker sa valeur dans une variable plutôt que de la coder en dur..
Dans ce qui précède, nous avons défini la méthode afficher()
pour être le rappel de notre page, nous définissons ceci ensuite:
fonction statique display () echo ''; screen_icon (); écho ''. __ ('Exporter les journaux d'activité', 'wptuts-log'). '
'; ?>Enfin, nous souhaitons savoir quand le formulaire ci-dessus est soumis et déclencher le téléchargement du fichier d'exportation..
static function Maybe_download () / * Écouter la soumission du formulaire * / if (vide ($ _ POST ['action']) || 'export-logs'! == $ _POST ['action']) return; / * Vérifier les autorisations et les droits * / if (! Current_user_can ('manage_options')) wp_die ("); check_admin_referer ('wptuts-export-logs', '_ wplnonce'); / * Téléchargement du déclencheur * / wptuts_export_logs ();Il ne reste plus qu'à créer la fonction
wptuts_export_logs ()
qui crée et retourne notre fichier .xml.
Création du fichier d'exportation
La première chose que nous voulons que notre fonction soit de récupérer les journaux. S'il y en a, nous devrons définir les en-têtes appropriés et les imprimer au format XML. Puisque nous voulons que l’utilisateur télécharge un fichier XML, nous allons définir le type de contenu sur
text / xml
et contenu-description àTransfert de fichier
. Nous allons également générer un nom approprié pour le fichier téléchargé. Enfin, nous ajouterons quelques commentaires - ceux-ci sont entièrement facultatifs, mais peuvent être utiles pour indiquer à l'utilisateur comment utiliser le fichier téléchargé..Comme dans la partie précédente de cette série, nous avons créé une API pour notre table, notre gestionnaire d’exportation n’a pas besoin de toucher directement à la base de données - nous n’avons pas non plus besoin de nettoyer le fichier.
$ args
tableau comme cela est géré par lewptuts_get_logs ()
.fonction wptuts_export_logs ($ args = array ()) / * Journaux de requête * / $ logs = wptuts_get_logs ($ args); / * S'il n'y a pas de journaux - abandonner * / if (! $ Logs) renvoie false; / * Crée un nom de fichier * / $ sitename = sanitize_key (get_bloginfo ('name')); if (! empty ($ sitename)) $ sitename. = '.'; $ filename = $ sitename. 'wptuts-logs.' . date ('Y-m-d'). '.xml'; / * En-tête d'impression * / en-tête ('Description du contenu: transfert de fichier'); en-tête ('Content-Disposition: attachment; nomfichier = ". $ nomfichier); en-tête (" Content-Type: text / xml; charset = ". get_option (" blog_charset'), true); / * Imprimer les commentaires * / echo "\ n "; echo"\ n "; echo"\ n "; / * Imprimer les journaux * /Vous remarquerez que nous avons passé le tableau de requête réel comme argument pour la
wptuts_export_logs ()
une fonction. Nous aurions pu coder cela en dur, mais il est logique de ne pas le faire. Bien que l'intention ici soit simplement d'exporter tout dans la table, passer la requête sous forme d'argument nous permet d'ajouter plus tard l'option d'exportation des journaux dans un laps de temps donné ou pour un utilisateur particulier.Lors de la création du fichier XML, nous devons nous assurer qu'aucune valeur imprimée entre les balises ne contient les caractères.
Et
,<
ou>
. Pour ce faire, nous nettoyons les données avec les IDabsenter
, et les types d'objets et activités avecsanitize_key
(puisque nous nous attendons à ce qu'ils ne contiennent que des caractères alphanumériques minuscules, des caractères de soulignement et des traits d'union)./ * Imprimer les journaux dans un fichier * / echo ''; foreach ($ log en tant que $ log) ?> - ';
log_id); ?> date_activité, faux); ?> identifiant d'utilisateur); ?> object_id); ?> type d'objet); ?> activité); ?> Plus généralement, vous pouvez assainir les valeurs imprimées en les enveloppant à l'intérieur
CDATA
tag en utilisant la fonction suivante:/ ** * Enveloppe la chaîne passée dans une balise XML CDATA. * * @param string $ string Chaîne à insérer dans une balise XML CDATA. * @retour string * / function wptuts_wrap_cdata ($ string) if (semble_utf8 ($ string) == false) $ string = utf8_encode ($ string); revenir '',']]]]>', $ string). ']]>';Enfin nous
sortie()
pour empêcher tout traitement ultérieur:/ * Terminé - quitte maintenant * / exit ();En accédant à notre page d'exportation, cliquez sur "Télécharger les journaux d'activité" pour permettre le téléchargement d'un fichier XML..
Résumé
Dans ce tutoriel, nous avons examiné l’exportation de données à partir de notre tableau personnalisé. Malheureusement, là où les données font référence à des tables WordPress natives, c'est au mieux problématique. La méthode décrite ci-dessus n'est utile que dans les cas où les données ne le font pas. L'exemple utilisé (nos journaux d'activité) n'entre évidemment pas dans cette catégorie, mais sert simplement à la cohérence avec le reste de cette série..
Quand les données Est-ce que référencer les tables natives, il est évidemment nécessaire de l'importer avec les tables natives et, ce faisant, de garder trace de tout changement d'ID intervenu lors de l'importation. Actuellement, ce n'est pas possible avec les gestionnaires d'importation et d'exportation existants - et la seule option réalisable consiste à créer le vôtre. Dans les cas plus simples où les données personnalisées ne font référence qu'à un seul type de publication, il est possible de concevoir vos gestionnaires d'importation et d'exportation pour gérer ce type de publication, ainsi que vos données personnalisées, et d'indiquer à l'utilisateur de ne pas utiliser l'exportateur natif pour ce type de publication..
Dans la prochaine partie de cette série, nous allons créer un simple gestionnaire d'importation pour le fichier .xml exporté..