2

We have a class which is common to few plugins that we develop. As time goes we improve the class and add new functions so we have class variable which is the class version.

Because multiple plugins have this class with different versions it's happen that a plugin initiate an older version of the class because it's loaded first and another plugin which may need the new version does not initiate it as it was already defined.

What is the best way to manage this kind of situation so only the newest version of the class will be the one the will be declared & initiate.

Thanks Bob

2 Answers 2

2

CMB2 has a clever way of handling the same situation. It establishes a version constant that is a high number for the first release (9999), and on each subsequent release, the version constant is decremented. The version number is used for the priority of the action that instantiates the main class. This ensures that the most recent version of the library is loaded.

From CMB2's init.php

if ( ! class_exists( 'CMB2_Bootstrap_212', false ) ) {
    /**
     * Handles checking for and loading the newest version of CMB2
     *
     * @since  2.0.0
     *
     * @category  WordPress_Plugin
     * @package   CMB2
     * @author    WebDevStudios
     * @license   GPL-2.0+
     * @link      http://webdevstudios.com
     */
    class CMB2_Bootstrap_212 {
        /**
         * Current version number
         * @var   string
         * @since 1.0.0
         */
        const VERSION = '2.1.2';
        /**
         * Current version hook priority.
         * Will decrement with each release
         *
         * @var   int
         * @since 2.0.0
         */
        const PRIORITY = 9987;
        /**
         * Single instance of the CMB2_Bootstrap_212 object
         *
         * @var CMB2_Bootstrap_212
         */
        public static $single_instance = null;
        /**
         * Creates/returns the single instance CMB2_Bootstrap_212 object
         *
         * @since  2.0.0
         * @return CMB2_Bootstrap_212 Single instance object
         */
        public static function initiate() {
            if ( null === self::$single_instance ) {
                self::$single_instance = new self();
            }
            return self::$single_instance;
        }
        /**
         * Starts the version checking process.
         * Creates CMB2_LOADED definition for early detection by other scripts
         *
         * Hooks CMB2 inclusion to the init hook on a high priority which decrements
         * (increasing the priority) with each version release.
         *
         * @since 2.0.0
         */
        private function __construct() {
            /**
             * A constant you can use to check if CMB2 is loaded
             * for your plugins/themes with CMB2 dependency
             */
            if ( ! defined( 'CMB2_LOADED' ) ) {
                define( 'CMB2_LOADED', true );
            }
            add_action( 'init', array( $this, 'include_cmb' ), self::PRIORITY );
        }
        /**
         * A final check if CMB2 exists before kicking off our CMB2 loading.
         * CMB2_VERSION and CMB2_DIR constants are set at this point.
         *
         * @since  2.0.0
         */
        public function include_cmb() {
            if ( class_exists( 'CMB2', false ) ) {
                return;
            }
            if ( ! defined( 'CMB2_VERSION' ) ) {
                define( 'CMB2_VERSION', self::VERSION );
            }
            if ( ! defined( 'CMB2_DIR' ) ) {
                define( 'CMB2_DIR', trailingslashit( dirname( __FILE__ ) ) );
            }
            $this->l10ni18n();
            // Include helper functions
            require_once 'includes/helper-functions.php';
            // Now kick off the class autoloader
            spl_autoload_register( 'cmb2_autoload_classes' );
            // Kick the whole thing off
            require_once 'bootstrap.php';
        }

        /**
         * Registers CMB2 text domain path
         * @since  2.0.0
         */
        public function l10ni18n() {
            $loaded = load_plugin_textdomain( 'cmb2', false, '/languages/' );
            if ( ! $loaded ) {
                $loaded = load_muplugin_textdomain( 'cmb2', '/languages/' );
            }
            if ( ! $loaded ) {
                $loaded = load_theme_textdomain( 'cmb2', get_stylesheet_directory() . '/languages/' );
            }
            if ( ! $loaded ) {
                $locale = apply_filters( 'plugin_locale', get_locale(), 'cmb2' );
                $mofile = dirname( __FILE__ ) . '/languages/cmb2-' . $locale . '.mo';
                load_textdomain( 'cmb2', $mofile );
            }
        }
    }
    // Make it so...
    CMB2_Bootstrap_212::initiate();
}
0
1

If you are using a version control (like Git) then using a submodule seems the best way to version a common piece among projects.

Your class as a submodule then becomes a child of multiple parent plugins: https://git-scm.com/book/en/v2/Git-Tools-Submodules

1
  • I don't think it's the same case, as some customers do not update the plugin and the plugin initiate a older version but other plugins require newer versions I only need to initiate the newer version. Commented Dec 1, 2015 at 17:05

Your Answer

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

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