Simplifying WordPress Plugin Development Using Object-Oriented Programming: Part 1 — Bootstrapping The Plugin
Introduction
As a WordPress plugin developer, I have noticed that many people find it difficult to understand certain aspects of WordPress plugin development. This led me to start working on a project to simplify some of the complex WordPress plugin tasks using object-oriented programming. It took me a long time to fully understand how the WordPress settings API works. That is why in my first article, Demystifying WordPress Settings API using OOP, I created a tool that can interact with the WordPress Settings API. In this article, I will show you how you can use the other tools I have created to simplify your WordPress plugin development.
We shall use the following tools in this series:
KMRoute
: A tool that enables you to create custom routes in WordPress.KMMigration
: Creating and managing custom database tables can become a difficult task. This tool allows you to easily create database migrations which will be automatically converted to database tables. It also helps you update an existing table without writing a single SQL command. Can you imagine 😳?KMModel
: This tool makes querying (create, read, update, delete) data in your tables in the WordPress database as easy as ABC. You will be amazed by how much time you can save using this tool.KMValidator
: This tool helps you validate your REST API requests. Gone are the days when you write a dozen if-else statements.KMMenuPage
andKMSubMenuPage
: These tools help you create custom WordPress admin menu items and sub-menu items.
You will see a lot of similarities between these tools and Laravel. I want to thank Taylor Ortwell. Laravel has been my main source of inspiration while building these tools.
Note: The tools used in the article are still under development. A lot may change in the future.
What You Will Learn: Overview
In this article, we will build a question-answer plugin that allows a registered user to ask and answer questions. You can download the codes from the GitHub Repository.
This article assumes you already know how to create a WordPress plugin. I would try my best to simplify the steps as much as I can.
Project Setup
If you have not yet installed WordPress on your PC, you can download and install the latest version from WordPress.org.
In the wp-content/plugins
folder, we will create a new folder called wp-questions
. Next, we will create a blank PHP file, wp-questions.php
in the wp-questions
folder. Your plugin folder should look like this:
Download The Libraries
Before we write any code, let us download the tools from the WordPress Tools GitHub repository. Please leave a star ⭐️ on the repository 🤩.
Next, create a lib
folder in our plugin folder. This folder will contain all the libraries we will need.
Now, let us extract the contents of the zip file into the lib folder
Copy the .env.example
file in the wordpress_tools folder to the plugin’s root directory. Rename the file to .env
Plugin Activation Script
Great 😊 . Now that we have our libraries downloaded, let us set up the plugin activation script. We will use the wp_questions
namespace in all our PHP files
Namespace allows for better organization by grouping classes that work together to perform a task
In the wp-questions.php
file, we add the following code
<?php
namespace wp_questions;
use WordPressTools;
defined( 'ABSPATH' ) or die( 'Giving To Cesar What Belongs To Caesar' );
/**
* @link www.example.org
* @since 1.0.0
* @package wp_questions
*
* @wordpress-plugin
* Plugin Name: WP Questions
* Plugin URI: https://some-url.com
* Description: <<Add Description>>.
* Version: 1.0.0
* Author: Kofi Mokome
* Author URI: https://github.com/kofimokome
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Text Domain: wp-questions
* Domain Path: /languages
*/
/**
* Shows an error message on the admin dashboard
* @since 1.0.0
* @author kofimokome
*/
const WPQ_TEXT_DOMAIN = 'wp-questions';
function ErrorNotice( $message = '' ): void {
if ( trim( $message ) != '' ):
?>
<div class="error notice is-dismissible">
<p><strong>WP Questions: </strong><?php echo esc_attr( $message ) ?></p>
</div>
<?php
endif;
}
add_action( 'admin_notices', 'wp_questions\\ErrorNotice', 10, 1 );
$error = false;
// scan directories for requires.php files
foreach ( scandir( __DIR__ ) as $dir ) {
if ( strpos( $dir, '.' ) === false && is_dir( __DIR__ . '/' . $dir ) && is_file( __DIR__ . '/' . $dir . '/requires.php' ) ) {
require_once __DIR__ . '/' . $dir . '/requires.php';
}
}
$requires = apply_filters( 'kmwpq_requires_filter', [] );
foreach ( $requires as $file ) {
if ( ! $filepath = file_exists( $file ) ) {
ErrorNotice( sprintf( __( 'Error locating <b>%s</b> for inclusion', WPQ_TEXT_DOMAIN ), $file ) );
$error = true;
} else {
require_once $file;
}
}
$wordpress_tools = new WordPressTools( __FILE__ );
// scan directories for includes.php files
foreach ( scandir( __DIR__ ) as $dir ) {
if ( strpos( $dir, '.' ) === false && is_dir( __DIR__ . '/' . $dir ) && is_file( __DIR__ . '/' . $dir . '/includes.php' ) ) {
require_once __DIR__ . '/' . $dir . '/includes.php';
}
}
$includes = apply_filters( 'kmwpq_includes_filter', [] );
foreach ( $includes as $file ) {
if ( ! $filepath = file_exists( $file ) ) {
ErrorNotice( sprintf( __( 'Error locating <b>%s</b> for inclusion', WPQ_TEXT_DOMAIN ), $file ) );
$error = true;
} else {
include_once $file;
}
}
// remove options upon deactivation
register_deactivation_hook( __FILE__, 'wp_questions\\OnDeactivation' );
/**
* Set of actions to be performed on deactivation
* @since 1.0.0
* @author kofimokome
*/
function OnDeactivation(): void {
// set options to remove here
}
register_uninstall_hook( __FILE__, 'wp_questions\\OnUninstall' );
/**
* Set of actions to be performed on uninstallation
* @since 1.0.0
* @author kofimokome
*/
function OnUninstall(): void {
// some code here
}
register_activation_hook( __FILE__, 'wp_questions\\OnActivation' );
/**
* Set of actions to be performed on activation
* @since 1.0.0
* @author kofimokome
*/
function OnActivation(): void {
// some code here
}
// todo: for future use
load_plugin_textdomain( WPQ_TEXT_DOMAIN, false, basename( dirname( __FILE__ ) ) . '/languages' ); . '/languages' );
First, we create a constant, WPQ_TEXT_DOMAIN
that holds our text-domain. The text domain is needed if you would like to make your plugin available in more than one language.
The ErrorNotice
function displays a warning on the WordPress dashboard if a module is not found. To display the error on the admin dashboard, the function is added to the admin_notices
action.
Next, we scan through the directories and imports the files needed for the plugin to function. We will look at it in a bit.
Next, we initialize the WordPress Tools library, passing the location to the plugin as a parameter.
Finally, we register the uninstall hook( OnUninstall
), activation hook ( OnActivation
), deactivation hook ( OnDeactivation
) and the text domain.
Activating The Plugin
We can now go to the plugins page on the WordPress dashboard to activate the plugin by clicking on the Activate
link.
Importing Modules
Now that our plugin is activated, let us import the first modules. To import the modules, we scan through all the sub-directories and import the files that are needed from that sub-directory. The files to import are either placed inside a requires.php
file or an includes.php
file. Files placed in the requires.php
file are imported via the require statement while files in the includes.php
are imported via the include statement. We also see the exposure of two filters:
kmwpg_requires_filter
used to specify the files to be required andkmwpg_includes_filter
which is used to specify the files to be included.
We want to require all the files in the lib directory. We will create a requires.php
file in the lib
folder.
We add the following codes to the requires.php
file to import all the files in the wordpress_tools
folder.
<?php
/**
* Add libraries to be included
*/
add_filter( 'kmwpq_requires_filter', function ( $includes ) {
$plugin_path = plugin_dir_path( __FILE__ );
$files = [
$plugin_path . 'wordpress_tools/WordPressTools.php', //
];
return array_merge( $includes, $files );
} );
Configuring the CLI Script
The WordPressTools ships with a CLI script. To use the script, copy the wptools
file in the wordpress_tools
folder to the root of your plugin
Finally, open your terminal, navigate to the root of your plugin and type php wptools
to see the list of commands
In the next article, we will look at using the KMModel
and the KMMigration
tools to create models and migrations.