¿Cómo hacer que un plugin requiera otro plugin?
Estoy desarrollando un plugin que añade funcionalidad extra a un plugin principal. Idealmente, en la pantalla de administración de plugins, el enlace "activar" debería estar desactivado y se debería agregar una nota en línea que indique al usuario que debe instalar y activar el plugin principal antes de poder usar el plugin actual.

Gracias por las respuestas, chicos. Aunque ambas respuestas me pusieron en el camino correcto, ninguna funcionó de inmediato. Así que comparto mis soluciones a continuación.
Método 1 - Usando register_activation_hook:
Crea el Plugin Padre en plugins/parent-plugin/parent-plugin.php:
<?php
/*
Plugin Name: Plugin Padre
Description: Plugin de demostración con un plugin hijo dependiente.
Version: 1.0.0
*/
Crea el Plugin Hijo en plugins/child-plugin/child-plugin.php:
<?php
/*
Plugin Name: Plugin Hijo
Description: El Plugin Padre debe estar instalado y activo para usar este plugin.
Version: 1.0.0
*/
register_activation_hook( __FILE__, 'child_plugin_activate' );
function child_plugin_activate(){
// Requiere el plugin padre
if ( ! is_plugin_active( 'parent-plugin/parent-plugin.php' ) and current_user_can( 'activate_plugins' ) ) {
// Detiene la activación y muestra error
wp_die('Lo sentimos, pero este plugin requiere que el Plugin Padre esté instalado y activo. <br><a href="' . admin_url( 'plugins.php' ) . '">« Volver a Plugins</a>');
}
}
Observa que no estoy usando deactivate_plugins( $plugin );
ya que por alguna razón no funciona. Así que usé wp_die para cancelar la redirección de activación e informar al usuario.
Ventaja:
- Solución simple y no genera consultas adicionales a la base de datos en comparación con el método 2
Desventajas:
- La pantalla de wp_die es poco atractiva
- La pantalla de wp_die AÚN aparecerá si activas el Plugin Padre y el Plugin Hijo al mismo tiempo usando las casillas de verificación en la pantalla de administración de plugins.
Método 2 - Usando admin_init y admin_notices
Crea el Plugin Padre en plugins/parent-plugin/parent-plugin.php:
<?php
/*
Plugin Name: Plugin Padre
Description: Plugin de demostración con un plugin hijo dependiente.
Version: 1.0.0
*/
Crea el Plugin Hijo en plugins/child-plugin/child-plugin.php:
<?php
/*
Plugin Name: Plugin Hijo
Description: El Plugin Padre debe estar instalado y activo para usar este plugin.
Version: 1.0.0
*/
add_action( 'admin_init', 'child_plugin_has_parent_plugin' );
function child_plugin_has_parent_plugin() {
if ( is_admin() && current_user_can( 'activate_plugins' ) && !is_plugin_active( 'parent-plugin/parent-plugin.php' ) ) {
add_action( 'admin_notices', 'child_plugin_notice' );
deactivate_plugins( plugin_basename( __FILE__ ) );
if ( isset( $_GET['activate'] ) ) {
unset( $_GET['activate'] );
}
}
}
function child_plugin_notice(){
?><div class="error"><p>Lo sentimos, pero el Plugin Hijo requiere que el Plugin Padre esté instalado y activo.</p></div><?php
}
Ventaja:
- Funciona cuando activas el Plugin Padre e Hijo al mismo tiempo usando las casillas de verificación
Desventaja:
- Genera consultas adicionales a la base de datos ya que el plugin en realidad se activa primero y se desactiva una vez que se ejecuta admin_init.
En cuanto a mi pregunta sobre desactivar el enlace de activación, podría usar:
add_filter( 'plugin_action_links', 'disable_child_link', 10, 2 );
function disable_child_link( $links, $file ) {
if ( 'child-plugin/child-plugin.php' == $file and isset($links['activate']) )
$links['activate'] = '<span>Activar</span>';
return $links;
}
Sin embargo, resultó ser muy poco práctico ya que NO hay un lugar para poner este código. No podía ponerlo en el plugin padre porque el plugin padre debería estar activo para que este código se ejecute. Ciertamente no pertenece al plugin hijo ni a functions.php. Así que estoy descartando esta idea.

¡El método 2 funcionó genial! Lo usé para extender el plugin de otra persona.

Desde la versión 6.5 de WordPress, puedes definir dependencias de plugins dentro del archivo principal del plugin usando el encabezado Requires Plugins
. Por ejemplo:
/**
* Plugin Name: Mi Plugin
* Requires Plugins: plugin-uno, plugin-dos
*/
Simplemente añade una lista separada por comas de los slugs de plugins del repositorio de WP.org, y estarás listo.
Las dependencias se muestran en la tarjeta del plugin mismo, en las pantallas de Plugins → Todos los plugins
y Plugins → Añadir nuevo
.
También se pueden listar plugins que no estén alojados en WordPress.org, pero estos deben instalarse manualmente.
Ten en cuenta que esto no funciona para temas, solo para plugins. Además, no puedes definir versiones específicas de plugins, y todos los plugins listados serán obligatorios. No hay forma de requerir solo uno de los plugins listados.
Lee el anuncio completo de esta función en la publicación relacionada del blog make.wordpress.org.

