1

Background:

Hi, I am using Justified Gallery plugin, and I am attempting to load the necessary resources only in the pages where I use galleries.

The Problem:

The plugin loads some inline elements and scripts which I failed to not load when not in the right page.

Here is the code for the Core class which instantiates the other classes:

<?php
// Exit if accessed directly
if ( !defined( 'ABSPATH' ) ) {
    exit;
}

 $fspath = dirname(__FILE__) . '/includes/fs/config.php';
if ( file_exists($fspath) ) {
require_once $fspath;
}

if ( !class_exists( 'DGWT_JG_Core' ) ) {

final class DGWT_JG_Core {

    private static $instance;
    private $tnow;
    public $detector;
    public $settings;
    public $gallery;
    public $lightbox;
    public $tilesStyle;

    public static function get_instance() {
        if ( !isset( self::$instance ) && !( self::$instance instanceof DGWT_JG_Core ) ) {
            self::$instance      = new DGWT_JG_Core;
            self::$instance->constants();

            if ( !self::$instance->check_requirements() ) {
                return;
            }

            self::$instance->load_textdomain();

            self::$instance->includes();
            self::$instance->hooks();

            self::$instance->detector = new DGWT_JG_MobileDetect;
            self::$instance->settings    = new DGWT_JG_Settings;
            self::$instance->gallery     = new DGWT_JG_Gallery;
            self::$instance->lightbox    = new DGWT_JG_Lightbox_Loader;
            self::$instance->tilesStyle = new DGWT_TilesStyle_Loader;

        }
        self::$instance->tnow = time();

        return self::$instance;
    }

    /**
     * Constructor Function
     */
    private function __construct() {
        self::$instance = $this;
    }

    /*
     * Check requirements
     * @since 1.2.2
     */

    private function check_requirements() {
        if ( version_compare( PHP_VERSION, '5.3.0' ) < 0 ) {
            add_action( 'admin_notices', array( $this, 'admin_notice_php' ) );

            return false;
        }

        return true;
    }

    /**
     * Setup plugin constants
     */
    private function constants() {

        $this->define( 'DGWT_JG_VERSION', '1.2.3' );
        $this->define( 'DGWT_JG_NAME', 'Justified Gallery' );
        $this->define( 'DGWT_JG_FILE', __FILE__ );
        $this->define( 'DGWT_JG_DIR', plugin_dir_path( __FILE__ ) );
        $this->define( 'DGWT_JG_URL', plugin_dir_url( __FILE__ ) );
        $this->define( 'DGWT_JG_DOMAIN', 'justified-gallery' );

        $this->define( 'DGWT_JG_SETTINGS_KEY', 'dgwt_jg_settings' );

        $this->define( 'DGWT_JG_DEBUG', false );
    }

    /**
     * Define constant if not already set
     * @param  string $name
     * @param  string|bool $value
     */
    private function define( $name, $value ) {
        if ( !defined( $name ) ) {
            define( $name, $value );
        }
    }

    /**
     * Include required core files.
     */
    public function includes() {

        require_once DGWT_JG_DIR . 'includes/Utils/Helpers.php';
        require_once DGWT_JG_DIR . 'includes/Utils/MobileDetect.php';

        require_once DGWT_JG_DIR . 'includes/Install.php';

        require_once DGWT_JG_DIR . 'includes/admin/settings/SettingsApi.php';
        require_once DGWT_JG_DIR . 'includes/admin/settings/Settings.php';

        require_once DGWT_JG_DIR . 'includes/RegisterScripts.php';

        require_once DGWT_JG_DIR . 'includes/admin/admin.php';
        require_once DGWT_JG_DIR . 'includes/admin/Promo/FeedbackNotice.php';

        require_once DGWT_JG_DIR . 'includes/Gallery.php';
        require_once DGWT_JG_DIR . 'includes/TilesStyle/Loader.php';
        require_once DGWT_JG_DIR . 'includes/Lightbox/Loader.php';

    }

    /**
     * Actions and filters
     */
    private function hooks() {

        add_action( 'admin_init', array( $this, 'admin_scripts' ) );
    }

    /*
     * Enqueue admin sripts
     */

    public function admin_scripts() {
        // Register CSS
        wp_register_style( 'dgwt-jg-admin-style', DGWT_JG_URL . 'assets/css/admin-style.css', array(), DGWT_JG_VERSION );



        // Enqueue CSS            
        wp_enqueue_style( array(
            'dgwt-jg-admin-style',
        //'wp-color-picker'
        ) );


        //wp_enqueue_script( 'wp-color-picker' );
    }

    /*
     * Register text domain
     */

    private function load_textdomain() {
        $lang_dir = dirname( plugin_basename( DGWT_JG_FILE ) ) . '/languages/';
        load_plugin_textdomain( DGWT_JG_DOMAIN, false, $lang_dir );
    }

    /*
     * Notice: PHP version less than 5.3
     */

    public function admin_notice_php() {
        ?>
        <div class="error">
            <p>
                <?php
                printf(__( '<b>Justified Gallery Plugin</b>: You need PHP version at least 5.3 to run this plugin. You are currently using PHP version %s. Please upgrade PHP version or uninstall this plugin.', 'justified-gallery' ), PHP_VERSION);
                ?>
            </p>
        </div>
        <?php
    }

}

}

