จะปิดการใช้งาน“ 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 answer ...

ผลการวิจัย

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' );
} );

ทันทีที่ปลั๊กอินที่สองถูกเปิดใช้งานประเภทโพสต์เบียร์ของเราไม่มีการล็อกโพสต์อีกแล้ว สิ่งนี้ควรใช้งานได้ดีและสามารถย้อนกลับได้อย่างง่ายดายผ่านหน้าจอผู้ดูแลระบบปลั๊กอิน

ปิดใช้งาน heartbeat API

การขยายปลั๊กอินเพื่อปิดใช้งาน Hearbeat 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 อย่างสมบูรณ์ ไม่แน่ใจว่าคุณต้องการจัดการมันอย่างไร แต่คุณยังสามารถเรียกใช้ heartbeat API ในปลั๊กอินโดยใช้wp.heartbeat.start();ใน JavaScript ของคุณ
ไกเซอร์

2
เป็นความคิดที่ดีที่จะใช้post_type_supportsเพื่อจัดการสิ่งนี้สำหรับโพสต์แบบกำหนดเองแต่ละประเภทฉันหวังว่าฉันจะให้ upvotes ได้มากขึ้น ;-)
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เพื่อให้สภาพiffalse

ปรับปรุง:

หากต้องการใช้สิ่งนี้บน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

อาบางที Dunno ในขณะนี้ Btw มีwp_is_autosave()- ไม่แน่ใจว่าบัญชีดังกล่าวเป็นการกระทำใด ๆ เหล่านั้นหรือไม่
ไกเซอร์

ฉันสงสัยว่าadd_filter( 'show_post_locked_dialog', '__return_false' );จากฟังก์ชั่น_admin_notice_post_locked()มีความช่วยเหลือหรือไม่?
Birgire

@ Birgire ไม่ไม่ทำงาน ฉันคิดว่าเป็นไปไม่ได้ที่จะหยุดwp_ajax_heartbeat()(WP-admin / includes / อาแจ็กซ์-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');
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.