{"id":36397448,"url":"https://github.com/wp-pluginmaster/pluginmaster","last_synced_at":"2026-01-11T16:00:33.285Z","repository":{"id":43602286,"uuid":"252908329","full_name":"WP-PluginMaster/PluginMaster","owner":"WP-PluginMaster","description":"An application development framework for WordPress. More than WordPress Plugin Boilerplate Generator. You will fall in love with PluginMaster. Let's try. visit: https://www.wppluginmaster.com","archived":false,"fork":false,"pushed_at":"2023-09-25T09:19:40.000Z","size":971,"stargazers_count":55,"open_issues_count":1,"forks_count":16,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-11T18:50:49.303Z","etag":null,"topics":["database-migration","enqueue","framework","schema-builder","vue-js","wordpress","wordpressplugin"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WP-PluginMaster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-04-04T04:27:22.000Z","updated_at":"2025-07-10T07:36:39.000Z","dependencies_parsed_at":"2025-05-13T03:30:18.165Z","dependency_job_id":null,"html_url":"https://github.com/WP-PluginMaster/PluginMaster","commit_stats":null,"previous_names":["wp-pluginmaster/pluginmaster","wp-plugin-master/pluginmaster"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/WP-PluginMaster/PluginMaster","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WP-PluginMaster%2FPluginMaster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WP-PluginMaster%2FPluginMaster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WP-PluginMaster%2FPluginMaster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WP-PluginMaster%2FPluginMaster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WP-PluginMaster","download_url":"https://codeload.github.com/WP-PluginMaster/PluginMaster/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WP-PluginMaster%2FPluginMaster/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28312075,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T14:58:17.114Z","status":"ssl_error","status_checked_at":"2026-01-11T14:55:53.580Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database-migration","enqueue","framework","schema-builder","vue-js","wordpress","wordpressplugin"],"created_at":"2026-01-11T16:00:19.035Z","updated_at":"2026-01-11T16:00:33.190Z","avatar_url":"https://github.com/WP-PluginMaster.png","language":"PHP","readme":"# PluginMaster (an Application Development Framework for WordPress)\n# What is PluginMaster?\n  \u003cblockquote\u003e\n    « PluginMaster is an Application development framework for WordPress. It changes the flavor of plugin development.»\n  \u003c/blockquote\u003e\n\n# Code Features   \n \u003col type=\"1\"\u003e\n\u003cli\u003e \u003ca href=\"#DatabaseMigrationSystem\"\u003e Database Migration System \u003c/a\u003e\u003c/li\u003e\n \u003cli\u003e\u003ca href=\"#SimpleSideMenuDeclaration\"\u003e  Simple Side Menu Declaration\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#EasyRestAPIRouteDeclaration\"\u003e  Simple Rest API Declaration\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#QueryBuilder\"\u003e   Database Query Builder\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#SimpleEnqueueDeclaration\"\u003e  Simple Enqueue Declaration\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#ShortCode\"\u003e Easy Shortcode Handler \u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#RequestHandlingSystem\"\u003e  Http Request Handling \u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#Validator\"\u003e  Request Validation\u003c/a\u003e\u003c/li\u003e \n\u003cli\u003e\u003ca href=\"#BuildinVueJSConfiguration\"\u003e  Build-in Vue JS Configuration\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#GlobalFunction\"\u003e  Global Functions \u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#SessionHandler\"\u003e  Session Handler \u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e Middleware (upcoming) \u003c/li\u003e \n\u003cli\u003e Action Handler (upcoming) \u003c/li\u003e\n\u003cli\u003e Filter Handler (upcoming)  \u003c/li\u003e\n\u003c/ol\u003e\n\n# Installation \n \u003col\u003e \n \u003cli\u003eGo to \u003ccode\u003ewp-content/plugins/\u003c/code\u003e directory in your WordPress\u003c/li\u003e\n \u003cli\u003eOpen terminal and run : \u003ccode\u003ecomposer create-project plugin-master/plugin-master\u003c/code\u003e \u003cb\u003eOR\u003c/b\u003e \u003ccode\u003ecomposer\n                            create-project plugin-master/plugin-master project_name\u003c/code\u003e\u003c/li\u003e\n \u003cli\u003e A demo application includes with Vue JS . Just active from Plugin section\u003c/li\u003e\n \n\u003c/ol\u003e\n# Configuration \n\u003col\u003e \n \u003cli\u003e Change your Plugin name, version etc from \u003ccode\u003eindex.php\u003c/code\u003e page in root folder.\u003c/li\u003e\n \u003cli\u003eChange Rest API Namespace from \u003ccode\u003econfig.php\u003c/code\u003e, located in \u003ccode\u003eapp/config/\u003c/code\u003e\n                        directory (You can add any configuration related data in \u003ccode\u003econfig.php \u003c/code\u003e)\n                    \u003c/li\u003e\n \n \u003c/ol\u003e\n\n# 1. Database Migration System\n \u003cdiv id=\"DatabaseMigrationSystem\"\u003e\u003c/div\u003e\n\n\u003cp\u003e Migrations are typically paired with the \u003cb\u003ePluginMaster\u003c/b\u003e 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.  \u003c/p\u003e\n \u003cb\u003eMigration file directory : \u003ccode\u003edatabase/migrations/\u003c/code\u003e\u003c/b\u003e\n \n \u003cb\u003eStructure\u003c/b\u003e \n \n\u003cp\u003eThe migration file name has 2 parts :\n \u003col\u003e\n \u003cli\u003e\u003cb\u003eFirst\u003c/b\u003e  for sequence maintain for foreign key and \u003cb\u003esecond\u003c/b\u003e for the  table name.  \u003cb\u003e Second \u003c/b\u003e part must be the same as table name .\u003c/li\u003e\n\u003c/ol\u003e\n \u003cblockquote\u003e  Also class name will be the same as the table name.\u003cbr\u003e File name like : \u003ccode\u003e1_demo_users.php\u003c/code\u003e.\n                This means, \u003ccode\u003e1\u003c/code\u003e is for sequence maintain and \u003ccode\u003edemo_users\u003c/code\u003e is the table name and also class\n                name. the table prefix will be set from the schema builder.\n \u003c/blockquote\u003e\n\n\u003cp\u003eA migration class contains one method: up. The up method is used to add new tables to your database.\u003c/p\u003e\n \u003cb\u003eSample Migration File\u003c/b\u003e\n \u003cp class=\"mt-3\"\u003eFile Name: \u003ccode\u003e1_demo_users.php\u003c/code\u003e\u003c/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e\nuse App\\system\\schema\\Schema;\n\nclass demo_users\n{\n    public function up()\n    {\n      return Schema::create('demo_users', function (Schema $column) {\n            $column-\u003eintIncrements('id');\n            $column-\u003estring('name')-\u003enullable() ;\n            $column-\u003estring('mobile') ;\n            $column-\u003estring('email')-\u003enullable();\n            $column-\u003etext('description')-\u003enullable();\n            $column-\u003eenum('status', ['ok', 'not']);\n            $column-\u003einteger('user_id')-\u003eunsigned()-\u003enullable();\n            $column-\u003eforeign('user_id')-\u003eon('demo_users.id');\n            $column-\u003etimestamp('student_created_at')-\u003edefault('current_timestamp')-\u003eonUpdateTimeStamp();\n        });\n    }\n\n}\n \u003c/code\u003e\n \u003c/pre\u003e\n\n\u003cb\u003eSchema Functions \u003c/b\u003e\n \u003col\u003e\n\u003cli\u003e \u003ccode\u003eintIncrements($column)\u003c/code\u003e : integer (10), auto_increment, primary key \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003ebigIntIncrements($column)\u003c/code\u003e : bigint (20), auto_increment, primary key \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003einteger($column, $length = 10)\u003c/code\u003e : integer (10)  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003ebigInt($column, $length = 20)\u003c/code\u003e : bigint (20)  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003edecimal($column, $length = 20, $places = 2)\u003c/code\u003e : decimal (20, 2)  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003etext($column)\u003c/code\u003e : text \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003eenum($column, $values)\u003c/code\u003e : enum( value, value) ($values must be array).  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003edate($column)\u003c/code\u003e : date  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003etimestamp($column)\u003c/code\u003e : timestamp  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003enullable() \u003c/code\u003e : null  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003eunsigned() \u003c/code\u003e : unsigned  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003edefault($value)\u003c/code\u003e : default 'value' (if $value == 'CURRENT_TIMESTAMP' OR 'current_timestamp' then set \u003ccode\u003eCURRENT_TIMESTAMP \u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e \u003ccode\u003eonUpdateTimeStamp()\u003c/code\u003e : ON UPDATE CURRENT_TIMESTAMP  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003eforeign($column)\u003c/code\u003e : make CONSTRAINT for foreign key  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003eon($reference)\u003c/code\u003e : $reference means table.column. check following example.\n\u003cpre\u003e\n\u003ccode\u003e    \n$column-\u003einteger('user_id')-\u003eunsigned();\n$column-\u003eforeign('user_id')-\u003eon('demo_users.id'); \u003c/code\u003e\n\u003c/pre\u003e\n\n\u003c/li\u003e\n\u003c/ol\u003e\n\n\n# 2. Simple Side Menu Declaration \n \u003cdiv id=\"SimpleSideMenuDeclaration\"\u003e\u003c/div\u003e\n\n\u003cp\u003eCreate a WP side menu in easy way. just declare your side nav with controller, method \u0026, etc.   \u003c/p\u003e\n\u003cb\u003e Side Menu declaration file : routes/sidenav.php \u003c/b\u003e\u003cbr\u003e\n\u003cb\u003e Side Menu Controller must declare inside : app/controller/sidenav/ \u003c/b\u003e\n\u003cp class=\"mt-3\"\u003e\u003cb\u003eSample Structure\u003c/b\u003e\u003c/p\u003e\n\u003cpre\u003e\n\u003ccode\u003e\n$sidenav-\u003emain('DemoPlugin', [\"icon\" =\u003e \"dashicons-admin-site\",  \"as\" =\u003e 'DemoController@main', \"position\" =\u003e 500, \"removeFirstSubmenu\" =\u003e true], function ($sidenav) {\n    $sidenav-\u003esub('Dashboard', [\"title\" =\u003e \"Dashboard\", \"as\" =\u003e 'DemoController@sub']);\n}); \n\u003c/code\u003e\n \u003c/pre\u003e\n \u003cp class=\"mt-2\"\u003e\u003cb\u003eThe \u003ccode\u003emain method \u003c/code\u003e has   three parameters..\u003c/b\u003e  \u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eOne : menu slug . (Required)\u003c/li\u003e\n\u003cli\u003eTwo : menu options . Its type must be an array. \u003cbr\u003e\n\u003cb\u003eMandatory index:\u003c/b\u003e  icon (dashboard icon), as ( controller and method must be with \u003ccode\u003e@\u003c/code\u003e sign) \u003cbr\u003e\n\u003cb\u003eOptional index:\u003c/b\u003e  position (default is 500),  removeFirstSubmenu ( for delete first submenu, default false) \u003cbr\u003e\n\u003c/li\u003e\n \u003cli\u003eThird: closer function for registering submenu under main menu\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp class=\"mt-4\"\u003e\u003cb\u003eThe \u003ccode\u003esub method \u003c/code\u003e has two parameters.\u003c/b\u003e  \u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eOne : menu slug . (Required)\u003c/li\u003e\n\u003cli\u003eTwo : menu options . Its type must be an array. \u003cbr\u003e\n\u003cb\u003eMandatory index:\u003c/b\u003e  title (Menu Title), as ( controller and method must be with \u003ccode\u003e@\u003c/code\u003e sign) \u003cbr\u003e\n  \u003cblockquote\u003eIn \u003ccode\u003eDemoController@main\u003c/code\u003e: \u003ccode\u003eDemoController\u003c/code\u003e is controller name\n                        located at \u003ccode\u003e app/controller/sidenav/ \u003c/code\u003e and \u003ccode\u003emain\u003c/code\u003e is method name of\n                        DemoController\n \u003c/blockquote\u003e\n  \u003cb\u003eOptional index:\u003c/b\u003e position (default is 500), removeFirstSubmenu ( for delete first submenu, default false) \u003cbr\u003e\n\u003c/li\u003e\n\u003cli\u003eThird: closer function for registering submenu under main menu\u003c/li\u003e\n \u003c/ol\u003e\n \u003cp class=\"mt-4\"\u003e\u003cb\u003eThe \u003ccode\u003esub method \u003c/code\u003e has two parameters.\u003c/b\u003e\u003c/p\u003e\n \u003col\u003e\n \u003cli\u003eOne : menu slug . (Required)\u003c/li\u003e\n \u003cli\u003eTwo : menu options . Its type must be an array. \u003cbr\u003e\n  \u003cb\u003eMandatory index:\u003c/b\u003e title (Menu Title), as ( controller and method must be with\n  \u003ccode\u003e@\u003c/code\u003e sign) \u003cbr\u003e\n  \u003cblockquote\u003eIn \u003ccode\u003eDemoController@main\u003c/code\u003e: \u003ccode\u003eDemoController\u003c/code\u003e is controller name\n                        located at \u003ccode\u003e app/controller/sidenav/ \u003c/code\u003e and \u003ccode\u003esub\u003c/code\u003e is method name of\n                        DemoController\n \u003c/blockquote\u003e\n\n \u003c/li\u003e\n \u003c/ol\u003e\n            \n            \n  \n # 3. Easy Rest API Route Declaration\n \u003cdiv id=\"EasyRestAPIRouteDeclaration\"\u003e\u003c/div\u003e\n \n\u003cp\u003eCreate WP rest route in easy way.     \u003c/p\u003e\n\u003cp\u003e \u003cb\u003e Rest Route declaration file : routes/route.php \u003c/b\u003e\n \u003cbr\u003e \u003cb\u003e Rest Route Controller must declare inside : app/controller/api/ \u003c/b\u003e\u003c/p\u003e\n \u003cp\u003e\u003cb\u003eAPI Namespace:\u003c/b\u003e Namespace maintain by \u003ccode\u003eapi_namespace\u003c/code\u003e of config.php. It's located in \u003ccode\u003eapp/config/config.php\u003c/code\u003e\n            \u003c/p\u003e\n\u003cp class=\"mt-3\"\u003e\u003cb\u003eSample Structure\u003c/b\u003e\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\n$route-\u003eget('dashboard/{id?}', 'DemoController@dashboard');\n$route-\u003epost('add-note', 'DemoController@addNote'); \n$route-\u003epost('update-note', 'DemoController@addNote', true); \n\u003c/code\u003e\n\u003c/pre\u003e\n\u003cspan\u003e\u003ccode\u003eDemoController\u003c/code\u003e is controller name and \u003ccode\u003edashboard\u003c/code\u003e is method name , located in \u003ccode\u003eapp/controller/api/\u003c/code\u003e directory\u003c/span\u003e\n\u003cp class=\"mt-2\"\u003e\u003cb\u003e PluginMaster has two methods: GET, POST   \u003c/b\u003e  \u003c/p\u003e\n\u003cp\u003eBoth Route has 3 parts/parameters\u003c/p\u003e\n\u003cul\u003e\n  \u003cli\u003e \u003cb\u003eFirst Parameter\u003c/b\u003e: Route Name \n\u003col\u003e\n \u003cli\u003eDynamic Parameter : \u003ccode\u003e{parameter_name}\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eDynamic Optional Parameter : \u003ccode\u003e{parameter_name?} \u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e Access Dynamic Param in Controller's method : set parameter like : \u003ccode\u003efunction dashboard($variable)\u003c/code\u003e then \u003ccode\u003e$variable['param_name'] \u003c/code\u003e\u003c/li\u003e\n\u003c/ol\u003e\n    \n\u003c/li\u003e\n \u003cli\u003e\u003cb\u003eSecond Parameter\u003c/b\u003e:  Conteoller and Method Name ( with @ sign) \u003c/li\u003e \n \u003cli\u003e\u003cb\u003eThird Parameter \u003c/b\u003e: CSRF protection (Optional).Default value false. If you set true, can not access this route without \u003ca href=\"#wpNonce\"\u003eWP Nonce Token \u003c/a\u003e. You must pass token in header with \u003ccode\u003eX-WP-Nonce: token\u003c/code\u003e  \u003c/li\u003e\n \n \u003c/ul\u003e\n \n \n # 4. DB Query Builder\n \u003cdiv id=\"QueryBuilder\"\u003e\u003c/div\u003e\n \u003cp\u003ePluginMaster's database query builder provides a convenient, fluent interface to run\n                database queries. It can be used to perform most database operations in your application. \u003c/p\u003e\n \u003cb\u003eNamespace: \u003ccode\u003ePluginMaster\\DB\\DB;\u003c/code\u003e\u003c/b\u003e\u003cbr\u003e \n \n\u003cbr\u003e\n\u003cb\u003eDB Functions \u003c/b\u003e\n\u003col\u003e\n\u003cli\u003e   Retrieving A Single Row\u003cbr\u003e\u003ccode\u003e  DB::table('users')-\u003efirst();\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e  Retrieving A multiple Row \u003cbr\u003e\u003ccode\u003e  DB::table('users')-\u003eget();\u003c/code\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\n \u003col\u003e\n \u003cli\u003e\u003ccode\u003ewhere($column, $value )\u003c/code\u003e :\n \n\n \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003ewhere('id', 1)\n     -\u003eget()\u003c/code\u003e\u003c/pre\u003e\n\n  \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003ewhere(function($query){\n       $query-\u003ewhere('id', 1);\n       $query-\u003eorWhere('name', \"name\");\n     })\n     -\u003eget()\u003c/code\u003e\u003c/pre\u003e\n\n \u003c/li\u003e\n  \u003cli\u003e\u003ccode\u003eorWhere($column, $value)\u003c/code\u003e :\n \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003ewhere('id', 1)\n     -\u003eorWhere('name', \"name\")\n     -\u003eget()\u003c/code\u003e\u003c/pre\u003e\n\n \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003ewhere('id', 1)\n     -\u003eorWhere(function($query){\n         $query-\u003ewhere('field', 'value);\n         $query-\u003ewhere('field', 'value);\n         })\n     -\u003efirst()\u003c/code\u003e\u003c/pre\u003e\n\n \u003c/li\u003e\n \u003cli\u003e\u003ccode\u003ewhereRaw($query)\u003c/code\u003e :\n \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003ewhereRaw('id = 1')\n     -\u003efirst()\u003c/code\u003e\u003c/pre\u003e\n    \u003c/li\u003e\n\n  \u003cli\u003e\u003ccode\u003eorWhereRaw($query)\u003c/code\u003e :\n  \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003ewhereRaw('id = 1')\n     -\u003eorWhereRaw('id = 1')\n     -\u003efirst()\u003c/code\u003e\u003c/pre\u003e\n \u003c/li\u003e\n\n\n \u003cli\u003e\u003ccode\u003eorderBy($columns, $direction)\u003c/code\u003e :\n \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003eorderBy('id', 'desc')\u003c/code\u003e\u003c/pre\u003e\n                    \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003eorderBy('id,name', 'desc')\u003c/code\u003e\u003c/pre\u003e\n \u003c/li\u003e\n\n   \u003cli\u003e\u003ccode\u003egroupBy($columns)\u003c/code\u003e :\n \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003egroupBy('id')\u003c/code\u003e\u003c/pre\u003e\n                    \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003egroupBy('id,name')\u003c/code\u003e\u003c/pre\u003e\n \u003c/li\u003e\n\n\n  \u003cli\u003e\u003ccode\u003elimit($number)\u003c/code\u003e :\n \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003ewhere('id', 1)\n     -\u003elimit(number)-\u003eget()\u003c/code\u003e\u003c/pre\u003e\n  \u003c/li\u003e\n\n \u003cli\u003e\u003ccode\u003eoffset($number)\u003c/code\u003e :\n \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003ewhere('id', 1)\n     -\u003elimit(number)-\u003eoffset(number)-\u003eget()\u003c/code\u003e\u003c/pre\u003e\n \u003c/li\u003e\n\n\u003cli\u003e\u003ccode\u003eselect($fields)\u003c/code\u003e :\n\u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003eselect('id,name')\n        -\u003eget()\u003c/code\u003e\u003c/pre\u003e\n                \u003c/li\u003e\n                \u003cli\u003e\u003ccode\u003einsert($data)\u003c/code\u003e :\n                    \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003einsert(['name' =\u003e \"demo\"])\u003c/code\u003e\u003c/pre\u003e\n \u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eupdate($data,$where)\u003c/code\u003e :\n\u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003ewhere('id', 1)\n     -\u003eupdate(['name' =\u003e \"demo\"])\u003c/code\u003e\u003c/pre\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003edelete($where)\u003c/code\u003e :\n\u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('users')\n     -\u003ewhere('id', 1)\n     -\u003edelete()\u003c/code\u003e\u003c/pre\u003e\n\u003c/li\u003e\n\n\u003cli\u003e\u003ccode\u003ejoin($table, $first, $operator = null, $second = null) (INNER JOIN)\u003c/code\u003e:\n\u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('demo_notes as n')\n        -\u003ejoin('demo_users as u', 'u.id', '=', 'n.user_id')\n        -\u003efirst()\n\u003c/code\u003e\u003c/pre\u003e\n\u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('demo_notes as n')\n        -\u003ejoin('demo_users as u', function($query){\n          $query-\u003eon( 'u.id', '=', 'n.user_id')\n          $query-\u003eorOn( 'u.id', '=', 'n.user_id')\n        })\n        -\u003efirst()\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::table('demo_notes as n')\n        -\u003ejoin('demo_users as u', function($query) use($request){\n          $query-\u003eon( 'u.id', '=', 'n.user_id')\n          $query-\u003eonWhere( 'u.id', '=', $request-\u003eid)\n        })\n        -\u003efirst()\n\u003c/code\u003e\u003c/pre\u003e\n\n\n \u003cblockquote\u003eNote: Must use table alias for using join or leftJoin.\u003c/blockquote\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003ccode\u003eleftJoin($table, $first, $operator = null, $second = null) (LEFT JOIN)\u003c/code\u003e: \u003cb\u003e Same as\n                        join()\u003c/b\u003e\n\u003c/li\u003e\n\n \u003cli\u003e\u003ccode\u003etransaction()\u003c/code\u003e:\n\u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::startTransaction(function(){\n    DB::table('demo_notes')\n      -\u003einsert([\n         \"note\" =\u003e \"Hello\",\n       ]);\n})\u003c/code\u003e\u003c/pre\u003e\n\n\u003cpre class=\"mt-2\"\u003e\u003ccode\u003eDB::startTransaction(function(DB $query){\n    $query-\u003etable('demo_notes')\n      -\u003einsert([\n         \"note\" =\u003e \"Hello\",\n       ]);\n})\u003c/code\u003e\u003c/pre\u003e\n\n \u003c/li\u003e\n \u003c/ol\u003e\n\n\n\n# 5. Simple Enqueue Declaration \n\u003cdiv id=\"SimpleEnqueueDeclaration\"\u003e\u003c/div\u003e\n\n \u003cp\u003e Easy way to add css and js file to application\u003c/p\u003e\n\u003cb\u003e Enqueue Declaration file : enqueue/enqueue.php \u003c/b\u003e\u003cbr\u003e\n\u003cb\u003ePlugin Deactivation Script Declaration : enqueue/deactiveAction.php \u003c/b\u003e\n\u003cp class=\"mt-3\"\u003e\u003cb\u003eFunctions\u003c/b\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003e  headerScript($path) :  \u003c/code\u003e  : \u003cbr\u003e\n    \u003ccode\u003e$enqueue-\u003eheaderScript('assets/js/index.js');\u003c/code\u003e \u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e  headerScriptCdn($path) :  \u003c/code\u003e : \u003cbr\u003e \u003ccode\u003e$enqueue-\u003eheaderScriptCdn('http://alemran.me/js/index.js');\u003c/code\u003e \u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e  footerScript($path) :  \u003c/code\u003e: \u003cbr\u003e \u003ccode\u003e$enqueue-\u003efooterScript('assets/js/index.js');\u003c/code\u003e \u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e  footerScriptCdn($path) :  \u003c/code\u003e :\u003cbr\u003e \u003ccode\u003e$enqueue-\u003efooterScriptCdn('http://alemran.me/js/index.js');\u003c/code\u003e \u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e  style($path) :  \u003c/code\u003e :\u003cbr\u003e \u003ccode\u003e$enqueue-\u003estyle('assets/css/style.css');\u003c/code\u003e \u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e  styleCdn($path) :  \u003c/code\u003e:\u003cbr\u003e \u003ccode\u003e$enqueue-\u003estyle('assets/js/index.css');\u003c/code\u003e \u003c/li\u003e\n\u003cli id=\"wpNonce\"\u003e \u003ccode\u003e csrfToken($handler, $objectName):  \u003c/code\u003e :\u003cbr\u003e\n\n\u003cpre\u003e\n\u003ccode\u003e\n$enqueue-\u003efooterScript('assets/js/index.js','DemoScriptIndex');\n$enqueue-\u003ecsrfToken('DemoScriptIndex','corsData');\n\u003c/code\u003e\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003eDemoScriptIndex\u003c/code\u003e is Handler and \u003ccode\u003ecorsData\u003c/code\u003e is object name. You can access   api  ROOT url and token  corsData object. \u003c/p\u003e\n \u003cblockquote\u003e\u003cb\u003eNote:\u003c/b\u003e CSRF token must define under a js file's Handler.\u003c/blockquote\u003e\n\u003c/li\u003e\n\n\u003cli\u003e\u003ccode\u003e $enqueue-\u003ehotScript('file_name.js') \u003c/code\u003e for Webpack (DevServer) hot mode with Vue js (main url will be \u003ccode\u003e  http://localhost:8080/file_name.js\u003c/code\u003e)\n \u003c/li\u003e\n\u003c/ol\u003e\n\n\n# 6. Easy Shortcode Handler\n \u003cdiv id=\"ShortCode\"\u003e \u003c/div\u003e \n \u003cp\u003eCreate and manage shortcode in easy way\u003c/p\u003e\n \u003cb\u003e Shortcode Declaration file : shortcode/shortcode.php \u003c/b\u003e\u003cbr\u003e\n \u003cb\u003eController root directory for shortcode : app/controller/shortcode/ \u003c/b\u003e\u003cbr\u003e\n \u003cb\u003eExample: \u003c/b\u003e\n \u003cpre\u003e \u003ccode\u003e $shortCode-\u003eadd('pluginmaster', 'ShortCodeController@index' ) ; \u003c/code\u003e  \u003c/pre\u003e\n \u003cp\u003e\u003ccode\u003epluginmaster\u003c/code\u003e is the name of shortcode. \u003ccode\u003eShortCodeController\u003c/code\u003e is controller and \u003ccode\u003eindex\u003c/code\u003e is method name.\u003c/p\u003e\n \u003cp\u003eMethod Sample\u003c/p\u003e\n  \u003cpre\u003e\u003ccode\u003e\n    public function index(){\n          $data = DB::table('table_name')-\u003eget();\n        return  view('shortcode', compact('data')) ;\n    }\n  \u003c/code\u003e\u003c/pre\u003e\n  \n  \n\n# 7. Request Handling System\n\u003cdiv id=\"RequestHandlingSystem\" \u003e\u003c/div\u003e\n\n\u003cp\u003e Easy way to access request data from native or AJAX request\u003c/p\u003e\n \u003cb\u003e No need isset function to check. just call \u003ccode\u003e$request-\u003ename\u003c/code\u003e , it will return null if not\n            set \u003c/b\u003e\u003cbr\u003e\n\u003cp class=\"mt-3\"\u003e\u003cb\u003eExample\u003c/b\u003e\u003c/p\u003e\n\u003cpre\u003e \u003ccode\u003e\n     use App\\system\\request\\Request;\n     $request = new Request();\n     echo $request-\u003ename;\n    \u003c/code\u003e\n    \u003c/pre\u003e\n\u003cp\u003e\u003cb\u003eAccess Header:\u003c/b\u003e \u003ccode\u003e$request-\u003eheader(name)\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e\u003cb\u003eGet All Data as Array:\u003c/b\u003e \u003ccode\u003e$request-\u003eall()\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e\u003cb\u003eCheck Request Method :\u003c/b\u003e \u003ccode\u003eif($request-\u003eisMethod('post')){}\u003c/code\u003e\u003c/p\u003e\n\n\n# 8. Validator \n\n\n\u003cp\u003e Validate data is easy in PluginMaster\u003c/p\u003e\n \u003cp class=\"mt-3\"\u003e\u003cb\u003e Manually Validate ( not compatible for REST API) \u003c/b\u003e:  \u003c/p\u003e\n  \u003cpre\u003e\n  \u003ccode\u003e\n use App\\system\\Validator;\n  $validator = Validator::make($request, [\n            'ID' =\u003e 'required|number|limit:10,11',\n            'name' =\u003e 'required|wordLimit:10,20',\n            'slug' =\u003e 'required|noSpecialChar',\n        ]);\n\n if ($validator-\u003efails()) {\n     $errors =  $validator-\u003eerrors();\n }\n\n\u003c/code\u003e\n\u003c/pre\u003e\n\u003cp\u003eFor checking validation fail: \u003ccode\u003e$validator-\u003efail();\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eFor Validation errors: \u003ccode\u003e $validator-\u003eerrors() \u003c/code\u003e.\u003c/p\u003e \n\u003cp\u003eYou can use \u003ccode\u003e$validator-\u003eflashErrors();\u003c/code\u003e for flashing errors as flash session and you can access  all flashed errors through \u003ccode\u003eformErrors()\u003c/code\u003e global function. Also you can access single field error  through \u003ccode\u003eformError(field name).\u003c/code\u003e\u003c/p\u003e\n \n \u003cb\u003eDisplay Errors in View file :\u003c/b\u003e\n\u003cp\u003eIn controller\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\n      use App\\system\\Validator;\n      $validator = Validator::make($request, [\n      'ID' =\u003e 'required|number|limit:10,11',\n      'name' =\u003e 'required|wordLimit:10,20',\n      'slug' =\u003e 'required|noSpecialChar',\n      ]);\n \u003c/code\u003e \u003c/pre\u003e    \n  \u003cpre\u003e\u003ccode\u003e    \n    if ($validator-\u003efails()) {\n      $errors =  $validator-\u003eformErrors();\n    }  \n\u003c/code\u003e \u003c/pre\u003e\n\n\u003cp\u003eIn view file\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e             \nif ( count(formErrors()) ) :\n      \u0026lt;div class=\"alert alert-danger\"\u0026gt;\n           \u0026lt;ul\u0026gt;\n            \u0026lt;php foreach (formErrors() as $key=\u003e$value): ?\u0026gt;\n                   \u0026lt;li\u0026gt; \u0026lt;php  echo $value; ?\u0026gt;  \u0026lt;/li\u0026gt;\n           \u0026lt;php  endforeach; ?\u0026gt;\n         \u0026lt;/ul\u0026gt;\n     \u0026lt;/div\u0026gt;\n   \u0026lt;php endif;  ?\u0026gt;\n\n  \u0026lt;input type=\"text\" name=\"email\"\u0026gt;\n  \u0026lt;p\u0026gt; \u0026lt;php  formError('email'); ?\u0026gt;  \u0026lt;/p\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cb\u003eOR\u003c/b\u003e\n\u003cp\u003eYou can pass errors to view file with compact\u003c/p\u003e\n\u003cpre\u003e\nview('path to view', compact('errors'));\n\u003c/pre\u003e\n\n\u003cp class=\"mt-3\"\u003e\u003cb\u003eStopping On Validation Failure (Compatible for REST API) \u003c/b\u003e: If validation fail then stop   other execution, just return validation errors.\u003c/p\u003e\n \u003cp\u003eExample:\u003c/p\u003e\n \u003cpre\u003e\u003ccode\u003e\n          use App\\system\\request\\Request;\n                $request = new Request();\n                $request-\u003evalidate([\n                  'name' =\u003e 'required',\n                ]);\n\n \u003c/code\u003e \u003c/pre\u003e\n \u003cp\u003eError will return as like following: \u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\n             [\n                \"message\" =\u003e \"Validation failed\",\n                \"errors\" =\u003e [\n                 \"name\" =\u003e \"name Field is required\"\n                 ]\n              ]\n\u003c/code\u003e\u003c/pre\u003e\n\n\u003cb\u003eAvailable Validation:\u003c/b\u003e\n\u003col\u003e\n    \u003cli\u003erequired\u003c/li\u003e\n    \u003cli\u003emobile (start with zero and must be in 0-9)\u003c/li\u003e\n    \u003cli\u003enumber\u003c/li\u003e\n    \u003cli\u003efloatNumber\u003c/li\u003e\n    \u003cli\u003enoNumber( accept all character without number)\u003c/li\u003e\n    \u003cli\u003eletter( accept only letter :A-Za-z))\u003c/li\u003e\n    \u003cli\u003enoSpecialChar\u003c/li\u003e\n    \u003cli\u003elimit: min, max\u003c/li\u003e\n    \u003cli\u003ewordLimit: min, max\u003c/li\u003e\n    \u003cli\u003eemail\u003c/li\u003e\n\u003c/ol\u003e\n\n\n# 9. Build in Vue JS Configuration \n\u003cdiv id=\"BuildinVueJSConfiguration\"\u003e\u003c/div\u003e\n\n \u003cp\u003e  Build Vue JS application with your plugin\u003c/p\u003e\n \u003cp class=\"mt-3\"\u003e\u003cb\u003eConfiguration\u003c/b\u003e\u003c/p\u003e\n \u003cp\u003e Configuration file located in root directory as \u003ccode\u003ewebpack.config.js\u003c/code\u003e. \u003c/p\u003e\n \u003cp\u003e \u003cb\u003e Vue js files Default directory is : \u003ccode\u003eresources/js\u003c/code\u003e\u003c/b\u003e. \u003c/p\u003e\n\u003cp\u003e \u003cb\u003e Run  : \u003ccode\u003enpm run dev\u003c/code\u003e\u003c/b\u003e. (for development mode)\u003c/p\u003e\n\u003cp\u003e \u003cb\u003e Run  : \u003ccode\u003enpm run watch\u003c/code\u003e\u003c/b\u003e. (for on-change build)\u003c/p\u003e\n\u003cp\u003e \u003cb\u003e Run  : \u003ccode\u003enpm run hot\u003c/code\u003e\u003c/b\u003e. (for on-change build and reload) (default hot mode(webpack dev server) listen from port 8080. if you run this command , you must declare   \u003ccode\u003e$enqueue-\u003ehotScript('file_name.js') \u003c/code\u003e in enqueue .\u003c/p\u003e\n\u003cp\u003eConfiguration for Build\u003c/p\u003e\n\u003cpre\u003e\n \u003ccode\u003e\n const buildConfig = [\n    {\n        source: 'resources/js/app.js',\n        outputDir: 'assets/js',  // targeted output directory name\n        outputFileName: 'app'  // can be with .js extension\n    }\n];\n  \u003c/code\u003e\n  \u003c/pre\u003e\n# OR may be\n \u003cpre\u003e\n \u003ccode\u003e\n const buildConfig = [\n    {\n        source: 'resources/js/app.js',\n        outputDir: 'assets/js',  // targeted output directory name\n        outputFileName: 'app'  // can be with .js extension\n    } ,\n     {\n        source: 'resources/js/nextApp.js',\n        outputDir: 'assets/js',  // targeted output directory name\n        outputFileName: 'nextApp'  // can be with .js extension\n    }\n];\n  \u003c/code\u003e\n  \u003c/pre\u003e\n                    \n \n \n # 10. Global Functions\n \n\u003cdiv id=\"GlobalFunction\"\u003e\u003c/div\u003e\n\n  \u003col\u003e\n \u003cli\u003e\u003ccode\u003eview()\u003c/code\u003e : root of view file : \u003ccode\u003eresources/view/\u003c/code\u003e. you have to pass only file name withour extention  . Example: \u003ccode\u003e view('home/index') \u003c/code\u003e . \n  \u003cbr\u003e \u003cb\u003e Also you can pass data to view with \u003ccode\u003ecompact \u003c/code\u003e\n     \u003ccode\u003e\u003cpre\u003e\n       $title = \"......\";\n       $data = [] ;\n       return view('home/index', compact('title', 'data'))\n     \u003c/pre\u003e\u003c/code\u003e\n  \u003c/li\u003e\n\u003cli\u003e \u003ccode\u003e json($data, $code)\u003c/code\u003e : for returning as json with status code\u003c/li\u003e\n\n\u003cli\u003e \u003ccode\u003e config($key)\u003c/code\u003e : for returning configuration data. you can set/ change  configuration data from : \u003ccode\u003eadd/config/config.php\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e \u003ccode\u003e current_url()\u003c/code\u003e : for current url\u003c/code\u003e\u003c/pre\u003e\n\u003cli\u003e \u003ccode\u003e formErrors()\u003c/code\u003e : for form validation errors as array\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e \u003ccode\u003e formError($field_name)\u003c/code\u003e : for single field  validation error \u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e \u003ccode\u003e session_flush($key, $value = null)\u003c/code\u003e : for getting and setting \u003ca href=\"#SessionHandler\"\u003e flush session\u003c/a\u003e \u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e \u003ccode\u003e session($key, $value = null)\u003c/code\u003e : for getting and setting \u003ca href=\"#SessionHandler\"\u003e  session \u003c/a\u003e \u003c/code\u003e\u003c/li\u003e\n\n\u003c/ol\u003e\n  \n # 11.  Session Handler\n \n \u003cdiv id=\"SessionHandler\"\u003e\u003c/div\u003e\n\u003col\u003e\n\u003cli\u003eGet OR Set Flush Session: \u003cbr\u003e\n\u003ccode\u003eSession::flush(key)\u003c/code\u003e for getting onetime Session and \u003ccode\u003eSession::flush(key, value)\u003c/code\u003e\n                for setting onetime session.\n\u003cblockquote\u003e Flush session unset after page loading completed\u003c/blockquote\u003e\n\u003c/li\u003e\n\u003cli\u003e Set Session:\n\u003ccode\u003eSession::flush(key, value)\u003c/code\u003e\n \u003c/li\u003e\n\u003cli\u003e Get Session:\n                \u003ccode\u003eSession::get(key)\u003c/code\u003e\n\u003c/li\u003e\n\u003cli\u003e Forget Session:\n                \u003ccode\u003eSession::forget(key)\u003c/code\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\n# License\n\u003cp\u003eThe MIT License (MIT)\u003c/p\u003e\n\n\u003cp\u003eDeveloped by : \u003ca href=\"https://alemran.me\"\u003eAL EMRAN\u003c/a\u003e\u003c/p\u003e\n\n# Support for this project\nAssalamu Alikum ! You can donate for the project.\n\n[![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)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwp-pluginmaster%2Fpluginmaster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwp-pluginmaster%2Fpluginmaster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwp-pluginmaster%2Fpluginmaster/lists"}