在WordPress中删除导航菜单时重置自定义字段

时间:2018-11-30 05:32:42

标签: php wordpress custom-fields

我有一个与所有帖子和页面关联的自定义字段。这是所有导航菜单的下拉列表。 这是我填充自定义字段下拉列表的方式:(字段名称为custom_menu ...)

function acf_load_menu_field_choices( $field ) {

    // reset choices
    $field['choices'] = array();

    $menus = get_terms( 'nav_menu', array( 'hide_empty' => true ) );

    $blank_list = json_encode(array( "name" => "Select Menu", "slug" => "")); 
    $blank_list = json_decode($blank_list);
    array_unshift($menus, $blank_list);
    foreach ( $menus as $val ) {

        $value = $val->slug;
        $label = $val->name;

        $field['choices'][ $value ] = $label;
    }

    // return the field
    return $field;

}
add_filter('acf/load_field/name=custom_menu', 'acf_load_menu_field_choices');

这是我在每个页面上使用的常见菜单位置:

function register_custom_menu() {  //function to register new menu
     register_nav_menu('custom-menu',__( 'Custom Menu' ));
}
add_action( 'init', 'register_custom_menu' );

然后,我根据每页上的自定义字段菜单,将菜单动态分配给位置custom-menu

这是加载页面时会触发的函数:

add_action("wp_ajax_load_custom_menu", "load_custom_menu");
add_action("wp_ajax_nopriv_load_custom_menu", "load_custom_menu");
function load_custom_menu(){
    $post_id = $_POST['page_id'];
    $page_custom_menu = get_field('custom_menu', $post_id);
    if(empty($page_custom_menu) || $page_custom_menu == "primary") return;
    $locations = get_theme_mod( 'nav_menu_locations' );
    if(!empty($locations)) {
        foreach($locations as $locationId => $menuValue) { 
            if($locationId == "custom-menu") $menu = get_term_by('slug', $page_custom_menu, 'nav_menu');  
            if(isset($menu)) { $locations[$locationId] = $menu->term_id; }
        } 
    } 
    set_theme_mod('nav_menu_locations', $locations);

    wp_nav_menu( array( 
        'theme_location' => 'custom-menu', 
        'menu_id' => 'primary-menu', 
        'menu_class' => 'main-nav underline-decoration l-to-r-line level-arrows-on outside-item-remove-margin',
        'container' => false
        ) 
    );

    wp_die();
}

此ajax函数在ready事件上触发,并接收名为POST的{​​{1}}值。此函数检查page_id的给定page_id的自定义字段值,并将该菜单分配给名为custom-menu的{​​{1}}。

这是我的JavaScript,以备您浏览:

menu location

这就是我的代码的工作方式,到目前为止一切正常。

现在是问题所在 每当我从外观>菜单>删除菜单中删除导航菜单时,由于自定义字段值仍指向已删除的菜单,因此我的自定义菜单开始异常运行。 我要在这里做的是,我想在删除菜单时删除自定义字段首先,我要获取已删除菜单的信息,然后查找具有该信息的自定义字段值,最后,删除或重置该自定义字段。

2 个答案:

答案 0 :(得分:2)

WordPress中的菜单仅为terms in a taxonomy。因此,您可以使用所有术语“挂钩”。

尤其是pre_delete_term钩子。

add_action( 'pre_delete_term', 'my_func' );
function my_func($term, $taxonomy){

  // Check the taxonomy is really 'menu', then check term
}

答案 1 :(得分:1)

您正在寻找需要一个参数-wp_delete_nav_menu的操作menu id。到那时,您的导航菜单将被删除,因此您将无法处理它。

如果可以存储导航菜单ID而不是子弹,那将大大简化事情。

acf_load_menu_field_choices中替换:

foreach ( $menus as $val ) {
    $value = $val->term_id;
    $label = $val->name;
    $field['choices'][ $value ] = $label;
}

load_custom_menu中:

$page_custom_menu = get_field('custom_menu', $post_id);
if(empty($page_custom_menu) || $page_custom_menu == /* Should be your primary menu ID */) return;
$locations = get_theme_mod( 'nav_menu_locations' );
if(!empty($locations)) {
    foreach($locations as $locationId => $menuValue) {
        if($locationId == "custom-menu") $menu = get_term_by('id', $page_custom_menu, 'nav_menu');
        if(isset($menu)) { $locations[$locationId] = $menu->term_id; }
    }
}

这些更改之后,您将需要在所有帖子\页面中重写custom_menu

此后,以下功能将在删除菜单时删除所有相关字段。仅在典型的ACF字段(字符串)上测试了它,而不是对它进行了测试,但也可以在您的代码上正常工作。

add_action('wp_delete_nav_menu', 'delete_all_acf_fields_with_menu', 10, 1);
function delete_all_acf_fields_with_menu($term_id) {
    $args = array(
        'post_type'        => array('post', 'page'),
        'posts_per_page'   => -1,
        'meta_key' => 'custom_menu',
        'meta_value' => $term_id,
    );
    $posts = get_posts($args);
    if( $posts ) {
        foreach( $posts as $p ) {
            delete_field('custom_menu', $p->ID);
        }
    }
}