// Init the plugin
function DGWT_JG() {
    return DGWT_JG_Core::get_instance();
}

DGWT_JG();

here is DGWT_JG_Gallery Class constructor that adds an action that I would like to remove on unnecessary pages:

class DGWT_JG_Gallery {

/**
 * Store array with options
 * @var array
 */
public $options;

function __construct() {

    $this->set_options();

    add_filter( 'post_gallery', array( $this, 'post_gallery' ), 15, 3 );

    add_action( 'wp_footer', array( $this, 'init_gallery' ), 90 );
}

I have added this to my child theme's function.php

function remove_justified_gallery() {
    remove_action( 'wp_footer', array( $gallery, 'init_gallery' ), 90 );
    // remove_action( 'wp_footer', 'include_modal', 90 );
    // remove_action( 'wp_footer', 'gallery_init', 90 );
}
add_action( 'wp_head', 'remove_justified_gallery', 1);

The struggle here is to access the class that holds the function

according to the codex, to remove a function in a class from an action: https://codex.wordpress.org/Function_Reference/remove_action

If an action has been added from within a class, for example by a plugin, removing it will require accessing the class through a variable that holds the class instance. Unless the function is static in which case you could call the class and function directly.

example:

add_action( 'wp_head', 'remove_my_class_action' );
function remove_my_class_action(){
    global $my_class;
    remove_action( 'wp_footer', array( $my_class, 'class_function_being_removed' ) );
}

1 Answer 1

0

Because of the way the plugin is structured, the hooked function appears to be ultimately exist on the gallery property of the instance property of the DGWT_JG_Core class.

When an instance of DGWT_JG_Core is created, a DGWT_JG_Gallery class is instantiated and added to the gallery property of the DGWT_JG_Core instance. So we need to remove the action from the gallery property of the instance of DGWT_JG_Core that was created when the plugin was run.

Since DGWT_JG_Core is a singleton there is only ever one instance of DGWT_JG_Core and we can access it with the get_instance() method. Helpfully for us, the plugin defines a function that calls this method for us. It's that DGWT_JG() function at the end.

So to be able to remove the action we use DGWT_JG() to get the instance of DGWT_JG_Core, and access the DGWT_JG_Gallery class through the gallery property:

function wpse_284486_remove_justified_gallery() {
    $instance = DGWT_JG();

    remove_action( 'wp_footer', array( $instance->gallery, 'init_gallery' ), 90 );
}
add_action( 'wp_head', 'wpse_284486_remove_justified_gallery', 0 );

I tested this on a fake version of the classes that just implemented a single hook and it worked. I'll post it here so you can maybe see what's going on:

class My_Test_Gallery {
    function __construct() {
        add_action( 'wp_footer', array( $this, 'init_gallery' ), 90 );
    }

    function init_gallery() {
        echo 'Hello world!';
    }
}

class My_Test_Plugin {
    private static $instance;

    public static function get_instance() {
        if ( ! isset( self::$instance ) && ! ( self::$instance instanceof My_Test_Plugin ) ) {
            self::$instance = new My_Test_Plugin;
            self::$instance->gallery = new My_Test_Gallery;
        }

        return self::$instance;
    }

    private function __construct() {
        self::$instance = $this;
    }
}

function My_TP() {
    return My_Test_Plugin::get_instance();
}

My_TP();

function wpse_284486_remove_justified_gallery() {
    $instance = My_TP();

    remove_action( 'wp_footer', array( $instance->gallery, 'init_gallery' ), 90 );
}
add_action( 'wp_head', 'wpse_284486_remove_justified_gallery', 0 );
3
  • Amazing, this is the correct way of doing it. Another solution came into my mind, since it's not only one action that I need to remove but a bunch of them, as the class is pluggable would it be more correct to override the class and instantiate the DGWT_JG_Core only on specific pages? or the right way would be to remove all actions one by one
    – user130629
    Oct 31, 2017 at 14:10
  • I don't know enough about the plugin to say, but if I had to guess DGWT_JG_Core gets loaded before you're able to run any conditional template functions so you wouldn't be able to plug it based on the current query. It's sounds like you're probably engaging in a little bit of premature optimisation though. Would this prevent any expensive database queries? What else would the plugin be doing that would so heavily affect performance? Oct 31, 2017 at 14:43
  • 1
    That's true, I picked your answer as the solution, it was very helpful thank you!
    – user130629
    Oct 31, 2017 at 15:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.