Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm building a plugin that adds extra functionality to a main plugin. Ideally in the plugins administration screen, the "activate" link should be disabled and an inline note should be added that tells the user to install and activate the main plugin first before he/she can use the current plugin.

share|improve this question
    
What about using: is_plugin_active() ? eg: if (is_plugin_active('path/to/plugin.php')) { // Do something } –  TomC Dec 28 '13 at 9:29

3 Answers 3

up vote 5 down vote accepted

Thanks for the answers guys. Though both answers set me on the right path, none worked out of the box. So I'm sharing my solutions below.

Method 1 - Using register_activation_hook:

Create the Parent Plugin in plugins/parent-plugin/parent-plugin.php:

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

Create the Child Plugin in plugins/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>');
    }
}

Notice that I'm not using deactivate_plugins( $plugin ); as for some reason it does not work. So I used wp_die to cancel the activation redirection and inform the user.

Advantage:

  • Simple solution and does not incur additional db hits compared to method 2

Disadvantages:

  • wp_die screen is ugly
  • wp_die screen will STILL show up if you activated the Parent Plugin and Child Plugin at the same time using the checkboxes in the plugins admin screen.

Method 2 - Using admin_init and admin_notices

Create the Parent Plugin in plugins/parent-plugin/parent-plugin.php:

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

Create the Child Plugin in plugins/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:

  • Works when you activate the Parent and Child plugin at the same time using checkboxes

Disadvantage:

  • Incur additional db hits as the plugin is actually activated at first and deactivated once admin_init runs.

As for my question regarding disabling the activate link, I could use:

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;
}

However, it turned out to be highly impractical as there is NO place to put this code. I could not put it on the parent plugin as the parent plugin should be active for this code to run. Certainly does not belong to child plugin or functions.php. So I'm scrapping this idea.

share|improve this answer
    
Method 2 worked great! I used it to extend someone else's plugin. –  Collin Price Jul 17 at 18:32

Try this out, it's commented, so that should help you understand it.

<?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'
    }
}
?> 

If this throws out an error, you could also check the 'option' of 'myplugin' and set it to false or not activated.

share|improve this answer

You need to replace the parent plugin directory name and its main plugin file name here in the below code snippet. is_plugin_active( 'plugin-directory/plugin-file.php' ) And put this code inside your child plugin's main file.

/**
 * Show admin notice & de-activate if parent plugin is not active
 */
function has_parent_plugin() {
    if ( is_admin() && ( current_user_can( 'activate_plugins' ) &&  is_plugin_active( 'plugin-directory/plugin-file.php' ) ) {
        add_action( 'admin_notices', create_function( null, 'echo \'<div class="error"><p>Activation failed: Parent plugin must be activated to use the <strong>My Current</strong> Plugin. Visit your plugins page to activate.</p></div>\';' ) );

        deactivate_plugins( plugin_basename( __FILE__ ) ); 

        if ( isset( $_GET['activate'] ) ) {
            unset( $_GET['activate'] );
        }
    }
}
add_action( 'admin_init', 'has_parent_plugin' );
share|improve this answer
2  
Please do not use create_function() anymore. It is slow, and opcode caches cannot handle it very well. –  toscho Dec 28 '13 at 13:42
    
Thanks @toscho for the nice tip. I will take care of this from now on. :) –  Subharanjan Dec 28 '13 at 13:44

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.