¿Cómo hacer que un complemento requiera otro complemento?

23

Estoy creando un complemento que agrega funcionalidad adicional a un complemento principal. Idealmente, en la pantalla de administración de complementos, el enlace "activar" debería estar deshabilitado y debería agregarse una nota en línea que indique al usuario que instale y active el complemento principal antes de que pueda usar el complemento actual.

    
pregunta kosinix 28.12.2013 - 10:15

4 respuestas

31

Gracias por las respuestas chicos. Aunque ambas respuestas me pusieron en el camino correcto, ninguna de ellas salió de la caja. Así que estoy compartiendo mis soluciones a continuación.

Método 1: uso de register_activation_hook:

Cree el complemento para padres en los complementos / parent-plugin / parent-plugin.php:

<?php
/*
Plugin Name: Parent Plugin
Description: Demo plugin with a dependent child plugin.
Version: 1.0.0
*/

Crea el complemento infantil en complementos / child-plugin / child-plugin.php:

<?php
/*
Plugin Name: Child Plugin
Description: Parent Plugin should be installed and active to use this plugin.
Version: 1.0.0
*/
register_activation_hook( __FILE__, 'child_plugin_activate' );
function child_plugin_activate(){

    // Require parent plugin
    if ( ! is_plugin_active( 'parent-plugin/parent-plugin.php' ) and current_user_can( 'activate_plugins' ) ) {
        // Stop activation redirect and show error
        wp_die('Sorry, but this plugin requires the Parent Plugin to be installed and active. <br><a href="' . admin_url( 'plugins.php' ) . '">&laquo; Return to Plugins</a>');
    }
}

Observe que no estoy usando deactivate_plugins( $plugin ); porque, por alguna razón, no funciona. Así que utilicé wp_die para cancelar la redirección de activación e informar al usuario.

Advantage:

  • Solución simple y no incurre en db hits adicionales en comparación con el método 2

Desventajas:

  • la pantalla wp_die es fea
  • la pantalla wp_die AÚN se mostrará si activó el complemento principal y el complemento secundario al mismo tiempo utilizando las casillas de verificación en la pantalla de administración de complementos.

Método 2: uso de admin_init y admin_notices

Cree el complemento para padres en los complementos / parent-plugin / parent-plugin.php:

<?php
/*
Plugin Name: Parent Plugin
Description: Demo plugin with a dependent child plugin.
Version: 1.0.0
*/

Crea el complemento infantil en complementos / child-plugin / child-plugin.php:

<?php
/*
Plugin Name: Child Plugin
Description: Parent Plugin should be installed and active to use this 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>Sorry, but Child Plugin requires the Parent plugin to be installed and active.</p></div><?php
}

Advantage:

  • Funciona cuando activa el complemento de Padres e Hijos al mismo tiempo usando las casillas de verificación

Desventaja :

  • Incurra en db hits adicionales ya que el complemento se activa al principio y se desactiva una vez que se ejecuta admin_init.

En cuanto a mi pregunta sobre la desactivación del 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>Activate</span>';

    return $links;
}

Sin embargo, resultó ser poco práctico ya que NO hay lugar para poner este código. No podría ponerlo en el complemento principal, ya que el complemento principal debería estar activo para que se ejecute este código. Ciertamente no pertenece al plugin hijo o functions.php. Así que estoy desechando esta idea.

    
respondido por el kosinix 28.01.2014 - 07:43
2

Prueba esto, está comentado, por lo que debería ayudarte a entenderlo.

<?php
register_activation_hook( __FILE__, 'myplugin_activate' ); // Register myplugin_activate on
function myplugin_activate() {
    $plugin = plugin_basename( __FILE__ ); // 'myplugin'
    if ( is_plugin_active( 'plugin-directory/first-plugin.php' ) ) {
        // Plugin was active, do hook for 'myplugin'
    } else {
        // Plugin was not-active, uh oh, do not allow this plugin to activate
        deactivate_plugins( $plugin ); // Deactivate 'myplugin'
    }
}
?> 

Si esto arroja un error, también puede marcar la 'opción' de 'myplugin' y configurarlo como falso o no activado.

    
respondido por el MrJustin 28.12.2013 - 10:48
2

Ambas soluciones sugeridas tienen fallas.

Método 1: Como se mencionó anteriormente, la pantalla wp_die () AÚN se mostrará cuando el complemento para padres y el complemento para niños se activen al mismo tiempo usando las casillas de verificación en la pantalla de administración de complementos.

Método 2: en algunos casos de uso no es bueno ya que 'admin_init' se ejecuta mucho después de 'plugins_loaded' ( enlace ), y después del enlace de desinstalación ( enlace ). Por ejemplo, si queremos que el complemento ejecute algún código en la desinstalación, ya sea que el complemento principal esté activo o no, este enfoque NO funcionará.

Solución:

En primer lugar, debemos agregar el siguiente código al final del archivo PHP principal del complemento principal:

do_action( 'my_plugin_loaded' );

Esto enviará un evento / señal a todos los suscriptores, informando que el complemento del núcleo se cargó.

Luego, la clase del complemento debería tener el siguiente aspecto:

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

    /**
     * Check if parent plugin is activated (not necessarly loaded).
     *
     * @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;
    }

    /**
     * Check if parent plugin is active and loaded.
     *
     * @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__ ) );

            // Message error + allow back link.
            wp_die( __( 'My Add-on requires My Plugin to be installed and activated.' ), __( 'Error' ), array( 'back_link' => true ) );
        }
    }

    #endregion Parent Plugin Check
}

if (My_Addon::_is_parent_active_and_loaded())
{
    // If parent plugin already included, init add-on.
    My_Addon::init();
}
else if (My_Addon::_is_parent_activated())
{
    // Init add-on only after the parent plugins is loaded.
    add_action( 'my_plugin_loaded', array( __CLASS__, 'init' ) );
}
else
{
    // Even though the parent plugin is not activated, execute add-on for activation / uninstall hooks.
    My_Addon::init();
}

Espero que ayude :)

    
respondido por el vovafeldman 26.03.2016 - 20:58
0

Creo que necesitas Activación del complemento TGM .

  

Activación del complemento TGM es una biblioteca de PHP que te permite hacerlo fácilmente.   requiere o recomienda complementos para tus temas de WordPress (y complementos).   Permite a sus usuarios instalar, actualizar e incluso automáticamente.   Activar complementos en forma singular o masiva utilizando WordPress nativo   Clases, funciones e interfaces. Puede hacer referencia a complementos empaquetados,   complementos del repositorio de complementos de WordPress o incluso complementos alojados   en otros lugares de internet.

    
respondido por el Amir Hossein Hossein Zadeh 08.10.2018 - 18:53

Lea otras preguntas en las etiquetas