Comment désactiver le «Post Lock / Edit Lock»?

16

Je souhaite désactiver cela uniquement pour un type de publication, car cela n'a pas vraiment d'importance si un autre utilisateur le modifie (la zone principale de modification du contenu est Ajaxified et les non-administrateurs ne peuvent que le voir).

entrez la description de l'image ici

J'ai regardé les fonctions principales mais je n'ai pas trouvé de point d'entrée. D'après la fonction, wp_set_post_lockje suppose que je devrais intercepter le get_post_meta, mais y a-t-il un moyen officiel de le faire?

Et il y a un deuxième verrou qui ne semble pas être affecté par le filtre wp_check_post_lock_window( comme le montre birgire , ici dans une réponse). J'ai essayé remove_filter( 'heartbeat_received', 'wp_refresh_post_lock', 10, 3 );à plusieurs reprises mais ça continue de battre sans respecter remove_filter.

entrez la description de l'image ici

brasofilo
la source
1
J'ai ajouté une clarification sur les motifs, et cela apporte une solution à l'esprit: montrer ce contenu aux non-administrateurs sur un autre écran. Mais ce serait bien de savoir post_lockquand même un crochet approprié .
brasofilo

Réponses:

10

En complément de la réponse @birgire

Résultats

register_post_type()permet d'enregistrer un support de type post, qui peut aussi bien être fait plus tard en utilisantadd_post_type_support() . Et cela peut être vérifié encore plus tard en utilisant le tout puissant post_type_supports( $cpt, $feat ).

Un mini plugin général qui ajoute une nouvelle fonctionnalité

Maintenant, le plugin (mu) suivant vérifie un nouveau type de support de type de publication qui désactive la fonction de verrouillage de publication. C'est nommé 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' );
}

Un plugin par CPT

Ensuite, nous pouvons facilement ajouter des mini plugins pour désactiver la prise en charge du type de post pour nos propres plugins ou tiers (nous économisant de la bande passante et de la taille de la base de données dans la méta-table utilisateur):

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

Dès que le deuxième plugin est activé, notre type de poste de bière n'a plus de verrouillage de poste. Cela devrait fonctionner correctement et est facilement réversible via l'écran d'administration des plugins.

Désactiver l'API Heartbeat

Extension du plugin pour désactiver également l'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 );
        } );
    }
}
kaiser
la source
Ceci est une solution vraiment chic , comment géreriez-vous la admin-ajax.phppièce (Q mis à jour et A ajouté)?
brasofilo
@brasofilo J'ai ajouté une modification pour désactiver complètement l'API Heartbeat. Vous ne savez pas comment vous souhaitez gérer cela, mais vous pouvez toujours exécuter l'API Heartbeat dans les plugins en utilisant wp.heartbeat.start();dans votre JavaScript.
kaiser
2
c'est une excellente idée d'utiliser le post_type_supportspour gérer cela pour chaque type de message personnalisé, j'aimerais pouvoir vous donner plus de votes positifs ;-)
birgire
7

Pour supprimer la fenêtre contextuelle de verrouillage d'édition , vous pouvez essayer:

add_filter( 'wp_check_post_lock_window', '__return_zero' );

Je ne sais pas si c'est la voie à suivre, mais j'ai vérifié la source de wp_check_post_lock() et là nous avons ces lignes:

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

donc l'idée est de changer $time_windowla ifcondition false.

Mise à jour:

Pour appliquer cela à l' edit.phpécran, avec le type de message personnalisé beerpar exemple:

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

Et puis on peut ajouter:

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

pour le supprimer également pour l' post.phpécran.

Plus de fouilles ...

La fonction _admin_notice_post_locked()est définie juste en dessous de la wp_set_post_lock()fonction. Il contient ces lignes:

...cut...
if ( ! apply_filters( 'show_post_locked_dialog', true, $post, $user ) )
    return;
...cut...

donc on peut aussi essayer le show_post_locked_dialogfiltre:

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
la source
Ne serait-il pas plus facile de simplement l'utiliser à la __return_false()place comme premier contrôle pour $timerésumer simplement en tant que bool TRUE?
kaiser
ok peut - être, mais je ne suis pas sûr comment mettre $timeà falsealors je suis allé à la $time_windowplace ...
birgire
3

La combinaison finale que j'ai fini d'utiliser est

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

mais si quelqu'un a une autre prise, je serais ravi d'entendre, car je ne comprends pas vraiment l'ensemble des filtres disponibles.

Auparavant, en utilisant load-edit.php+ load-post.php, je devais supprimer le filtre wp_refresh_post_lockavec:

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

mais le chargement à chaque fois admin_initne semble pas une bonne idée.

brasofilo
la source
Veuillez utiliser à la get_current_screen()->post_typeplace. Voici un joli plugin appelé Current Admin Info pour vous aider à récupérer ces informations.
kaiser
1
@kaiser, mon intention ici est de bloquer le rythme cardiaque pour Ajax, je devrais peut-être ajouter quelques DOING_AJAXvérifications ... Et si je comprends bien, Ajax n'a pas global $current_screen(retourné par get_current_screen()).
brasofilo
Ah, peut-être. Je ne sais pas pour le moment. Btw, il n'y a wp_is_autosave()- je ne sais pas si cela explique l'une de ces actions.
kaiser
Je me demande si add_filter( 'show_post_locked_dialog', '__return_false' );la fonction _admin_notice_post_locked()est utile?
birgire
@birgire, non, n'a pas fonctionné. Je pense que ce n'est pas possible d'arrêter wp_ajax_heartbeat()(wp-admin / includes / ajax-actions.php) en utilisant la chaîne load-$hook-> get_current_something(). . . . . De plus, il y a 3 crochets dans cette fonction, mais je ne suis pas en mesure d'arrêter le rythme en les utilisant (et ils en ont $screen_id, ce qui correspond au type de message.
brasofilo
3

Voici la solution finale qui fonctionne pour moi. :

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
la source