Ambas soluciones sugeridas tienen fallas.
Método 1: Como se mencionó, la pantalla de wp_die() AÚN aparecerá cuando el Plugin Padre y el Plugin Hijo se activen al mismo tiempo usando las casillas de verificación en la pantalla de administración de plugins.
Método 2: En algunos casos de uso no es bueno ya que 'admin_init' se ejecuta mucho después de 'plugins_loaded' (https://codex.wordpress.org/Plugin_API/Action_Reference), y después del hook de desinstalación (https://codex.wordpress.org/Function_Reference/register_uninstall_hook). Por ejemplo, si queremos que el add-on ejecute algún código durante la desinstalación ya sea que el plugin padre esté activo o no, este enfoque NO funcionará.
Solución:
Primero que nada, necesitamos agregar el siguiente código al final del archivo PHP principal del plugin padre:
do_action( 'my_plugin_loaded' );
Esto enviará una señal/evento a todos los suscriptores, indicando que el plugin principal fue cargado.
Luego, la clase del add-on debería verse así:
class My_Addon
{
static function init ()
{
register_activation_hook( __FILE__, array( __CLASS__, '_install' ) );
if ( ! self::_is_parent_active_and_loaded() ) {
return;
}
}
#region Parent Plugin Check
/**
* Verifica si el plugin padre está activado (no necesariamente cargado).
*
* @author Vova Feldman (@svovaf)
*
* @return bool
*/
static function _is_parent_activated()
{
$active_plugins_basenames = get_option( 'active_plugins' );
foreach ( $active_plugins_basenames as $plugin_basename ) {
if ( false !== strpos( $plugin_basename, '/my-plugin-main-file.php' ) ) {
return true;
}
}
return false;
}
/**
* Verifica si el plugin padre está activo y cargado.
*
* @author Vova Feldman (@svovaf)
*
* @return bool
*/
static function _is_parent_active_and_loaded()
{
return class_exists( 'My_Plugin' );
}
/**
*
* @author Vova Feldman (@svovaf)
*/
static function _install()
{
if ( ! self::_is_parent_active_and_loaded() ) {
deactivate_plugins( basename( __FILE__ ) );
// Mensaje de error + enlace para regresar.
wp_die( __( 'My Add-on requiere que My Plugin esté instalado y activado.' ), __( 'Error' ), array( 'back_link' => true ) );
}
}
#endregion Parent Plugin Check
}
if (My_Addon::_is_parent_active_and_loaded())
{
// Si el plugin padre ya está incluido, inicializar el add-on.
My_Addon::init();
}
else if (My_Addon::_is_parent_activated())
{
// Inicializar el add-on solo después de que el plugin padre se cargue.
add_action( 'my_plugin_loaded', array( __CLASS__, 'init' ) );
}
else
{
// Aunque el plugin padre no esté activado, ejecutar el add-on para los hooks de activación/desinstalación.
My_Addon::init();
}
Espero que ayude :)

Esta respuesta también tiene un defecto. :-) Asume que tienes control total sobre el plugin padre donde puedes agregar do_action( 'my_plugin_loaded' ); en su código. La respuesta seleccionada funcionará con o sin control del plugin padre (por ejemplo, si el plugin padre no es tuyo)

Prueba esto, está comentado, así que debería ayudarte a entenderlo.
<?php
register_activation_hook( __FILE__, 'myplugin_activate' ); // Registra myplugin_activate al activar
function myplugin_activate() {
$plugin = plugin_basename( __FILE__ ); // 'myplugin'
if ( is_plugin_active( 'plugin-directory/first-plugin.php' ) ) {
// El plugin estaba activo, ejecuta el hook para 'myplugin'
} else {
// El plugin no estaba activo, oh oh, no permitas que este plugin se active
deactivate_plugins( $plugin ); // Desactiva 'myplugin'
}
}
?>
Si esto genera un error, también podrías verificar la 'opción' de 'myplugin' y establecerla en falso o no activada.

Creo que necesitas TGM Plugin Activation.
TGM Plugin Activation es una biblioteca PHP que te permite requerir o recomendar plugins para tus temas de WordPress (y plugins). Permite a tus usuarios instalar, actualizar e incluso activar automáticamente plugins de forma individual o masiva utilizando las clases, funciones e interfaces nativas de WordPress. Puedes hacer referencia a plugins incluidos, plugins del Repositorio de WordPress o incluso plugins alojados en cualquier otro lugar de internet.
