<p><img src="https://img.php.cn/upload/article/000/887/227/169364887365792.jpg" alt="Exportation de données : table de base de données personnalisée"></p>
<p>Comme mentionné dans le premier article de cette série, l'un des principaux problèmes des tables de bases de données personnalisées est 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 pleinement satisfaisante. </p>
<p>Considérons deux scénarios : </p>
<ol>
<li>Les tableaux personnalisés font référence aux tableaux WordPress natifs</li>
<li>Les tables personnalisées sont complètement indépendantes des tables natives</li>
</ol>
<p>Le « pire scénario » est le premier scénario. Prenons comme exemple une table personnalisée qui enregistre les journaux d'activité des utilisateurs. Il fait référence à l’ID utilisateur, à l’ID d’objet et au type d’objet, qui font tous référence à des données stockées dans des tables WordPress natives. Imaginez maintenant que quelqu’un souhaite importer toutes les données de son site WordPress vers un deuxième site Web. Par exemple, il est tout à fait possible que lors de l’importation d’une publication, WordPress doive lui attribuer un nouvel identifiant, car une publication avec cet identifiant existe peut-être déjà sur le deuxième site. </p>
<p>Dans ce cas, il est nécessaire de suivre ces modifications et de mettre à jour les identifiants référencés dans le tableau. En soi, ce n’est pas si difficile. <em>Malheureusement</em>, le plugin WordPress Importer pour gérer l'importation de données depuis d'autres sites WordPress ne dispose pas des crochets nécessaires pour y parvenir. Comme suggéré dans ce commentaire, une solution de contournement potentielle consisterait également à stocker les données dans des métadonnées. Malheureusement, cela entraîne des données en double et viole la normalisation de la base de données, ce qui n'est généralement pas une bonne idée. En fin de compte, ce n’est vraiment réalisable que dans quelques cas d’utilisation. </p>
<p>Le deuxième cas évite cette complexité mais nécessite toujours des gestionnaires d'importation et d'exportation personnalisés. Nous démontrerons cette situation dans les deux prochains articles. Cependant, par souci de cohérence avec le reste de cette série, nous nous en tiendrons au tableau du journal d'activité, même s'il s'agit d'un exemple du cas (1). </p>
<hr>
<h2>Décidez du format</h2>
<p>Nous devons d’abord décider du format du fichier exporté. Le meilleur format dépend de la nature (ou « structure ») des données et de la manière dont elles seront utilisées. À mon avis, XML est généralement meilleur car il peut gérer des relations un-à-plusieurs. Cependant, parfois, si les données sont sous forme de tableau, le format CSV peut être préférable, notamment en raison de sa facilité d'intégration avec les tableurs. Dans cet exemple, nous utiliserons XML. </p>
<hr>
<h2>Augmentation des prix</h2>
<p>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. La page contient uniquement un bouton invitant l'utilisateur à télécharger le fichier d'exportation. La classe ajoutera également un gestionnaire pour écouter les soumissions de formulaires et déclencher le téléchargement de fichiers. </p>
<p>Regardons d’abord la structure de la classe, puis complétons les détails de ses méthodes. </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">class WPTuts_Log_Export_Admin_Page{
/**
* The page hook suffix
*/
static $hook_suffix='';
static function load(){
add_action('admin_menu', array(__CLASS__,'add_submenu'));
add_action('admin_init', array(__CLASS__,'maybe_download'));
}
static function add_submenu(){}
static function maybe_download(){}
static function display(){}
}
WPTuts_Log_Export_Admin_Page::load();
</pre><div class="contentsignin">Copier après la connexion</div></div>
<p><code>WPTuts_Log_Export_Admin_Page::load()</code> Initialisez la classe et accrochez les rappels aux opérations appropriées : </p>
<ul>
<li>
<code>add_submenu</code> – Méthode responsable de l’ajout de pages dans le menu Outils. </li>
<li>
<code>maybe_download</code> – Cette méthode écoutera pour vérifier si la demande de téléchargement a été soumise. Cela vérifiera également les autorisations et les noms occasionnels. </li>
</ul>
<p>L'écouteur d'exportation doit être appelé tôt avant l'envoi des en-têtes, car nous définirons ces en-têtes nous-mêmes. On peut le brancher sur <code>init</code> 上,但由于我们只允许在管理中下载导出文件,因此 <code>admin_init</code> ce qui est plus approprié ici. </p>
<p>Ajouter des pages à votre menu est facile. Pour ajouter une page sous Outils, il suffit d'appeler <code>add_management_page()</code>. </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">static function add_submenu(){
self::$hook_suffix = add_management_page( __('Export Logs','wptuts-log'), __('Export Logs','wptuts-log'), 'manage_options', 'wptuts-export', array(__CLASS__,'display') );
}
</pre><div class="contentsignin">Copier après la connexion</div></div>
<p>Le <code>$hook_suffix</code> ici est un suffixe utilisé pour divers crochets spécifiques à l'écran, discutés ici. Nous ne l'utilisons pas ici - mais si vous le faites, il est préférable de stocker sa valeur dans une variable plutôt que de la coder en dur. </p>
<p> Ci-dessus nous définissons la méthode <code>display()</code> comme rappel de notre page, ensuite nous la définissons : </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">static function display(){
echo '<div class="wrap">';
screen_icon();
echo '<h2>' . __( 'Export Activity Logs', 'wptuts-log' ) . '</h2>';
?>
<form id="wptuts-export-log-form" method="post" action="">
<p>
<label><?php _e( 'Click to export the activity logs','wptuts-log' ); ?></label>
<input type="hidden" name="action" value="export-logs" />
</p>
<?php wp_nonce_field('wptuts-export-logs','_wplnonce') ;?>
<?php submit_button( __('Download Activity Logs','wptuts-log'), 'button' ); ?>
</form>
<?php
}
</pre><div class="contentsignin">Copier après la connexion</div></div>
<p>Enfin, nous souhaitons surveiller le moment où le formulaire ci-dessus est soumis et déclencher le téléchargement du fichier d'exportation. </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">static function maybe_download(){
/* Listen for form submission */
if( empty($_POST['action']) || 'export-logs' !== $_POST['action'] )
return;
/* Check permissions and nonces */
if( !current_user_can('manage_options') )
wp_die('');
check_admin_referer( 'wptuts-export-logs','_wplnonce');
/* Trigger download */
wptuts_export_logs();
}
</pre><div class="contentsignin">Copier après la connexion</div></div>
<p>Il ne reste plus qu'à créer la fonction <code>wptuts_export_logs()</code> qui crée et renvoie notre fichier .xml. </p>
<hr>
<h2>Créer un fichier d'exportation</h2>
<p>La première chose que nous voulons que la fonction fasse est de récupérer le journal. Le cas échéant, nous devons définir les en-têtes appropriés et les imprimer au format XML. Puisque nous voulons que l'utilisateur télécharge le fichier XML, nous définissons le Content-Type sur <code>text/xml</code>,将 Content-Description 设置为 <code>File Transfer</code>. Nous générerons également un nom approprié pour le fichier téléchargé. Enfin, nous ajouterons quelques commentaires – ceux-ci sont totalement facultatifs, mais utiles pour guider l’utilisateur sur quoi faire avec le fichier téléchargé. </p>
<p>Depuis que nous avons créé l'API pour la table dans la partie précédente de cette série, notre gestionnaire d'exportation n'a pas besoin de toucher directement la base de données - ni de la nettoyer <code>$args</code> 数组,因为这是由 <code> 处理的wptuts_get_logs()</code>. </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">function wptuts_export_logs( $args = array() ) {
/* Query logs */
$logs = wptuts_get_logs($args);
/* If there are no logs - abort */
if( !$logs )
return false;
/* Create a file name */
$sitename = sanitize_key( get_bloginfo( 'name' ) );
if ( ! empty($sitename) ) $sitename .= '.';
$filename = $sitename . 'wptuts-logs.' . date( 'Y-m-d' ) . '.xml';
/* Print header */
header( 'Content-Description: File Transfer' );
header( 'Content-Disposition: attachment; filename=' . $filename );
header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
/* Print comments */
echo "<!-- This is a export of the wptuts log table -->\n";
echo "<!-- (Demonstration purposes only) -->\n";
echo "<!-- (Optional) Included import steps here... -->\n";
/* Print the logs */
}
</pre><div class="contentsignin">Copier après la connexion</div></div>
<p>您会注意到,我们已将实际查询数组作为参数传递给 <code>wptuts_export_logs()</code> 函数。我们可以对此进行硬编码,但不这样做也是有道理的。虽然这里的目的只是导出表中的<em>所有内容</em>,但将查询作为参数传递允许我们稍后添加在特定时间范围内或针对特定用户导出日志的选项。</ p>
<p>创建 XML 文件时,我们需要确保标签之间打印的值不包含字符 <code>&</code>、<code><</code> 或 <code>></code>。为了确保这一点,对于 ID,我们使用 <code>absint</code> 清理数据,并使用 <code>sanitize_key</code> 清理对象类型和活动(因为我们希望这些仅包含小写字母数字、下划线和连字符)。</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">/* Print logs to file */
echo '<logs>';
foreach ( $logs as $log ) { ?>
<item>
<log_id><?php echo absint($log->log_id); ?></log_id>
<activity_date><?php echo mysql2date( 'Y-m-d H:i:s', $log->activity_date, false ); ?></activity_date>
<user_id><?php echo absint($log->user_id); ?></user_id>
<object_id><?php echo absint($log->object_id); ?></object_id>
<object_type><?php echo sanitize_key($log->object_type); ?></object_type>
<activity><?php echo sanitize_key($log->activity); ?></activity>
</item>
<?php }
echo '</logs>';
</pre><div class="contentsignin">Copier après la connexion</div></div>
<p>更一般地,您可以使用以下函数将要打印的值包装在 <code>CDATA</code> 标记内来清理它们:</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">/**
* Wraps the passed string in a XML CDATA tag.
*
* @param string $string String to wrap in a XML CDATA tag.
* @return string
*/
function wptuts_wrap_cdata( $string ) {
if ( seems_utf8( $string ) == false )
$string = utf8_encode( $string );
return '<![CDATA[' . str_replace( ']]>', ']]]]><![CDATA[>', $string ) . ']]>';
}
</pre><div class="contentsignin">Copier après la connexion</div></div>
<p>最后我们 <code>exit()</code> 以防止任何进一步的处理:</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;"> /* Finished - now exit */
exit();
</pre><div class="contentsignin">Copier après la connexion</div></div>
<p>导航到我们的导出页面,单击“下载活动日志”应提示下载 XML 文件。</p>
<hr>
<h2>摘要</h2>
<p>在本教程中,我们研究了从自定义表中导出数据。不幸的是,当数据引用本机 WordPress 表时,这充其量是有问题的。上述方法仅适用于数据无法做到这一点的情况。使用的示例(我们的活动日志)显然不属于此类,只是为了与本系列的其余部分保持一致而使用。</p>
<p>当数据<em>确实</em>引用本机表时,显然有必要将其与本机表一起导入,并在此过程中跟踪导入期间发生的 ID 任何更改。目前,现有的导入和导出处理程序无法实现这一点,因此唯一可行的选择是创建自己的处理程序。在自定义数据仅引用单个帖子类型的简单情况下,可以设计导入和导出处理程序来处理该帖子类型以及自定义数据,并通知用户不要使用该帖子类型的本机导出器。
</p>
<p>在本系列的下一部分中,我们将为导出的 .xml 文件创建一个简单的导入处理程序。</p>
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!