/PluginMaster

An application development framework for WordPress

Primary LanguagePHP

PluginMaster (an Application Development Framework for WordPress)

What is PluginMaster?

« PluginMaster is an Application development framework for WordPress. It changes the flavor of plugin development.»

Code Features

  1. Database Migration System
  2. Simple Side Menu Declaration
  3. Simple Rest API Declaration
  4. Database Query Builder
  5. Simple Enqueue Declaration
  6. Http Request Handling
  7. Request Validation
  8. Build-in Vue JS Configuration
  9. Global Functions
  10. Session Handler
  11. Middleware (upcoming)
  12. Action Handler (upcoming)
  13. Filter Handler (upcoming)

Installation

  1. Go to wp-content/plugins/ directory in your WordPress
  2. Open terminal and run : composer create-project plugin-master/plugin-master OR composer create-project plugin-master/plugin-master project_name
  3. A demo application includes with Vue JS . Just active from Plugin section
# Configuration
  1. Change your Plugin name, version etc from index.php page in root folder.
  2. Change Rest API Namespace from config.php, located in app/config/ directory (You can add any configuration related data in config.php )

1. Database Migration System

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 :

  1. 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 and demo_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 File

File 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

  1. intIncrements($column) : integer (10), auto_increment, primary key
  2. bigIntIncrements($column) : bigint (20), auto_increment, primary key
  3. integer($column, $length = 10) : integer (10)
  4. bigInt($column, $length = 20) : bigint (20)
  5. decimal($column, $length = 20, $places = 2) : decimal (20, 2)
  6. text($column) : text
  7. enum($column, $values) : enum( value, value) ($values must be array).
  8. date($column) : date
  9. timestamp($column) : timestamp
  10. nullable() : null
  11. unsigned() : unsigned
  12. default($value) : default 'value' (if $value == 'CURRENT_TIMESTAMP' OR 'current_timestamp' then set CURRENT_TIMESTAMP
  13. onUpdateTimeStamp() : ON UPDATE CURRENT_TIMESTAMP
  14. foreign($column) : make CONSTRAINT for foreign key
  15. on($reference) : $reference means table.column. check following example.
        
    $column->integer('user_id')->unsigned();
    $column->foreign('user_id')->on('demo_users.id'); 
    

2. Simple Side Menu Declaration

Create a WP side menu in easy way. just declare your side nav with controller, method &, etc.

Side Menu declaration file : routes/sidenav.php
Side 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..

  1. One : menu slug . (Required)
  2. 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)
  3. Third: closer function for registering submenu under main menu

The sub method has two parameters.

  1. One : menu slug . (Required)
  2. 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 at app/controller/sidenav/ and main is method name of DemoController
    Optional index: position (default is 500), removeFirstSubmenu ( for delete first submenu, default false)
  3. Third: closer function for registering submenu under main menu

The sub method has two parameters.

  1. One : menu slug . (Required)
  2. 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 at app/controller/sidenav/ and sub is method name of DemoController

3. Easy Rest API Route Declaration

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
    1. Dynamic Parameter : {parameter_name}
    2. Dynamic Optional Parameter : {parameter_name?}
    3. Access Dynamic Param in Controller's method : set parameter like : function dashboard($variable) then $variable['param_name']
  • 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

