├── .gitignore ├── README.md ├── app ├── Http │ ├── Controllers │ │ ├── Actions │ │ │ └── ActionController.php │ │ ├── Api │ │ │ └── ApiController.php │ │ ├── Shortcodes │ │ │ └── ShortcodeController.php │ │ └── SideMenu │ │ │ └── SideMenuController.php │ └── Middleware │ │ └── TestMiddleware.php └── Providers │ └── TestServiceProvider.php ├── artisan ├── assets ├── css │ ├── app.css │ └── index.css └── js │ ├── app.js │ ├── index.js │ ├── react │ └── app.js │ └── vue │ └── app.js ├── bootstrap ├── Activation.php ├── Bootstrap.php ├── DeActivation.php └── System │ ├── Action.php │ ├── Api.php │ ├── Application.php │ ├── Cache.php │ ├── Config.php │ ├── Controller.php │ ├── Enqueue.php │ ├── Helpers │ ├── App.php │ ├── Response.php │ ├── View.php │ └── helpers.php │ ├── Providers │ ├── ActionServiceProvider.php │ ├── ApiServiceProvider.php │ ├── EnqueueServiceProvider.php │ ├── InitialDataProvider.php │ ├── ShortcodeServiceProvider.php │ └── SideMenuServiceProvider.php │ ├── Session.php │ ├── Shortcode.php │ └── SideMenu.php ├── composer.json ├── config └── app.php ├── database └── Migration.php ├── enqueues └── enqueue.php ├── hooks ├── action.php └── shortcode.php ├── package-lock.json ├── package.json ├── plugin-master.php ├── resources ├── js │ ├── react │ │ ├── Home.jsx │ │ └── app.js │ └── vue │ │ ├── App.vue │ │ └── app.js ├── scss │ └── app.scss └── views │ ├── action.php │ ├── index.php │ ├── react-app.php │ └── vue-app.php ├── routes ├── api.php └── sidemenu.php └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /vendor 3 | /node_modules 4 | composer.lock 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PluginMaster (an Application Development Framework for WordPress) 2 | # What is PluginMaster? 3 |
4 | « PluginMaster is an Application development framework for WordPress. It changes the flavor of plugin development.» 5 |
6 | 7 | # Code Features 8 |
    9 |
  1. Database Migration System
  2. 10 |
  3. Simple Side Menu Declaration
  4. 11 |
  5. Simple Rest API Declaration
  6. 12 |
  7. Database Query Builder
  8. 13 |
  9. Simple Enqueue Declaration
  10. 14 |
  11. Easy Shortcode Handler
  12. 15 |
  13. Http Request Handling
  14. 16 |
  15. Request Validation
  16. 17 |
  17. Build-in Vue JS Configuration
  18. 18 |
  19. Global Functions
  20. 19 |
  21. Session Handler
  22. 20 |
  23. Middleware (upcoming)
  24. 21 |
  25. Action Handler (upcoming)
  26. 22 |
  27. Filter Handler (upcoming)
  28. 23 |
24 | 25 | # Installation 26 |
    27 |
  1. Go to wp-content/plugins/ directory in your WordPress
  2. 28 |
  3. Open terminal and run : composer create-project plugin-master/plugin-master OR composer 29 | create-project plugin-master/plugin-master project_name
  4. 30 |
  5. A demo application includes with Vue JS . Just active from Plugin section
  6. 31 | 32 |
33 | # Configuration 34 |
    35 |
  1. Change your Plugin name, version etc from index.php page in root folder.
  2. 36 |
  3. Change Rest API Namespace from config.php, located in app/config/ 37 | directory (You can add any configuration related data in config.php ) 38 |
  4. 39 | 40 |
41 | 42 | # 1. Database Migration System 43 |
44 | 45 |

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.

46 | Migration file directory : database/migrations/ 47 | 48 | Structure 49 | 50 |

The migration file name has 2 parts : 51 |

    52 |
  1. First for sequence maintain for foreign key and second for the table name. Second part must be the same as table name .
  2. 53 |
54 |
Also class name will be the same as the table name.
File name like : 1_demo_users.php. 55 | This means, 1 is for sequence maintain and demo_users is the table name and also class 56 | name. the table prefix will be set from the schema builder. 57 |
58 | 59 |

A migration class contains one method: up. The up method is used to add new tables to your database.

60 | Sample Migration File 61 |

File Name: 1_demo_users.php

62 | 63 |

 64 | use App\system\schema\Schema;
 65 | 
 66 | class demo_users
 67 | {
 68 |     public function up()
 69 |     {
 70 |       return Schema::create('demo_users', function (Schema $column) {
 71 |             $column->intIncrements('id');
 72 |             $column->string('name')->nullable() ;
 73 |             $column->string('mobile') ;
 74 |             $column->string('email')->nullable();
 75 |             $column->text('description')->nullable();
 76 |             $column->enum('status', ['ok', 'not']);
 77 |             $column->integer('user_id')->unsigned()->nullable();
 78 |             $column->foreign('user_id')->on('demo_users.id');
 79 |             $column->timestamp('student_created_at')->default('current_timestamp')->onUpdateTimeStamp();
 80 |         });
 81 |     }
 82 | 
 83 | }
 84 |  
 85 |  
