Cum să dezactivezi "Post Lock/Edit Lock"?

26 oct. 2013, 17:22:05
Vizualizări: 18.2K
Voturi: 16

Vreau să dezactivez această funcție doar pentru un anumit tip de postare, deoarece nu contează dacă un alt utilizator o editează (zona principală de editare a conținutului folosește Ajax și utilizatorii non-administratori pot vedea doar acest lucru).

Imagine demonstrativă a blocării editării

Am analizat funcțiile din nucleu dar nu am găsit un punct de intrare. Din funcția wp_set_post_lock presupun că ar trebui să interceptez get_post_meta, dar există o metodă oficială de a face asta?

Și mai există o a doua blocare care nu pare să fie afectată de filtrul wp_check_post_lock_window (după cum a arătat birgire, aici într-un Răspuns). Am încercat remove_filter( 'heartbeat_received', 'wp_refresh_post_lock', 10, 3 ); în diverse puncte dar continuă să funcționeze fără a respecta remove_filter.

Imagine demonstrativă a celei de-a doua blocări

1
Comentarii

Am adăugat o clarificare privind motivele, iar asta îmi aduce în minte o soluție: afișarea acestui conținut pentru utilizatorii non-administratori într-un alt ecran. Dar tot ar fi util să știu un hook adecvat pentru post_lock.

brasofilo brasofilo
26 oct. 2013 18:32:24
Toate răspunsurile la întrebare 4
3
11

Ca o completare la răspunsul @birgire

Descoperiri

register_post_type() permite înregistrarea suportului pentru un tip de postare, care poate fi de asemenea adăugat ulterior folosind add_post_type_support(). Acest lucru poate fi verificat ulterior folosind puternicul post_type_supports( $cpt, $feat ).

Un mini-plugin general care adaugă o nouă funcționalitate

Următorul (mu-)plugin verifică un nou tip de suport pentru tipul de postare care dezactivează funcționalitatea de blocare a postării. Acesta se numește disabled_post_lock.

<?php
defined( 'ABSPATH' );
/** Plugin Name: (#120179) Poate Dezactiva Suportul pentru Tipul de Postare */

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

Un plugin pentru fiecare CPT

Putem adăuga cu ușurință mini-pluginuri pentru a dezactiva suportul pentru tipul de postare pentru pluginurile noastre sau ale terților (economisind lățime de bandă și spațiu în baza de date în tabelul user meta):

<?php
defined( 'ABSPATH' );
/** Plugin Name: (#120179) Dezactivează Suportul pentru Tipul de Postare "Beer" */

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

Imediat ce al doilea plugin este activat, tipul nostru de postare beer nu va mai avea blocare de postare. Acest lucru ar trebui să funcționeze bine și poate fi ușor revenit prin ecranul de administrare a pluginurilor.

Dezactivarea API-ului Heartbeat

Extinderea pluginului pentru a dezactiva și API-ul Heartbeat:

<?php
defined( 'ABSPATH' );
/** Plugin Name: (#120179) Poate Dezactiva Suportul pentru Tipul de Postare */

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 );
        } );
    }
}
27 oct. 2013 06:16:07
Comentarii

Aceasta este o soluție cu adevărat elegantă, cum ai gestiona partea cu admin-ajax.php (Întrebarea actualizată și Răspuns adăugat)?

brasofilo brasofilo
27 oct. 2013 09:39:27

@brasofilo Am adăugat o editare pentru a dezactiva complet API-ul Heartbeat. Nu sunt sigur cum dorești să gestionezi asta, dar poți continua să rulezi heartbeat API în plugin-uri folosind wp.heartbeat.start(); în JavaScript-ul tău.

kaiser kaiser
27 oct. 2013 12:34:11

este o idee excelentă să folosești post_type_supports pentru a gestiona asta pentru fiecare tip de postare personalizat, aș vrea să-ți pot da mai multe voturi pozitive ;-)

birgire birgire
27 oct. 2013 13:12:18
2

Pentru a elimina fereastra pop-up edit-lock, poți încerca:

add_filter( 'wp_check_post_lock_window', '__return_zero' );

Nu sunt sigur dacă aceasta este cea mai bună metodă, dar am verificat codul sursă al funcției wp_check_post_lock() și acolo avem următoarele linii:

...tăiat...

$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;

...tăiat...

