如果你有菜单数组,如何设置wordpress菜单

时间:2015-10-19 09:52:24

标签: php arrays wordpress

假设我有一个输出wp_get_nav_menus()(和一些修改)的数组,我想将它导入到wordpress的新安装中。数组看起来像这样(我们称之为$menu_array):

Array
(
    [0] => Array
        (
            [term_id] => 5
            [name] => my second menu
            [slug] => my-second-menu
            [term_group] => 0
            [term_taxonomy_id] => 5
            [taxonomy] => nav_menu
            [description] => 
            [parent] => 0
            [count] => 2
            [items] => Array
                (
                    [0] => Array
                        (
                            [ID] => 14
                            [post_author] => 1
                            [post_date] => 2015-10-06 07:32:03
                            [post_date_gmt] => 2015-10-06 07:32:03
                            [post_content] => 
                            [post_title] => This is my menu
                            [post_excerpt] => 
                            [post_status] => publish
                            [comment_status] => closed
                            [ping_status] => closed
                            [post_password] => 
                            [post_name] => this-is-my-menu
                            [to_ping] => 
                            [pinged] => 
                            [post_modified] => 2015-10-12 10:31:23
                            [post_modified_gmt] => 2015-10-12 10:31:23
                            [post_content_filtered] => 
                            [post_parent] => 0
                            [guid] => http://www.example.com/?p=14
                            [menu_order] => 1
                            [post_type] => nav_menu_item
                            [post_mime_type] => 
                            [comment_count] => 0
                            [filter] => raw
                            [db_id] => 14
                            [menu_item_parent] => 0
                            [object_id] => 14
                            [object] => custom
                            [type] => custom
                            [type_label] => Custom Link
                            [title] => This is my menu
                            [url] => #
                            [target] => 
                            [attr_title] => 
                            [description] => 
                            [classes] => Array
                                (
                                    [0] => 
                                )

                            [xfn] => 
                        )

                    [1] => Array
                        (
                            [ID] => 15
                            [post_author] => 1
                            [post_date] => 2015-10-06 07:32:03
                            [post_date_gmt] => 2015-10-06 07:32:03
                            [post_content] => 
                            [post_title] => second menu
                            [post_excerpt] => 
                            [post_status] => publish
                            [comment_status] => closed
                            [ping_status] => closed
                            [post_password] => 
                            [post_name] => second-menu
                            [to_ping] => 
                            [pinged] => 
                            [post_modified] => 2015-10-12 10:31:23
                            [post_modified_gmt] => 2015-10-12 10:31:23
                            [post_content_filtered] => 
                            [post_parent] => 0
                            [guid] => http://www.example.com/?p=15
                            [menu_order] => 2
                            [post_type] => nav_menu_item
                            [post_mime_type] => 
                            [comment_count] => 0
                            [filter] => raw
                            [db_id] => 15
                            [menu_item_parent] => 0
                            [object_id] => 15
                            [object] => custom
                            [type] => custom
                            [type_label] => Custom Link
                            [title] => second menu
                            [url] => #
                            [target] => 
                            [attr_title] => 
                            [description] => 
                            [classes] => Array
                                (
                                    [0] => 
                                )

                            [xfn] => 
                        )

                )

        )

    [1] => Array
        (
            [term_id] => 2
            [name] => My Menu
            [slug] => my-menu
            [term_group] => 0
            [term_taxonomy_id] => 2
            [taxonomy] => nav_menu
            [description] => 
            [parent] => 0
            [count] => 3
            [items] => Array
                (
                    [0] => Array
                        (
                            [ID] => 1104
                            [post_author] => 1
                            [post_date] => 2015-10-19 13:31:48
                            [post_date_gmt] => 2015-10-19 13:31:48
                            [post_content] =>  
                            [post_title] => 
                            [post_excerpt] => 
                            [post_status] => publish
                            [comment_status] => closed
                            [ping_status] => closed
                            [post_password] => 
                            [post_name] => 1104
                            [to_ping] => 
                            [pinged] => 
                            [post_modified] => 2015-10-19 13:31:48
                            [post_modified_gmt] => 2015-10-19 13:31:48
                            [post_content_filtered] => 
                            [post_parent] => 0
                            [guid] => http://www.example.com/?p=1104
                            [menu_order] => 1
                            [post_type] => nav_menu_item
                            [post_mime_type] => 
                            [comment_count] => 0
                            [filter] => raw
                            [db_id] => 1104
                            [menu_item_parent] => 0
                            [object_id] => 1016
                            [object] => page
                            [type] => post_type
                            [type_label] => Page
                            [url] => http://www.example.com/Test-page
                            [title] => Test page
                            [target] => 
                            [attr_title] => 
                            [description] =>  
                            [classes] => Array
                                (
                                    [0] => 
                                )

                            [xfn] => 
                        )

                    [1] => Array
                        (
                            [ID] => 12
                            [post_author] => 1
                            [post_date] => 2015-10-05 13:52:35
                            [post_date_gmt] => 2015-10-05 13:52:35
                            [post_content] => 
                            [post_title] => Google
                            [post_excerpt] => 
                            [post_status] => publish
                            [comment_status] => closed
                            [ping_status] => closed
                            [post_password] => 
                            [post_name] => google
                            [to_ping] => 
                            [pinged] => 
                            [post_modified] => 2015-10-19 13:31:48
                            [post_modified_gmt] => 2015-10-19 13:31:48
                            [post_content_filtered] => 
                            [post_parent] => 0
                            [guid] => http://www.example.com/?p=12
                            [menu_order] => 2
                            [post_type] => nav_menu_item
                            [post_mime_type] => 
                            [comment_count] => 0
                            [filter] => raw
                            [db_id] => 12
                            [menu_item_parent] => 0
                            [object_id] => 12
                            [object] => custom
                            [type] => custom
                            [type_label] => Custom Link
                            [title] => Google
                            [url] => http://google.com
                            [target] => 
                            [attr_title] => 
                            [description] => 
                            [classes] => Array
                                (
                                    [0] => 
                                )

                            [xfn] => 
                        )

                    [2] => Array
                        (
                            [ID] => 13
                            [post_author] => 1
                            [post_date] => 2015-10-06 07:22:39
                            [post_date_gmt] => 2015-10-06 07:22:39
                            [post_content] => 
                            [post_title] => Gmail
                            [post_excerpt] => 
                            [post_status] => publish
                            [comment_status] => closed
                            [ping_status] => closed
                            [post_password] => 
                            [post_name] => gmail
                            [to_ping] => 
                            [pinged] => 
                            [post_modified] => 2015-10-19 13:31:48
                            [post_modified_gmt] => 2015-10-19 13:31:48
                            [post_content_filtered] => 
                            [post_parent] => 0
                            [guid] => http://www.example.com/?p=13
                            [menu_order] => 3
                            [post_type] => nav_menu_item
                            [post_mime_type] => 
                            [comment_count] => 0
                            [filter] => raw
                            [db_id] => 13
                            [menu_item_parent] => 12
                            [object_id] => 13
                            [object] => custom
                            [type] => custom
                            [type_label] => Custom Link
                            [title] => Gmail
                            [url] => #
                            [target] => 
                            [attr_title] => 
                            [description] => 
                            [classes] => Array
                                (
                                    [0] => 
                                )

                            [xfn] => 
                        )

                )

        )

)

