Как отключить «Пост Блокировка / Редактировать Блокировку»?

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.

введите описание изображения здесь

brasofilo
источник
1
Я добавил разъяснения о мотивах, и это заставляет задуматься: показывать этот контент не администраторам на другом экране. Но все- post_lockтаки было бы неплохо узнать правильный крючок .
brasofilo

Ответы:

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 пульса

Расширение плагина, чтобы отключить интерфейс beatbeat также:

<?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. Не уверен, как вы хотите справиться с этим, но вы все равно можете запустить API пульса в плагинах, используя wp.heartbeat.start();в своем JavaScript.
Кайзер
2
это отличная идея, используя post_type_supportsдля обработки этого для каждого пользовательского типа сообщения, я хотел бы дать вам больше голосов ;-)
birgire
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;
}
birgire
источник
Разве не было бы проще просто использовать __return_false()вместо этого в качестве первой проверки $timeпросто итоги в виде bool TRUE?
Кайзер
ОК , может быть, но я не уверен , как установить $timeна falseтак что я пошел $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не кажется хорошей идеей.

brasofilo
источник
Пожалуйста, используйте get_current_screen()->post_typeвместо этого. Вот хороший плагин под названием Current Admin Info, который поможет вам получить такую ​​информацию.
Кайзер
1
@kaiser, я собираюсь заблокировать сердцебиение для Ajax, может быть, мне стоит добавить DOING_AJAXпроверку ... И, насколько я понимаю, у Ajax нет global $current_screen(возвращено get_current_screen()).
brasofilo
Ах, может быть. Не знаю в данный момент. Кстати, есть ... wp_is_autosave()не уверен, что это связано с каким-либо из этих действий.
Кайзер
Интересно add_filter( 'show_post_locked_dialog', '__return_false' );, из функции _admin_notice_post_locked(), какая-нибудь помощь?
Birgire
@ birgire, нет, не работает. Я думаю, что невозможно остановить wp_ajax_heartbeat()(wp-admin / includes / ajax-actions.php), используя цепочку load-$hook-> get_current_something(). , , , , Кроме того, в этой функции есть 3 хука, но я не могу остановить удар, используя их (и они имеют $screen_id, что соответствует типу поста.
brasofilo
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');
Trubisha
источник