{eac}Doojigger: Custom Extensions

Document Header

Homepage:https://eacDoojigger.earthasylum.com/ Author:EarthAsylum Consulting Contributors:Kevin Burkholder Requires {eac}Doojigger:1.0.0

Custom extensions to {eac}Doojigger or derivatives (add simple to complex extensions using the extension framework)

Description

{eac}Doojigger extensions are, relatively, small PHP classes that extend the main plugin. Typically they are created to address specific requirements for your website or business. An extension focuses on your requirements while having available the full plugin functionality of {eac}Doojigger.

Define the extension class by extending abstract_extension

namespace myAwesomeNamespace\Extensions;
class myAwesomeExtension_extension extends \EarthAsylumConsulting\abstract_extension
{
    public function __construct($plugin)
    {
        parent::__construct($plugin, self::ALLOW_ALL);
        $this->registerExtension( [$this->className, {admin_tab_name}],
            [
                ...option meta data...
            ]
        );
    }
    public function initialize()
    {
    }
    public function addActionsAndFilters()
    {
    }
    public function addShortcodes()
    {
    }
}
return new myAwesomeExtension($this);

The name of the child class must be unique:

  • Required file name : myAwesomeExtension.extension.php or class.myAwesomeExtension.extension.php.
  • Recommended class name : myAwesomeExtension or myAwesomeExtension_extension.
  • Using myAwesomeExtension.myOtherExtension.extension.php will use myOtherExtension_extension_enabled as the 'Enabled' option for myAwesomeExtension.
  • For example: debugging.extension.php and test_api.debugging.extension.php both use debugging_extension_enabled

Instantiating The Extension

The extension file (myAwesomeExtension.extension.php) must return the instantiated class passing $this (the main plugin instance) as the first argument:

return new myAwesomeExtension($this);

The main plugin will automatically load the class/extension file when WordPress triggers the 'plugins_loaded' filter.

The extension must call the parent constructor:

parent::__construct( $plugin, {option_flags} );
  • Sets $this->plugin to the class instance of the main plugin (eacDoojigger).
  • Sets $this->pluginName to the short name of the main plugin (sans namespace - 'eacDoojigger').
  • Sets $this->className to the short name of this extension class (sans namespace - 'myAwesomeExtension').
  • Returns bool (enabled).

The main plugin will then:

  • Fire the eacDoojigger_extensions_loaded action.
  • Call the initialize() method.
  • Fire the eacDoojigger_initialize action.
  • Call the addActionsAndFilters() method.
  • Call the addShortcodes() method.
  • Fire the eacDoojigger_ready action.

Registering The Extension

The extension must register itself in the constructor with:

$this->registerExtension( [$this->className, {admin_tab_name}], [option meta data] );
  • Registers '{classname}_extension_enabled' option for this class.
  • Registers extension options with 'Enabled' checkbox option.
  • Adds options to the {admin_tab_name} tab on the settings page.

The 1st argument may be replaced with another extension's name to append options to that extension & tab:

$this->registerExtension( 'debugging', [...additional debugging options] );

if the extension has no options/settings to register:

$this->registerExtension( [$this->className, {admin_tab_name}]);

if the extension has no options/settings to register AND wants no 'Enabled' option:

$this->registerExtension( false );

If the 1st argument is a string (and not another class name), the options will be added to the 'general' tab:

$this->registerExtension( $this->className, [option meta data] );

if the extension has options/settings to register BUT wants no 'Enabled' option:

$this->enable_option = false; // <- before registerExtension();
$this->registerExtension( [$this->className, {admin_tab_name}], [option meta data] );

Extension Option Flags

The {option_flags} passed to the parent constructor may included any of the abstract_extension constants shown here.

