Cum să dezactivezi "Post Lock/Edit Lock"?
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).
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
.

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

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 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.

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

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
?

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 filtrulwp_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ă.

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, 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()
).

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

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

@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.

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, 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.

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