Verificar si existe un hook de acción antes de añadir acciones
Estoy intentando añadir etiquetas de enlace rel=next
y rel=prev
al elemento head de la plantilla image.php
. Tengo instalado Wordpress SEO y me gustaría engancharme al hook de acción wpseo_head
de este plugin para lograrlo.
Lo que me gustaría hacer es verificar si el hook de acción wpseo_head
existe antes de adjuntar mi acción, y si no existe (como en el caso de que el plugin no esté instalado o esté desactivado), usaría wp_head
en su lugar.
He probado la función has_action('wpseo_head')
, pero el problema es que si no hay funciones adjuntas a este hook, devolverá false
incluso si el plugin está instalado y activado.
if (has_action('wpseo_head')) {
add_action('wpseo_head', 'ad_add_link_tag_image_head');
} else {
add_action('wp_head', 'ad_add_link_tag_image_head');
}
¿Cuál es la forma correcta de verificar acciones que pueden no existir en WordPress?
Gracias.
No puedes verificar si una acción será llamada antes de que suceda. Incluso si ya hay callbacks adjuntos a la acción, no habría garantía de que se use el do_action()
correspondiente.
En tu caso, prueba con is_plugin_active()
:
if ( is_plugin_active( 'wordpress-seo/wp-seo.php' ) )
{
// hacer algo
}
Como menciona @Barry Carlyon en los comentarios, el directorio puede ser renombrado. Podrías verificar si una constante o una clase ha sido definida/declarada. Pero no hay una solución 100% segura: Las constantes, funciones o clases pueden cambiar después de una actualización, u otro plugin podría definir estas constantes previamente. Especialmente en este caso: Existe otro plugin de WP SEO disponible (nunca entendí por qué usó un nombre que ya estaba en uso...), y podrías obtener un falso positivo.
Existe la función get_file_data()
. Un pseudocódigo, no probado:
$wpseo_active = FALSE;
$plugins = get_option( 'active_plugins', array() );
foreach ( $plugins as $plugin )
{
if ( FALSE !== stripos( $plugin, 'wp-seo' )
{
$data = get_file_data( WP_PLUGIN_DIR . "$plugin" , array ( 'Author' ) );
if ( 'Joost de Valk' === $data[0] )
{
$wpseo_active = TRUE;
}
}
}
if ( $wpseo_active )
{
// hacer algo
}
Y esto aún no es seguro: Los nombres pueden cambiar.

Una mejor manera que intentar usar la ruta al plugin es probar las constantes que wp-seo crea (o las clases), porque si instalé wordpress-seo podría no colocarlo en la carpeta wordpress-seo. Pero en este caso, wp_head siempre debería funcionar como hook ya que wpseo_head debería llamar a wp_head.

Encontré esta respuesta que responde en parte a la pregunta,
// verificar la existencia del filtro "some_hook_filter"
if( array_key_exists( 'some_hook_filter' , $GLOBALS['wp_filter']) ) {
//tu código aquí
}
Sin embargo, como señaló el colaborador original, esto no mostrará todos los filtros posibles dependiendo de cuándo se ejecute el código. Por ejemplo, los filtros contribuidos por el tema no aparecerán durante la carga del plugin. Tanto filtros como acciones están incluidos en este array.
Encontré un listado de variables de WP almacenadas en el array $GLOBALS.

No puedes verificar de manera confiable si existe una acción.
Porque la única vez que la acción existe es cuando se llama a do_action o cuando alguien más agrega acciones a ella.
Así que la acción solo existe cuando alguien le añade acciones o cuando la acción es llamada.
Y si alguien añade acciones, no garantiza que la acción será llamada en absoluto.
Un gran problema que algunos desarrolladores de plugins pueden tener es depender de la acción wp_head, ¡pero un tema mal construido no llamará a la acción wp_head!

Deberías usar la función has_action
.
Función
has_action( string $hook_name, callable|false $callback = false )
Esta función verifica si alguna acción ha sido registrada para un hook.
Parámetros
$hook_name (string) (Requerido) El nombre del action hook.
$callback (callable|false) (Opcional) El callback a verificar. Valor por defecto: false
Más información
Por favor consulta para más información el sitio WP Code Reference: has_action
