These are a set of helper classes that will make WordPress plugin development easier
Read this Article on Medium to find out how to use these tools.
- Copy the extracted folder to your plugin directory
- Copy the .env.example to the root of your plugin and rename the file to .env. Then update the values in the .env
- If you would like to use the
wptoolscommand line interface:- Copy/move the
wptoolsfile to the root of your plugin - In your
.envfile, make sure to set theWPTOOLS_DIRandNAMESPACEvariables. - cd to the root of your plugin and run
php wptoolsfor the list of commands.
- Copy/move the
$ php wptools- Import the
WPTools.phpfile in your plugin main file and instantiate the class.
$wordpress_tools = new WPTools( __FILE__ );To get the instance of the WPTools class from any file in your plugin, you can use the get_instance() method.
NOTE: An exception is thrown if you have not created an instance of the WPTools class.
$wordpress_tools = WPTools::get_instance(__FILE__);The WPTools provides an easy-to-use interface for managing database migrations.
Before you can use the migrations, you need to make sure you have done the following:
- Make sure you have created a folder to store the migrations in your plugin
- Make sure you have set the
MIGRATIONS_DIRvariable in your.envfile to this folder. - Make sure you have set the
TABLE_PREFIXvariable in your.envfile to this folder. The table prefix helps to avoid conflicts with other plugins.
To create a migration, you can use the make:migration command.
The command takes one argument which is the name of the migration.
The name of the migration should be in the format create_table_name_table or add_column_name_to_table
or remove_column_name_from_table
NOTE: The migration name should be in snake case.
$ php wptools make:migration create_users_tableYou can also specify the name of the table using the --table option
$ php wptools make:migration create_users_table --table=usersA new migration file will be created the migrations folder.
The file name will be in the format YYYYMMDDHHMMSS_migration_name.php
You can specify the commands to run in the up and down methods of the migration class.
class CreateMessagesTable extends KMMigration {
protected $table_name = 'messages';
public function up( KMBlueprint $blueprint ) {
$blueprint->id();
$blueprint->string( 'contact_form' );
$blueprint->string( 'form_id' );
$blueprint->text( 'message' );
$blueprint->timestamps();
}
public function down( KMBlueprint $blueprint ) {
$blueprint->drop();
}
}To run migrations, you need to add the code below to your plugin main file.
$wordpress_tools = new WPTools( __FILE__ );
$wordpress_tools->migration_manager->runMigrations();Rolling back a migration can be done using the dropMigration method in the migration_manager.
The method takes two arguments which are the name of the migration to be rolled back and an optional delete file boolean
flag, which is try by default.
NOTE Deleting a migration can lead to an infinite loop if the delete flag is set to false. We recommend you leave the delete flag as true.
$migration = $wordpress_tools->migration_manager->getMigration('create_users_table');
$wordpress_tools->migration_manager->dropMigration($migration);You can also use the dropAll method to drop all migrations.
$wordpress_tools->migration_manager->dropAll();If you want to create a migration to update/alter a table, you must add the --update flag when creating the
migration.
$ php wptools make:migration add_slug_to_questions_table --table=questions --updateAn update migration will have the is_update property set to true
class AddSlugToQuestionsTable extends KMMigration {
protected $table_name = 'questions';
protected $is_update = true;
public function up( KMBlueprint $blueprint ) {
$blueprint->string( 'slug', 100 );
}
public function down( KMBlueprint $blueprint ) {
$blueprint->dropColumn( 'slug' );
}
}You can use models to query the database, without writing a single SQL command.
The WPTools provides an easy-to-use interface for query the database. Before you can use the model, you need to
make sure you have done the following:
- Make sure you have created a folder to store the models in your plugin
- Make sure you have set the
MODELS_DIRvariable in your.envfile to this folder.
To create a model, you can use the make:model command.
The command takes one argument which is the name of the model.
The name of the model should be in the format ModelName
NOTE: The model name should be in Pascal case.
$ php wptools make:model UserThe model will be created in the models directory, a typical model will look like this:
class User extends KMModel {
}By default, the User model will automatically point to the users table in your plugin ([your_table_prefix]_users).
If you want to link the model
to another table, say the default WordPress users table, add the --table flag to the command
$ php wptools make:model User --table=wp_usersThe table property will be automatically set.
class User extends KMModel {
protected $table_name = 'wp_users';
}The KMModel class provides two other options for customizing your model.
protected $timestamps = false;
protected $soft_delete = false;- The
$timestampsproperty, if set is true tells the model to automatically update the created_at and updated_at columns when creating or updating a record.
You can use the$blueprint->timestamps();statement to add the created_at and updated_at columns to your migration. - The
$soft_deleteproperty, if set is true tells the model to automatically update the deleted_at column when deleting a record
You can use the$blueprint->softDelete();statement to add the deleted_at column to your migration.
To add a new record, you can create a new instance of the model class and call the save method on the instance.
$message = new Message();
$message->contact_form = 'cf7';
$message->form_id = 2;
$message->message = 'Hello World!';
$message->save();To update a record, you can use the save method on the model.
$message = Message::find(1);
$message->contact_form = 'cf7';
$message->form_id = 2;
$message->message = 'Hello World Edited!';
$message->save();To delete a record, you can use the delete method on the model.
$message = Message::find(1);
$message->delete();If your migration has the soft_delete column, you can use the softDelete method
$message = Message::find(1);
$message->softDelete();The delete method automatically calls the softDelete method if the soft_delete property is set to true.
- You can retrieve a single record using the
findmethod on the model.
$message = Message::find(1);The find method takes one argument which is the id of the record to be retrieved. It returns the record or null if it
not found
- You can retrieve all records using the
allmethod on the model.
$messages = Message::all();The all method takes no argument and returns an array of all the records in the table.
- You can also retrieve records using the
wheremethod on the model.
$messages = Message::where( 'contact_form', '=', 'cf7' )->get();- The model class supports method chaining
$messages = Message::where( 'contact_form', '=', 'cf7' )
->where( 'form_id', '=', 2 )
->get();- The
firstmethod can be used to retrieve the first record that matches the query
$message = Message::where( 'contact_form', '=', 'cf7' )
->where( 'form_id', '=', 2 )
->first();- The
takemethod can be used to limit the number of records to be retrieved
$messages = Message::where( 'contact_form', '=', 'cf7' )
->where( 'form_id', '=', 2 )
->take( 10 );- The
orderBymethod can be used to order the records
$messages = Message::where( 'contact_form', '=', 'cf7' )
->orderBy( 'created_at', 'desc' )
->get();- The
groupBymethod can be used to group the records
$messages = Message::groupBy( 'contact_form' )
->get();- The
orWhereandandWheremethods can be used to add or and where clauses to the query
$messages = Message::where( 'contact_form', '=', 'wp_form' )
->orWhere( 'contact_form', '=', 'cf7' )
->get();- You can also perform joins using the
innerJoin,leftJoin, andrightJoinmethods
$applications = JobApplication::orderBy($sort_by, $order);
$applications->leftJoin('jobs')
->on('job_id', 'id')
->leftJoin('accounts')
->on('account_id', 'id');
$results = $applications->get();The table prefix will be automatically added to the table name in the join. For example, jobs will
become [table_prefix]_jobs.
If you do not want to add the table prefix, you can set the second parameter of the join methods to false.
$applications = JobApplication::orderBy($sort_by, $order);
$applications->leftJoin('jobs', false)
->on('job_id', 'id')
->leftJoin('accounts', false)
->on('account_id', 'id');
$results = $applications->get();- The
selectmethod can be used to get particular fields from the result
$messages = Message::select( ['id', 'message'] )->where( 'contact_form', '=', 'cf7' )
->where( 'form_id', '=', 2 )
->get();or
$messages = Message::select( 'id, message' )->where( 'contact_form', '=', 'cf7' )
->where( 'form_id', '=', 2 )
->get();- The
paginatemethod can be used to paginate the results
$messages = Message::where( 'contact_form', '=', 'cf7' )
->where( 'form_id', '=', 2 )
->paginate( 10 );The paginate method takes two parameters: the first is the number of records to be displayed per page and the second
is the current page number.
$applications = JobApplication::paginate($per_page, $page)->orderBy($sort_by, $order);
$applications->leftJoin('jobs', false)
->on('job_id', 'id')
->leftJoin('accounts', false)
->on('account_id', 'id');
$select_fields = [
JobApplication::tableName() . '.*',
Job::tableName() . '.name AS job_name',
Job::tableName() . '.slug AS job_slug',
Account::tableName() . '.name AS account_name ',
];
$results = $applications->get( $select_fields);The paginate method returns an array with the following properties:
$data = [
'data' => [], // the results
'page' => 1,
'totalPages' => 10,
'perPage' => 2,
'totalItems' => 100
];You can use the KMValidator class to validate your API requests.
$validator = KMValidator::make( [
'title' => 'required',
'content' => 'required',
], $_POST );The KMValidator class takes two parameters, the first is an array of rules and the second is the data to be validated.
To run the validation, call the validate method on the validator object.
$validator->validate();The validate method returns a 400 response if the validation fails. It can also return a boolean.
Always check if the validation is successful before using the data.
if ( $validator->validate() ) {
// use the data
}You can validate the request while instantiation the KMValidator class
$validator = KMValidator::validate( [
'title' => 'required',
'content' => 'required',
], $_POST );You can pass more than one rule to a field by separating them with a pipe |.
$validator = KMValidator::validate( [
'title' => 'required|numeric',
'content' => 'required',
], $_POST );The following rules are available:
required- The field is requirednumeric- The field must be a numeric valueinteger- The field must be an integerbool- The field must be a boolean value (true or false) or (1 or 0)pdf- The field must be a pdf file
a. In a class
$menu_title = 'CF7 Form Filter';
$menu_page = new KMMenuPage(
array(
'page_title' => 'CF7 Form Filter',
'menu_title' => $menu_title,
'capability' => 'read',
'menu_slug' => 'kmcf7-message-filter',
'icon_url' => 'dashicons-filter',
'position' => null,
'function' => array(
$this,
'dashboard_view'
)
) );
$menu_page->run();b. Not in a class
$menu_title = 'CF7 Form Filter';
$menu_page = new KMMenuPage(
array(
'page_title' => 'CF7 Form Filter',
'menu_title' => $menu_title,
'capability' => 'read',
'menu_slug' => 'kmcf7-message-filter',
'icon_url' => 'dashicons-filter',
'position' => null,
'function' => 'dashboard_view'
) );
$menu_page->run();$menu_title = 'CF7 Form Filter';
$menu_page = new KMMenuPage(
array(
'page_title' => 'CF7 Form Filter',
'menu_title' => $menu_title,
'capability' => 'read',
'menu_slug' => 'kmcf7-message-filter',
'icon_url' => 'dashicons-filter',
'position' => null,
'function' => array(
$this,
'dashboard_view'
)
) );
$messages_page = new KMSubMenuPage(
array(
'parent_slug' => $menu_page->get_menu_slug(),
'page_title' => 'Blocked Messages',
'menu_title' => 'Blocked Messages',
'capability' => 'manage_options',
'menu_slug' => 'kmcf7-filtered-messages',
'position' => 1
'function' => array(
$this,
'messages_view'
)
) );
$menu_page->add_sub_menu_page( $messages_page );
$menu_page->run(); $settings_page = new KMSubMenuPage(
array(
'parent_slug' => $menu_page->get_menu_slug(),
'page_title' => 'Settings',
'menu_title' => 'Settings',
'capability' => 'manage_options',
'menu_slug' => 'kmcf7-message-filter-options',
'function' => array(
$this,
'settings_view'
),
'use_tabs' => true
) );
$settings_page->add_tab( 'basic', 'Basic Settings', array(
$this,
'status_tab_view'
), array( 'tab' => 'basic' ) );
$settings_page->add_tab( 'advanced', 'Advanced Settings', array(
$this,
'status_tab_view'
), array( 'tab' => 'advanced' ) );
$settings_page->add_tab( 'plugins', 'More Plugins', array(
$this,
'status_tab_view'
), array( 'tab' => 'plugins' ) );
$menu_page->add_sub_menu_page( $settings_page );public function status_tab_view( $args ) {
switch ( $args['tab'] ) {
case 'plugins':
include "views/settings/plugins.php";
break;
case 'advanced':
include "views/settings/advanced.php";
break;
default:
include "views/settings/basic.php";
break;
}
}The KMSetting class is a wrapper for the WordPress Settings API. It provides a simple way to create settings page with sections and fields.
$settings = new KMSetting( 'kmcf7-message-filter-options&tab=advanced' );
$settings->add_section( 'kmcfmf_message_filter_advanced' );
$settings->add_field(
array(
'type' => 'checkbox',
'id' => 'kmcfmf_message_storage_toggle',
'label' => 'Disable file storage: ',
'tip' => "<span class='text-danger' style='color:red;'>Note: This is an experimental feature.</span><br/>Blocked messages are currently stored in a file. <br/>If you are unable to view blocked messages, disable this option. <br/> <b>Note: </b> Auto delete will be activated if it's currently not enabled"
)
);
$settings->add_field(
array(
'type' => 'checkbox',
'id' => 'kmcfmf_message_auto_delete_toggle',
'label' => 'Auto delete messages: ',
'tip' => ''
)
);
$settings->add_field(
array(
'type' => 'number',
'id' => 'kmcfmf_message_auto_delete_duration',
'label' => 'Number of days: ',
'tip' => '',
'min' => 1,
'max' => ''
)
);
$settings->add_field(
array(
'type' => 'select',
'id' => 'kmcfmf_message_auto_delete_duration',
'label' => 'Number of days: ',
'options' => array(
'1 Month' => '30',
'1 Day' => '1',
'3 Days' => '3',
'1 Week' => '7',
'2 Weeks' => '14',
),
// 'default_option' => ''
)
);
$settings->add_field(
array(
'type' => 'select',
'id' => 'kmcfmf_message_auto_delete_amount',
'label' => 'Number of messages to delete: ',
'options' => array(
'10 Messages' => '10',
'20 Messages' => '20',
'40 Messages' => '40',
'80 Messages' => '80',
),
// 'default_option' => ''
)
);
$settings->save();$default_data = array(
'type' => '',
'id' => '',
'label' => '',
'tip' => '',
'min' => '',
'max' => '',
'input_class' => '', // class for input element
'class' => '', // class for parent element
'options' => array( 'Select a value' => '' ),
'default_option' => '',
'autocomplete' => 'on',
'placeholder' => ''
);You can display the form using
$settings->show_form();Alternatively, you don't want to use show_form(), you can display the form with your own code
<?php
?>
<h2>Advanced Settings </h2>
<?php settings_errors(); ?>
<form method="post" action="options.php">
<?php
settings_fields( 'kmcfmf_message_filter_advanced' );
do_settings_sections( 'kmcf7-message-filter-options&tab=advanced' );
submit_button();
?>
</form>
<?php-
Do not create the setting in the callback function of a menu or submenu, this will not allow the helper to hook into the
admin_initaction.You can either call the
show_form()method in the menu page callback function or write the code manually to display the form (as shown above) in the callback function -
If you get
Options page not found in the allowed options list.error, set your munu slug as the section id More Info Here