86 | 87 | Schema Functions 88 |
    89 |
  1. intIncrements($column) : integer (10), auto_increment, primary key
  2. 90 |
  3. bigIntIncrements($column) : bigint (20), auto_increment, primary key
  4. 91 |
  5. integer($column, $length = 10) : integer (10)
  6. 92 |
  7. bigInt($column, $length = 20) : bigint (20)
  8. 93 |
  9. decimal($column, $length = 20, $places = 2) : decimal (20, 2)
  10. 94 |
  11. text($column) : text
  12. 95 |
  13. enum($column, $values) : enum( value, value) ($values must be array).
  14. 96 |
  15. date($column) : date
  16. 97 |
  17. timestamp($column) : timestamp
  18. 98 |
  19. nullable() : null
  20. 99 |
  21. unsigned() : unsigned
  22. 100 |
  23. default($value) : default 'value' (if $value == 'CURRENT_TIMESTAMP' OR 'current_timestamp' then set CURRENT_TIMESTAMP
  24. 101 |
  25. onUpdateTimeStamp() : ON UPDATE CURRENT_TIMESTAMP
  26. 102 |
  27. foreign($column) : make CONSTRAINT for foreign key
  28. 103 |
  29. on($reference) : $reference means table.column. check following example. 104 |
    105 |     
    106 | $column->integer('user_id')->unsigned();
    107 | $column->foreign('user_id')->on('demo_users.id'); 
    108 | 
    109 | 110 |
  30. 111 |
112 | 113 | 114 | # 2. Simple Side Menu Declaration 115 |
116 | 117 |

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

118 | Side Menu declaration file : routes/sidenav.php
119 | Side Menu Controller must declare inside : app/controller/sidenav/ 120 |

Sample Structure

121 |
122 | 
123 | $sidenav->main('DemoPlugin', ["icon" => "dashicons-admin-site",  "as" => 'DemoController@main', "position" => 500, "removeFirstSubmenu" => true], function ($sidenav) {
124 |     $sidenav->sub('Dashboard', ["title" => "Dashboard", "as" => 'DemoController@sub']);
125 | }); 
126 | 
127 |  
128 |

The main method has three parameters..

129 |
    130 |
  1. One : menu slug . (Required)
  2. 131 |
  3. Two : menu options . Its type must be an array.
    132 | Mandatory index: icon (dashboard icon), as ( controller and method must be with @ sign)
    133 | Optional index: position (default is 500), removeFirstSubmenu ( for delete first submenu, default false)
    134 |
  4. 135 |
  5. Third: closer function for registering submenu under main menu
  6. 136 |
137 |

The sub method has two parameters.

138 |
    139 |
  1. One : menu slug . (Required)
  2. 140 |
  3. Two : menu options . Its type must be an array.
    141 | Mandatory index: title (Menu Title), as ( controller and method must be with @ sign)
    142 |
    In DemoController@main: DemoController is controller name 143 | located at app/controller/sidenav/ and main is method name of 144 | DemoController 145 |
    146 | Optional index: position (default is 500), removeFirstSubmenu ( for delete first submenu, default false)
    147 |
  4. 148 |
  5. Third: closer function for registering submenu under main menu
  6. 149 |
150 |

The sub method has two parameters.

151 |
    152 |
  1. One : menu slug . (Required)
  2. 153 |
  3. Two : menu options . Its type must be an array.
    154 | Mandatory index: title (Menu Title), as ( controller and method must be with 155 | @ sign)
    156 |
    In DemoController@main: DemoController is controller name 157 | located at app/controller/sidenav/ and sub is method name of 158 | DemoController 159 |
    160 | 161 |
  4. 162 |
163 | 164 | 165 | 166 | # 3. Easy Rest API Route Declaration 167 |
168 | 169 |

Create WP rest route in easy way.

170 |

Rest Route declaration file : routes/route.php 171 |
Rest Route Controller must declare inside : app/controller/api/

172 |

API Namespace: Namespace maintain by api_namespace of config.php. It's located in app/config/config.php 173 |

174 |

Sample Structure

175 |

176 | $route->get('dashboard/{id?}', 'DemoController@dashboard');
177 | $route->post('add-note', 'DemoController@addNote'); 
178 | $route->post('update-note', 'DemoController@addNote', true); 
179 | 
180 | 
181 | DemoController is controller name and dashboard is method name , located in app/controller/api/ directory 182 |

PluginMaster has two methods: GET, POST

183 |

Both Route has 3 parts/parameters

184 | 197 | 198 | 199 | # 4. DB Query Builder 200 |
201 |

PluginMaster's database query builder provides a convenient, fluent interface to run 202 | database queries. It can be used to perform most database operations in your application.

203 | Namespace: PluginMaster\DB\DB;
204 | 205 |
206 | DB Functions 207 |
    208 |
  1. Retrieving A Single Row
    DB::table('users')->first();
  2. 209 |
  3. Retrieving A multiple Row
    DB::table('users')->get();
  4. 210 |
211 | 212 |
    213 |
  1. where($column, $value ) : 214 | 215 | 216 |
    DB::table('users')
    217 |      ->where('id', 1)
    218 |      ->get()
    219 | 220 |
    DB::table('users')
    221 |      ->where(function($query){
    222 |        $query->where('id', 1);
    223 |        $query->orWhere('name', "name");
    224 |      })
    225 |      ->get()
    226 | 227 |
  2. 228 |
  3. orWhere($column, $value) : 229 |
    DB::table('users')
    230 |      ->where('id', 1)
    231 |      ->orWhere('name', "name")
    232 |      ->get()
    233 | 234 |
    DB::table('users')
    235 |      ->where('id', 1)
    236 |      ->orWhere(function($query){
    237 |          $query->where('field', 'value);
    238 |          $query->where('field', 'value);
    239 |          })
    240 |      ->first()
    241 | 242 |
  4. 243 |
  5. whereRaw($query) : 244 |
    DB::table('users')
    245 |      ->whereRaw('id = 1')
    246 |      ->first()
    247 |
  6. 248 | 249 |
  7. orWhereRaw($query) : 250 |
    DB::table('users')
    251 |      ->whereRaw('id = 1')
    252 |      ->orWhereRaw('id = 1')
    253 |      ->first()
    254 |
  8. 255 | 256 | 257 |
  9. orderBy($columns, $direction) : 258 |
    DB::table('users')
    259 |      ->orderBy('id', 'desc')
    260 |
    DB::table('users')
    261 |      ->orderBy('id,name', 'desc')
    262 |
  10. 263 | 264 |
  11. groupBy($columns) : 265 |
    DB::table('users')
    266 |      ->groupBy('id')
    267 |
    DB::table('users')
    268 |      ->groupBy('id,name')
    269 |
  12. 270 | 271 | 272 |
  13. limit($number) : 273 |
    DB::table('users')
    274 |      ->where('id', 1)
    275 |      ->limit(number)->get()
    276 |
  14. 277 | 278 |
  15. offset($number) : 279 |
    DB::table('users')
    280 |      ->where('id', 1)
    281 |      ->limit(number)->offset(number)->get()
    282 |
  16. 283 | 284 |
  17. select($fields) : 285 |
    DB::table('users')
    286 |      ->select('id,name')
    287 |         ->get()
    288 |
  18. 289 |
  19. insert($data) : 290 |
    DB::table('users')
    291 |      ->insert(['name' => "demo"])
    292 |
  20. 293 |
  21. update($data,$where) : 294 |
    DB::table('users')
    295 |      ->where('id', 1)
    296 |      ->update(['name' => "demo"])
    297 |
  22. 298 |
  23. delete($where) : 299 |
    DB::table('users')
    300 |      ->where('id', 1)
    301 |      ->delete()
    302 |
  24. 303 | 304 |
  25. join($table, $first, $operator = null, $second = null) (INNER JOIN): 305 |
    DB::table('demo_notes as n')
    306 |         ->join('demo_users as u', 'u.id', '=', 'n.user_id')
    307 |         ->first()
    308 | 
    309 |
    DB::table('demo_notes as n')
    310 |         ->join('demo_users as u', function($query){
    311 |           $query->on( 'u.id', '=', 'n.user_id')
    312 |           $query->orOn( 'u.id', '=', 'n.user_id')
    313 |         })
    314 |         ->first()
    315 | 
    316 | 317 |
    DB::table('demo_notes as n')
    318 |         ->join('demo_users as u', function($query) use($request){
    319 |           $query->on( 'u.id', '=', 'n.user_id')
    320 |           $query->onWhere( 'u.id', '=', $request->id)
    321 |         })
    322 |         ->first()
    323 | 
    324 | 325 | 326 |
    Note: Must use table alias for using join or leftJoin.
    327 |
  26. 328 |
  27. 329 | leftJoin($table, $first, $operator = null, $second = null) (LEFT JOIN): Same as 330 | join() 331 |
  28. 332 | 333 |
  29. transaction(): 334 |
    DB::startTransaction(function(){
    335 |     DB::table('demo_notes')
    336 |       ->insert([
    337 |          "note" => "Hello",
    338 |        ]);
    339 | })
    340 | 341 |
    DB::startTransaction(function(DB $query){
    342 |     $query->table('demo_notes')
    343 |       ->insert([
    344 |          "note" => "Hello",
    345 |        ]);
    346 | })
    347 | 348 |
  30. 349 |
350 | 351 | 352 | 353 | # 5. Simple Enqueue Declaration 354 |
355 | 356 |

Easy way to add css and js file to application

357 | Enqueue Declaration file : enqueue/enqueue.php
358 | Plugin Deactivation Script Declaration : enqueue/deactiveAction.php 359 |

Functions

360 |
    361 |
  1. headerScript($path) : :
    362 | $enqueue->headerScript('assets/js/index.js');
  2. 363 |
  3. headerScriptCdn($path) : :
    $enqueue->headerScriptCdn('http://alemran.me/js/index.js');
  4. 364 |
  5. footerScript($path) : :
    $enqueue->footerScript('assets/js/index.js');
  6. 365 |
  7. footerScriptCdn($path) : :
    $enqueue->footerScriptCdn('http://alemran.me/js/index.js');
  8. 366 |
  9. style($path) : :
    $enqueue->style('assets/css/style.css');
  10. 367 |
  11. styleCdn($path) : :
    $enqueue->style('assets/js/index.css');
  12. 368 |
  13. csrfToken($handler, $objectName): :
    369 | 370 |
    371 | 
    372 | $enqueue->footerScript('assets/js/index.js','DemoScriptIndex');
    373 | $enqueue->csrfToken('DemoScriptIndex','corsData');
    374 | 
    375 | 
    376 |

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

    377 |
    Note: CSRF token must define under a js file's Handler.
    378 |
  14. 379 | 380 |
  15. $enqueue->hotScript('file_name.js') for Webpack (DevServer) hot mode with Vue js (main url will be http://localhost:8080/file_name.js) 381 |
  16. 382 |
383 | 384 | 385 | # 6. Easy Shortcode Handler 386 |
387 |

Create and manage shortcode in easy way

388 | Shortcode Declaration file : shortcode/shortcode.php
389 | Controller root directory for shortcode : app/controller/shortcode/
390 | Example: 391 |
  $shortCode->add('pluginmaster', 'ShortCodeController@index' ) ;   
392 |

pluginmaster is the name of shortcode. ShortCodeController is controller and index is method name.

393 |

Method Sample

394 |

395 |     public function index(){
396 |           $data = DB::table('table_name')->get();
397 |         return  view('shortcode', compact('data')) ;
398 |     }
399 |   
400 | 401 | 402 | 403 | # 7. Request Handling System 404 |
405 | 406 |

Easy way to access request data from native or AJAX request

407 | No need isset function to check. just call $request->name , it will return null if not 408 | set
409 |

Example

410 |
 
411 |      use App\system\request\Request;
412 |      $request = new Request();
413 |      echo $request->name;
414 |     
415 |     
416 |

Access Header: $request->header(name)

417 |

Get All Data as Array: $request->all()

418 |

Check Request Method : if($request->isMethod('post')){}

419 | 420 | 421 | # 8. Validator 422 | 423 | 424 |

Validate data is easy in PluginMaster

425 |

Manually Validate ( not compatible for REST API) :

426 |
427 |   
428 |  use App\system\Validator;
429 |   $validator = Validator::make($request, [
430 |             'ID' => 'required|number|limit:10,11',
431 |             'name' => 'required|wordLimit:10,20',
432 |             'slug' => 'required|noSpecialChar',
433 |         ]);
434 | 
435 |  if ($validator->fails()) {
436 |      $errors =  $validator->errors();
437 |  }
438 | 
439 | 
440 | 
441 |

For checking validation fail: $validator->fail();.

442 |

For Validation errors: $validator->errors() .

443 |

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).

444 | 445 | Display Errors in View file : 446 |

In controller

447 |

448 |       use App\system\Validator;
449 |       $validator = Validator::make($request, [
450 |       'ID' => 'required|number|limit:10,11',
451 |       'name' => 'required|wordLimit:10,20',
452 |       'slug' => 'required|noSpecialChar',
453 |       ]);
454 |   
455 |
    
456 |     if ($validator->fails()) {
457 |       $errors =  $validator->formErrors();
458 |     }  
459 |  
460 | 461 |

In view file

462 |
             
463 | if ( count(formErrors()) ) :
464 |       <div class="alert alert-danger">
465 |            <ul>
466 |             <php foreach (formErrors() as $key=>$value): ?>
467 |                    <li> <php  echo $value; ?>  </li>
468 |            <php  endforeach; ?>
469 |          </ul>
470 |      </div>
471 |    <php endif;  ?>
472 | 
473 |   <input type="text" name="email">
474 |   <p> <php  formError('email'); ?>  </p>
475 | 
476 | OR 477 |

You can pass errors to view file with compact

478 |
479 | view('path to view', compact('errors'));
480 | 
481 | 482 |

Stopping On Validation Failure (Compatible for REST API) : If validation fail then stop other execution, just return validation errors.

483 |

Example:

484 |

485 |           use App\system\request\Request;
486 |                 $request = new Request();
487 |                 $request->validate([
488 |                   'name' => 'required',
489 |                 ]);
490 | 
491 |   
492 |

Error will return as like following:

493 |

494 |              [
495 |                 "message" => "Validation failed",
496 |                 "errors" => [
497 |                  "name" => "name Field is required"
498 |                  ]
499 |               ]
500 | 
501 | 502 | Available Validation: 503 |
    504 |
  1. required
  2. 505 |
  3. mobile (start with zero and must be in 0-9)
  4. 506 |
  5. number
  6. 507 |
  7. floatNumber
  8. 508 |
  9. noNumber( accept all character without number)
  10. 509 |
  11. letter( accept only letter :A-Za-z))
  12. 510 |
  13. noSpecialChar
  14. 511 |
  15. limit: min, max
  16. 512 |
  17. wordLimit: min, max
  18. 513 |
  19. email
  20. 514 |
515 | 516 | 517 | # 9. Build in Vue JS Configuration 518 |
519 | 520 |

Build Vue JS application with your plugin

521 |

Configuration

522 |

Configuration file located in root directory as webpack.config.js.

523 |

Vue js files Default directory is : resources/js.

524 |

Run : npm run dev. (for development mode)

525 |

Run : npm run watch. (for on-change build)

526 |

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 .

527 |

Configuration for Build

528 |
529 |  
530 |  const buildConfig = [
531 |     {
532 |         source: 'resources/js/app.js',
533 |         outputDir: 'assets/js',  // targeted output directory name
534 |         outputFileName: 'app'  // can be with .js extension
535 |     }
536 | ];
537 |   
538 |   
539 | # OR may be 540 |
541 |  
542 |  const buildConfig = [
543 |     {
544 |         source: 'resources/js/app.js',
545 |         outputDir: 'assets/js',  // targeted output directory name
546 |         outputFileName: 'app'  // can be with .js extension
547 |     } ,
548 |      {
549 |         source: 'resources/js/nextApp.js',
550 |         outputDir: 'assets/js',  // targeted output directory name
551 |         outputFileName: 'nextApp'  // can be with .js extension
552 |     }
553 | ];
554 |   
555 |   
556 | 557 | 558 | 559 | # 10. Global Functions 560 | 561 |
562 | 563 |
    564 |
  1. view() : root of view file : resources/view/. you have to pass only file name withour extention . Example: view('home/index') . 565 |
    Also you can pass data to view with compact 566 |
    567 |        $title = "......";
    568 |        $data = [] ;
    569 |        return view('home/index', compact('title', 'data'))
    570 |      
    571 |
  2. 572 |
  3. json($data, $code) : for returning as json with status code
  4. 573 | 574 |
  5. config($key) : for returning configuration data. you can set/ change configuration data from : add/config/config.php
  6. 575 |
  7. current_url() : for current url 576 |
  8. formErrors() : for form validation errors as array
  9. 577 |
  10. formError($field_name) : for single field validation error
  11. 578 |
  12. session_flush($key, $value = null) : for getting and setting flush session
  13. 579 |
  14. session($key, $value = null) : for getting and setting session
  15. 580 | 581 |
582 | 583 | # 11. Session Handler 584 | 585 |
586 |
    587 |
  1. Get OR Set Flush Session:
    588 | Session::flush(key) for getting onetime Session and Session::flush(key, value) 589 | for setting onetime session. 590 |
    Flush session unset after page loading completed
    591 |
  2. 592 |
  3. Set Session: 593 | Session::flush(key, value) 594 |
  4. 595 |
  5. Get Session: 596 | Session::get(key) 597 |
  6. 598 |
  7. Forget Session: 599 | Session::forget(key) 600 |
  8. 601 |
602 | 603 | # License 604 |

The MIT License (MIT)

605 | 606 |

Developed by : AL EMRAN

607 | 608 | # Support for this project 609 | Assalamu Alikum ! You can donate for the project. 610 | 611 | [![Beerpay](https://beerpay.io/emrancu/PluginMaster/badge.svg?style=beer-square)](https://beerpay.io/emrancu/PluginMaster) [![Beerpay](https://beerpay.io/emrancu/PluginMaster/make-wish.svg?style=flat-square)](https://beerpay.io/emrancu/PluginMaster?focus=wish) 612 | -------------------------------------------------------------------------------- /app/Http/Controllers/Actions/ActionController.php: -------------------------------------------------------------------------------- 1 | "This message from PluginMaster Action."]); 14 | } 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/ApiController.php: -------------------------------------------------------------------------------- 1 | $this->request->url(), 16 | "name" => $request->get_param('name'), 17 | ]); 18 | } 19 | 20 | public function getProductsName(WP_REST_Request $request): string 21 | { 22 | return Response::json([ 23 | "url" => $this->request->url(), 24 | "name" => $request->get_param('name'), 25 | "dynamic" => "This is dynamic api", 26 | ]); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/Http/Controllers/Shortcodes/ShortcodeController.php: -------------------------------------------------------------------------------- 1 | This message from PluginMaster ShortCode. read more..'; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/Http/Controllers/SideMenu/SideMenuController.php: -------------------------------------------------------------------------------- 1 | boot(); 48 | }, 100); 49 | 50 | /** 51 | * destroy onetime flush session 52 | */ 53 | Session::destroyFlush(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /bootstrap/DeActivation.php: -------------------------------------------------------------------------------- 1 | add($name, $callback, $priority); 24 | } 25 | 26 | private static function handler(): ActionHandler 27 | { 28 | if (!static::$actionHandler) { 29 | static::$actionHandler = App::get(ActionHandler::class); 30 | } 31 | 32 | return static::$actionHandler; 33 | } 34 | 35 | /** 36 | * add only wp_ajax_ action and resolve callback 37 | * @note no need to pass 'wp_ajax_' 38 | * @param string $name 39 | * @param $callback 40 | * @param int $priority 41 | */ 42 | public static function ajax(string $name, $callback, int $priority = 10): void 43 | { 44 | static::handler()->add('wp_ajax_' . $name, $callback, $priority); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /bootstrap/System/Api.php: -------------------------------------------------------------------------------- 1 | register($api, $dynamic); 104 | } 105 | 106 | /** 107 | * @param string $route 108 | * @param string|callable $callback 109 | * @param bool $public 110 | */ 111 | public static function post(string $route, $callback, bool $public = false): void 112 | { 113 | static::registerAPI([$route, 'POST', $callback, $public]); 114 | } 115 | 116 | /** 117 | * @param string $route 118 | * @param string|callable $callback 119 | * @param bool $public 120 | */ 121 | public static function put(string $route, $callback, bool $public = false): void 122 | { 123 | static::registerAPI([$route, 'PUT', $callback, $public]); 124 | } 125 | 126 | /** 127 | * @param string $route 128 | * @param string|callable $callback 129 | * @param bool $public 130 | */ 131 | public static function patch(string $route, $callback, bool $public = false): void 132 | { 133 | static::registerAPI([$route, 'PATCH', $callback, $public]); 134 | } 135 | 136 | /** 137 | * @param string $route 138 | * @param string|callable $callback 139 | * @param bool $public 140 | */ 141 | public static function delete(string $route, $callback, bool $public = false): void 142 | { 143 | static::registerAPI([$route, 'DELETE', $callback, $public]); 144 | } 145 | 146 | /** 147 | * @param string $route 148 | * @param string|callable $callback 149 | * @param bool $public 150 | */ 151 | public static function all(string $route, $callback, bool $public = false): void 152 | { 153 | static::registerAPI([$route, 'GET, POST, PUT, PATCH, DELETE', $callback, $public]); 154 | } 155 | 156 | /** 157 | * @param string $route 158 | * @param string $class 159 | * @param bool $public 160 | */ 161 | public static function dynamic(string $route, string $class, bool $public = false): void 162 | { 163 | static::registerAPI([$route, 'GET, POST, PUT, PATCH, DELETE', $class, $public], true); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /bootstrap/System/Application.php: -------------------------------------------------------------------------------- 1 | setBasePath($path); 57 | $this->setAppConfig(); 58 | $this->setVersion($this->config('version')); 59 | } 60 | 61 | /** 62 | * @set application base path ( Plugin directory path ) 63 | * @set pluginFile 64 | * @set pluginBasename 65 | * @param string $path 66 | * @return mixed 67 | */ 68 | public function setBasePath(string $path): void 69 | { 70 | $this->pluginFile = $path; 71 | $this->basePath = untrailingslashit(plugin_dir_path($path)); 72 | $this->pluginBasename = plugin_basename($path); 73 | } 74 | 75 | /** 76 | * set ConfigHandler instance inside container 77 | * and set config path for ConfigHandler to resolve config data 78 | * @return mixed 79 | * @throws \ReflectionException 80 | */ 81 | private function setAppConfig(): void 82 | { 83 | // create instance 84 | $configHandler = $this->get(ConfigHandler::class); 85 | $configHandler->setPath($this->configPath()); 86 | 87 | // set app config data from config/app.php 88 | $this->config = $configHandler->resolveData('app'); 89 | } 90 | 91 | /** 92 | * @param string|null $path 93 | * @return mixed 94 | */ 95 | public function configPath(string $path = null): string 96 | { 97 | return $this->basePath . DIRECTORY_SEPARATOR . 'config' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 98 | } 99 | 100 | /** 101 | * @param string $version 102 | * @return mixed 103 | */ 104 | public function setVersion(string $version): void 105 | { 106 | $this->version = $version; 107 | } 108 | 109 | /** 110 | * get app config data 111 | * just pass config/app.php 's array key to access (Like config('provider') - do not need to pass 'app.providers') ) 112 | * @param $key 113 | * @return mixed 114 | */ 115 | public function config($key) 116 | { 117 | $keys = explode('.', $key); 118 | 119 | $finalData = $this->config; 120 | 121 | foreach ($keys as $key) { 122 | $finalData = $finalData[$key] ?? ''; 123 | } 124 | 125 | return $finalData; 126 | } 127 | 128 | /** 129 | * @param null $path 130 | * @return Application 131 | * @throws \ReflectionException 132 | */ 133 | public static function getInstance($path = null): ?Application 134 | { 135 | if (null === self::$instance) { 136 | self::$instance = new self($path); 137 | } 138 | 139 | return self::$instance; 140 | } 141 | 142 | /** 143 | * Get the version number of the application. 144 | * 145 | * @return string 146 | */ 147 | public function version(): string 148 | { 149 | return $this->version; 150 | } 151 | 152 | /** 153 | * Get the plugin base name. 154 | * 155 | * @return string 156 | */ 157 | public function baseName(): string 158 | { 159 | return $this->pluginBasename; 160 | } 161 | 162 | /** 163 | * @param string|null $path 164 | * @return mixed 165 | */ 166 | public function basePath(string $path = null): string 167 | { 168 | return $this->basePath . ($path ? DIRECTORY_SEPARATOR . $path : $path); 169 | } 170 | 171 | /** 172 | * @param string $path 173 | * @return mixed 174 | */ 175 | public function asset(string $path): string 176 | { 177 | return $this->baseUrl() . 'assets/' . $path; 178 | } 179 | 180 | /** 181 | * @param null $path 182 | * @return mixed 183 | */ 184 | public function baseUrl($path = null): string 185 | { 186 | return trailingslashit(plugins_url('/', $this->pluginFile)) . ($path ? '/' . $path : $path); 187 | } 188 | 189 | /** 190 | * @param string|null $path 191 | * @return mixed 192 | */ 193 | public function bootstrapPath(string $path = null): string 194 | { 195 | return $this->basePath . DIRECTORY_SEPARATOR . 'bootstrap' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 196 | } 197 | 198 | /** 199 | * @param string|null $path 200 | * @return mixed 201 | */ 202 | public function appPath(string $path = null): string 203 | { 204 | return $this->basePath . DIRECTORY_SEPARATOR . 'app' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 205 | } 206 | 207 | /** 208 | * @param string $path 209 | * @return mixed 210 | */ 211 | public function databasePath(string $path = ''): string 212 | { 213 | return $this->basePath . DIRECTORY_SEPARATOR . 'database' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 214 | } 215 | 216 | /** 217 | * @param string|null $path 218 | * @return mixed 219 | */ 220 | public function viewPath(string $path = null): string 221 | { 222 | return $this->basePath . DIRECTORY_SEPARATOR . 'resources/views' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 223 | } 224 | 225 | /** 226 | * @param string|null $path 227 | * @return mixed 228 | */ 229 | public function assetPath(string $path = null): string 230 | { 231 | return $this->basePath . DIRECTORY_SEPARATOR . 'assets' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 232 | } 233 | 234 | /** 235 | * @param string|null $path 236 | * @return mixed 237 | */ 238 | public function enqueuePath(string $path = null): string 239 | { 240 | return $this->basePath . DIRECTORY_SEPARATOR . 'enqueues' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 241 | } 242 | 243 | /** 244 | * @param string|null $path 245 | * @return mixed 246 | */ 247 | public function hookPath(string $path = null): string 248 | { 249 | return $this->basePath . DIRECTORY_SEPARATOR . 'hooks' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 250 | } 251 | 252 | /** 253 | * @param string|null $path 254 | * @return mixed 255 | */ 256 | public function routePath(string $path = null): string 257 | { 258 | return $this->basePath . DIRECTORY_SEPARATOR . 'routes' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 259 | } 260 | 261 | /** 262 | * @param string|null $path 263 | * @return mixed 264 | */ 265 | public function hooksPath(string $path = null): string 266 | { 267 | return $this->basePath . DIRECTORY_SEPARATOR . 'hooks' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 268 | } 269 | 270 | public function cachePath($path = null): string 271 | { 272 | return wp_upload_dir()['basedir'] . DIRECTORY_SEPARATOR . $this->config( 273 | 'slug' 274 | ) . ($path ? DIRECTORY_SEPARATOR . $path : ''); 275 | } 276 | 277 | /** 278 | * Boot the application's service providers. 279 | * 280 | * @return void 281 | * @throws \ReflectionException 282 | */ 283 | public function boot(): void 284 | { 285 | if ($this->isBooted()) { 286 | return; 287 | } 288 | 289 | $this->bootProvider(); 290 | $this->booted = true; 291 | } 292 | 293 | /** 294 | * Determine if the application has booted. 295 | * 296 | * @return bool 297 | */ 298 | public function isBooted(): bool 299 | { 300 | return $this->booted; 301 | } 302 | 303 | /** 304 | * boot service providers 305 | * @return void 306 | * @throws \ReflectionException 307 | */ 308 | protected function bootProvider(): void 309 | { 310 | /** 311 | * run system service providers 312 | */ 313 | foreach ($this->config('system_providers') as $serviceProvider) { 314 | if (method_exists($serviceProvider, 'boot')) { 315 | $this->call([$serviceProvider, 'boot']); 316 | } 317 | } 318 | 319 | /** 320 | * run your service providers for your modules / functionalities 321 | */ 322 | foreach ($this->config('providers') as $serviceProvider) { 323 | if (method_exists($serviceProvider, 'boot')) { 324 | $this->call([$serviceProvider, 'boot']); 325 | } 326 | } 327 | } 328 | 329 | } 330 | -------------------------------------------------------------------------------- /bootstrap/System/Cache.php: -------------------------------------------------------------------------------- 1 | get($fileName, $directory); 22 | } 23 | 24 | /** 25 | * @return CacheHandler 26 | */ 27 | private static function getHandler(): CacheHandler 28 | { 29 | if (!static::$cacheHandlerInstance) { 30 | $app = App::get(); 31 | static::$cacheHandlerInstance = $app->get(CacheHandler::class)->setAppVersion( 32 | $app->version() 33 | )->setCachePath($app->cachePath()); 34 | } 35 | 36 | return static::$cacheHandlerInstance; 37 | } 38 | 39 | /** 40 | * @param string $fileName 41 | * @param $content 42 | * @param null $directory 43 | * @return bool|int 44 | */ 45 | public static function set(string $fileName, $content, $directory = null): bool 46 | { 47 | return static::getHandler()->createFile($fileName, $content, $directory); 48 | } 49 | 50 | /** 51 | * @return bool|int 52 | */ 53 | public static function reset(): bool 54 | { 55 | return static::getHandler()->reset(); 56 | } 57 | 58 | /** 59 | * @param string $fileName 60 | * @param string|null $directory 61 | * @return bool 62 | */ 63 | public static function check(string $fileName, string $directory = null): bool 64 | { 65 | return static::getHandler()->check($fileName, $directory); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /bootstrap/System/Config.php: -------------------------------------------------------------------------------- 1 | resolveData($key); 22 | } 23 | 24 | /** 25 | * @return ConfigHandler 26 | */ 27 | private static function getInstance() 28 | { 29 | if (!self::$instance) { 30 | self::$instance = App::get(ConfigHandler::class); 31 | } 32 | 33 | return self::$instance; 34 | } 35 | 36 | /** 37 | * @param $key 38 | */ 39 | public static function set($key) 40 | { 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /bootstrap/System/Controller.php: -------------------------------------------------------------------------------- 1 | request = App::get()->get(Request::class); 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bootstrap/System/Enqueue.php: -------------------------------------------------------------------------------- 1 | data[] = [ 70 | 'id' => $id, 71 | 'path' => $path, 72 | 'script' => true, 73 | 'hook' => static::$hook, 74 | ]; 75 | 76 | return $this; 77 | } 78 | 79 | /** 80 | * @param array $deps 81 | * @return Enqueue 82 | */ 83 | public function dependency(array $deps): self 84 | { 85 | $this->data[$this->getCurrentIndex()]['dependency'] = $deps; 86 | 87 | return $this; 88 | } 89 | 90 | private function getCurrentIndex(): int 91 | { 92 | return count($this->data) - 1; 93 | } 94 | 95 | /** 96 | * @return Enqueue 97 | */ 98 | public function inHeader(): self 99 | { 100 | $this->data[$this->getCurrentIndex()]['in_footer'] = false; 101 | 102 | return $this; 103 | } 104 | 105 | /** 106 | * @return Enqueue 107 | */ 108 | public function inFooter(): self 109 | { 110 | $this->data[$this->getCurrentIndex()]['in_footer'] = true; 111 | 112 | return $this; 113 | } 114 | 115 | /** 116 | * @param string $ver 117 | * @return Enqueue 118 | */ 119 | public function version(string $ver): self 120 | { 121 | $this->data[$this->getCurrentIndex()]['version'] = $ver; 122 | 123 | return $this; 124 | } 125 | 126 | /** 127 | * @param array $attributes 128 | * @return Enqueue 129 | */ 130 | public function attributes(array $attributes): self 131 | { 132 | $this->data[$this->getCurrentIndex()]['attributes'] = $attributes; 133 | 134 | return $this; 135 | } 136 | 137 | /** 138 | * @param string $cdnPath 139 | * @param string|null $id 140 | * @return Enqueue 141 | */ 142 | public function scriptCdn(string $cdnPath, ?string $id = null): self 143 | { 144 | $this->data[] = [ 145 | 'id' => $id, 146 | 'path' => $cdnPath, 147 | 'cdn' => true, 148 | 'script' => true, 149 | 'hook' => static::$hook, 150 | ]; 151 | 152 | return $this; 153 | } 154 | 155 | /** 156 | * @param string $path 157 | * @param string|null $id 158 | * @param string $media 159 | * @return Enqueue 160 | */ 161 | public function style(string $path, ?string $id = null, string $media = 'all'): self 162 | { 163 | $this->data[] = [ 164 | 'id' => $id, 165 | 'path' => $path, 166 | 'media' => $media, 167 | 'hook' => static::$hook, 168 | ]; 169 | 170 | return $this; 171 | } 172 | 173 | /** 174 | * @param string $cdnPath 175 | * @param string|null $id 176 | * @param string $media 177 | * @return Enqueue 178 | */ 179 | public function styleCdn(string $cdnPath, ?string $id = null, string $media = 'all'): self 180 | { 181 | $this->data[] = [ 182 | 'id' => $id, 183 | 'path' => $cdnPath, 184 | 'media' => $media, 185 | 'cdn' => true, 186 | 'hook' => static::$hook, 187 | ]; 188 | 189 | return $this; 190 | } 191 | 192 | /** 193 | * @param string $handle 194 | * @param string $objectName 195 | * @param $data 196 | */ 197 | public function localizeScript(string $handle, string $objectName, $data): void 198 | { 199 | $this->data[] = [ 200 | 'param' => [$handle, $objectName, $data], 201 | 'type' => 'localizeScript', 202 | 'hook' => static::$hook, 203 | ]; 204 | } 205 | 206 | /** 207 | * @param string $data 208 | * @param array $option 209 | */ 210 | public function inlineScript(string $data, array $option = []): void 211 | { 212 | $this->data[] = [ 213 | 'param' => [$data, $option], 214 | 'type' => 'inlineScript', 215 | 'hook' => static::$hook, 216 | ]; 217 | } 218 | 219 | /** 220 | * @param string $data 221 | * @param string $handle 222 | */ 223 | public function inlineStyle(string $data, string $handle = ''): void 224 | { 225 | $this->data[] = [ 226 | 'param' => [$data, $handle], 227 | 'type' => 'inlineStyle', 228 | 'hook' => static::$hook, 229 | ]; 230 | } 231 | 232 | private function getData(): array 233 | { 234 | return $this->data; 235 | } 236 | 237 | public function __call($method, $args): array 238 | { 239 | if($method == 'getData'){ 240 | return $this->getData(); 241 | } 242 | 243 | return []; 244 | } 245 | } 246 | 247 | 248 | -------------------------------------------------------------------------------- /bootstrap/System/Helpers/App.php: -------------------------------------------------------------------------------- 1 | basePath(); 24 | } 25 | 26 | /** 27 | * @param null $class 28 | * @return Application|null 29 | */ 30 | public static function get($class = null) 31 | { 32 | if (is_null($class)) { 33 | return Application::getInstance(); 34 | } 35 | 36 | return Application::getInstance()->get($class); 37 | } 38 | 39 | /** 40 | * access only config/app.php 's config data 41 | * no need to pass app just like: config('slug') for app slug name 42 | * @param $key 43 | * @return Application|null 44 | */ 45 | public static function config($key) 46 | { 47 | return static::get()->config($key); 48 | } 49 | 50 | /** 51 | * @return mixed|string 52 | */ 53 | public static function baseUrl() 54 | { 55 | return static::get()->baseUrl(); 56 | } 57 | 58 | /** 59 | * @return mixed|string 60 | */ 61 | public static function textDomain() 62 | { 63 | return static::get()->config('slug'); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /bootstrap/System/Helpers/Response.php: -------------------------------------------------------------------------------- 1 | resolvePHP($viewInstance->resolvePath($path), $data); 21 | } 22 | 23 | 24 | /** 25 | * @param $path 26 | * @return string 27 | */ 28 | protected function resolvePath($path): string 29 | { 30 | $viewPath = ''; 31 | 32 | foreach (explode('.', $path) as $path) { 33 | $viewPath .= '/' . $path; 34 | } 35 | 36 | return $viewPath; 37 | } 38 | 39 | /** 40 | * @param string $path 41 | * @param array $data 42 | * @return string 43 | */ 44 | protected function resolvePHP(string $path, array $data = []): string 45 | { 46 | if (count($data)) { 47 | extract($data); 48 | } 49 | 50 | return include App::get()->viewPath() . $path . '.php'; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /bootstrap/System/Helpers/helpers.php: -------------------------------------------------------------------------------- 1 | get($class); 23 | } 24 | } 25 | 26 | 27 | if (!function_exists('plugin_master_asset')) { 28 | /** 29 | * @param $path 30 | * @return string 31 | */ 32 | 33 | function plugin_master_asset($path): string 34 | { 35 | return Application::getInstance()->asset($path); 36 | } 37 | } 38 | 39 | 40 | if (!function_exists('plugin_master_config')) { 41 | /** 42 | * Get config. 43 | * @param $key 44 | * @return mixed 45 | */ 46 | 47 | function plugin_master_config($key) 48 | { 49 | return Config::get($key); 50 | } 51 | } 52 | 53 | 54 | if (!function_exists('plugin_master_url')) { 55 | /** 56 | * Get config. 57 | * @return mixed 58 | */ 59 | 60 | function plugin_master_url() 61 | { 62 | return App::get()->baseUrl(); 63 | } 64 | } 65 | 66 | 67 | if (!function_exists('plugin_master_view')) { 68 | /** 69 | * Get view file. 70 | * @param $path 71 | * @param array $data 72 | * @param bool $noTemplate 73 | * @return mixed 74 | */ 75 | 76 | function plugin_master_view($path, $data = [], $noTemplate = false) 77 | { 78 | return View::render($path, $data, $noTemplate); 79 | } 80 | } 81 | 82 | 83 | if (!function_exists('plugin_master_domain')) { 84 | /** 85 | * Get text domain / slug. 86 | */ 87 | 88 | function plugin_master_domain() 89 | { 90 | return App::get()->config('slug'); 91 | } 92 | } 93 | 94 | if (!function_exists('plugin_master_slug')) { 95 | /** 96 | * generate slug from string. 97 | */ 98 | 99 | function plugin_master_slug(string $string) 100 | { 101 | return str_replace(' ', '-', strtolower($string)); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /bootstrap/System/Providers/ActionServiceProvider.php: -------------------------------------------------------------------------------- 1 | get(ActionHandler::class); 22 | 23 | $actionHandler->setAppInstance($app) 24 | ->setControllerNamespace($this->controllerNamespace) 25 | ->loadFile($app->hooksPath('action.php')); 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /bootstrap/System/Providers/ApiServiceProvider.php: -------------------------------------------------------------------------------- 1 | get(ApiHandler::class); 23 | 24 | $apiHandler->setAppInstance($app) 25 | ->setNamespace($app->config('api_namespace')) 26 | ->setControllerNamespace($this->controllerNamespace) 27 | ->setMiddleware($app->config('middleware')) 28 | ->loadRoutes($app->routePath('api.php')); 29 | }); 30 | 31 | add_action('rest_api_init', function () use ($app) { 32 | 33 | /** @var \PluginMaster\Foundation\Api\ApiHandler $apiHandler */ 34 | $apiHandler = $app->get(ApiHandler::class); 35 | $apiHandler->apiGenerate(); 36 | 37 | }, 100); 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /bootstrap/System/Providers/EnqueueServiceProvider.php: -------------------------------------------------------------------------------- 1 | get(EnqueueHandler::class); 22 | 23 | /** @var \PluginMaster\Bootstrap\System\Enqueue $enqueue */ 24 | $enqueue = $app->get(Enqueue::class); 25 | 26 | $enqueueHandler->setAppInstance($app)->loadEnqueueFile($app->enqueuePath('enqueue.php')); 27 | 28 | add_action('init', function () use ($enqueueHandler, $enqueue) { 29 | $enqueueHandler->initEnqueue($enqueue); 30 | }, 12); 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /bootstrap/System/Providers/InitialDataProvider.php: -------------------------------------------------------------------------------- 1 | config('slug'); 28 | 29 | /** 30 | * basic data need for ajax request 31 | * you can add your custom data here 32 | */ 33 | $data = [ 34 | "name" => $app->config('name'), 35 | "slug" => $slug, 36 | "version" => $app->version(), 37 | "api_namespace" => $app->config('api_namespace'), 38 | 'api_endpoint' => home_url().'?rest_route=/'.$app->config('api_namespace'), 39 | "ajax_url" => admin_url('admin-ajax.php'), 40 | "nonce" => wp_create_nonce("wp_rest") 41 | ]; 42 | 43 | /** 44 | * generate object name from application slug ( in config/app.php as 'slug') 45 | */ 46 | $objectName = str_replace("-", "_", $slug); 47 | 48 | /** 49 | * add localize script data 50 | * @for admin area 51 | */ 52 | Enqueue::admin()->localizeScript('jquery-core', $objectName, $data); 53 | 54 | /** 55 | * add localize script data 56 | * @for front-end area 57 | */ 58 | Enqueue::front()->localizeScript('jquery-core', $objectName, $data); 59 | 60 | } 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /bootstrap/System/Providers/ShortcodeServiceProvider.php: -------------------------------------------------------------------------------- 1 | get(ShortcodeHandler::class); 22 | 23 | $shortcodeHandler->setAppInstance($app) 24 | ->setControllerNamespace($this->controllerNamespace) 25 | ->loadFile($app->hooksPath('shortcode.php')); 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /bootstrap/System/Providers/SideMenuServiceProvider.php: -------------------------------------------------------------------------------- 1 | get(SideMenu::class); 22 | 23 | add_action('admin_menu', function () use ($app, $SideMenu) { 24 | 25 | /** @var SideMenuHandler $sideMenuHandler */ 26 | $sideMenuHandler = $app->get(SideMenuHandler::class); 27 | 28 | $sideMenuHandler->setAppInstance($app) 29 | ->setNamespace($this->controllerNamespace) 30 | ->loadMenuFile($app->routePath('sidemenu.php')) 31 | ->setSideMenu($SideMenu); 32 | 33 | }); 34 | 35 | add_action('admin_menu', function () use ($app) { 36 | $app->get(SideMenuHandler::class)->removeFirstSubMenu(); 37 | }, 12); 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /bootstrap/System/Session.php: -------------------------------------------------------------------------------- 1 | add($name, $callback); 25 | } 26 | 27 | private static function handler(): ShortcodeHandler 28 | { 29 | if (!static::$shortcodeHandler) { 30 | static::$shortcodeHandler = App::get(ShortcodeHandler::class); 31 | } 32 | 33 | return static::$shortcodeHandler; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /bootstrap/System/SideMenu.php: -------------------------------------------------------------------------------- 1 | prentSlug = $slug; 49 | 50 | static::getInstance()->data[] = [ 51 | 'title' => $title, 52 | 'menu_title' => $title, 53 | 'slug' => $slug, 54 | ]; 55 | 56 | return static::getInstance(); 57 | } 58 | 59 | private function getCurrentIndex(): int 60 | { 61 | return count($this->data) - 1; 62 | } 63 | 64 | public function capability(string $capability = 'manage_options'): self 65 | { 66 | $this->data[$this->getCurrentIndex()]['capability'] = $capability; 67 | 68 | return $this; 69 | } 70 | 71 | public function menuTitle(string $title): self 72 | { 73 | $this->data[$this->getCurrentIndex()]['menu_title'] = $title; 74 | 75 | return $this; 76 | } 77 | 78 | public function callback($callback): self 79 | { 80 | $this->data[$this->getCurrentIndex()]['callback'] = $callback; 81 | 82 | return $this; 83 | } 84 | 85 | public function icon(string $icon): self 86 | { 87 | $this->data[$this->getCurrentIndex()]['icon'] = $icon; 88 | 89 | return $this; 90 | } 91 | 92 | public function position(int $position): self 93 | { 94 | $this->data[$this->getCurrentIndex()]['position'] = $position; 95 | 96 | return $this; 97 | } 98 | 99 | /** 100 | * $option['as'] required 101 | * @param string $title 102 | * @param string|null $slug 103 | * @return SideMenu 104 | */ 105 | public function child(string $title, string $slug = null): self 106 | { 107 | if(!$this->prentSlug){ 108 | return $this; 109 | } 110 | 111 | $this->data[] = [ 112 | 'title' => $title, 113 | 'menu_title' => $title, 114 | 'submenu' => true, 115 | 'parent_slug' => $this->prentSlug, 116 | 'slug' => $slug ?? plugin_master_slug($title), 117 | ]; 118 | 119 | return $this; 120 | } 121 | 122 | /** 123 | * @param string $parentSlug 124 | * @param string $title 125 | * @param string|null $slug 126 | * @return SideMenu 127 | */ 128 | public static function submenu(string $parentSlug, string $title, string $slug = null): self 129 | { 130 | static::getInstance()->data[] = [ 131 | 'title' => $title, 132 | 'menu_title' => $title, 133 | 'submenu' => true, 134 | 'parent_slug' => $parentSlug, 135 | 'slug' => $slug ?? plugin_master_slug($title), 136 | ]; 137 | 138 | return static::getInstance(); 139 | } 140 | 141 | public function getData(): array 142 | { 143 | return $this->data; 144 | } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plugin-master/plugin-master", 3 | "description": "An Application Development Framework for Wordpress.", 4 | "license": "MIT", 5 | "homepage": "https://github.com/emrancu/PluginMaster", 6 | "support": { 7 | "issues": "https://github.com/emrancu/PluginMaster/issues", 8 | "source": "https://github.com/emrancu/PluginMaster" 9 | }, 10 | "authors": [ 11 | { 12 | "name": "AL EMRAN", 13 | "email": "emrancu1@gmail.com" 14 | } 15 | ], 16 | "keywords": [ 17 | "framework", 18 | "PluginMaster", 19 | "WordPress Plugin Development framework" 20 | ], 21 | "type": "project", 22 | "autoload": { 23 | "classmap": [], 24 | "files": [ 25 | "bootstrap/System/Helpers/helpers.php" 26 | ], 27 | "psr-4": { 28 | "PluginMaster\\App\\": "app/", 29 | "PluginMaster\\Bootstrap\\": "bootstrap/", 30 | "PluginMaster\\Database\\": "database/" 31 | } 32 | }, 33 | "require": { 34 | "php": "^7.0|^8.0", 35 | "plugin-master/contracts": "^1.0", 36 | "plugin-master/db": "^1.0", 37 | "plugin-master/request": "^1.0", 38 | "plugin-master/validator": "^1.0", 39 | "plugin-master/foundation": "^1.0", 40 | "plugin-master/schema": "^1.0" 41 | }, 42 | "require-dev": { 43 | "automattic/jetpack-autoloader": "2.10.1" 44 | }, 45 | "minimum-stability": "dev", 46 | "prefer-stable": true, 47 | "config": { 48 | "allow-plugins": { 49 | "automattic/jetpack-autoloader": true 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /config/app.php: -------------------------------------------------------------------------------- 1 | "Plugin Master", 19 | 20 | /** 21 | * application/plugin slug/text domain 22 | * @type string 23 | */ 24 | 'slug' => "plugin-master", 25 | 26 | /** 27 | * application/plugin version 28 | * @type string 29 | */ 30 | 'version' => "1.0.1", 31 | 32 | /** 33 | * rest api namespace 34 | * @type string 35 | */ 36 | 37 | 'api_namespace' => "PluginMaster/v1", 38 | 39 | /** 40 | * add your custom Service Providers here 41 | * service provider path App/Providers 42 | * @type array 43 | */ 44 | 'providers' => [ 45 | TestServiceProvider::class, 46 | ], 47 | 48 | /** 49 | * add your rest api middleware here 50 | * middleware path App/Middleware 51 | * @type array 52 | */ 53 | 'middleware' => [ 54 | 'test' => TestMiddleware::class 55 | ], 56 | 57 | /** 58 | * system service provide 59 | * do not add your service provider here 60 | * if you want to disable any system service provider just comment out or remove from here 61 | * @type array 62 | */ 63 | 'system_providers' => [ 64 | SystemSideMenuServiceProvider::class, 65 | SystemApiServiceProvider::class, 66 | SystemActionServiceProvider::class, 67 | SystemShortcodeServiceProvider::class, 68 | SystemEnqueueServiceProvider::class, 69 | InitialDataProvider::class, 70 | ], 71 | ]; 72 | -------------------------------------------------------------------------------- /database/Migration.php: -------------------------------------------------------------------------------- 1 | intIncrements( 'id' ); 19 | $column->integer( 'user_id' ) ; 20 | $column->text( 'note' )->nullable(); 21 | $column->enum( 'status', [ 'active', 'completed' ] ); 22 | $column->timestamp( 'created_at' )->default( 'current_timestamp' ); 23 | $column->timestamp( 'updated_at' )->nullable()->onUpdateTimeStamp(); 24 | } )->execute(); 25 | 26 | */ 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /enqueues/enqueue.php: -------------------------------------------------------------------------------- 1 | script('js/react/app.js')->inFooter(); 6 | Enqueue::admin()->script('js/js/vue/app.js')->inFooter(); 7 | 8 | Enqueue::admin()->style('css/app.css')->version(time()); 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /hooks/action.php: -------------------------------------------------------------------------------- 1 | { 4 | return

Hello world, React JS ❤️

5 | } 6 | 7 | export default Home 8 | -------------------------------------------------------------------------------- /resources/js/react/app.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Home from './Home.jsx'; 4 | 5 | if( document.getElementById('reactApp') ){ 6 | 7 | ReactDOM.render( 8 | , 9 | document.getElementById('reactApp') 10 | ); 11 | } -------------------------------------------------------------------------------- /resources/js/vue/App.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /resources/js/vue/app.js: -------------------------------------------------------------------------------- 1 | import {createApp} from 'vue' 2 | 3 | import App from './App.vue' 4 | 5 | 6 | if( document.getElementById('vueApp') ) { 7 | 8 | const app = createApp(App) 9 | 10 | app.mount('#vueApp') 11 | 12 | } -------------------------------------------------------------------------------- /resources/scss/app.scss: -------------------------------------------------------------------------------- 1 | .app{ 2 | color: green; 3 | } -------------------------------------------------------------------------------- /resources/views/action.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /resources/views/index.php: -------------------------------------------------------------------------------- 1 |

2 | 3 |

-------------------------------------------------------------------------------- /resources/views/react-app.php: -------------------------------------------------------------------------------- 1 | 2 |

Plugin Master: React Application

3 |
4 | -------------------------------------------------------------------------------- /resources/views/vue-app.php: -------------------------------------------------------------------------------- 1 | 2 |

Plugin Master: Vue Application

3 |
4 | -------------------------------------------------------------------------------- /routes/api.php: -------------------------------------------------------------------------------- 1 | 'test'], function () { 9 | Api::get('test/{id}', ApiController::class); 10 | Api::dynamic('test/{id}', ApiController::class, false); 11 | }); 12 | -------------------------------------------------------------------------------- /routes/sidemenu.php: -------------------------------------------------------------------------------- 1 | menuTitle("Home | Plugin Master") 9 | ->child('Home','pluginmaster-home')->callback('SideMenuController@home') ; 10 | 11 | SideMenu::submenu('plugin-master', 'React App', 'plugin-master-react')->callback('SideMenuController@react'); 12 | SideMenu::submenu('plugin-master', 'Vue App', 'plugin-master-vue')->callback('SideMenuController@vue'); -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | let builder = require("bundle-master") 3 | 4 | module.exports = builder 5 | .react('resources/js/react/app.js', 'assets/js/react/app.js') 6 | .vue('resources/js/vue/app.js', 'assets/js/vue/app.js') 7 | .scss('resources/scss/app.scss', 'assets/css/app.css') 8 | .init(); 9 | --------------------------------------------------------------------------------