WordPress防止删除分类

yacmzcpb  于 2022-11-22  发布在  WordPress
关注(0)|答案(4)|浏览(124)

我想防止一些类别被意外删除。为此,我使用一个 meta条目的类别被保护。
我使用以下代码:

// edit: wrong hook! ** add_action( 'delete_term_taxonomy', 'taxonomy_delete_protection', 10, 1 );
add_action( 'pre_delete_term', 'taxonomy_delete_protection', 10, 1 );
function taxonomy_delete_protection ( $term_id )
{
    
    if (get_term_meta ($term_id, 'delete-protect', true) === true)
    {
      wp_die('Cannot delete this category');
    }
    
}

不幸的是,而不是我的错误信息,只显示“出错了”,为什么?
编辑:'delete_term_taxonomy'对于我的代码来说是错误的钩子,因为它在我检查元条目之前就删除了 meta。'pre_delete_term'在类别发生任何事情之前就触发了。

5n0oy7gb

5n0oy7gb1#

“为什么”是因为WordPress附带的以下JavaScript:

$.post(ajaxurl, data, function(r){
    if ( '1' == r ) {
        $('#ajax-response').empty();
        tr.fadeOut('normal', function(){ tr.remove(); });

        /**
         * Removes the term from the parent box and the tag cloud.
         *
         * `data.match(/tag_ID=(\d+)/)[1]` matches the term ID from the data variable.
         * This term ID is then used to select the relevant HTML elements:
         * The parent box and the tag cloud.
         */
        $('select#parent option[value="' + data.match(/tag_ID=(\d+)/)[1] + '"]').remove();
        $('a.tag-link-' + data.match(/tag_ID=(\d+)/)[1]).remove();

    } else if ( '-1' == r ) {
        $('#ajax-response').empty().append('<div class="error"><p>' + wp.i18n.__( 'Sorry, you are not allowed to do that.' ) + '</p></div>');
        tr.children().css('backgroundColor', '');

    } else {
        $('#ajax-response').empty().append('<div class="error"><p>' + wp.i18n.__( 'Something went wrong.' ) + '</p></div>');
        tr.children().css('backgroundColor', '');
    }
});

此POST请求的预期响应为:

  • '1'(如果术语已删除)
  • '-1'(如果您的用户没有删除术语的权限)。

对于所有其他情况,将显示“出错”。
您使用wp_die提前终止了脚本,产生了意外的响应,这属于“其他情况”。
如果不编写一些自己的JavaScript,就无法在此处的通知框中提供自定义错误消息。

qxgroojn

qxgroojn2#

这是我目前的解决方案,不完美,但它的工作。
如果你用行操作删除分类,“出错了”的消息就会出现,所以我取消了“删除”操作,这样就不会触发它了。

add_filter ('category_row_actions', 'unset_taxonomy_row_actions', 10, 2);
function unset_taxonomy_row_actions ($actions, $term)
{

$delete_protected = get_term_meta ($term->term_id, 'delete-protect', true);

   if ($delete_protected)
   {
    unset ($actions['delete']);
   }

return $actions;
}

然后我用css隐藏了分类编辑表单中的“删除”链接。如果你检查网站和它的链接,它仍然可以被触发,但是没有钩子来删除这个操作。

add_action( 'category_edit_form', 'remove_delete_edit_term_form', 10, 2 );

function remove_delete_edit_term_form ($term, $taxonomy)
{

    $delete_protected = get_term_meta ($term->term_id, 'delete-protect', true);
    
    if ($delete_protected)
    {
        // insert css
        echo '<style type="text/css">#delete-link {display: none !important;}</style>';
    }
    
}

最后是删除分类法之前的检查。这应该会捕获所有其他方式,比如批量操作“delete”。我还没有找到其他方法来阻止脚本删除分类法。

add_action ('pre_delete_term', 'taxonomy_delete_protection', 10, 1 );

function taxonomy_delete_protection ( $term_id )
{
    
    $delete_protected = get_term_meta ($term_id, 'delete-protect', true);
    
    if ($delete_protected)
    {
        $term = get_term ($term_id);

        $error = new WP_Error ();
        $error->add (1, '<h2>Delete Protection Active!</h2>You cannot delete "' . $term->name . '"!');
        wp_die ($error);
    }
}
mqxuamgl

mqxuamgl3#

这个解决方案提供了一种方法来禁止所有类别被非管理员删除。这是为任何人喜欢我谁一直在搜索。

function disable_delete_cat() {
  global $wp_taxonomies;
  if(!current_user_can('administrator')){ 
  $wp_taxonomies[ 'category' ]->cap->delete_terms = 'do_not_allow';
  }
}
add_action('init','disable_delete_cat');
fxnxkyjh

fxnxkyjh4#

最简单的解决方案(它会自动处理所有可能删除类别/术语的不同位置),在我看来也是最灵活的一个是使用user_has_cap钩子:

function maybeDoNotAllowDeletion($allcaps, $caps, array $args, $user)
{
    if ($args[0] !== 'delete_term') return $allcaps;

    // you can skip protection for any user here
    // let's say that for the default admin with id === 1
    if ($args[1] === 1) return $allcaps;

    $termId = $args[2];
    $term = get_term($termId);

    // you can skip protection for all taxonomies except
    // some special one - let's say it is called 'sections'
    if ($term->taxonomy !== 'sections') return $allcaps;

    // you can protect only selected set of terms from
    // the 'sections' taxonomy here
    $protectedTermIds = [23, 122, 3234];
    
    if (in_array($termId, $protectedTermIds )) {
      $allcaps['delete_categories'] = false;
      // if you have some custom caps set
      $allcaps['delete_sections'] = false;
    }

    return $allcaps;
}
add_filter('user_has_cap', 'maybeDoNotAllowDeletion', 10, 4);

相关问题