Quel est le timing valide pour utiliser current_user_can () et les fonctions associées?

10

Pendant le chargement du noyau WP de vanille, l’utilisateur actuel est configuré dans $wp-init() , soit après le chargement du thème et avant le init hook. Cela va dans le sens des bonnes pratiques pour que les fonctionnalités deviennent liées à init ou plus tard.

Cependant, il est également courant d'appeler des fonctions associées, telles que current_user_can() plus tôt que cela. Il est par définition requis pour les plugins fonctionnant avec les étapes précédentes du processus de chargement (mon plugin Toolbar Theme Switcher en serait un exemple).

La documentation ne fait aucune réclamation pour ou contre cette pratique (que j'ai pu trouver).

Cependant, certains plugins semblent s’accrocher aux fonctionnalités liées à l’utilisateur et s’attendent à ce que l’état post - init soit toujours présent.

Par exemple, bbPress émet l’avis suivant:

// If the current user is being setup before the "init" action has fired,
// strange (and difficult to debug) role/capability issues will occur.
if ( ! did_action( 'after_setup_theme' ) ) {
    _doing_it_wrong( __FUNCTION__, __( 'The current user is being initialized without using $wp->init().', 'bbpress' ), '2.3' );
}

Pour une démonstration rapide, ajoutez ceci à la définition de current_user_can() :

function current_user_can( $capability ) {

    if ( ! did_action('after_setup_theme') ) {
        echo wp_debug_backtrace_summary();
    }

Qui a "raison" dans cette situation? Existe-t-il une détermination canonique concernant l'utilisation autorisée / interdite de fonctions liées à l'utilisateur avant init ?

    
posée Rarst 10.08.2015 - 14:32

3 réponses

7

La seule condition requise pour current_user_can() est un wp_get_current_user() existant. Ce dernier est défini dans pluggable.php , vous pouvez donc l'utiliser après plugins_loaded .

L'appel _doing_it_wrong() que vous citez dans votre question est faux pour lui-même. Je suppose que vous avez pris cela dans BuddyPress ou bbPress. Les deux courent dans une récursivité s'ils n'attendent pas si longtemps. Il existe d'autres moyens plus efficaces pour empêcher la récursivité.

Dans certains cas, comme modification de l'environnement local , vous devez choisir accéder à l'objet utilisateur actuel plus tôt, donc attendre after_setup_theme n'est même pas une option.

    
réponse donnée fuxia 10.08.2015 - 15:03
2

Si vous vérifiez les capacités de l'utilisateur avant init , cela signifie que vous êtes responsable du paramétrage de l'objet utilisateur actuel.

Si vous accédez à l'utilisateur après init , vous êtes sûr que quelque chose d'autre a déjà configuré l'utilisateur, la plupart du temps au centre même.

C’est pourquoi l'accès à l'utilisateur après init est considéré comme sûr .

En fait, un accès anticipé peut éventuellement empêcher certains filtres de s'exécuter sur determine_current_user .

Cela vaut la peine de dire qu’il s’agit d’un crochet «fragile», car il ya des chances qu’il ne fonctionne jamais, étant déclenché uniquement dans des fonctions enfichables.

Cependant, il existe des cas (tels que @toscho ) où vous ne pouvez pas attendre l'init, dans ce cas, vous n'avez pas le choix.

Le seul moyen de résoudre toute incompatibilité est au cas par cas, si vous le souhaitez.

Une solution qui peut fonctionner dans la plupart des cas (y compris bbPress / BuddyPress) consiste à utiliser la fonction suivante à la place de current_user_can :

function compat_current_user_can( $capability )
{
  if ( did_action( 'init' ) ) {
     return current_user_can( $capability );
  }

  $user_id = apply_filters( 'determine_current_user', false );

  return user_can( $user_id, $capability );
}

Cela permet de vérifier les capacités des utilisateurs actuels à un stade précoce sans configurer l'utilisateur global. Par conséquent, en théorie ne peut être exécuté avant init .

Le problème est que, comme indiqué ci-dessus, tout code qui annule les fonctions enfichables et ne déclenche pas determine_current_user le casse.

    
réponse donnée gmazzap 10.08.2015 - 21:31
1

J'ai tendance à penser que BuddyPress et bbPress devraient vérifier autre chose avant d'envoyer le message _doing_it_wrong

J'ai modifié les deux routines pour vérifier également le paramètre actuel de $ current_user.

global $current_user; 
if ( is_null( $current_user ) ) {
    _doing_it_wrong( ... );
}

Les avis n'étaient plus affichés.

Le test de did_action( "after_setup_theme" ) devient l’attelle qui va avec la ceinture.

    
réponse donnée bobbingwide 10.08.2015 - 15:49

Lire d'autres questions sur les étiquettes