Bootstrapping a Plugin

This process is basically to register your plugin with Membership. Membership then handles the plugin's initialization upon resolution of dependencies.

Before we get any further, I'd like to point out that we have 2 main files:

  1. the main plugin file - is located in the root plugin folder and registers core application with the Membership
  2. the core application file - is located in /classes/ directory and executes your plugin business logic.

Schematically it would look like this:

Main Plugin File -> Membership (via bootstrap) -> Core Application File

Step 1: Files & Directories

Directory Structure

Our plugins use the following directory structure:

/wp-content/plugins/
    hji-my-plugin/
        classes/
            controllers/
            models/
            utils/
                PluginBootstrap.php
            views/
            App.php
        resources/
            images/
            scripts/
            styles/        
        templates/
        third-party/
        autoload.php
        my-plugin.php
        readme.txt

Mostly, all plugins consistently use the same structure, except for cases when some directories simply do not apply (i.e.  third-party).

Naming Conventions

Class file names should match the names of their classes following CamelCase pattern.

Files with procedural code like public functions should be lower case (i.e. functions.php).

Scripts, stylesheets and config files should be in lower case as well.

Step 2: Main Plugin File

The main plugin file is the only php file (except autoload.php) that should be located in the plugin's root directory. The same file as illustrated above with the name  my-plugin.php. The autoload.php is a standard file used in all our plugins.

The main file consists of standard WordPress header data and PHP code responsible for plugin activation.

Plugin Header

The plugin header is standard WP header with an addition of 2 custom parameters:

  1. HJI Package: hji-membership - which is always standard for Membership plugins.
  2. HJI Require Plugins: HJI Membership: 2.7.0

HJI Require Plugins accepts a comma-separated list of HJI plugins (i.e. HJI Users:1.0, HJI Responsive IDX:2.0). Each required plugin has to have a corresponding version number, which is treated as  equal or more.

HJI Membership is always required for plugins bootstrapped by Membership.

/*
Plugin Name: HJI {Plugin Name}
Description: {Comprehensive Description}
Plugin URI:
Version: 0.1
Author: Home Junction
Author URI: http://HomeJunction.com
Text Domain: {plugin_textdomain}
License: GPL2
HJI Package: hji-membership
HJI Require Plugins: HJI Membership:2.7.0
*/

/*  Copyright 2018  Home Junction, Inc. (email : help@homejunction.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License, version 2, as
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

Bootstrapping Code

namespace hji\myplugin;

require dirname(__FILE__) . '/autoload.php';

(new utils\PluginBootstrap(__FILE__, App::class))->run()

The code above has only 2 moving parts:

  1. requiring the autoloader to automatically load all our classes;
  2. instantiating PluginBootstrap and passing the current file path and fully qualified namespace for your core application file that will execute business logic of your plugin.

If you look into the source code of the PluginBootstrap, you'll see what  run() method does:

public function run()
{
    $this->registerPlugin();
    $this->setActivationProcedures();
    $this->setDeactivationProcedures();
    $this->setAdminNotices();
}
  1. Registers plugin with Membership
  2. Sets standard plugin activation procedures (you may define your own in your core application)
  3. Sets standard plugin deactivation procedures (you may define your own in your core application)
  4. Sets standard admin notices that may (or may not) show up for the user upon plugin activation/deactivation (think errors).

Step 3: Core Application File

Let's talk about your Core Application file. It's the actual main file that will lead to the business logic of your plugin. In Step 1 (Files & Directories) we referenced this file under  /classes/App.php.

In Step 2 you learned that we simply passed a reference (fully qualified namespace) of your Core Application class into the PluginBootstrap. This means that Membership expects to deal with a known interface, which in our case is  hji\common\Plugin. So, hji\myplugin\App has to extend the hji\common\Plugin class.

Example:

namespace hji\myplugin;

use hji\common\Plugin;
use hji\common\plugin\PluginAPI;


class App extends Plugin
{
    function __construct($mainFilePath, PluginAPI $pluginAPI = null)
    {
        parent::__construct('My Plugin Name', 'hji-my-plugin', $mainFilePath, $pluginAPI);
    }


    function init()
    {
        //@todo do great things!
    }
}

The  hji\common\Plugin has an explicit constructor and we only need to pass the plugin name and slug parameters along with already pre-defined arguments ($mainFilePath and $pluginAPI). It also has an abstract Plugin::init() method, which serves as an entry point into your plugin's code, and has to be defined in your child class (hji\myplugin\App). After Membership instantiates your App class, it will inevitably call the App::init().

Still need help? Contact Us Contact Us