这是一个叫做“我的菜单”的菜单,里面有2个页面,我可以有多个菜单的多个数组,层次结构跟菜单的层次结构。

我看了一下wordpress如何处理导入它,它使用wp_update_nav_menu_item()wp_nav_menu_update_menu_items()

我试过了,但到目前为止我没有运气。

但是由于wordpress菜单是带有自定义分类nav_menu_item的帖子类型nav_menu,我可以使用wp_insert_post导入我的菜单,还是有一些复杂的方法(比如我需要为每个菜单设置对象术语?

我只需要一些关于如何以正确方式插入菜单的指示。

部分解决方案

所以我发现this链接,我接近实现我的需要。我这样做了

foreach ($menu_array as $menu => $menu_val) {
    // Check if the menu exists
    $old_menu_id = $menu_val['term_id'];
    $menu_location = '';
    foreach (get_theme_mod('nav_menu_locations') as $old_menu_loc => $loc_id) {
        if ($old_menu_id == $loc_id) {
            $menu_location .= $old_menu_loc;
        }
    }
    $menu_name = $menu_val['name'];
    $menu_exists = wp_get_nav_menu_object( $menu_name );
    // If it doesn't exist, let's create it.
    if( !$menu_exists){
        $menu_id = wp_create_nav_menu($menu_name);
        $old_object_id = array();
        // Set up default menu items
        foreach ($menu_val['items'] as $item => $item_value) {

            $old_url = $item_value['url'];
            $old_object_id[] .= $item_value['object_id'];

            $new_url = (isset($url_relation_table[$old_url]) && $url_relation_table[$old_url]>0) ? $url_relation_table[$old_url] : $old_url;

            $menu_data = array(
                'menu-item-db-id' => 0,
                'menu-item-object-id' => '',
                'menu-item-object' => $item_value['object'],
                'menu-item-parent-id' => 0,
                'menu-item-position' => $item_value['menu_order'],
                'menu-item-title' => $item_value['title'],
                'menu-item-type' =>  $item_value['type'], //when removed no error but also no menu type!
                'menu-item-url' => ($new_url != '') ? $new_url : '#',
                'menu-item-description' => $item_value['description'],
                'menu-item-attr-title' => $item_value['attr_title'],
                'menu-item-target' => $item_value['target'],
                'menu-item-classes' => implode(' ', $item_value['classes']),
                'menu-item-xfn' => $item_value['xfn'],
                'menu-item-status' => $item_value['post_status'],
                );
            wp_update_nav_menu_item($menu_id, 0, $menu_data);

        }

        $new_menu_item = wp_get_nav_menu_items($menu_id);
        $new_object_id = array();
        foreach ($new_menu_item as $new_item => $new_item_value) {
            $new_object_id[] .= $new_item_value->ID;
        }
        $object_id_relation_array = array_combine($old_object_id, $new_object_id);

        $menu_obj_data = array(
            'description' => $menu_val['description'],
            'menu-name' => $menu_val['name'],
            'parent' => $menu_val['parent'],
            );
        wp_update_nav_menu_object($menu_id, $menu_obj_data);
    }

    $locations = array();
    if ($menu_location != '') {
        $locations[$menu_location] = $menu_id;
        set_theme_mod( 'nav_menu_locations', $locations );
    }

}

编辑:最后一段代码会将我的菜单设置为其中一个位置(我认为这不是正确的位置)。 $menu_location数组只是位置名称slug作为键,名称作为值(它们在主题中定义,因此它们存在)。

此代码创建菜单,并将第一个分配给一个位置,但不链接任何页面。

EDIT2:我对foreach进行了一些编辑,包括实际工作的菜单位置。但有一些事情是行不通的。我无法在菜单上显示网址,菜单层次结构不起作用(parent->子关系)。

困扰我的是阵列$menu_data。我把所有这些我不确定甚至有效的钥匙都放了。例如urlparent-id。所有developer page说的是它是一个菜单项数据的数组(好duuuh)。如果我能看到我需要的钥匙并放在里面会很有用......

EDIT3:所以我摆脱了我的错误(类需要是一个由空格分隔的字符串),但我不确定为什么我的层次结构不起作用,为什么我不喜欢得到一个网址字段。我需要更详细地浏览nav-menus.php,看看我错过了什么。

EDIT4:好的,所以它几乎可以正常工作!出于某种原因,我收到了通知:

  

注意:尝试在第404行的C:\ xampp \ htdocs \ test \ wp-includes \ nav-menu.php中获取非对象的属性

     

注意:尝试在第405行的C:\ xampp \ htdocs \ test \ wp-includes \ nav-menu.php中获取非对象的属性

     

注意:尝试在第712行的C:\ xampp \ htdocs \ test \ wp-includes \ nav-menu.php中获取非对象的属性

当我删除$item_value['type']时,一切正常,但我没有得到我的菜单的帖子类型,所以所有都是自定义的,没有链接,所以简而言之,它不起作用xD

真正困扰我的另一件事是我无法让层次结构发挥作用。因此,当我导入菜单时,我会得到menu_item_parent是菜单项对象的ID(如果是)。在我的示例中,object id 13的最后一个菜单是object id 12的菜单项的子项,因此他的menu_item_parent为12.当您创建新菜单时,这会更改。所以我创建了一个关系表,它将旧菜单ID与新菜单ID相关联。但我仍然坚持如何更新。当我再次尝试更新菜单时,我会破坏所有内容。我设法替换url(我有url关系表,其中包含旧的和新的url),这可以工作,但由于菜单项是从零开始创建的,我不能只去检查他们现在有什么ID,除非他们是完成它。所以我被困在这里...

1 个答案:

答案 0 :(得分:0)

好的,所以我解决了这个问题,经过大量的讨论。

<?php

foreach ($menu_array as $menu => $menu_val) {
    // Check if the menu exists
    $old_menu_id = $menu_val['term_id'];
    $menu_location = '';
    foreach (get_theme_mod('nav_menu_locations') as $old_menu_loc => $loc_id) {
        if ($old_menu_id == $loc_id) {
            $menu_location .= $old_menu_loc;
        }
    }
    $menu_name = $menu_val['name'];
    $menu_exists = wp_get_nav_menu_object( $menu_name );
    // If it doesn't exist, let's create it.
    if( !$menu_exists){
        $menu_id = wp_create_nav_menu($menu_name);
        $old_object_id = array();

        //Set up default menu items
        foreach ($menu_val['items'] as $item => $item_value) {

            $old_url = $item_value['url'];
            $old_object_id[] .= $item_value['object_id'];

            $new_url = (isset($url_relation_table[$old_url])) ? $url_relation_table[$old_url] : $old_url;

            $obj_ID = url_to_postid($new_url);

            $menu_data = array(
                'menu-item-db-id' => '',
                'menu-item-object-id' => ( $obj_ID != 0 ) ? $obj_ID : '',
                'menu-item-object' => $item_value['object'],
                'menu-item-parent-id' => $item_value['menu_item_parent'],
                'menu-item-position' => $item_value['menu_order'],
                'menu-item-title' => $item_value['title'],
                'menu-item-type' =>  $item_value['type'],
                'menu-item-url' => ($new_url != '') ? $new_url : '#',
                'menu-item-description' => $item_value['description'],
                'menu-item-attr-title' => $item_value['attr_title'],
                'menu-item-target' => $item_value['target'],
                'menu-item-classes' => implode(' ', $item_value['classes']),
                'menu-item-xfn' => $item_value['xfn'],
                'menu-item-status' => $item_value['post_status'],
                );
            wp_update_nav_menu_item($menu_id, 0, $menu_data);

        }

        $new_menu_item = wp_get_nav_menu_items($menu_id);
        $new_object_id = array();
        $parent_id = array();

        foreach ($new_menu_item as $new_item => $new_item_value) {
            $new_object_id[] .= $new_item_value->ID;
            $parent_id[] .= $new_item_value->menu_item_parent;
        }

        $object_id_relation_array = array_combine($old_object_id, $new_object_id);
        $parent_relation_array = array_combine($new_object_id, $parent_id);

        foreach ($object_id_relation_array as $object_id_relation_key => $object_id_relation_value) {
            foreach ($parent_id as $parent_id_key => $parent_id_value) {
                if ($object_id_relation_key == $parent_id_value) {
                    $new_parent_id = $object_id_relation_value;
                    $item_id = array_search($parent_id_value, $parent_relation_array);

                    foreach ($new_menu_item as $single_item => $single_item_value) {
                        if ($single_item_value->ID == $item_id) {
                            $object = $single_item_value->object;
                            $object_ID = $single_item_value->object_id;
                            $position = $single_item_value->menu_order;
                            $title = $single_item_value->title;
                            $type = $single_item_value->type;
                            $url = $single_item_value->url;
                            $description = $single_item_value->description;
                            $attr_title = $single_item_value->attr_title;
                            $target = $single_item_value->target;
                            $classes = implode(' ', $single_item_value->classes);
                            $xfn = $single_item_value->xfn;
                            $status = $single_item_value->post_status;

                            $update_parent_id = array(
                                    'menu-item-db-id' => $item_id,
                                    'menu-item-object-id' => $object_ID,
                                    'menu-item-object' => $object,
                                    'menu-item-parent-id' => $new_parent_id,
                                    'menu-item-position' => $position ,
                                    'menu-item-title' => $title ,
                                    'menu-item-type' =>  $type ,
                                    'menu-item-url' => $url ,
                                    'menu-item-description' => $description ,
                                    'menu-item-attr-title' => $attr_title ,
                                    'menu-item-target' => $target ,
                                    'menu-item-classes' => $classes ,
                                    'menu-item-xfn' => $xfn ,
                                    'menu-item-status' => $status ,
                                );
                            wp_update_nav_menu_item($menu_id, $item_id, $update_parent_id);
                        }
                    }


                }
            }
        }

        $menu_obj_data = array(
            'description' => $menu_val['description'],
            'menu-name' => $menu_val['name'],
            'parent' => $menu_val['parent'],
            );
        wp_update_nav_menu_object($menu_id, $menu_obj_data);
    }

    $locations = array();
    if ($menu_location != '') {
        $locations[$menu_location] = $menu_id;
        set_theme_mod( 'nav_menu_locations', $locations );
    }

}

所以要解释一下。

首先,您需要获取菜单位置(可以从主题模型中获得,您也可以将其放入数组中),然后创建菜单。即使从现有名称创建菜单,也会创建一个带有新ID的全新菜单。更重要的是,菜单项也会有新的ID。这让事情变得复杂了。

之后,您将列出现有项目,并在foreach循环中逐个开始更新新项目。但是你还需要有一种关系表,它将在旧网址和新网址之间建立关系。这非常重要,因为您之前导出的帖子与新地点的网址不同。

但是如果你拥有它,那么你只需要拉出这些关系,并在菜单项中放置新的url。此外,如果您的菜单项是一个页面,那么您需要将其ID放在menu-item-object-id所在的位置。这非常重要,因为如果你不这样做,你会收到关于无法从wordpress nav-menu.php获取非对象属性的通知。这是url_to_postid()函数派上用场的地方。只需将你的网址放在那里,你就可以获得帖子的ID,或者如果它没有得到0。

现在您已经建立了菜单,并且您很高兴。可是等等!层次结构怎么样?

您在新菜单中添加的是菜单之间的旧关系。使用旧ID。这显然不会起作用,因为当你更新菜单项时,你会得到新的ID。因此,您需要一个新的关系表,它将旧的ID与新ID相关联,您还需要一种方法来查看哪些菜单项中包含parent-id个,这样你就可以重新获取所有信息。

问题是,您已经创建了菜单,因此您需要再次检查这些关系,并替换它们,最好的办法就是看看哪些菜单有这样的关系,只更新那些菜单(这就是你有2 wp_update_nav_menu_item()个电话的原因。

之后你可以更新导航菜单对象(虽然我不确定这是否真的需要,但我看不出错误,为什么不呢),并将菜单设置到正确的位置。

我只需要检查多个子菜单和一些细节。但是现在这有效:)