deci ideea este să modificăm $time_window astfel încât condiția if să fie false.

Actualizare:

Pentru a aplica acest lucru pe ecranul edit.php, cu tipul de postare personalizată beer de exemplu:

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

Și apoi putem adăuga:

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

pentru a elimina și pentru ecranul post.php.

Mai multe detalii ...

Funcția _admin_notice_post_locked() este definită chiar sub funcția wp_set_post_lock(). Ea conține următoarele linii:

...tăiat...
if ( ! apply_filters( 'show_post_locked_dialog', true, $post, $user ) )
    return;
...tăiat...

deci se poate încerca și filtrul 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;
}
26 oct. 2013 19:34:51
Comentarii

Nu ar fi mai ușor să folosești direct __return_false() în loc de prima verificare pentru $time, deoarece aceasta se reduce la un simplu bool TRUE?

kaiser kaiser
27 oct. 2013 06:03:49

ok, poate, dar nu sunt sigur cum să setez $time la false, așa că am ales varianta cu $time_window în schimb...

birgire birgire
27 oct. 2013 14:34:47
8

Combinația finală pe care am ajuns să o folosesc este

# Se ocupă de mesajul "Cineva altcineva editează acest conținut"
add_action( 'load-edit.php', function()
{
    if( 'beer' === get_current_screen()->post_type )
        add_filter( 'wp_check_post_lock_window', '__return_false' );
});

# Se ocupă de post.php și mesajul "Utilizatorul a preluat controlul"
add_filter( 'show_post_locked_dialog', function( $bool, $post, $user )
{
    if( 'beer' === $post->post_type )
        return false;
    return $bool;
}, 
10, 3 );

dar dacă cineva are o altă abordare, aș fi curios să aud, deoarece nu înțeleg întreaga imagine a filtrelor disponibile.

Anterior, folosind load-edit.php + load-post.php, a trebuit să elimin filtrul wp_refresh_post_lock cu:

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

dar încărcarea la fiecare admin_init nu pare o idee bună.

27 oct. 2013 09:36:50
Comentarii

Te rog folosește get_current_screen()->post_type în schimb. Iată un plugin util numit Current Admin Info care te poate ajuta să obții astfel de informații.

kaiser kaiser
27 oct. 2013 12:36:13

@kaiser, intenția mea aici este să blochez heartbeat pentru Ajax, poate ar trebui să adaug o verificare DOING_AJAX... Și după cum înțeleg, Ajax nu are global $current_screen (returnat de get_current_screen()).

brasofilo brasofilo
27 oct. 2013 12:46:36

Ah, poate. Nu știu momentan. Apropo, există wp_is_autosave() - nu sunt sigur dacă se aplică la oricare dintre acele acțiuni.

kaiser kaiser
27 oct. 2013 13:11:41

Mă întreb dacă add_filter( 'show_post_locked_dialog', '__return_false' );, din funcția _admin_notice_post_locked(), este de ajutor?

birgire birgire
27 oct. 2013 14:37:59

@birgire, nu, nu a funcționat. Cred că nu este posibil să oprești wp_ajax_heartbeat() (wp-admin/includes/ajax-actions.php) folosind lanțul load-$hook -> get_current_something(). . . . . De asemenea, există 3 hook-uri în acea funcție, dar nu reușesc să opresc bătăile folosindu-le (și ele au $screen_id, care se potrivește cu tipul de postare.

brasofilo brasofilo
27 oct. 2013 14:59:55

Se simte ca și cum ai încerca să-i dai WordPress-ului un atac de cord ... ;-) Dar funcționează dacă adaugi/elimini filtrele direct (astfel pentru toate cpt-urile?)

birgire birgire
27 oct. 2013 15:11:55

@birgire, da, domnule, acela este cel care oprește bataia :) Am dat OL'WP un atac de cord! Filtrul acceptă și $post și $user ca argumente, a fost cuiul din sicriu. Te rog, adaugă-l în Răspunsul tău.

brasofilo brasofilo
27 oct. 2013 15:26:17

ok grozav, săracul vechi WP ;-)

birgire birgire
27 oct. 2013 16:07:10
Arată celelalte 3 comentarii
0

Iată soluția finală care funcționează pentru mine:

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

    // Dezactivează blocarea pentru pagină, articol și unele tipuri personalizate de postări
    $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');
26 apr. 2015 18:23:01