Як відключити "Post Lock / Edit Lock"?


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

Відповіді:


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 серцебиття

Розширення плагіна, щоб також відключити API hearbeat:

<?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 Я додав редагування, щоб повністю відключити API Heartbeat. Не знаєте, як ви хочете це впоратися, але ви все одно можете запустити 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;
}

Чи не було б простіше просто використовувати його, __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не здається гарною ідеєю.


Будь ласка, використовуйте get_current_screen()->post_typeзамість цього. Ось приємний плагін під назвою Поточна інформація про адміністратора, який допоможе вам отримати таку інформацію.
кайзер

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 / include / 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');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.