导航菜单元导入失败

时间:2013-02-01 作者:helgatheviking

我是Nav菜单角色插件的作者,该插件允许您根据用户的角色显示/隐藏菜单项。我注意到,当使用常规WordPress插件/工具进行导入时,菜单项meta不会导入。

每个菜单项本质上只是数据库中的一篇文章,我一直将数据保存为post meta。它显示在导出的XML中。这是我刚在当地做的一个出口测试的样本。

<item>
    <title>Art &amp; Design</title>
    <link>http://localhost/blog/2013/01/13/263/</link>
    <pubDate>Mon, 14 Jan 2013 03:36:16 +0000</pubDate>
    <dc:creator>helga</dc:creator>
    <guid isPermaLink="false">http://localhost/blog/2013/01/13/263/</guid>
    <description></description>
    <content:encoded><![CDATA[]]></content:encoded>
    <excerpt:encoded><![CDATA[]]></excerpt:encoded>
    <wp:post_id>263</wp:post_id>
    <wp:post_date>2013-01-13 22:36:16</wp:post_date>
    <wp:post_date_gmt>2013-01-14 03:36:16</wp:post_date_gmt>
    <wp:comment_status>open</wp:comment_status>
    <wp:ping_status>open</wp:ping_status>
    <wp:post_name>263</wp:post_name>
    <wp:status>publish</wp:status>
    <wp:post_parent>0</wp:post_parent>
    <wp:menu_order>1</wp:menu_order>
    <wp:post_type>nav_menu_item</wp:post_type>
    <wp:post_password></wp:post_password>
    <wp:is_sticky>0</wp:is_sticky>
    <category domain="nav_menu" nicename="main-menu"><![CDATA[Main Menu]]></category>
    <wp:postmeta>
        <wp:meta_key>_menu_item_type</wp:meta_key>
        <wp:meta_value><![CDATA[taxonomy]]></wp:meta_value>
    </wp:postmeta>
    <wp:postmeta>
        <wp:meta_key>_menu_item_menu_item_parent</wp:meta_key>
        <wp:meta_value><![CDATA[0]]></wp:meta_value>
    </wp:postmeta>
    <wp:postmeta>
        <wp:meta_key>_menu_item_object_id</wp:meta_key>
        <wp:meta_value><![CDATA[6]]></wp:meta_value>
    </wp:postmeta>
    <wp:postmeta>
        <wp:meta_key>_menu_item_object</wp:meta_key>
        <wp:meta_value><![CDATA[category]]></wp:meta_value>
    </wp:postmeta>
    <wp:postmeta>
        <wp:meta_key>_menu_item_target</wp:meta_key>
        <wp:meta_value><![CDATA[]]></wp:meta_value>
    </wp:postmeta>
    <wp:postmeta>
        <wp:meta_key>_menu_item_classes</wp:meta_key>
        <wp:meta_value><![CDATA[a:1:{i:0;s:6:"design";}]]></wp:meta_value>
    </wp:postmeta>
    <wp:postmeta>
        <wp:meta_key>_menu_item_xfn</wp:meta_key>
        <wp:meta_value><![CDATA[]]></wp:meta_value>
    </wp:postmeta>
    <wp:postmeta>
        <wp:meta_key>_menu_item_url</wp:meta_key>
        <wp:meta_value><![CDATA[]]></wp:meta_value>
    </wp:postmeta>
    <wp:postmeta>
        <wp:meta_key>_nav_menu_role</wp:meta_key>
        <wp:meta_value><![CDATA[a:2:{i:0;s:13:"administrator";i:1;s:12:"shop_manager";}]]></wp:meta_value>
    </wp:postmeta>
</item>
但在导入时,元键_nav_menu_role 甚至没有出现在数据库中。我在本地运行一个多站点,但引起我注意的用户没有。我想为每个使用这个插件的人解决这个问题,但我对从哪里开始寻找都感到困惑。我认为序列化/非序列化可能有问题,但密钥没有损坏,甚至在导入后都没有。

UPDATE: 我研究了导入器插件,对于菜单项,该插件只导入传统的预定义元。。例如“类”。

1 个回复
最合适的回答,由SO网友:helgatheviking 整理而成

问题最终出在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&#8217;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&amp;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

结束

相关推荐

Wordpress Custom Menus Issue

在我的模板中,我使用这样的调用来输出一些自定义菜单:<?php wp_nav_menu(array(\'container_class\' => \'secondary-navigation\', \'theme_location\' => \'secondary\')); ?> 自从升级到WordPress 3.1.4后,我就可以获得完整的页面列表,而不是自定义菜单我看到修复程序(通过谷歌)说我应该添加以下内容来修复此问题:\'fallback_cb\' => f