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

Php 在WordPress中删除导航菜单时重置自定义字段,php,wordpress,custom-fields,Php,Wordpress,Custom Fields,我有一个与所有帖子和页面关联的自定义字段。它是所有导航菜单的下拉列表。 下面是我填充自定义字段下拉列表的方式:(字段名称是custom_menu…) 以下是我在每页上使用的常用菜单位置: function register_custom_menu() { //function to register new menu register_nav_menu('custom-menu',__( 'Custom Menu' )); } add_action( 'init', 'registe

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

以下是我在每页上使用的常用菜单位置:

function register_custom_menu() {  //function to register new menu
     register_nav_menu('custom-menu',__( 'Custom Menu' ));
}
add_action( 'init', 'register_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
事件中激发,并接收一个名为
page\u id
POST
值。此函数检查给定
页面id
自定义菜单
的自定义字段值,并将该菜单分配到名为
自定义菜单
菜单位置

以下是我的JavaScript,以备您需要查看:

jQuery(document).ready( function($){
    let customMenu;
    let page_id = script_vars.postID;
    $.post(dtLocal.ajaxurl, { action: "load_custom_menu", page_id: page_id }, resp => customMenu = resp);
    $(window).scroll(() => {
        if(customMenu !== "0"){
            $("#phantom .main-nav").remove();
            $("#phantom .menu-box").html(customMenu);
        }
    })
})
这就是我的代码的工作方式,到目前为止,一切都很好

现在问题出在这里 每当我从外观>菜单>删除菜单中删除导航菜单时,我的自定义菜单会意外地开始运行,因为自定义字段值仍指向已删除的菜单。
我想在这里做的是,每当菜单被删除时,我想删除自定义字段。首先,我想获取已删除菜单的slug,然后找到带有该slug的自定义字段值,最后,删除或重置该自定义字段。

您正在查找操作
wp\u delete\u nav\u menu
,该操作将使用一个参数-
菜单id
。问题是,在这一点上,你的导航菜单将被删除,所以你将无法采取它slug

如果您可以存储nav菜单ID而不是slug,这将大大简化工作

acf\u加载\u菜单\u字段\u选项中
replace:

foreach ( $menus as $val ) {
    $value = $val->term_id;
    $label = $val->name;
    $field['choices'][ $value ] = $label;
}
加载自定义菜单中

$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; }
    }
}
在这些更改之后,您需要在所有POST\页面中重写
自定义菜单

之后,当您删除菜单时,以下函数将删除所有相关字段。它只在典型的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);
        }
    }
}

您正在查找操作
wp\u delete\u nav\u menu
,该操作将使用一个参数-
menu id
。问题是,在这一点上,你的导航菜单将被删除,所以你将无法采取它slug

如果您可以存储nav菜单ID而不是slug,这将大大简化工作

acf\u加载\u菜单\u字段\u选项中
replace:

foreach ( $menus as $val ) {
    $value = $val->term_id;
    $label = $val->name;
    $field['choices'][ $value ] = $label;
}
加载自定义菜单中

$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; }
    }
}
在这些更改之后,您需要在所有POST\页面中重写
自定义菜单

之后,当您删除菜单时,以下函数将删除所有相关字段。它只在典型的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);
        }
    }
}

WordPress中的菜单只是简单的。因此,您可以使用所有术语挂钩

尤其是钩子


WordPress中的菜单只是简单的。因此,您可以使用所有术语挂钩

尤其是钩子


您正在寻找操作“wp_delete_nav_menu”,该操作将使用一个参数-menu id。问题是,此时您的nav menu将被删除,因此您将无法使用slug。您是否可能使用ID作为自定义字段值?您正在寻找将包含一个参数的操作“wp_delete_nav_menu”。问题是,此时您的nav menu将被删除,因此无法将其删除。您是否可以使用ID作为自定义字段值?
nav\u menu\u项目
只是菜单中的一个项目,而不是菜单本身。虽然删除菜单会触发删除项目(我猜),但这个钩子会执行多次,并不是一个有效的解决方案。是的,我已经用正确的方法编辑了答案,用术语进行编辑。
nav\u menu\u item
只是菜单中的一个项目,而不是菜单本身。虽然删除菜单会触发删除项目(我猜),但这个钩子会执行多次,并不是一个有效的解决方案。是的,我已经用正确的方法编辑了答案来处理术语。非常感谢。我已经修改了我的代码并实现了与您类似的解决方案。非常感谢。我已经修改了我的代码并实现了与您类似的解决方案。