4. DB Query Builder

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
  1. Retrieving A Single Row
    DB::table('users')->first();
  2. Retrieving A multiple Row
    DB::table('users')->get();
  1. 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()
  2. 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()
  3. whereRaw($query) :
    DB::table('users')
         ->whereRaw('id = 1')
         ->first()
  4. orWhereRaw($query) :
    DB::table('users')
         ->whereRaw('id = 1')
         ->orWhereRaw('id = 1')
         ->first()
  5. orderBy($columns, $direction) :
    DB::table('users')
         ->orderBy('id', 'desc')
    DB::table('users')
         ->orderBy('id,name', 'desc')
  6. groupBy($columns) :
    DB::table('users')
         ->groupBy('id')
    DB::table('users')
         ->groupBy('id,name')
  7. limit($number) :
    DB::table('users')
         ->where('id', 1)
         ->limit(number)->get()
  8. offset($number) :
    DB::table('users')
         ->where('id', 1)
         ->limit(number)->offset(number)->get()
  9. select($fields) :
    DB::table('users')
         ->select('id,name')
            ->get()
  10. insert($data) :
    DB::table('users')
         ->insert(['name' => "demo"])
  11. update($data,$where) :
    DB::table('users')
         ->where('id', 1)
         ->update(['name' => "demo"])
  12. delete($where) :
    DB::table('users')
         ->where('id', 1)
         ->delete()
  13. 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.
  14. leftJoin($table, $first, $operator = null, $second = null) (LEFT JOIN): Same as join()
  15. transaction():
    DB::startTransaction(function(){
        DB::table('demo_notes')
          ->insert([
             "note" => "Hello",
           ]);
    })
    DB::startTransaction(function(DB $query){
        $query->table('demo_notes')
          ->insert([
             "note" => "Hello",
           ]);
    })

5. Simple Enqueue Declaration

Easy way to add css and js file to application

Enqueue Declaration file : enqueue/enqueue.php
Plugin Deactivation Script Declaration : enqueue/deactiveAction.php

Functions

  1. headerScript($path) : :
    $enqueue->headerScript('assets/js/index.js');
  2. headerScriptCdn($path) : :
    $enqueue->headerScriptCdn('http://alemran.me/js/index.js');
  3. footerScript($path) : :
    $enqueue->footerScript('assets/js/index.js');
  4. footerScriptCdn($path) : :
    $enqueue->footerScriptCdn('http://alemran.me/js/index.js');
  5. style($path) : :
    $enqueue->style('assets/css/style.css');
  6. styleCdn($path) : :
    $enqueue->style('assets/js/index.css');
  7. csrfToken($handler, $objectName): :
    
    $enqueue->footerScript('assets/js/index.js','DemoScriptIndex');
    $enqueue->csrfToken('DemoScriptIndex','corsData');
    
    

    DemoScriptIndex is Handler and corsData is object name. You can access api ROOT url and token corsData object.

    Note: CSRF token must define under a js file's Handler.
  8. $enqueue->hotScript('file_name.js') for Webpack (DevServer) hot mode with Vue js (main url will be http://localhost:8080/file_name.js)

6. Request Handling System

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')){}

7. Validator

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

             
if ( 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>

OR

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:

  1. required
  2. mobile (start with zero and must be in 0-9)
  3. number
  4. floatNumber
  5. noNumber( accept all character without number)
  6. letter( accept only letter :A-Za-z))
  7. noSpecialChar
  8. limit: min, max
  9. wordLimit: min, max
  10. email

8. Build in Vue JS Configuration

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
    }
];
  
  
# OR may be
 
 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
    }
];
  
  

9. Global Functions

  1. 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 with compact
           $title = "......";
           $data = [] ;
           return view('home/index', compact('title', 'data'))
         
  2. json($data, $code) : for returning as json with status code
  3. config($key) : for returning configuration data. you can set/ change configuration data from : add/config/config.php
  4. current_url() : for current url
  5. formErrors() : for form validation errors as array
  6. formError($field_name) : for single field validation error
  7. session_flush($key, $value = null) : for getting and setting flush session
  8. session($key, $value = null) : for getting and setting session

Session Handler

  1. Get OR Set Flush Session:
    Session::flush(key) for getting onetime Session and Session::flush(key, value) for setting onetime session.
    Flush session unset after page loading completed
  2. Set Session: Session::flush(key, value)
  3. Get Session: Session::get(key)
  4. Forget Session: Session::forget(key)

License

The MIT License (MIT)

Developed by : AL EMRAN

Support for this project

Assalamu Alikum ! You can donate for the project.

Beerpay Beerpay