问题最终出在WordPress导入器插件上。我可以对此进行破解(并向开发人员提出了改进建议),但我将通过编写自己的自定义导入程序来解决这个问题。这不是最方便的(重新上传.XML文件),但如果用户有复杂的菜单,这总比丢失元数据好。
它需要更多的测试,但我应该在下一个版本中将它添加到我的插件中。
Custom Importer for Menu Item Meta
问题最终出在WordPress导入器插件上。我可以对此进行破解(并向开发人员提出了改进建议),但我将通过编写自己的自定义导入程序来解决这个问题。这不是最方便的(重新上传.XML文件),但如果用户有复杂的菜单,这总比丢失元数据好。
它需要更多的测试,但我应该在下一个版本中将它添加到我的插件中。
Custom Importer for Menu Item Meta
<?php
/**
* Nav Menu Roles Importer - import menu item meta
*
*/
if ( ! defined( \'ABSPATH\' ) ) exit; // Exit if accessed directly
if ( class_exists( \'WP_Importer\' ) ) {
class Nav_Menu_Roles_Import extends WP_Importer {
var $max_wxr_version = 1.2; // max. supported WXR version
var $id; // WXR attachment ID
// information to import from WXR file
var $version;
var $posts = array();
var $base_url = \'\';
/**
* __construct function.
*
* @access public
* @return void
*/
public function __construct() {
$this->import_page = \'nav_menu_roles\';
}
/**
* Registered callback function for the WordPress Importer
*
* Manages the three separate stages of the WXR import process
*/
function dispatch() {
$this->header();
$step = empty( $_GET[\'step\'] ) ? 0 : (int) $_GET[\'step\'];
switch ( $step ) {
case 0:
$this->greet();
break;
case 1:
check_admin_referer( \'import-upload\' );
if ( $this->handle_upload() ) {
$file = get_attached_file( $this->id );
set_time_limit(0);
$this->import( $file );
}
break;
}
$this->footer();
}
/**
* The main controller for the actual import stage.
*
* @param string $file Path to the WXR file for importing
*/
function import( $file ) {
add_filter( \'import_post_meta_key\', array( $this, \'is_valid_meta_key\' ) );
add_filter( \'http_request_timeout\', array( &$this, \'bump_request_timeout\' ) );
$this->import_start( $file );
wp_suspend_cache_invalidation( true );
$this->process_nav_menu_meta();
wp_suspend_cache_invalidation( false );
$this->import_end();
}
/**
* Parses the WXR file and prepares us for the task of processing parsed data
*
* @param string $file Path to the WXR file for importing
*/
function import_start( $file ) {
if ( ! is_file($file) ) {
echo \'<p><strong>\' . __( \'Sorry, there has been an error.\', \'nav-menu-roles\' ) . \'</strong><br />\';
echo __( \'The file does not exist, please try again.\', \'nav-menu-roles\' ) . \'</p>\';
$this->footer();
die();
}
$import_data = $this->parse( $file );
if ( is_wp_error( $import_data ) ) {
echo \'<p><strong>\' . __( \'Sorry, there has been an error.\', \'nav-menu-roles\' ) . \'</strong><br />\';
echo esc_html( $import_data->get_error_message() ) . \'</p>\';
$this->footer();
die();
}
$this->version = $import_data[\'version\'];
$this->posts = $import_data[\'posts\'];
$this->base_url = esc_url( $import_data[\'base_url\'] );
wp_defer_term_counting( true );
wp_defer_comment_counting( true );
do_action( \'import_start\' );
}
/**
* Performs post-import cleanup of files and the cache
*/
function import_end() {
wp_import_cleanup( $this->id );
wp_cache_flush();
foreach ( get_taxonomies() as $tax ) {
delete_option( "{$tax}_children" );
_get_term_hierarchy( $tax );
}
wp_defer_term_counting( false );
wp_defer_comment_counting( false );
echo \'<p>\' . __( \'All done.\', \'nav-menu-roles\' ) . \' <a href="\' . admin_url() . \'">\' . __( \'Have fun!\', \'nav-menu-roles\' ) . \'</a>\' . \'</p>\';
do_action( \'import_end\' );
}
/**
* Handles the WXR upload and initial parsing of the file to prepare for
* displaying author import options
*
* @return bool False if error uploading or invalid file, true otherwise
*/
function handle_upload() {
$file = wp_import_handle_upload();
if ( isset( $file[\'error\'] ) ) {
echo \'<p><strong>\' . __( \'Sorry, there has been an error.\', \'nav-menu-roles\' ) . \'</strong><br />\';
echo esc_html( $file[\'error\'] ) . \'</p>\';
return false;
} else if ( ! file_exists( $file[\'file\'] ) ) {
echo \'<p><strong>\' . __( \'Sorry, there has been an error.\', \'nav-menu-roles\' ) . \'</strong><br />\';
printf( __( \'The export file could not be found at <code>%s</code>. It is likely that this was caused by a permissions problem.\', \'nav-menu-roles\' ), esc_html( $file[\'file\'] ) );
echo \'</p>\';
return false;
}
$this->id = (int) $file[\'id\'];
$import_data = $this->parse( $file[\'file\'] );
if ( is_wp_error( $import_data ) ) {
echo \'<p><strong>\' . __( \'Sorry, there has been an error.\', \'nav-menu-roles\' ) . \'</strong><br />\';
echo esc_html( $import_data->get_error_message() ) . \'</p>\';
return false;
}
$this->version = $import_data[\'version\'];
if ( $this->version > $this->max_wxr_version ) {
echo \'<div class="error"><p><strong>\';
printf( __( \'This WXR file (version %s) may not be supported by this version of the importer. Please consider updating.\', \'nav-menu-roles\' ), esc_html($import_data[\'version\']) );
echo \'</strong></p></div>\';
}
return true;
}
/**
* Create new posts based on import information
*
* Posts marked as having a parent which doesn\'t exist will become top level items.
* Doesn\'t create a new post if: the post type doesn\'t exist, the given post ID
* is already noted as imported or a post with the same title and date already exists.
* Note that new/updated terms, comments and meta are imported for the last of the above.
*/
function process_nav_menu_meta() {
foreach ( $this->posts as $post ) {
// we only want to deal with the nav_menu_item posts
if ( \'nav_menu_item\' != $post[\'post_type\'] || ! empty( $post[\'post_id\'] ) )
continue;
// ok we\'ve got a nav_menu_item
$post_id = (int) $post[\'post_id\'];
// add/update post meta
if ( isset( $post[\'postmeta\'] ) ) {
foreach ( $post[\'postmeta\'] as $meta ) {
$key = apply_filters( \'import_post_meta_key\', $meta[\'key\'] );
$value = false;
if ( $key ) {
// export gets meta straight from the DB so could have a serialized string
if ( ! $value )
$value = maybe_unserialize( $meta[\'value\'] );
update_post_meta( $post_id, $key, $value );
do_action( \'import_post_meta\', $post_id, $key, $value );
}
}
}
}
unset( $this->posts );
}
/**
* Parse a WXR file
*
* @param string $file Path to WXR file for parsing
* @return array Information gathered from the WXR file
*/
function parse( $file ) {
$parser = new WXR_Parser();
return $parser->parse( $file );
}
// Display import page title
function header() {
echo \'<div class="wrap">\';
screen_icon();
echo \'<h2>\' . __( \'Import Nav Menu Roles\', \'nav-menu-roles\' ) . \'</h2>\';
$updates = get_plugin_updates();
$basename = plugin_basename(__FILE__);
if ( isset( $updates[$basename] ) ) {
$update = $updates[$basename];
echo \'<div class="error"><p><strong>\';
printf( __( \'A new version of this importer is available. Please update to version %s to ensure compatibility with newer export files.\', \'nav-menu-roles\' ), $update->update->new_version );
echo \'</strong></p></div>\';
}
}
// Close div.wrap
function footer() {
echo \'</div>\';
}
/**
* Display introductory text and file upload form
*/
function greet() {
echo \'<div class="narrow">\';
echo \'<p>\'.__( \'Re-Upload your normal WordPress eXtended RSS (WXR) file and we’ll import the Nav Menu Roles and any other missing post meta for the Nav Menu items.\', \'nav-menu-roles\' ).\'</p>\';
echo \'<p>\'.__( \'Choose a WXR (.xml) file to upload, then click Upload file and import.\', \'nav-menu-roles\' ).\'</p>\';
wp_import_upload_form( \'admin.php?import=nav_menu_roles&step=1\' );
echo \'</div>\';
}
/**
* Decide if the given meta key maps to information we will want to import
*
* @param string $key The meta key to check
* @return string|bool The key if we do want to import, false if not
*/
function is_valid_meta_key( $key ) {
// skip attachment metadata since we\'ll regenerate it from scratch
// skip _edit_lock as not relevant for import
if ( in_array( $key, array( \'_wp_attached_file\', \'_wp_attachment_metadata\', \'_edit_lock\' ) ) )
return false;
return $key;
}
/**
* Added to http_request_timeout filter to force timeout at 60 seconds during import
* @return int 60
*/
function bump_request_timeout() {
return 60;
}
// return the difference in length between two strings
function cmpr_strlen( $a, $b ) {
return strlen($b) - strlen($a);
}
} // end class
} // end if