const ALLOW_ADMIN       = 0b00000001;       // enabled on admin pages (default is disabled)
const ONLY_ADMIN        = 0b00000010;       // enabled only on admin pages, not front-end
const ALLOW_NETWORK     = 0b00000100;       // enabled for network admin in multisite (uses network options)
const ALLOW_CRON        = 0b00001000;       // enabled for cron requests
const ALLOW_CLI         = 0b00010000;       // enabled for wp-cli requests
const DEFAULT_DISABLED  = 0b00100000;       // force {classname}_enabled' option to default to not enabled
const ALLOW_ALL         = self::ALLOW_ADMIN|self::ALLOW_NETWORK|self::ALLOW_CRON|self::ALLOW_CLI;

Multiple options are logically OR'd together:

parent::__construct( $plugin, self::ALLOW_ADMIN | self::ONLY_ADMIN | self::ALLOW_NETWORK );

Extension Option Meta Data

Option Meta Data is an array of arrays defining options/settings that can be updated from the plugin's 'settings' page. Each option name is automatically prefixed with the plugin name (i.e. 'eacDoojigger').

An option is defined as:

'my_option_name'   => array(
                        'type'          =>  'type: {input type}',
                        'label'         =>  'label: {field label}',
                        'title'         =>  'title: information text/html to be displayed',
                        'options'       =>  array({option,...}),
                        'default'       =>  'default: {default option or value}',
                        'info'          =>  'info: Information/instructions',
                        'attributes'    =>  html attributes array ['name="value", name="value"']
                ),

See the 'readme.txt' file in the Extras/OptionMetaData folder for details on registering and using options in you plugin and extensions.

Extension Methods

The extension may use:

$this->isEnabled(false);

to disable further calls to the extension

The extension should use:

$this->is_option(optionName [,value]);

to check for option value; returns true|false or actual value, 'Enabled'=true, 'Disabled'=false.

The extension may use:

$this->isNetworkEnabled();

to check if the same extension is enabled at the network level.

The extension should use:

$this->is_network_option(optionName [,value]);

to check network enabled and network option value.

The extension may use:

$this->registerExtensionOptions( $this->className, [option meta data] );

to register additional options (after $this->registerExtension(...)).

Extension Version Updates

If a constant 'VERSION' is set, automatic version checking and update methods may be used. When the VERSION changes:

  • An action is triggered : {pluginname}_version_updated_{extension}.
  • If the method adminVersionUpdate() is defined by the extension, it will be called directly.

Both options take 2 parameters, the previous version and the version being updated.

Extension Method Calling

Extension methods may be called programmatically through the plugin class:

by using:

$this->plugin->callMethod([extensionName, extensionMethodName], [,args...]);

or

$this->plugin->callExtension(extensionName, extensionMethodName [,args...]);

this will attempt to call "extensionMethodName" in the 'extensionName' extensions.

by using:

$this->plugin->callAllExtensions(extensionMethodName [,args...]);

this will attempt to call "extensionMethodName" in all enabled extensions.

Filters and Shortcodes

Through the abstract_extension class, extensions provide a filter to overrids the $this->enabled() method (as part of the method)...

This filter is called for each extension and passes the extension class name as the 2nd argument. Other external code may enable or disable an extension through this filter.

/**
 * filter {pluginName}_extension_enabled allow disabling extensions
 * @param   bool current enabled status
 * @param   string $this->className (extension name)
 * @return  bool enabled value
 */
$this->enabled = $this->plugin->apply_filters( 'extension_enabled', $this->enabled, $this->className );

Filter Examples:

\add_filters( 'extension_enabled', function($enabled,$extension) {
    if ($extension == 'myDisabledExtension') $enabled = false;
    return $enabled;
});

{eac}Doojigger (and derivatives) provides a front-end filter and shortcode that gives access to (nearly) all public methods in extensions.

The filter and shortcode name is the plugin class name ('eacDoojigger'). Arguments include:

  • method='{methodName}', which is made up of the extension name and the extension method (extension.method).
  • args='...', to pass a list of arguments/values.
  • default='...', to set a default value.
  • index='...', to index an item from an array returned by your method.

