¿Cuál es el tiempo válido para usar current_user_can () y las funciones relacionadas?

10

Durante la carga principal de Vanilla WP, el usuario actual se está configurando en $wp-init() , que es después de la carga del tema y antes de init hook. Esto está en línea con la buena práctica de que la funcionalidad se enganche a init o posterior.

Sin embargo, también es una práctica común llamar a funciones relacionadas, como current_user_can() anterior que eso. Es, por definición, requerido para los complementos que funcionan con etapas anteriores del proceso de carga (mi complemento para el conmutador de temas de la barra de herramientas sería un ejemplo).

La documentación no hace reclamaciones a favor o en contra de esta práctica (que podría encontrar).

Sin embargo, parece que algunos complementos se enganchan en la funcionalidad relacionada con el usuario y esperan el estado post- init en todo momento.

Por ejemplo, bbPress lanza el siguiente aviso:

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

Para una demostración rápida, incluya esto en la definición de current_user_can() del núcleo:

function current_user_can( $capability ) {

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

¿Quién es "correcto" en esta situación? ¿Existe una determinación canónica sobre el uso permitido / prohibido de las funciones relacionadas con el usuario antes de init ?

    
pregunta Rarst 10.08.2015 - 14:32

3 respuestas

7

El único requisito previo para current_user_can() es un wp_get_current_user() existente. Este último se define en pluggable.php , por lo que puede usarlo después de plugins_loaded .

La llamada _doing_it_wrong() que está citando en su pregunta es incorrecta por sí misma. Mi conjetura es que tomaste eso de BuddyPress o bbPress. Ambos están corriendo en una recursión si no esperan tanto tiempo. Hay otras formas mejores de prevenir la recursión.

En algunos casos, como cambiando la ubicación , tienes para acceda al objeto de usuario actual antes, por lo que esperar after_setup_theme ni siquiera es una opción.

    
respondido por el fuxia 10.08.2015 - 15:03
2

Si verifica la capacidad del usuario antes de init significa que hay posibilidades de que usted sea el responsable de la configuración del objeto de usuario actual.

Si accede al usuario después init , entonces está seguro de que otra cosa ya configura al usuario, la mayoría de las veces son el núcleo.

Esta es la razón por la que el acceso al usuario después de init se considera seguro .

De hecho, el acceso temprano posiblemente rompa algunos filtros que se ejecutan en determine_current_user .

Vale la pena decir que uno es un gancho "frágil", porque existe la posibilidad de que nunca se ejecute, siendo disparado solo en funciones conectables.

Sin embargo, hay casos (como @toscho dicho) donde no puede esperar hasta que inicie, en esos casos no tiene otra opción.

La única forma de resolver cualquier incompatibilidad es caso por caso, si tiene voluntad.

Una solución que puede funcionar en la mayoría de los casos (incluido bbPress / BuddyPress) es usar la siguiente función en lugar 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 );
}

Esto permite verificar la capacidad actual del usuario sin configurar un usuario global, por lo que en teoría es seguro ejecutar antes de init .

El problema es que, como se dijo anteriormente, cualquier código que reemplaza las funciones conectables y que no se dispara determine_current_user lo rompe.

    
respondido por el gmazzap 10.08.2015 - 21:31
1

Me inclino a pensar que BuddyPress y bbPress deberían estar revisando otra cosa antes de emitir el mensaje _doing_it_wrong

Cambié ambas rutinas para verificar también la configuración real de $ current_user.

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

Los avisos ya no se mostraban.

La prueba para did_action( "after_setup_theme" ) se convierte en los frenos para ir con el cinturón.

    
respondido por el bobbingwide 10.08.2015 - 15:49

Lea otras preguntas en las etiquetas