如何禁用“后锁/编辑锁”?


16

我只想针对一种帖子类型禁用此功能,因为如果有其他用户对其进行编辑并没有什么关系(主要内容编辑区域为Ajaxified,非管理员只能看到该内容)。

在此处输入图片说明

我查看了核心功能,但找不到入口点。从函数中,wp_set_post_lock我猜测我必须拦截get_post_meta,但是有官方的方法吗?

还有第二个锁似乎不受过滤器的影响wp_check_post_lock_window答案中birgire所示)。我已经remove_filter( 'heartbeat_received', 'wp_refresh_post_lock', 10, 3 );在不同方面进行了尝试,但是它一直在受到不尊重的殴打remove_filter

在此处输入图片说明


1
我添加了有关动机的说明,这使我想到了一个解决方案:在另一个屏幕上向非管理员显示此内容。但是,post_lock尽管如此,知道合适的钩子还是很高兴的。
brasofilo

Answers:


10

作为@birgire答案的补充...

发现

register_post_type()允许注册帖子类型支持,也可以稍后使用add_post_type_support()完成。而且甚至可以在以后使用所有强大功能进行检查post_type_supports( $cpt, $feat )

通用迷你插件,增加了新功能

现在,以下(mu-)插件会检查一种新的帖子类型支持,该支持会禁用帖子锁定功能。名为disabled_post_lock

<?php
defined( 'ABSPATH' );
/** Plugin Name: (#120179) Maybe Disable Post Type Support */

add_action( 'load-edit.php', 'wpse120179MaybeDisablePostLock' );
function wpse120179MaybeDisablePostLock()
{
    if ( post_type_supports( get_current_screen()->post_type, 'disabled_post_lock' ) )
        add_filter( 'wp_check_post_lock_window', '__return_false' );
}

每个CPT一个插件

然后,我们可以轻松地添加迷你插件来禁用对我们自己或第三方插件的帖子类型支持(为我们在用户元表中节省了一些带宽和数据库大小):

<?php
defined( 'ABSPATH' );
/** Plugin Name: (#120179) Disable Post Type Support for "Beer" Posts */

add_action( 'init', function()
{
    add_post_type_support( 'beer', 'disabled_post_lock' );
} );

一旦第二个插件被激活,我们的啤酒发布类型将不再具有发布锁定。这应该很好用,并且可以通过插件管理屏幕轻松还原。

禁用心跳API

扩展插件以同时禁用Listenbeat API:

<?php
defined( 'ABSPATH' );
/** Plugin Name: (#120179) Maybe Disable Post Type Support */

add_action( 'load-edit.php', 'wpse120179MaybeDisablePostLock' );
function wpse120179MaybeDisablePostLock()
{
    if ( post_type_supports( get_current_screen()->post_type, 'disabled_post_lock' ) )
    {
        add_filter( 'wp_check_post_lock_window', '__return_false' );
        add_filter( 'heartbeat_settings', function( $settings )
        {
            return wp_parse_args( [ 'autostart' => false ], $settings );
        } );
    }
}

这是一个非常经典的解决方案,您将如何处理admin-ajax.php零件(Q更新并添加A)?
brasofilo

@brasofilo我添加了一个编辑以完全禁用Heartbeat API。不确定如何处理,但仍可以通过wp.heartbeat.start();在JavaScript中使用在插件中运行心跳API 。
kaiser

2
最好post_type_supports针对每个自定义帖子类型使用来处理此问题,希望我能给您更多的支持;-)
birgire 2013年

7

要删除编辑锁弹出窗口,您可以尝试:

add_filter( 'wp_check_post_lock_window', '__return_zero' );

我不确定这是否可行,但是我检查了来源,wp_check_post_lock() 然后有以下几行:

...cut...

$time_window = apply_filters( 'wp_check_post_lock_window', 120 );

if ( $time && $time > time() - $time_window && $user != get_current_user_id() )
    return $user;