Filter Examples:

\apply_filters('eacDoojigger', null, [ method='myAwesomeExtension.myCoolMethod' ]);

Shortcode Examples:

['eacDoojigger' method='myAwesomeExtension.myCoolMethod']

Arguments to the filter or shortcode may be passed as a comma-delimited string as 'args='.

\apply_filters('eacDoojigger', null, [ method='myAwesomeExtension.myCoolMethod' args='arg1,arg2,...']);
['eacDoojigger' method='myAwesomeExtension.myCoolMethod' args='arg1,arg2,...']

Extension Debugging

Extensions may implement a debugging filter to provide debugging/state information

/*
 * filter {pluginname}_debugging get debugging information
 * param    array   current array
 * return   array   extended array with [ extension_name => [key=>value array] ]
 */
add_filter( '{pluginname}_debugging', array($this, 'my_debugging'));

public function my_debugging($debugging_array)
{
    $debugging_array[$this->className] = array(
                'somekey'   => 'somevalue',
                'anotherkey'=> 'anothervalue',
    )
    return $debugging_array;
}

Extension Plugin

A simple plugin can be created to add extensions to an existing plugin (eacDoojigger) that are outside of the plugin folder. This new plugin answers a filter to point to a separate Extensions directory.

/**
 * Plugin Name: My Awesome Extensions
 */
namespace myAwesomeNamespace;

class myAwesomeExtensions
{
    public function __construct()
    {
        add_filter( 'eacDoojigger_load_extensions', function($extensionDirectories)
            {
                $extensionDirectories[ plugin_basename( __FILE__ ) ] = [ plugin_dir_path( __FILE__ ).'/Extensions' ];
                return $extensionDirectories;
            }
        );
    }
}
new \myAwesomeNamespace\myAwesomeExtensions();

Extensions are then placed in the '.../myAwesomeExtensions/Extensions' folder

Extras

Extensions in the eacDoojigger 'Extras' folder can be easily loaded in a new plugin by creating a new extension object that points to the extras in the constructor.

    $this->add_filter( 'load_extensions',   function($extensionDirectories)
        {
            $extensionDirectories[ plugin_basename( __FILE__ ) ] = [WP_PLUGIN_DIR.'/eacDoojigger/Extras/eacCodeInjection/Extensions'];
            return $extensionDirectories;
        }
    );

Extensions in the eacDoojigger 'Extensions' folder can be easily cloned (and auto-loaded) in a new plugin by creating a new extension object from the class.

namespace EarthAsylumConsulting\Extensions;

if ( class_exists(__NAMESPACE__.'\session_extension') )
{
    /**
     * return a new instance of this class
     */
    return new session_extension($this);
}

Skeleton/Framework

There is a complete, functional skeleton of these examples in the 'Extras' folder of {eac}Doojigger that you can use to build your extensions by simply changing the namespace name, plugin name, extension name, and adding your own code.

Top
Screen Shots
  1. My Awesome Plugin with My Awesome Extension myAwesomeExtension
Top
Other Notes
  • Extensions in the plugin 'Extensions' folder are automatically loaded.
  • Extensions in the plugin '{namespace}/Extensions' folder are automatically loaded.
  • Extensions in a 'admin' or 'backend' folder are only loaded for admin requests.
  • Extensions in a 'network' folder are only loaded for network admin requests.
  • Extensions in a 'public' or 'frontend' folder are only loaded for front-end requests.
  • Other directory names in the Extensions folder may be used to categorize extensions.
  • Directory or extension names beginning with '-', '_' or '.' are ignored (disabled).
  • New extensions can be added by placing them in one of the plugin 'Extensions' folders. However, when the plugin is updated, those extensions will be lost and must be re-installed. A better alternative is to create an extension plugin to add new extensions.
Top

    Write a Reply or Comment

    Your email address will not be published.


    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>