« PluginMaster is an Application development framework for WordPress. It changes the flavor of plugin development.»
- Database Migration System
- Simple Side Menu Declaration
- Simple Rest API Declaration
- Database Query Builder
- Simple Enqueue Declaration
- Http Request Handling
- Request Validation
- Build-in Vue JS Configuration
- Global Functions
- Session Handler
- Middleware (upcoming)
- Action Handler (upcoming)
- Filter Handler (upcoming)
- Go to
wp-content/plugins/
directory in your WordPress - Open terminal and run :
composer create-project plugin-master/plugin-master
ORcomposer create-project plugin-master/plugin-master project_name
- A demo application includes with Vue JS . Just active from Plugin section
- Change your Plugin name, version etc from
index.php
page in root folder. - Change Rest API Namespace from
config.php
, located inapp/config/
directory (You can add any configuration related data inconfig.php
)
Migrations are typically paired with the PluginMaster schema builder to build your application's database schema. When plugin activates, all migration migrate to the database and when deactivate plugin, all table will be deleted. You just need to define the migration file.
Migration file directory :database/migrations/
Structure
The migration file name has 2 parts :
- First for sequence maintain for foreign key and second for the table name. Second part must be the same as table name .
Also class name will be the same as the table name.
File name like :1_demo_users.php
. This means,1
is for sequence maintain anddemo_users
is the table name and also class name. the table prefix will be set from the schema builder.
A migration class contains one method: up. The up method is used to add new tables to your database.
Sample Migration FileFile Name: 1_demo_users.php
use App\system\schema\Schema;
class demo_users
{
public function up()
{
return Schema::create('demo_users', function (Schema $column) {
$column->intIncrements('id');
$column->string('name')->nullable() ;
$column->string('mobile') ;
$column->string('email')->nullable();
$column->text('description')->nullable();
$column->enum('status', ['ok', 'not']);
$column->integer('user_id')->unsigned()->nullable();
$column->foreign('user_id')->on('demo_users.id');
$column->timestamp('student_created_at')->default('current_timestamp')->onUpdateTimeStamp();
});
}
}
Schema Functions
-
intIncrements($column)
: integer (10), auto_increment, primary key -
bigIntIncrements($column)
: bigint (20), auto_increment, primary key -
integer($column, $length = 10)
: integer (10) -
bigInt($column, $length = 20)
: bigint (20) -
decimal($column, $length = 20, $places = 2)
: decimal (20, 2) -
text($column)
: text -
enum($column, $values)
: enum( value, value) ($values must be array). -
date($column)
: date -
timestamp($column)
: timestamp -
nullable()
: null -
unsigned()
: unsigned -
default($value)
: default 'value' (if $value == 'CURRENT_TIMESTAMP' OR 'current_timestamp' then setCURRENT_TIMESTAMP
-
onUpdateTimeStamp()
: ON UPDATE CURRENT_TIMESTAMP -
foreign($column)
: make CONSTRAINT for foreign key -
on($reference)
: $reference means table.column. check following example.$column->integer('user_id')->unsigned(); $column->foreign('user_id')->on('demo_users.id');
Create a WP side menu in easy way. just declare your side nav with controller, method &, etc.
Side Menu declaration file : routes/sidenav.phpSide Menu Controller must declare inside : app/controller/sidenav/
Sample Structure
$sidenav->main('DemoPlugin', ["icon" => "dashicons-admin-site", "as" => 'DemoController@main', "position" => 500, "removeFirstSubmenu" => true], function ($sidenav) {
$sidenav->sub('Dashboard', ["title" => "Dashboard", "as" => 'DemoController@sub']);
});
The main method
has three parameters..
- One : menu slug . (Required)
- Two : menu options . Its type must be an array.
Mandatory index: icon (dashboard icon), as ( controller and method must be with@
sign)
Optional index: position (default is 500), removeFirstSubmenu ( for delete first submenu, default false)
- Third: closer function for registering submenu under main menu
The sub method
has two parameters.
- One : menu slug . (Required)
- Two : menu options . Its type must be an array.
Mandatory index: title (Menu Title), as ( controller and method must be with@
sign)
In
Optional index: position (default is 500), removeFirstSubmenu ( for delete first submenu, default false)DemoController@main
:DemoController
is controller name located atapp/controller/sidenav/
andmain
is method name of DemoController
- Third: closer function for registering submenu under main menu
The sub method
has two parameters.
- One : menu slug . (Required)
- Two : menu options . Its type must be an array.
Mandatory index: title (Menu Title), as ( controller and method must be with@
sign)
In
DemoController@main
:DemoController
is controller name located atapp/controller/sidenav/
andsub
is method name of DemoController
Create WP rest route in easy way.
Rest Route declaration file : routes/route.php
Rest Route Controller must declare inside : app/controller/api/
API Namespace: Namespace maintain by api_namespace
of config.php. It's located in app/config/config.php
Sample Structure
$route->get('dashboard/{id?}', 'DemoController@dashboard');
$route->post('add-note', 'DemoController@addNote');
$route->post('update-note', 'DemoController@addNote', true);
DemoController
is controller name and dashboard
is method name , located in app/controller/api/
directory
PluginMaster has two methods: GET, POST
Both Route has 3 parts/parameters
- First Parameter: Route Name
- Dynamic Parameter :
{parameter_name}
- Dynamic Optional Parameter :
{parameter_name?}
- Access Dynamic Param in Controller's method : set parameter like :
function dashboard($variable)
then$variable['param_name']
- Dynamic Parameter :
- Second Parameter: Conteoller and Method Name ( with @ sign)
- Third Parameter : CSRF protection (Optional).Default value false. If you set true, can not access this route without WP Nonce Token . You must pass token in header with
X-WP-Nonce: token
PluginMaster's database query builder provides a convenient, fluent interface to run database queries. It can be used to perform most database operations in your application.
Namespace:PluginMaster\DB\DB;
DB Functions
- Retrieving A Single Row
DB::table('users')->first();
- Retrieving A multiple Row
DB::table('users')->get();
where($column, $value )
:DB::table('users') ->where('id', 1) ->get()
DB::table('users') ->where(function($query){ $query->where('id', 1); $query->orWhere('name', "name"); }) ->get()
orWhere($column, $value)
:DB::table('users') ->where('id', 1) ->orWhere('name', "name") ->get()
DB::table('users') ->where('id', 1) ->orWhere(function($query){ $query->where('field', 'value); $query->where('field', 'value); }) ->first()
whereRaw($query)
:DB::table('users') ->whereRaw('id = 1') ->first()
orWhereRaw($query)
:DB::table('users') ->whereRaw('id = 1') ->orWhereRaw('id = 1') ->first()
orderBy($columns, $direction)
:DB::table('users') ->orderBy('id', 'desc')
DB::table('users') ->orderBy('id,name', 'desc')
groupBy($columns)
:DB::table('users') ->groupBy('id')
DB::table('users') ->groupBy('id,name')
limit($number)
:DB::table('users') ->where('id', 1) ->limit(number)->get()
offset($number)
:DB::table('users') ->where('id', 1) ->limit(number)->offset(number)->get()
select($fields)
:DB::table('users') ->select('id,name') ->get()
insert($data)
:DB::table('users') ->insert(['name' => "demo"])
update($data,$where)
:DB::table('users') ->where('id', 1) ->update(['name' => "demo"])
delete($where)
:DB::table('users') ->where('id', 1) ->delete()
join($table, $first, $operator = null, $second = null) (INNER JOIN)
:DB::table('demo_notes as n') ->join('demo_users as u', 'u.id', '=', 'n.user_id') ->first()
DB::table('demo_notes as n') ->join('demo_users as u', function($query){ $query->on( 'u.id', '=', 'n.user_id') $query->orOn( 'u.id', '=', 'n.user_id') }) ->first()
DB::table('demo_notes as n') ->join('demo_users as u', function($query) use($request){ $query->on( 'u.id', '=', 'n.user_id') $query->onWhere( 'u.id', '=', $request->id) }) ->first()
Note: Must use table alias for using join or leftJoin.
-
leftJoin($table, $first, $operator = null, $second = null) (LEFT JOIN)
: Same as join() transaction()
:DB::startTransaction(function(){ DB::table('demo_notes') ->insert([ "note" => "Hello", ]); })
DB::startTransaction(function(DB $query){ $query->table('demo_notes') ->insert([ "note" => "Hello", ]); })
Easy way to add css and js file to application
Enqueue Declaration file : enqueue/enqueue.phpPlugin Deactivation Script Declaration : enqueue/deactiveAction.php
Functions
headerScript($path) :
:
$enqueue->headerScript('assets/js/index.js');
headerScriptCdn($path) :
:
$enqueue->headerScriptCdn('http://alemran.me/js/index.js');
footerScript($path) :
:
$enqueue->footerScript('assets/js/index.js');
footerScriptCdn($path) :
:
$enqueue->footerScriptCdn('http://alemran.me/js/index.js');
style($path) :
:
$enqueue->style('assets/css/style.css');
styleCdn($path) :
:
$enqueue->style('assets/js/index.css');
-
csrfToken($handler, $objectName):
:
$enqueue->footerScript('assets/js/index.js','DemoScriptIndex'); $enqueue->csrfToken('DemoScriptIndex','corsData');
DemoScriptIndex
is Handler andcorsData
is object name. You can access api ROOT url and token corsData object.Note: CSRF token must define under a js file's Handler.
$enqueue->hotScript('file_name.js')
for Webpack (DevServer) hot mode with Vue js (main url will behttp://localhost:8080/file_name.js
)
Easy way to access request data from native or AJAX request
No need isset function to check. just call$request->name
, it will return null if not
set Example
use App\system\request\Request;
$request = new Request();
echo $request->name;
Access Header: $request->header(name)
Get All Data as Array: $request->all()
Check Request Method : if($request->isMethod('post')){}
Validate data is easy in PluginMaster
Manually Validate ( not compatible for REST API) :
use App\system\Validator;
$validator = Validator::make($request, [
'ID' => 'required|number|limit:10,11',
'name' => 'required|wordLimit:10,20',
'slug' => 'required|noSpecialChar',
]);
if ($validator->fails()) {
$errors = $validator->errors();
}
For checking validation fail: $validator->fail();
.
For Validation errors: $validator->errors()
.
You can use $validator->flashErrors();
for flashing errors as flash session and you can access all flashed errors through formErrors()
global function. Also you can access single field error through formError(field name).
Display Errors in View file :
In controller
use App\system\Validator;
$validator = Validator::make($request, [
'ID' => 'required|number|limit:10,11',
'name' => 'required|wordLimit:10,20',
'slug' => 'required|noSpecialChar',
]);
if ($validator->fails()) {
$errors = $validator->formErrors();
}
In view file
ORif ( count(formErrors()) ) : <div class="alert alert-danger"> <ul> <php foreach (formErrors() as $key=>$value): ?> <li> <php echo $value; ?> </li> <php endforeach; ?> </ul> </div> <php endif; ?>
<input type="text" name="email"> <p> <php formError('email'); ?> </p>
You can pass errors to view file with compact
view('path to view', compact('errors'));
Stopping On Validation Failure (Compatible for REST API) : If validation fail then stop other execution, just return validation errors.
Example:
use App\system\request\Request; $request = new Request(); $request->validate([ 'name' => 'required', ]);
Error will return as like following:
[
"message" => "Validation failed",
"errors" => [
"name" => "name Field is required"
]
]
Available Validation:
- required
- mobile (start with zero and must be in 0-9)
- number
- floatNumber
- noNumber( accept all character without number)
- letter( accept only letter :A-Za-z))
- noSpecialChar
- limit: min, max
- wordLimit: min, max
Build Vue JS application with your plugin
Configuration
Configuration file located in root directory as webpack.config.js
.
Vue js files Default directory is : resources/js
.
Run : npm run dev
. (for development mode)
Run : npm run watch
. (for on-change build)
Run : npm run hot
. (for on-change build and reload) (default hot mode(webpack dev server) listen from port 8080. if you run this command , you must declare $enqueue->hotScript('file_name.js')
in enqueue .
Configuration for Build
const buildConfig = [
{
source: 'resources/js/app.js',
outputDir: 'assets/js', // targeted output directory name
outputFileName: 'app' // can be with .js extension
}
];
const buildConfig = [
{
source: 'resources/js/app.js',
outputDir: 'assets/js', // targeted output directory name
outputFileName: 'app' // can be with .js extension
} ,
{
source: 'resources/js/nextApp.js',
outputDir: 'assets/js', // targeted output directory name
outputFileName: 'nextApp' // can be with .js extension
}
];
view()
: root of view file :resources/view/
. you have to pass only file name withour extention . Example:view('home/index')
.
Also you can pass data to view withcompact
$title = "......"; $data = [] ; return view('home/index', compact('title', 'data'))
-
json($data, $code)
: for returning as json with status code -
config($key)
: for returning configuration data. you can set/ change configuration data from :add/config/config.php
-
current_url()
: for current url -
formErrors()
: for form validation errors as array -
formError($field_name)
: for single field validation error -
session_flush($key, $value = null)
: for getting and setting flush session -
session($key, $value = null)
: for getting and setting session
- Get OR Set Flush Session:
Session::flush(key)
for getting onetime Session andSession::flush(key, value)
for setting onetime session.Flush session unset after page loading completed
- Set Session:
Session::flush(key, value)
- Get Session:
Session::get(key)
- Forget Session:
Session::forget(key)
The MIT License (MIT)
Developed by : AL EMRAN
Assalamu Alikum ! You can donate for the project.