return false;

...cut...

所以想法是改变,$time_window这样if条件才是false

更新:

要将其应用到edit.php屏幕上,请使用自定义帖子类型beer,例如:

function wpse_120179()
{
    if( 'beer' === get_current_screen()->post_type )
        add_filter( 'wp_check_post_lock_window', '__return_zero' );

}
add_action( 'load-edit.php', 'wpse_120179' );

然后我们可以添加:

add_action( 'load-post.php', 'wpse_120179' );

同时将其删除post.php

更多挖掘...

该功能 _admin_notice_post_locked()定义只是下面的wp_set_post_lock()功能。它包含以下几行:

...cut...
if ( ! apply_filters( 'show_post_locked_dialog', true, $post, $user ) )
    return;
...cut...

所以也可以尝试使用show_post_locked_dialog过滤器:

add_filter( 'show_post_locked_dialog', 'wpse_120179_close_dialog', 99, 3 );

function wpse_120179_close_dialog( $show, $post, $user )
{
    if( 'beer' === $post->post_type )
        return FALSE;

    return $show;
}

仅仅使用它__return_false()作为第一个检查的$time总和会不会更容易bool TRUE
kaiser

好的,但是我不确定如何设置$timefalse所以我去了$time_window……
birgire

3

我最终使用的最终组合是

# Takes care of the message "Someone else is editing this"
add_action( 'load-edit.php', function()
{
    if( 'beer' === get_current_screen()->post_type )
        add_filter( 'wp_check_post_lock_window', '__return_false' );
});

# Takes care of post.php and the "User has taken over" message
add_filter( 'show_post_locked_dialog', function( $bool, $post, $user )
{
    if( 'beer' === $post->post_type )
        return false;
    return $bool;
}, 
10, 3 );

但如果有人有其他建议,我很想听听,因为我不太了解可用过滤器的全部情况。

以前,使用load-edit.php+ load-post.php,我必须使用以下方法删除过滤器wp_refresh_post_lock

add_action( 'admin_init', function()
{
    if( !defined('DOING_AJAX') || !isset( $_POST['screen_id'] ) || 'beer' !== $_POST['screen_id'] )
        return;

    remove_filter( 'heartbeat_received', 'wp_refresh_post_lock', 10 );
});

但每次加载admin_init似乎都不是一个好主意。


get_current_screen()->post_type改用。这是一个名为Current Admin Info的好插件,可以帮助您检索此类信息。
kaiser

1
@kaiser,我的意图是阻止Ajax的心跳,也许我应该添加一些DOING_AJAX检查...据我所知,Ajax没有global $current_screen(返回get_current_screen())。
brasofilo

嗯,也许吧。此刻的邓诺。顺便说一句,有wp_is_autosave()-不知道这是否归因于任何这些行动。
kaiser

我想知道add_filter( 'show_post_locked_dialog', '__return_false' );从功能上_admin_notice_post_locked()是否有帮助?
birgire

@birgire,不,没有用。我想这不可能wp_ajax_heartbeat()使用链load-$hook-> 停止(wp-admin / includes / ajax-actions.php)get_current_something()。。。。。另外,该函数中有3个钩子,但是我无法使用它们来停止节拍(并且它们具有$screen_id,与
拍子

3

这是最适合我的最终解决方案。:

function my_remove_post_locked() {
    $current_post_type = get_current_screen()->post_type;   

    // Disable locking for page, post and some custom post type
    $post_types_arr = array(
        'page',
        'post',
        'custom_post_type'
    );

    if(in_array($current_post_type, $post_types_arr)) {
        add_filter( 'show_post_locked_dialog', '__return_false' );
        add_filter( 'wp_check_post_lock_window', '__return_false' );
        wp_deregister_script('heartbeat');
    }
}

add_action('load-edit.php', 'my_remove_post_locked');
add_action('load-post.php', 'my_remove_post_locked');
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.