├── .gitignore ├── README.md ├── TODO.md ├── boilerplate-generator.sh └── plugin-name ├── .editorconfig ├── .phpcs.xml.dist ├── .vscode └── settings.json ├── LICENSE.txt ├── README.txt ├── app ├── class-activator.php ├── class-deactivator.php ├── class-uninstaller.php ├── controllers │ ├── admin │ │ ├── class-admin-settings.php │ │ └── class-base-controller.php │ └── frontend │ │ └── class-base-controller.php ├── models │ ├── admin │ │ ├── class-admin-settings.php │ │ └── class-base-model.php │ ├── class-settings.php │ └── frontend │ │ └── class-base-model.php ├── templates │ └── admin │ │ ├── errors │ │ ├── admin-notice.php │ │ └── requirements-error.php │ │ └── page-settings │ │ ├── page-settings-fields.php │ │ ├── page-settings-section-headers.php │ │ └── page-settings.php └── views │ └── admin │ └── class-admin-settings.php ├── assets ├── css │ ├── admin │ │ └── plugin-name.css │ └── frontend │ │ └── plugin-name.css ├── fonts │ ├── admin │ │ └── README.md │ └── frontend │ │ └── README.md ├── images │ ├── admin │ │ └── README.md │ └── frontend │ │ └── README.md └── js │ ├── admin │ └── plugin-name.js │ └── frontend │ └── plugin-name.js ├── core ├── class-controller.php ├── class-model.php ├── class-route-type.php ├── class-router.php ├── class-view.php └── registry │ ├── class-controller.php │ ├── class-model.php │ └── trait-base-registry.php ├── docs ├── Plugin_Name-App-Activator.md ├── Plugin_Name-App-Controllers-Admin-Admin_Settings.md ├── Plugin_Name-App-Controllers-Admin-Base_Controller.md ├── Plugin_Name-App-Controllers-Frontend-Base_Controller.md ├── Plugin_Name-App-Deactivator.md ├── Plugin_Name-App-Models-Admin-Admin_Settings.md ├── Plugin_Name-App-Models-Admin-Base_Model.md ├── Plugin_Name-App-Models-Frontend-Base_Model.md ├── Plugin_Name-App-Models-Settings.md ├── Plugin_Name-App-Uninstaller.md ├── Plugin_Name-App-Views-Admin-Admin_Settings.md ├── Plugin_Name-Core-Controller.md ├── Plugin_Name-Core-Model.md ├── Plugin_Name-Core-Registry-Controller.md ├── Plugin_Name-Core-Registry-Model.md ├── Plugin_Name-Core-Route_Type.md ├── Plugin_Name-Core-Router.md ├── Plugin_Name-Core-View.md ├── Plugin_Name-Includes-Dependency_Loader.md ├── Plugin_Name-Includes-Requirements_Checker.md ├── Plugin_Name-Includes-i18n.md ├── Plugin_Name.md └── README.md ├── includes ├── class-dependency-loader.php ├── class-i18n.php ├── class-plugin-name.php ├── class-requirements-checker.php └── index.php ├── index.php ├── languages └── plugin-name.pot ├── plugin-name.php ├── requirements-config.php ├── routes.php └── uninstall.php /.gitignore: -------------------------------------------------------------------------------- 1 | # Numerous always-ignore extensions 2 | *.diff 3 | *.err 4 | *.orig 5 | *.log 6 | *.rej 7 | *.swo 8 | *.swp 9 | *.vi 10 | *~ 11 | *.sass-cache 12 | logs 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | package-lock.json 17 | 18 | # OS or Editor folders 19 | .DS_Store 20 | Thumbs.db 21 | .cache 22 | .project 23 | .settings 24 | .tmproj 25 | *.esproj 26 | nbproject 27 | *.sublime-project 28 | *.sublime-workspace 29 | 30 | # Dreamweaver added files 31 | _notes 32 | dwsync.xml 33 | 34 | # Komodo 35 | *.komodoproject 36 | .komodotools 37 | 38 | # Folders to ignore 39 | .hg 40 | .svn 41 | .CVS 42 | intermediate 43 | .idea 44 | cache 45 | 46 | # Runtime data 47 | pids 48 | *.pid 49 | *.seed 50 | *.pid.lock 51 | 52 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 53 | .grunt 54 | 55 | # Bower dependency directory (https://bower.io/) 56 | bower_components 57 | 58 | # node-waf configuration 59 | .lock-wscript 60 | 61 | # Compiled binary addons (https://nodejs.org/api/addons.html) 62 | build/Release 63 | 64 | # Dependency directories 65 | node_modules/ 66 | jspm_packages/ 67 | 68 | # Optional npm cache directory 69 | .npm 70 | 71 | # Optional eslint cache 72 | .eslintcache 73 | 74 | # Optional REPL history 75 | .node_repl_history 76 | 77 | # Output of 'npm pack' 78 | *.tgz 79 | 80 | # Yarn Integrity file 81 | .yarn-integrity 82 | 83 | # dotenv environment variables file 84 | .env 85 | 86 | # Postpone support for phpunit, until I learn how to write unit tests correctly 87 | .travis.yml 88 | phpunit.xml.dist 89 | install-wp-tests.sh 90 | bootstrap.php 91 | test-sample.php 92 | SampleTest.md 93 | 94 | # Intermediate doc generated by phpdoc 95 | interim-docs -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MVC Plugin Boilerplate for WordPress 2 | 3 | WordPress being Event driven system, it is difficult to follow MVC Design Pattern while creating a WordPress Plugin. 4 | 5 | This project aims to help plugin developers achieve MVC pattern in their coding. 6 | 7 | If you are new to the term MVC and have never worked with MVC architecture before, I would highly recommend going through this course: https://www.udemy.com/php-mvc-from-scratch/ 8 | 9 | ## Why? 10 | The original [WordPress Plugin Boilerplate](https://github.com/DevinVinson/WordPress-Plugin-Boilerplate) is great starting 11 | point for creating small plugins. So if your plugin is small, I definitely recommend using that boilerplate. However, as the plugin starts growing & we add more-n-more features to it, it somewhat becomes challenging to decide where a certain piece of code should go OR how/when to separate different functionalities. 12 | When these things are not clear in long term project to the developer, they end up creating GOD classes that try to do everything. 13 | 14 | The objective of this boilerplate is to separate concerns. Developer gets a chance to write individual `Model`, `View` & `Controller`. Also, the concern of whether to load a controller/model or not is delegated to `Router`, so that your controller & model can focus only on what they are supposed to do. 15 | 16 | Because this project is meant to be a boilerplate, it has only those features which are required to build plugin in MVC way - No ORM - No Extra Goodies - No Huge Learning Curve. 17 | 18 | ## Architecture 19 | Here is a bird eye's view at the architecture 20 | 21 | ![MVC Architecture](https://raw.githubusercontent.com/sumitpore/repo-assets/master/mvc-architecture.png) 22 | 23 | ## Installation 24 | 25 | The Boilerplate can be installed directly into your plugins folder "as-is". You will want to rename it and the classes inside of it to fit your needs. For example, if your plugin is named 'example-me' then: 26 | 27 | * rename files from `plugin-name` to `example-me` 28 | * change `plugin_name` to `example_me` 29 | * change `plugin-name` to `example-me` 30 | * change `Plugin_Name` to `Example_Me` 31 | * change `PLUGIN_NAME_` to `EXAMPLE_ME_` 32 | 33 | It's safe to activate the plugin at this point. Because the Boilerplate has no real functionality there will be no menu items, meta boxes, or custom post types added until you write the code. 34 | 35 | If you don't want to do search & replace manually, you can download the generator script & execute it. 36 | ```bash 37 | wget -O boilerplate-generator.sh https://raw.githubusercontent.com/sumitpore/mvc-plugin-boilerplate-for-wordpress/master/boilerplate-generator.sh && bash boilerplate-generator.sh 38 | ``` 39 | 40 | ## Getting Started 41 | 42 | We'll try to create a shortcode that prints 10 posts that will help you understand how this boilerplate works. The guide assumes that you have gone through Installation steps and created `Example Me` Plugin. 43 | 44 | If you prefer watching videos over reading, then here is a [playlist to get started.](https://www.youtube.com/watch?v=vxR6X8nFbXs&list=PLynzWOMAmxrOtGo6ptsdOaxYoANjOSV8h) 45 | [![YouTube Playlist on Writing a WordPress Plugin in MVC Way](https://raw.githubusercontent.com/sumitpore/repo-assets/master/mvc-playlist-preview-image.png)](https://www.youtube.com/watch?v=vxR6X8nFbXs&list=PLynzWOMAmxrOtGo6ptsdOaxYoANjOSV8h) 46 | 47 | ### 1. Writing your first Router 📡 48 | Routes can be defined inside `routes.php` file. Here is how a route can be defined for our example 49 | ```php 50 | 51 | // Full Class Name with Namespace 52 | $router 53 | ->register_route_of_type( ROUTE_TYPE::FRONTEND ) 54 | ->with_controller( 'Example_Me\App\Controllers\Frontend\Print_Posts_Shortcode@register_shortcode' ) 55 | ->with_model( 'Example_Me\App\Models\Frontend\Print_Posts_Shortcode' ); 56 | 57 | // ------------- OR -------------------- 58 | 59 | // Class Names Without specifying Namespaces explicitly. Boilerplate will automatically figure out the class based on the Route Type. 60 | $router 61 | ->register_route_of_type( ROUTE_TYPE::FRONTEND ) 62 | ->with_controller( 'Print_Posts_Shortcode@register_shortcode' ) 63 | ->with_model( 'Print_Posts_Shortcode' ); 64 | 65 | ``` 66 | > It is highly recommended to go through [`routes.php`](https://github.com/sumitpore/wordpress-mvc-plugin-boilerplate/blob/master/plugin-name/routes.php). You will get to know list of all available route types & examples in that file. 67 | 68 | 69 | ### 2. Writing your first Controller 🎮 70 | The boilerplate converts Class Name to a file name & loads that file automatically. 71 | 72 | We have passed `Example_Me\App\Controllers\Frontend\Print_Posts_Shortcode` as a controller in our `routes.php`. Boilerplate resolves this class name to file `example-me/app/controllers/frontend/class-print-posts-shortcode.php` 73 | 74 | Any controller that is a part of a Routing (Read: added in `routes.php`) __MUST__ extend `Base_Controller` class. 75 | * If it is Dashboard (admin) related controller, then it should extend 76 | `Plugin_Name\App\Controllers\Admin\Base_Controller`. 77 | * If it is Frontend related controller, then it should extend 78 | `Plugin_Name\App\Controllers\Frontend\Base_Controller`. 79 | 80 | Every controller that extends `Base_Controller` __MUST__ have `register_hook_callbacks` 81 | method. This method is defined as `abstract` in `Base_Controller`. 82 | 83 | `register_hook_callbacks` method register callbacks for actions and filters. Most of your add_action/add_filter will go into this method. 84 | 85 | `register_hook_callbacks` method is not called automatically. You 86 | as a developer have to call this method where you see fit. For Example, 87 | You may want to call this method in the route itself with `@` , if you feel hooks/filters 88 | callbacks should be registered when the new instance of the class 89 | is created. This way, we don't have to pollute constructor with add_action & add_filter. 90 | 91 | The purpose of this method is to set the convention that first place to 92 | find add_action/add_filter is register_hook_callbacks method. 93 | 94 | > NOTE: If you create a constructor inside a controller extending `Base_Controller`, then make sure you call `init` method inside that constructor. That means your custom constructors need to have this line `$this->init( $model, $view );` to set `Model` & `View` for your controller object. 95 | 96 |
97 | SHOW CONTROLLER EXAMPLE CODE 98 | Here is how this file would look for our example 99 | 100 | ```php 101 | get_view()->render_template( 139 | 'frontend/print-posts-shortcode.php', 140 | [ 141 | 'fetched_posts' => $this->get_model()->get_posts_for_shortcode( 'example_me_print_posts', $atts ) 142 | ] 143 | ); 144 | 145 | } 146 | 147 | } 148 | } 149 | 150 | ``` 151 | 152 |
153 | 154 | ### 3. Writing your first Model ![DNA](https://raw.githubusercontent.com/sumitpore/repo-assets/master/DNA.png) 155 | 156 | All models should extend `Base_Model` class. 157 | 158 | * If it is Dashboard (admin) related model, then it should extend 159 | `Plugin_Name\App\Models\Admin\Base_Model`. 160 | * If it is Frontend related model, then it should extend 161 | `Plugin_Name\App\Models\Frontend\Base_Model`. 162 | 163 | You may decide whether to create `register_hook_callbacks` method inside your model or not. It is not an abstract method in `Base_Model` If you want to write any add_action/add_filter, then that should ideally go inside this method. (I would suggest to place all add_action & add_filter calls inside `register_hook_callbacks` of the Controller class. It will show you all add_actions & add_filter in one glance but decision is yours! You should do what fits right in your situation.) 164 | 165 | Again `register_hook_callbacks` is not called automatically. If you feel hooks/filters 166 | callbacks should be registered when the new instance of the class 167 | is created, then call this method inside the constructor of your model. 168 | 169 | `@` is NOT supported in `with_model` method of Router class, however, `@` is supported in `with_just_model` method of the Router class. If you are confused, what these statements mean? Go through [`routes.php`](https://github.com/sumitpore/wordpress-mvc-plugin-boilerplate/blob/master/plugin-name/routes.php). It contains variety of examples. 170 | 171 |
172 | SHOW MODEL EXAMPLE CODE 173 | 174 | Create a file `example-me/app/models/frontend/class-print-posts-shortcode.php` because we have to create `Example_Me\App\Models\Frontend\Print_Posts_Shortcode` class. 175 | 176 | Here is how this file would look for our example 177 | 178 | ```php 179 | '10', 204 | ), $atts, $shortcode 205 | ); 206 | 207 | $args = array( 208 | 'post_type' => 'post', 209 | 'posts_per_page' => is_int( $atts['number_of_posts'] ) ? $atts['number_of_posts'] : 10, 210 | ); 211 | 212 | return new \WP_Query( $args ); 213 | } 214 | } 215 | } 216 | 217 | ``` 218 |
219 | 220 | ### 4. Writing a View 👸 221 | In our example, we did not have to create a separate View Class (Hint: we did not call `with_view` method in the route.). In the controller itself we are calling a `render_template` method of base `View` class. 222 | 223 | However, if you are going to deal with partial views, it is recommended to create a separate class that extends `View` class & that class will call templates for you. 224 | 225 | It gives us another advantage — the controller does not get tied to template file directly & thus allowing us to reduce the coupling. 226 | 227 |
228 | SHOW VIEW EXAMPLE CODE 229 | 230 | If we had created a separate class for the view, then it would have looked like this 231 | 232 | ```php 233 | register_route_of_type( ROUTE_TYPE::FRONTEND ) 239 | ->with_controller( 'Print_Posts_Shortcode@register_shortcode' ) 240 | ->with_model( 'Print_Posts_Shortcode' ) 241 | ->with_view( 'Print_Posts_Shortcode' ); 242 | 243 | 244 | 245 | // file: `example-me/app/views/frontend/class-print-posts-shortcode.php` 246 | 247 | namespace Example_Me\App\Views\Frontend; 248 | 249 | use \Example_Me\Core\View; 250 | use \Example_Me as Example_Me; 251 | 252 | if ( ! class_exists( __NAMESPACE__ . '\\' . 'Print_Posts_Shortcode' ) ) { 253 | /** 254 | * Class Responsibile for rendering the view of `example_me_print_posts` shortcode 255 | * 256 | * @since 1.0.0 257 | * @package Example_Me 258 | * @subpackage Example_Me/Views/Frontend 259 | */ 260 | class Print_Posts_Shortcode extends View { 261 | /** 262 | * Method that prints html for the `example_me_print_posts` shortcode 263 | * 264 | * @param array $args Arguments passed by controller's get_posts_for_shortcode method. 265 | * @return void 266 | */ 267 | public function shortcode_html( $args ){ 268 | return $this->render_template( 269 | 'frontend/print-posts-shortcode.php', 270 | $args 271 | ); 272 | } 273 | 274 | } 275 | } 276 | 277 | ``` 278 |
279 | 280 | ### 5. Writing your first template 👶 281 | Templates are the actual files which generate html for the module you are writing. 282 | 283 | A template file can be called by invoking `render_template` method on any `View` class's (parent as well as child) object. 284 | 285 | Template files are created inside `app/templates/` folder. 286 | 287 |
288 | SHOW TEMPLATE EXAMPLE CODE 289 | 290 | So the complete location of template file in our example is `example-me/app/templates/frontend/print-posts-shortcode.php` 291 | 292 | This is how it would look 293 | 294 | ```php 295 | 296 | // file: `example-me/app/templates/frontend/print-posts-shortcode.php` 297 | 298 | have_posts() ) : ?> 299 | 300 | 301 | have_posts() ) : ?> 303 | the_post(); ?> 304 |

305 | 306 | 307 | 308 | 309 | 310 | 311 |

312 | 313 | ``` 314 |
315 | 316 | ### 6. Interacting with Settings ⚙️ 317 | While developing the plugin, we sometimes need a way to manually interact with the settings information (Side Note - Settings are saved automatically by WordPress if Settings API is used to create settings page) 318 | 319 | Replace `Plugin_Name` with your plugin's namespace in below methods. 320 | 321 | `Plugin_Name\App\Models\Settings` provide some helper methods to interact with settings data. 322 | 323 | | Method | Description | 324 | | --- | --- | 325 | | `Plugin_Name\App\Models\Settings::get_plugin_settings_option_key()` | Returns the option key used in wp_options table to save the settings | 326 | | `Plugin_Name\App\Models\Settings::get_settings()` | Returns all saved settings | 327 | | `Plugin_Name\App\Models\Settings::get_setting( $setting_name )` | Returns a value of single setting | 328 | | `Plugin_Name\App\Models\Settings::delete_settings()` | Deletes All Settings | 329 | | `Plugin_Name\App\Models\Settings::delete_setting( $setting_name )` | Deletes a particular setting | 330 | | `Plugin_Name\App\Models\Settings::update_settings()` | Updates All Settings | 331 | | `Plugin_Name\App\Models\Settings::update_setting( $setting_name )` | Updates an individual setting | 332 | 333 | ### 7. Activation, Deactivation & Uninstall Procedures? ✨ 334 | Activation, Deactivation & Uninstall procedures of your plugin go into `Plugin_Name\App\Activator::activate()`, `Plugin_Name\App\Deactivator::deactivate()` & `Plugin_Name\App\Uninstaller::uninstall()` methods. 335 | 336 | ### 8. Folder Structure 📁 337 | | Folder Name | Description | 338 | | --- | --- | 339 | | `plugin-name/app` | Functionality shared between the models, controllers and views resides here. Almost everything you write will go into this folder. | 340 | | `plugin-name/app/models` | The Model component corresponds to all the data-related logic that the user works with. This can represent either the data that is being transferred between the View and Controller components or any other business logic-related data. ( It represents data objects, such as settings, values stored on the database, etc...) | 341 | | `plugin-name/app/models/admin` | Represents the admin side of the models. 342 | | `plugin-name/app/models/frontend` | Represents the frontend side of the models. 343 | | `plugin-name/app/contollers` | Acts as an interface between Model and View components to process all the business logic and incoming requests, manipulate data using the Model component and interact with the Views to render the final output | 344 | | `plugin-name/app/contollers/admin` | Represents the admin side of the controllers. 345 | | `plugin-name/app/contollers/frontend` | Represents the frontend side of the controllers. 346 | | `plugin-name/app/views` | The View component is used for all the UI logic of. It calls required templates. 347 | | `plugin-name/app/views/admin` | Calls admin side templates 348 | | `plugin-name/app/views/frontend` | Calls frontend side templates 349 | | `plugin-name/app/templates` | Represents html code for the feature 350 | | `plugin-name/app/templates/admin` | Represents html code for admin side features 351 | | `plugin-name/app/templates/frontend` | Represents html code for frontend side features 352 | | `plugin-name/assets` | Stores assets required for plugin 353 | | `plugin-name/core` | Main MVC Framework 354 | | `plugin-name/docs` | Represents Docs of the plugin 355 | | `plugin-name/includes` | Contains main class file of the plugin & i18n class 356 | | `plugin-name/languages` | All .po, .pot & .mo goes here 357 | 358 | ### INSPIRED? 359 | 360 | ![Build a Fort](https://raw.githubusercontent.com/sumitpore/repo-assets/master/build-a-fort.gif) 361 | 362 | If you like this approach of development, star this repository! 363 | 364 | ## Contents 365 | 366 | MVC Plugin Boilerplate for WordPress includes the following files: 367 | 368 | * `.gitignore`. Used to exclude certain files from the repository. 369 | * `README.md`. The file that you’re currently reading. 370 | * `TODO.md` . Contains list of tasks to be completed in future. 371 | * `plugin-name` directory that contains the source code - a fully executable WordPress plugin. 372 | * `boilerplate-generator.sh` Boilerplate Generator 373 | 374 | ## Features 375 | 376 | * The Boilerplate is based on the [Plugin API](http://codex.wordpress.org/Plugin_API), and [Documentation Standards](http://make.wordpress.org/core/handbook/inline-documentation-standards/php-documentation-standards/). 377 | * All classes, functions, and variables are documented so that you know what you need to be changed. 378 | * The project includes a `.pot` file as a starting point for internationalization. 379 | * Separation of concern between Model, View & Controller. 380 | * With the appropriate usage of router, plugin's footprint can be kept low. 381 | 382 | ## Recommended Tools 383 | 384 | ### i18n Tools 385 | 386 | MVC Plugin Boilerplate for WordPress uses a variable to store the text domain used when internationalizing strings throughout the Boilerplate. To take advantage of this method, there are tools that are recommended for providing correct, translatable files: 387 | 388 | * [Poedit](http://www.poedit.net/) 389 | * [makepot](http://i18n.svn.wordpress.org/tools/trunk/) 390 | * [i18n](https://github.com/grappler/i18n) 391 | 392 | Any of the above tools should provide you with the proper tooling to internationalize the plugin. 393 | 394 | ## License 395 | 396 | MVC Plugin Boilerplate for WordPress is licensed under the GPL v2 or later. 397 | 398 | > This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. 399 | 400 | > This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 401 | 402 | > You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 403 | 404 | A copy of the license is included in the root of the plugin’s directory. The file is named `LICENSE`. 405 | 406 | ## Credits 407 | 408 | The `MVC Plugin Boilerplate for WordPress` is built upon the `WordPress Plugin Boilerplate` project forked by [Roger Rodrigo](https://ca.linkedin.com/in/rogerrodrigo). The original `WordPress Plugin Boilerplate` project was started in 2011 by [Tom McFarlin](http://twitter.com/tommcfarlin/) and has since included a number of great contributions. In March of 2015 the project was handed over by Tom to Devin Vinson. 409 | 410 | This `MVC Plugin Boilerplate for WordPress` was developed and is being maintained by [Sumit Pore](https://www.linkedin.com/in/sumitpore/). 411 | 412 | To show support for the project, Star the repository or [follow me on Twitter](https://twitter.com/sumitpore), and say Hi! 413 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | - [ ] Implement ArrayAccess and Iterator interfaces in Router 2 | - [ ] Allow to load multiple models 3 | - [ ] Support Composer 4 | - [x] View methods should be accessible without class instantiation 5 | - [ ] Verify Dependency unmet condition 6 | - [x] Make Dependency loader a class so that activator, deactivator & uninstaller can load classes available inside `app` directory 7 | - [ ] Verify get all controllers and get models return all running controllers and models 8 | - [x] Change paths in dependency loader from self::plugin_path to Plugin_Name::get_plugin_path() 9 | - [x] Tool to replace plugin name with developers plugin name 10 | - [x] Add information about how to access saved settings 11 | - [x] Get settings from settings model 12 | - [x] @ support in the controller name & model name 13 | - [x] Proper place for activator, deactivator & uninstaller 14 | - [x] Separate branch for airbnb js style support 15 | - [ ] Writing Unit Tests 16 | - [ ] replacements.json - Json file that holds what is replaced with what 17 | - [ ] Tool to generate Model, View & Controller -------------------------------------------------------------------------------- /boilerplate-generator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # MVC Plugin Boilerplate Generator - Generates the base plugin out of `MVC Plugin Boilerplate for WordPress` 4 | # Copyright (C) <2019> 5 | 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # any later version. 10 | 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | take_consent_to_execute_script(){ 20 | echo ' MVC Plugin Boilerplate Generator - Copyright (C) <2019> '; 21 | echo ' This program is licensed under GPLv3 & comes with ABSOLUTELY NO WARRANTY;' 22 | echo ' Detalied copy of GNU General Public License can be found here: https://www.gnu.org/licenses/gpl-3.0.html' 23 | echo '' 24 | read -p 'Do you accept the license terms? [y/n]:' AGREE_TO_PROCEED 25 | if [ -z "$AGREE_TO_PROCEED" ] || [ "$AGREE_TO_PROCEED" != "y" ] ; then 26 | echo 'Execution Aborted!' 27 | exit 1 28 | fi 29 | echo '' 30 | } 31 | 32 | set_defaults_for_script(){ 33 | GIT_REPO_DIR='mvc-plugin-boilerplate-for-wordpress' 34 | GENERATED_PLUGIN_DIR='generated-plugin' 35 | BOILERPLATE_PLUGIN_NAME='MVC WordPress Plugin Boilerplate' 36 | PLUGIN_NAME="Plugin Name" 37 | } 38 | 39 | create_dir(){ 40 | 41 | # Generate Final Plugin Directory 42 | if [ -d "$1" ]; then 43 | echo -e "\033[0;31m Directory $1 exists already in the current folder. Script can not continue if this directory is present! \033[39m" 44 | exit 1 45 | fi 46 | 47 | mkdir -p $1 48 | 49 | if [ $? -ne 0 ]; then 50 | echo -e "\033[0;31m Could not create directory $1! \033[39m" 51 | exit 1 52 | fi 53 | 54 | } 55 | 56 | download_original_plugin(){ 57 | echo 'Downloading vanilla boilerplate from Git' 58 | git clone --single-branch --branch dev https://github.com/sumitpore/mvc-plugin-boilerplate-for-wordpress.git $GIT_REPO_DIR > /dev/null 2>&1 59 | echo 'Boilerplate Download Complete' 60 | } 61 | 62 | bring_plugin_outside(){ 63 | mv $GIT_REPO_DIR/plugin-name $GENERATED_PLUGIN_DIR/ 64 | } 65 | 66 | delete_git_repo_dir(){ 67 | rm -rf $GIT_REPO_DIR 68 | } 69 | 70 | switch_to_generated_plugin_dir(){ 71 | cd $GENERATED_PLUGIN_DIR 72 | } 73 | 74 | set_plugin_slug(){ 75 | echo -n -e "What is your plugin slug? [Plugin slug will be used to replace occurrances of \033[0;33m 'plugin-name' \033[39m in file names & text in files ]: " 76 | read PLUGIN_SLUG 77 | if [ -z "$PLUGIN_SLUG" ]; then 78 | set_plugin_slug 79 | fi 80 | } 81 | 82 | replace_text_in_files(){ 83 | 84 | if [ "$1" == "plugin-name" ]; then 85 | REPLACEMENT_TEXT=$PLUGIN_SLUG 86 | else 87 | echo -n -e "Replacement Text for \033[0;33m $1 \033[39m : " 88 | read REPLACEMENT_TEXT 89 | fi 90 | 91 | if [[ ! -z "$REPLACEMENT_TEXT" ]]; then 92 | find . -type f -exec sed -i -e 's/'"$1"'/'"$REPLACEMENT_TEXT"'/g' {} + 93 | 94 | # If we are replacing `Plugin Name`, then we have to revert the replacement 95 | # done in Plugin File header. Otherwise, WP won't be able to recognize the 96 | # plugin 97 | if [ "$1" == "Plugin Name" ]; then 98 | sed -i -e 's/'"$REPLACEMENT_TEXT:"'/'"$1:"'/g' plugin-name/plugin-name.php 99 | 100 | # Set Plugin Name 101 | sed -i -e 's/'"$BOILERPLATE_PLUGIN_NAME"'/'"$REPLACEMENT_TEXT"'/g' plugin-name/plugin-name.php 102 | 103 | # Set Plugin Name variable 104 | PLUGIN_NAME=$REPLACEMENT_TEXT 105 | fi 106 | 107 | # Save replacement being done for Plugin_Name class in a variable, it will be used while renaming files too 108 | if [ "$1" == "Plugin_Name" ]; then 109 | REPLACEMENT_FOR_PLUGIN_NAME_CLASS=$REPLACEMENT_TEXT 110 | fi 111 | fi 112 | } 113 | 114 | rename_plugin_folder(){ 115 | mv 'plugin-name' $PLUGIN_SLUG 116 | } 117 | 118 | rename_files(){ 119 | if [ ! -z "$2" ]; then 120 | # Rename Files inside a folder 121 | find . -type f -name "*$1*" | while read FILE ; do 122 | newfile="$(echo ${FILE} |sed -e 's/'"$1"'/'"$2"'/')" ; 123 | mv "${FILE}" "${newfile}" ; 124 | done 125 | fi 126 | } 127 | 128 | take_consent_to_execute_script 129 | set_defaults_for_script 130 | create_dir $GENERATED_PLUGIN_DIR 131 | create_dir $GIT_REPO_DIR 132 | download_original_plugin 133 | bring_plugin_outside 134 | delete_git_repo_dir 135 | switch_to_generated_plugin_dir 136 | 137 | echo '' 138 | 139 | set_plugin_slug 140 | replace_text_in_files 'plugin-name' 141 | replace_text_in_files 'Plugin Name' 142 | replace_text_in_files 'plugin_name' 143 | replace_text_in_files 'Plugin_Name' 144 | replace_text_in_files 'PLUGIN_NAME_' 145 | rename_plugin_folder 146 | rename_files 'plugin-name' $PLUGIN_SLUG 147 | rename_files 'Plugin_Name' $REPLACEMENT_FOR_PLUGIN_NAME_CLASS 148 | 149 | echo '' 150 | echo -e "\033[0;32mPlugin $PLUGIN_NAME is generated successfully inside $GENERATED_PLUGIN_DIR! \033[39m" 151 | echo ''; 152 | echo -e "\033[0;32mHappy Coding! \033[39m" -------------------------------------------------------------------------------- /plugin-name/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps keep your project formatting consistent. 2 | # See https://EditorConfig.org 3 | # 4 | # This is a modified version of the WordPress coding standards. 5 | # 6 | # Author: Sal Ferrarello (@salcode) 7 | # https://salferrarello.com/wordpress-editorconfig/ 8 | # 9 | # You can download this file directly 10 | # to your project from the command-line with 11 | # curl -O https://gist.githubusercontent.com/salcode/285303f7983ad729b74d13d752214f4c/raw/.editorconfig 12 | 13 | root = true 14 | 15 | [*] 16 | charset = utf-8 17 | end_of_line = lf 18 | insert_final_newline = true 19 | trim_trailing_whitespace = true 20 | indent_style = tab 21 | indent_size = 4 22 | 23 | [*.{js,json}] 24 | indent_style = space 25 | indent_size = 2 26 | 27 | [*.yml] 28 | indent_style = space 29 | indent_size = 2 30 | 31 | [*.md] 32 | trim_trailing_whitespace = false 33 | 34 | [{*.txt,wp-config-sample.php}] 35 | end_of_line = crlf -------------------------------------------------------------------------------- /plugin-name/.phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | Generally-applicable sniffs for WordPress plugins. 4 | 5 | 6 | . 7 | index.php 8 | /vendor/ 9 | /vendors/ 10 | /node_modules/ 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | *\.php$ 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /plugin-name/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "search.usePCRE2": true, 3 | "breadcrumbs.enabled": true, 4 | "phpcs.enable": true, 5 | "phpcs.autoConfigSearch": true, 6 | "phpcs.showSources": true, 7 | "phpcs.ignorePatterns": [ 8 | "*/vendor/*", 9 | "*/vendors/*", 10 | ], 11 | "phpcbf.enable": true, 12 | "phpcbf.onsave": false, 13 | "php.suggest.basic": true, 14 | "php.validate.run": "onSave", 15 | "editor.minimap.enabled": false 16 | } 17 | -------------------------------------------------------------------------------- /plugin-name/LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Frontend 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Frontend License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Frontend License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Frontend Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Frontend License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Frontend License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Frontend License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Frontend License for more details. 305 | 306 | You should have received a copy of the GNU General Frontend License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Frontend License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Frontend License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Frontend License instead of this License. 340 | -------------------------------------------------------------------------------- /plugin-name/README.txt: -------------------------------------------------------------------------------- 1 | === Plugin Name === 2 | Contributors: (this should be a list of wordpress.org userid's) 3 | Donate link: http://example.com/ 4 | Tags: comments, spam 5 | Requires at least: 3.0.1 6 | Tested up to: 3.4 7 | Stable tag: 4.3 8 | License: GPLv2 or later 9 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 | 11 | Here is a short description of the plugin. This should be no more than 150 characters. No markup here. 12 | 13 | == Description == 14 | 15 | This is the long description. No limit, and you can use Markdown (as well as in the following sections). 16 | 17 | For backwards compatibility, if this section is missing, the full length of the short description will be used, and 18 | Markdown parsed. 19 | 20 | A few notes about the sections above: 21 | 22 | * "Contributors" is a comma separated list of wp.org/wp-plugins.org usernames 23 | * "Tags" is a comma separated list of tags that apply to the plugin 24 | * "Requires at least" is the lowest version that the plugin will work on 25 | * "Tested up to" is the highest version that you've *successfully used to test the plugin*. Note that it might work on 26 | higher versions... this is just the highest one you've verified. 27 | * Stable tag should indicate the Subversion "tag" of the latest stable version, or "trunk," if you use `/trunk/` for 28 | stable. 29 | 30 | Note that the `readme.txt` of the stable tag is the one that is considered the defining one for the plugin, so 31 | if the `/trunk/readme.txt` file says that the stable tag is `4.3`, then it is `/tags/4.3/readme.txt` that'll be used 32 | for displaying information about the plugin. In this situation, the only thing considered from the trunk `readme.txt` 33 | is the stable tag pointer. Thus, if you develop in trunk, you can update the trunk `readme.txt` to reflect changes in 34 | your in-development version, without having that information incorrectly disclosed about the current stable version 35 | that lacks those changes -- as long as the trunk's `readme.txt` points to the correct stable tag. 36 | 37 | If no stable tag is provided, it is assumed that trunk is stable, but you should specify "trunk" if that's where 38 | you put the stable version, in order to eliminate any doubt. 39 | 40 | == Installation == 41 | 42 | This section describes how to install the plugin and get it working. 43 | 44 | e.g. 45 | 46 | 1. Upload `plugin-name.php` to the `/wp-content/plugins/` directory 47 | 1. Activate the plugin through the 'Plugins' menu in WordPress 48 | 1. Place `` in your templates 49 | 50 | == Frequently Asked Questions == 51 | 52 | = A question that someone might have = 53 | 54 | An answer to that question. 55 | 56 | = What about foo bar? = 57 | 58 | Answer to foo bar dilemma. 59 | 60 | == Screenshots == 61 | 62 | 1. This screen shot description corresponds to screenshot-1.(png|jpg|jpeg|gif). Note that the screenshot is taken from 63 | the /assets directory or the directory that contains the stable readme.txt (tags or trunk). Screenshots in the /assets 64 | directory take precedence. For example, `/assets/screenshot-1.png` would win over `/tags/4.3/screenshot-1.png` 65 | (or jpg, jpeg, gif). 66 | 2. This is the second screen shot 67 | 68 | == Changelog == 69 | 70 | = 1.0 = 71 | * A change since the previous version. 72 | * Another change. 73 | 74 | = 0.5 = 75 | * List versions from most recent at top to oldest at bottom. 76 | 77 | == Upgrade Notice == 78 | 79 | = 1.0 = 80 | Upgrade notices describe the reason a user should upgrade. No more than 300 characters. 81 | 82 | = 0.5 = 83 | This version fixes a security related bug. Upgrade immediately. 84 | 85 | == Arbitrary section == 86 | 87 | You may provide arbitrary sections, in the same format as the ones above. This may be of use for extremely complicated 88 | plugins where more information needs to be conveyed that doesn't fit into the categories of "description" or 89 | "installation." Arbitrary sections will be shown below the built-in sections outlined above. 90 | 91 | == A brief Markdown Example == 92 | 93 | Ordered list: 94 | 95 | 1. Some feature 96 | 1. Another feature 97 | 1. Something else about the plugin 98 | 99 | Unordered list: 100 | 101 | * something 102 | * something else 103 | * third thing 104 | 105 | Here's a link to [WordPress](http://wordpress.org/ "Your favorite software") and one to [Markdown's Syntax Documentation][markdown syntax]. 106 | Titles are optional, naturally. 107 | 108 | [markdown syntax]: http://daringfireball.net/projects/markdown/syntax 109 | "Markdown is what the parser uses to process much of the readme file" 110 | 111 | Markdown uses email style notation for blockquotes and I've been told: 112 | > Asterisks for *emphasis*. Double it up for **strong**. 113 | 114 | `` -------------------------------------------------------------------------------- /plugin-name/app/class-activator.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | class Activator { 15 | 16 | /** 17 | * Short Description. (use period) 18 | * 19 | * Long Description. 20 | * 21 | * @since 1.0.0 22 | */ 23 | public function activate() { 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /plugin-name/app/class-deactivator.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | class Deactivator { 15 | 16 | /** 17 | * Short Description. (use period) 18 | * 19 | * Long Description. 20 | * 21 | * @since 1.0.0 22 | */ 23 | public function deactivate() { 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /plugin-name/app/class-uninstaller.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | class Uninstaller { 15 | 16 | /** 17 | * Short Description. (use period) 18 | * 19 | * Long Description. 20 | * 21 | * @since 1.0.0 22 | */ 23 | public function uninstall() { 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /plugin-name/app/controllers/admin/class-admin-settings.php: -------------------------------------------------------------------------------- 1 | get_model(), 'register_settings' ) ); 58 | 59 | // Settings Link on Plugin's Page. 60 | add_filter( 61 | 'plugin_action_links_' . Plugin_Name::PLUGIN_ID . '/' . Plugin_Name::PLUGIN_ID . '.php', 62 | array( $this, 'add_plugin_action_links' ) 63 | ); 64 | } 65 | 66 | /** 67 | * Create menu for Plugin inside Settings menu 68 | * 69 | * @since 1.0.0 70 | */ 71 | public function plugin_menu() { 72 | // @codingStandardsIgnoreStart. 73 | static::$hook_suffix = add_options_page( 74 | __( Plugin_Name::PLUGIN_NAME, Plugin_Name::PLUGIN_ID ), // Page Title. 75 | __( Plugin_Name::PLUGIN_NAME, Plugin_Name::PLUGIN_ID ), // Menu Title. 76 | static::REQUIRED_CAPABILITY, // Capability. 77 | static::SETTINGS_PAGE_SLUG, // Menu URL. 78 | array( $this, 'markup_settings_page' ) // Callback. 79 | ); 80 | // @codingStandardsIgnoreEnd. 81 | } 82 | 83 | /** 84 | * Register the JavaScript for the admin area. 85 | * 86 | * @since 1.0.0 87 | */ 88 | public function enqueue_scripts() { 89 | 90 | /** 91 | * This function is provided for demonstration purposes only. 92 | */ 93 | 94 | wp_enqueue_script( 95 | Plugin_Name::PLUGIN_ID . '_admin-js', 96 | Plugin_Name::get_plugin_url() . 'assets/js/admin/plugin-name.js', 97 | array( 'jquery' ), 98 | Plugin_Name::PLUGIN_VERSION, 99 | true 100 | ); 101 | } 102 | 103 | /** 104 | * Register the JavaScript for the admin area. 105 | * 106 | * @since 1.0.0 107 | */ 108 | public function enqueue_styles() { 109 | 110 | /** 111 | * This function is provided for demonstration purposes only. 112 | */ 113 | 114 | wp_enqueue_style( 115 | Plugin_Name::PLUGIN_ID . '_admin-css', 116 | Plugin_Name::get_plugin_url() . 'assets/css/admin/plugin-name.css', 117 | array(), 118 | Plugin_Name::PLUGIN_VERSION, 119 | 'all' 120 | ); 121 | } 122 | 123 | /** 124 | * Creates the markup for the Settings page 125 | * 126 | * @since 1.0.0 127 | */ 128 | public function markup_settings_page() { 129 | if ( current_user_can( static::REQUIRED_CAPABILITY ) ) { 130 | $this->view->admin_settings_page( 131 | array( 132 | 'page_title' => Plugin_Name::PLUGIN_NAME, 133 | 'settings_name' => $this->get_model()->get_plugin_settings_option_key(), 134 | ) 135 | ); 136 | } else { 137 | wp_die( __( 'Access denied.' ) ); // WPCS: XSS OK. 138 | } 139 | } 140 | 141 | /** 142 | * Registers settings sections and fields 143 | * 144 | * @since 1.0.0 145 | */ 146 | public function register_fields() { 147 | 148 | // Add Settings Page Section. 149 | add_settings_section( 150 | 'plugin_name_section', // Section ID. 151 | __( 'Settings', Plugin_Name::PLUGIN_ID ), // Section Title. 152 | array( $this, 'markup_section_headers' ), // Section Callback. 153 | static::SETTINGS_PAGE_SLUG // Page URL. 154 | ); 155 | 156 | // Add Settings Page Field. 157 | add_settings_field( 158 | 'plugin_name_field', // Field ID. 159 | __( 'Plugin Name Field:', Plugin_Name::PLUGIN_ID ), // Field Title. 160 | array( $this, 'markup_fields' ), // Field Callback. 161 | static::SETTINGS_PAGE_SLUG, // Page. 162 | 'plugin_name_section', // Section ID. 163 | array( // Field args. 164 | 'id' => 'plugin_name_field', 165 | 'label_for' => 'plugin_name_field', 166 | ) 167 | ); 168 | } 169 | 170 | /** 171 | * Adds the section introduction text to the Settings page 172 | * 173 | * @param array $section Array containing information Section Id, Section 174 | * Title & Section Callback. 175 | * 176 | * @since 1.0.0 177 | */ 178 | public function markup_section_headers( $section ) { 179 | $this->view->section_headers( 180 | array( 181 | 'section' => $section, 182 | 'text_example' => __( 'This is a text example for section header', Plugin_Name::PLUGIN_ID ), 183 | ) 184 | ); 185 | } 186 | 187 | /** 188 | * Delivers the markup for settings fields 189 | * 190 | * @param array $field_args Field arguments passed in `add_settings_field` 191 | * function. 192 | * 193 | * @since 1.0.0 194 | */ 195 | public function markup_fields( $field_args ) { 196 | $field_id = $field_args['id']; 197 | $settings_value = $this->get_model()->get_setting( $field_id ); 198 | $this->view->markup_fields( 199 | array( 200 | 'field_id' => esc_attr( $field_id ), 201 | 'settings_name' => $this->get_model()->get_plugin_settings_option_key(), 202 | 'settings_value' => ! empty( $settings_value ) ? esc_attr( $settings_value ) : '', 203 | ) 204 | ); 205 | } 206 | 207 | /** 208 | * Adds links to the plugin's action link section on the Plugins page 209 | * 210 | * @param array $links The links currently mapped to the plugin. 211 | * @return array 212 | * 213 | * @since 1.0.0 214 | */ 215 | public function add_plugin_action_links( $links ) { 216 | $settings_link = '' . __( 'Settings', Plugin_Name::PLUGIN_ID ) . ''; 217 | array_unshift( $links, $settings_link ); 218 | 219 | return $links; 220 | } 221 | 222 | } 223 | 224 | } 225 | -------------------------------------------------------------------------------- /plugin-name/app/controllers/admin/class-base-controller.php: -------------------------------------------------------------------------------- 1 | register_hook_callbacks(); 24 | } 25 | 26 | /** 27 | * Register callbacks for actions and filters 28 | * 29 | * @since 1.0.0 30 | */ 31 | protected function register_hook_callbacks() { 32 | /** 33 | * If you think all model related add_actions & filters should be in 34 | * the model class only, then this this the place where you can place 35 | * them. 36 | * 37 | * You can remove this method if you are not going to use it. 38 | */ 39 | } 40 | 41 | /** 42 | * Register settings 43 | * 44 | * @since 1.0.0 45 | */ 46 | public function register_settings() { 47 | 48 | // The settings container. 49 | register_setting( 50 | Settings_Model::SETTINGS_NAME, // Option group Name. 51 | Settings_Model::SETTINGS_NAME, // Option Name. 52 | array( $this, 'sanitize' ) // Sanitize. 53 | ); 54 | } 55 | 56 | /** 57 | * Validates submitted setting values before they get saved to the database. 58 | * 59 | * @param array $input Settings Being Saved. 60 | * @since 1.0.0 61 | * @return array 62 | */ 63 | public function sanitize( $input ) { 64 | $new_input = array(); 65 | if ( isset( $input ) && ! empty( $input ) ) { 66 | $new_input = $input; 67 | } 68 | 69 | return $new_input; 70 | } 71 | 72 | /** 73 | * Returns the option key used to store the settings in database 74 | * 75 | * @since 1.0.0 76 | * @return string 77 | */ 78 | public function get_plugin_settings_option_key() { 79 | return Settings_Model::get_plugin_settings_option_key(); 80 | } 81 | 82 | /** 83 | * Retrieves all of the settings from the database 84 | * 85 | * @param string $setting_name Setting to be retrieved. 86 | * @since 1.0.0 87 | * @return array 88 | */ 89 | public function get_setting( $setting_name ) { 90 | return Settings_Model::get_setting( $setting_name ); 91 | } 92 | 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /plugin-name/app/models/admin/class-base-model.php: -------------------------------------------------------------------------------- 1 | $setting_value ] ); 120 | } 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /plugin-name/app/models/frontend/class-base-model.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | 5 | 6 | -------------------------------------------------------------------------------- /plugin-name/app/templates/admin/errors/requirements-error.php: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Your environment doesn't meet the system requirements listed below. Therefore Plugin Name has been deactivated.

4 | 5 |
    6 | 7 |
  • 8 | error_message ); ?> 9 | supportive_information ); ?> 10 |
  • 11 | 12 |
13 | 14 |
15 | -------------------------------------------------------------------------------- /plugin-name/app/templates/admin/page-settings/page-settings-fields.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /plugin-name/app/templates/admin/page-settings/page-settings-section-headers.php: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | -------------------------------------------------------------------------------- /plugin-name/app/templates/admin/page-settings/page-settings.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |

6 | 7 |
8 | 13 |
14 | 15 |
16 | -------------------------------------------------------------------------------- /plugin-name/app/views/admin/class-admin-settings.php: -------------------------------------------------------------------------------- 1 | render_template( 25 | 'admin/page-settings/page-settings.php', 26 | $args 27 | ); // WPCS: XSS OK. 28 | } 29 | 30 | /** 31 | * Prints Section's Description. 32 | * 33 | * @param array $args Arguments passed by `markup_section_headers` method from `Plugin_Name\App\Controllers\Admin\Admin_Settings` controller. 34 | * @return void 35 | * @since 1.0.0 36 | */ 37 | public function section_headers( $args = [] ) { 38 | echo $this->render_template( 39 | 'admin/page-settings/page-settings-section-headers.php', 40 | $args 41 | ); // WPCS: XSS OK. 42 | } 43 | 44 | /** 45 | * Prints text field 46 | * 47 | * @param array $args Arguments passed by `markup_fields` method from `Plugin_Name\App\Controllers\Admin\Admin_Settings` controller. 48 | * @return void 49 | * @since 1.0.0 50 | */ 51 | public function markup_fields( $args = [] ) { 52 | echo $this->render_template( 53 | 'admin/page-settings/page-settings-fields.php', 54 | $args 55 | ); // WPCS: XSS OK. 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /plugin-name/assets/css/admin/plugin-name.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS for your admin-facing functionality should be 3 | * included in this file. 4 | */ 5 | -------------------------------------------------------------------------------- /plugin-name/assets/css/frontend/plugin-name.css: -------------------------------------------------------------------------------- 1 | /** 2 | * All of the CSS for your frontend-facing functionality should be 3 | * included in this file. 4 | */ 5 | -------------------------------------------------------------------------------- /plugin-name/assets/fonts/admin/README.md: -------------------------------------------------------------------------------- 1 | Fonts required in the admin side 2 | -------------------------------------------------------------------------------- /plugin-name/assets/fonts/frontend/README.md: -------------------------------------------------------------------------------- 1 | Fonts required on Frontend 2 | -------------------------------------------------------------------------------- /plugin-name/assets/images/admin/README.md: -------------------------------------------------------------------------------- 1 | Add images required in dashboard area 2 | -------------------------------------------------------------------------------- /plugin-name/assets/images/frontend/README.md: -------------------------------------------------------------------------------- 1 | Images required on Frontend Side 2 | -------------------------------------------------------------------------------- /plugin-name/assets/js/admin/plugin-name.js: -------------------------------------------------------------------------------- 1 | (function( $ ) { 2 | 'use strict'; 3 | 4 | /** 5 | * All of the code for your admin-facing JavaScript source 6 | * should reside in this file. 7 | * 8 | * Note that this assume you're going to use jQuery, so it prepares 9 | * the $ function reference to be used within the scope of this 10 | * function. 11 | * 12 | * From here, you're able to define handlers for when the DOM is 13 | * ready: 14 | * 15 | * $(function() { 16 | * 17 | * }); 18 | * 19 | * Or when the window is loaded: 20 | * 21 | * $( window ).load(function() { 22 | * 23 | * }); 24 | * 25 | * ...and so on. 26 | * 27 | * Remember that ideally, we should not attach any more than a single DOM-ready or window-load handler 28 | * for any particular page. Though other scripts in WordPress core, other plugins, and other themes may 29 | * be doing this, we should try to minimize doing that in our own work. 30 | */ 31 | 32 | })( jQuery ); 33 | -------------------------------------------------------------------------------- /plugin-name/assets/js/frontend/plugin-name.js: -------------------------------------------------------------------------------- 1 | (function( $ ) { 2 | 'use strict'; 3 | 4 | /** 5 | * All of the code for your frontend-facing JavaScript source 6 | * should reside in this file. 7 | * 8 | * Note that this assume you're going to use jQuery, so it prepares 9 | * the $ function reference to be used within the scope of this 10 | * function. 11 | * 12 | * From here, you're able to define handlers for when the DOM is 13 | * ready: 14 | * 15 | * $(function() { 16 | * 17 | * }); 18 | * 19 | * Or when the window is loaded: 20 | * 21 | * $( window ).load(function() { 22 | * 23 | * }); 24 | * 25 | * ...and so on. 26 | * 27 | * Remember that ideally, we should not attach any more than a single DOM-ready or window-load handler 28 | * for any particular page. Though other scripts in WordPress core, other plugins, and other themes may 29 | * be doing this, we should try to minimize doing that in our own work. 30 | */ 31 | 32 | })( jQuery ); 33 | -------------------------------------------------------------------------------- /plugin-name/core/class-controller.php: -------------------------------------------------------------------------------- 1 | model; 83 | } 84 | 85 | /** 86 | * Get view 87 | * 88 | * In most of the cases, the view will be set as per routes in defined in routes.php. 89 | * So if you are not sure which view class is currently being used, search for the 90 | * current controller class name in the routes.php 91 | * 92 | * @return object 93 | * @since 1.0.0 94 | */ 95 | protected function get_view() { 96 | return $this->view; 97 | } 98 | 99 | /** 100 | * Sets the model to be used 101 | * 102 | * @param Model $model Model object to be associated with the current controller object. 103 | * @return void 104 | * @since 1.0.0 105 | */ 106 | protected function set_model( Model $model ) { 107 | $this->model = $model; 108 | } 109 | 110 | /** 111 | * Sets the view to be used 112 | * 113 | * @param View $view View object to be associated with the current controller object. 114 | * @return void 115 | * @since 1.0.0 116 | */ 117 | protected function set_view( View $view ) { 118 | $this->view = $view; 119 | } 120 | 121 | /** 122 | * Constructor 123 | * 124 | * @param Model $model Model object to be used with current controller object. 125 | * @param mixed $view View object to be used with current controller object. Otherwise false. 126 | */ 127 | protected function __construct( Model $model, $view = false ) { 128 | $this->init( $model, $view ); 129 | } 130 | 131 | /** 132 | * Sets Model & View to be used with current controller 133 | * 134 | * @param Model $model Model to be associated with this controller. 135 | * @param mixed $view Either View/its child class object or False. 136 | * @return void 137 | */ 138 | final protected function init( Model $model, $view = false ) { 139 | $this->set_model( $model ); 140 | 141 | if ( false === $view ) { 142 | $view = new View(); 143 | } 144 | 145 | $this->set_view( $view ); 146 | } 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /plugin-name/core/class-model.php: -------------------------------------------------------------------------------- 1 | 97 | * // get_the_ID function won't be accessible below if the route is registered 98 | * // with 'frontend' type. get_the_ID function will be accessible only if 99 | * // route is registered on Route_Type::LATE_FRONTEND or 100 | * // Route_Type::LATE_FRONTEND_WITH_POSSIBLE_AJAX 101 | * $router-> 102 | * ->register_route_of_type( Route_Type::LATE_FRONTEND ) 103 | * ->with_controller( 104 | * function() { 105 | * if ( get_the_ID() == '3367' ) { 106 | * return 'Sample_Shortcode'; 107 | * } 108 | * return false; 109 | * } 110 | * ) 111 | * ->with_view( 'Sample_Shortcode' ); 112 | * 113 | * 114 | * @since 1.0.0 115 | */ 116 | const LATE_FRONTEND = 'late_frontend'; 117 | 118 | /** 119 | * Use this route type if a controller/model needs to be loaded only on 120 | * Frontend, satisifies conditions you are looking for & has a support 121 | * for ajax. 122 | * 123 | * This route type is registered on `wp` hook. If a callback/function is 124 | * passed to `with_controller`, `with_model`,`with_view` or `with_just_model`, 125 | * then those callbacks will have access to global `$wp` variable 126 | * 127 | * 128 | * For Example, If you want to load a controller/model only when the current 129 | * post id is 3367, then you might want to write below route in the `routes.php` 130 | * 131 | * 132 | * // get_the_ID function won't be accessible below if the route is registered 133 | * // with 'frontend' type. get_the_ID function will be accessible only if 134 | * // route is registered on Route_Type::LATE_FRONTEND or 135 | * // Route_Type::LATE_FRONTEND_WITH_POSSIBLE_AJAX 136 | * $router-> 137 | * ->register_route_of_type( Route_Type::LATE_FRONTEND_WITH_POSSIBLE_AJAX ) 138 | * ->with_controller( 139 | * function() { 140 | * if ( get_the_ID() == '3367' ) { 141 | * return 'Sample_Controller'; 142 | * } 143 | * return false; 144 | * } 145 | * ) 146 | * ->with_view( 'Sample_View' ); 147 | * 148 | * 149 | * @since 1.0.0 150 | */ 151 | const LATE_FRONTEND_WITH_POSSIBLE_AJAX = 'late_frontend_with_possible_ajax'; 152 | 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /plugin-name/core/class-router.php: -------------------------------------------------------------------------------- 1 | register_hook_callbacks(); 47 | } 48 | 49 | /** 50 | * Register callbacks for actions and filters 51 | * 52 | * @since 1.0.0 53 | */ 54 | protected function register_hook_callbacks() { 55 | add_action( 'init', array( $this, 'register_generic_model_only_routes' ) ); 56 | add_action( 'wp', array( $this, 'register_late_frontend_model_only_routes' ) ); 57 | 58 | add_action( 'init', array( $this, 'register_generic_routes' ) ); 59 | add_action( 'wp', array( $this, 'register_late_frontend_routes' ) ); 60 | } 61 | 62 | /** 63 | * Register Generic `Model Only` Routes 64 | * 65 | * @return void 66 | * @since 1.0.0 67 | */ 68 | public function register_generic_model_only_routes() { 69 | $this->register_model_only_routes(); 70 | } 71 | 72 | /** 73 | * Register Late Frontend `Model Only` Routes 74 | * 75 | * @return void 76 | * @since 1.0.0 77 | */ 78 | public function register_late_frontend_model_only_routes() { 79 | $this->register_model_only_routes( self::REGISTER_LATE_FRONTEND_ROUTES ); 80 | } 81 | 82 | /** 83 | * Register Generic Routes 84 | * 85 | * @return void 86 | * @since 1.0.0 87 | */ 88 | public function register_generic_routes() { 89 | $this->register_routes(); 90 | } 91 | 92 | /** 93 | * Register Late Frontend Routes 94 | * 95 | * @return void 96 | * @since 1.0.0 97 | */ 98 | public function register_late_frontend_routes() { 99 | $this->register_routes( self::REGISTER_LATE_FRONTEND_ROUTES ); 100 | } 101 | 102 | /** 103 | * Returns List of commonly/mostly used Route types 104 | * 105 | * @since 1.0.0 106 | * @return array 107 | */ 108 | public function generic_route_types() { 109 | return apply_filters( 110 | 'plugin_name_route_types', [ 111 | Route_Type::ANY, 112 | Route_Type::ADMIN, 113 | Route_Type::ADMIN_WITH_POSSIBLE_AJAX, 114 | Route_Type::AJAX, 115 | Route_Type::CRON, 116 | Route_Type::FRONTEND, 117 | Route_Type::FRONTEND_WITH_POSSIBLE_AJAX, 118 | ] 119 | ); 120 | } 121 | 122 | /** 123 | * Returns list of Route types belonging to Frontend but registered late 124 | * 125 | * @since 1.0.0 126 | * @return array 127 | */ 128 | public function late_frontend_route_types() { 129 | return apply_filters( 130 | 'plugin_name_late_frontend_route_types', [ 131 | Route_Type::LATE_FRONTEND, 132 | Route_Type::LATE_FRONTEND_WITH_POSSIBLE_AJAX, 133 | ] 134 | ); 135 | } 136 | 137 | /** 138 | * Type of Route to be registered. Every time a new route needs to be 139 | * registered, this function should be called first on `$route` object 140 | * 141 | * @param string $type Type of route to be registered. 142 | * @return Router Returns `Router` object. 143 | * @since 1.0.0 144 | */ 145 | public function register_route_of_type( $type ) { 146 | if ( in_array( $type, $this->late_frontend_route_types() ) && did_action( 'wp' ) ) { 147 | trigger_error( __( 'Late Routes can not be registered after `wp` hook is triggered. Register your route before `wp` hook is triggered.', Plugin_Name::PLUGIN_ID ), E_USER_ERROR ); // @codingStandardsIgnoreLine. 148 | } 149 | 150 | if ( in_array( $type, $this->generic_route_types() ) && did_action( 'init' ) ) { 151 | trigger_error( __( 'Non-Late Routes can not be registered after `init` hook is triggered. Register your route before `init` hook is triggered.', Plugin_Name::PLUGIN_ID ), E_USER_ERROR ); // @codingStandardsIgnoreLine. 152 | } 153 | 154 | $this->route_type_to_register = $type; 155 | return $this; 156 | } 157 | 158 | /** 159 | * Enqueues a model to be associated with the Model only` Route 160 | * 161 | * @param mixed $model Model to be associated with the Route. Could be String or callback. 162 | * @return mixed 163 | * @since 1.0.0 164 | */ 165 | public function with_just_model( $model ) { 166 | if ( false === $model ) { 167 | return $this; 168 | } 169 | static::$models[ $this->route_type_to_register ][] = $model; 170 | } 171 | 172 | /** 173 | * Generates a Unique id for each controller 174 | * 175 | * This unique id is used as an array key inside mvc_components array which 176 | * is used while enqueueing models and views to associate them with the 177 | * controller. 178 | * 179 | * @param mixed $controller Controller to be associated with the Route. Could be String or callback. 180 | * @return string 181 | * @since 1.0.0 182 | */ 183 | public function build_controller_unique_id( $controller ) { 184 | $prefix = mt_rand() . '_'; 185 | 186 | if ( is_string( $controller ) ) { 187 | return $prefix . $controller; 188 | } 189 | 190 | if ( is_object( $controller ) ) { 191 | // Closures are currently implemented as objects. 192 | $controller = array( $controller, '' ); 193 | } else { 194 | $controller = (array) $controller; 195 | } 196 | 197 | if ( is_object( $controller[0] ) ) { 198 | // Object Class Calling. 199 | return $prefix . spl_object_hash( $controller[0] ) . $controller[1]; 200 | } 201 | 202 | if ( is_string( $controller[0] ) ) { 203 | // Static Calling. 204 | return $prefix . $controller[0] . '::' . $controller[1]; 205 | } 206 | } 207 | 208 | /** 209 | * Enqueues a controller to be associated with the Route 210 | * 211 | * @param mixed $controller Controller to be associated with the Route. Could be String or callback. 212 | * @return object Returns Router Object 213 | * @since 1.0.0 214 | */ 215 | public function with_controller( $controller ) { 216 | if ( false === $controller ) { 217 | return $this; 218 | } 219 | 220 | $this->current_controller = $this->build_controller_unique_id( $controller ); 221 | 222 | static::$mvc_components[ $this->route_type_to_register ][ $this->current_controller ] = [ 'controller' => $controller ]; 223 | 224 | return $this; 225 | } 226 | 227 | /** 228 | * Enqueues a model to be associated with the Route 229 | * 230 | * The object of this model is passed to controller. 231 | * 232 | * @param mixed $model Model to be associated with the Route. Could be String or callback. 233 | * @return object Returns Router Object 234 | * @since 1.0.0 235 | */ 236 | public function with_model( $model ) { 237 | if ( isset( static::$mvc_components[ $this->route_type_to_register ][ $this->current_controller ]['controller'] ) ) { 238 | static::$mvc_components[ $this->route_type_to_register ][ $this->current_controller ]['model'] = $model; 239 | } 240 | return $this; 241 | } 242 | 243 | /** 244 | * Registers view with the Route. The object of this view is passed to controller 245 | * 246 | * @param mixed $view View to be associated with the Route. Could be String or callback. 247 | * @return object Returns Router Object 248 | * @since 1.0.0 249 | */ 250 | public function with_view( $view ) { 251 | if ( isset( static::$mvc_components[ $this->route_type_to_register ][ $this->current_controller ]['controller'] ) ) { 252 | static::$mvc_components[ $this->route_type_to_register ][ $this->current_controller ]['view'] = $view; 253 | } 254 | return $this; 255 | } 256 | 257 | /** 258 | * Registers Enqueued Routes 259 | * 260 | * @param boolean $register_late_frontend_routes Whether to register late frontend routes. 261 | * @return void 262 | * @since 1.0.0 263 | */ 264 | private function register_routes( $register_late_frontend_routes = false ) { 265 | if ( $register_late_frontend_routes ) { 266 | $route_types = $this->late_frontend_route_types(); 267 | } else { 268 | $route_types = $this->generic_route_types(); 269 | } 270 | 271 | if ( empty( $route_types ) ) { 272 | return; 273 | } 274 | 275 | foreach ( $route_types as $route_type ) { 276 | if ( $this->is_request( $route_type ) && ! empty( static::$mvc_components[ $route_type ] ) ) { 277 | foreach ( static::$mvc_components[ $route_type ] as $mvc_component ) { 278 | $this->dispatch( $mvc_component, $route_type ); 279 | } 280 | } 281 | } 282 | } 283 | 284 | /** 285 | * Dispatches the route of specified $route_type by creating a controller object 286 | * 287 | * @param array $mvc_component Model-View-Controller triads for all registered routes. 288 | * @param string $route_type Route Type. 289 | * @return void 290 | * @since 1.0.0 291 | */ 292 | private function dispatch( $mvc_component, $route_type ) { 293 | $model = false; 294 | $view = false; 295 | 296 | if ( isset( $mvc_component['controller'] ) && false === $mvc_component['controller'] ) { 297 | return; 298 | } 299 | 300 | if ( is_callable( $mvc_component['controller'] ) ) { 301 | $mvc_component['controller'] = call_user_func( $mvc_component['controller'] ); 302 | 303 | if ( false === $mvc_component['controller'] ) { 304 | return; 305 | } 306 | } 307 | 308 | if ( isset( $mvc_component['model'] ) && false !== $mvc_component['model'] ) { 309 | if ( is_callable( $mvc_component['model'] ) ) { 310 | $mvc_component['model'] = call_user_func( $mvc_component['model'] ); 311 | } 312 | 313 | $model = $this->get_fully_qualified_class_name( $mvc_component['model'], 'model', $route_type ); 314 | } 315 | 316 | if ( isset( $mvc_component['view'] ) && false !== $mvc_component['view'] ) { 317 | if ( is_callable( $mvc_component['view'] ) ) { 318 | $mvc_component['view'] = call_user_func( $mvc_component['view'] ); 319 | } 320 | 321 | $view = $this->get_fully_qualified_class_name( $mvc_component['view'], 'view', $route_type ); 322 | } 323 | 324 | @list($controller, $action) = explode( '@', $mvc_component['controller'] ); 325 | 326 | $controller = $this->get_fully_qualified_class_name( $controller, 'controller', $route_type ); 327 | 328 | $controller_instance = $controller::get_instance( $model, $view ); 329 | 330 | if ( null !== $action ) { 331 | $controller_instance->$action(); 332 | } 333 | } 334 | 335 | /** 336 | * Registers `Model Only` Enqueued Routes 337 | * 338 | * @param boolean $register_late_frontend_routes Whether to register late frontend routes. 339 | * @return void 340 | * @since 1.0.0 341 | */ 342 | public function register_model_only_routes( $register_late_frontend_routes = false ) { 343 | if ( $register_late_frontend_routes && empty( $route_types = $this->late_frontend_route_types() ) ) { // @codingStandardsIgnoreLine. 344 | return; 345 | } elseif ( empty( $route_types = $this->generic_route_types() ) ) { // @codingStandardsIgnoreLine. 346 | return; 347 | } 348 | 349 | foreach ( $route_types as $route_type ) { 350 | if ( $this->is_request( $route_type ) && ! empty( static::$models[ $route_type ] ) ) { 351 | foreach ( static::$models[ $route_type ] as $model ) { 352 | $this->dispatch_only_model( $model, $route_type ); 353 | } 354 | } 355 | } 356 | } 357 | 358 | /** 359 | * Dispatches the model only route by creating a Model object 360 | * 361 | * @param mixed $model Model to be associated with the Route. Could be String or callback. 362 | * @param string $route_type Route Type. 363 | * @return void 364 | * @since 1.0.0 365 | */ 366 | private function dispatch_only_model( $model, $route_type ) { 367 | if ( false === $model ) { 368 | return; 369 | } 370 | 371 | if ( is_callable( $model ) ) { 372 | $model = call_user_func( $model ); 373 | 374 | if ( false === $model ) { 375 | return; 376 | } 377 | } 378 | 379 | @list($model, $action) = explode( '@', $model ); 380 | $model = $this->get_fully_qualified_class_name( $model, 'model', $route_type ); 381 | $model_instance = $model::get_instance(); 382 | 383 | if ( null !== $action ) { 384 | $model_instance->$action(); 385 | } 386 | } 387 | 388 | /** 389 | * Returns the Full Qualified Class Name for given class name 390 | * 391 | * @param string $class Class whose FQCN needs to be found out. 392 | * @param string $mvc_component_type Could be between 'model', 'view' or 'controller'. 393 | * @param string $route_type Could be 'admin' or 'frontend'. 394 | * @return string Retuns Full Qualified Class Name. 395 | * @since 1.0.0 396 | */ 397 | private function get_fully_qualified_class_name( $class, $mvc_component_type, $route_type ) { 398 | 399 | // If route type is admin or frontend. 400 | if ( \strpos( $route_type, 'admin' ) !== false || \strpos( $route_type, 'frontend' ) !== false ) { 401 | $fqcn = '\Plugin_Name\App\\'; 402 | $fqcn .= \ucfirst( $mvc_component_type ) . 's\\'; 403 | $fqcn .= \strpos( $route_type, 'admin' ) !== false ? 'Admin\\' : 'Frontend\\'; 404 | 405 | if ( class_exists( $fqcn . $class ) ) { 406 | return $fqcn . $class; 407 | } 408 | } 409 | 410 | return $class; 411 | } 412 | 413 | /** 414 | * Identifies Request Type 415 | * 416 | * @param string $route_type Route Type to identify. 417 | * @return boolean 418 | * @since 1.0.0 419 | */ 420 | private function is_request( $route_type ) { 421 | switch ( $route_type ) { 422 | case Route_Type::ANY: 423 | return true; 424 | case ROUTE_TYPE::ADMIN: 425 | case ROUTE_TYPE::ADMIN_WITH_POSSIBLE_AJAX: 426 | return is_admin(); 427 | case ROUTE_TYPE::AJAX: 428 | return defined( 'DOING_AJAX' ); 429 | case ROUTE_TYPE::CRON: 430 | return defined( 'DOING_CRON' ); 431 | case ROUTE_TYPE::FRONTEND: 432 | case ROUTE_TYPE::FRONTEND_WITH_POSSIBLE_AJAX: 433 | return ( ! is_admin() || defined( 'DOING_AJAX' ) ) && ! defined( 'DOING_CRON' ) && ! defined( 'REST_REQUEST' ); 434 | case ROUTE_TYPE::LATE_FRONTEND: 435 | case ROUTE_TYPE::LATE_FRONTEND_WITH_POSSIBLE_AJAX: 436 | return $this->is_request( 'frontend' ) || ( current_action() == 'wp' ) || ( did_action( 'wp' ) === 1 ); 437 | } 438 | } 439 | } 440 | 441 | } 442 | -------------------------------------------------------------------------------- /plugin-name/core/class-view.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | class View { 15 | /** 16 | * Render Templates 17 | * 18 | * @access public 19 | * @param mixed $template_name Template file to render. 20 | * @param array $args Variables to make available inside template file. 21 | * @param string $template_path Directory to search for template. 22 | * @param string $default_path Fallback directory to search for template if not found at $template_path. 23 | * @return void 24 | */ 25 | public static function render_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) { 26 | if ( $args && is_array( $args ) ) { 27 | extract( $args ); // @codingStandardsIgnoreLine. 28 | } 29 | 30 | $located = static::locate_template( $template_name, $template_path, $default_path ); 31 | if ( false == $located ) { 32 | return; 33 | } 34 | 35 | ob_start(); 36 | do_action( 'plugin_name_before_template_render', $template_name, $template_path, $located, $args ); 37 | include( $located ); 38 | do_action( 'plugin_name_after_template_render', $template_name, $template_path, $located, $args ); 39 | 40 | return ob_get_clean(); // @codingStandardsIgnoreLine. 41 | } 42 | 43 | /** 44 | * Locate a template and return the path for inclusion. 45 | * 46 | * This is the load order: 47 | * 48 | * yourtheme / $template_path / $template_name 49 | * yourtheme / $template_name 50 | * $default_path / $template_name 51 | * 52 | * @access public 53 | * @param mixed $template_name Template file to locate. 54 | * @param string $template_path $template_path Directory to search for template. 55 | * @param string $default_path Fallback directory to search for template if not found at $template_path. 56 | * @return string 57 | */ 58 | public static function locate_template( $template_name, $template_path = '', $default_path = '' ) { 59 | if ( ! $template_path ) { 60 | $template_path = 'plugin-name-templates/'; 61 | } 62 | if ( ! $default_path ) { 63 | $default_path = Plugin_Name::get_plugin_path() . 'app/templates/'; 64 | } 65 | 66 | // Look within passed path within the theme - this is priority. 67 | $template = locate_template( 68 | array( 69 | trailingslashit( $template_path ) . $template_name, 70 | $template_name, 71 | ) 72 | ); 73 | 74 | // Get default template. 75 | if ( ! $template ) { 76 | $template = $default_path . $template_name; 77 | } 78 | 79 | if ( file_exists( $template ) ) { 80 | // Return what we found. 81 | return apply_filters( 'plugin_name_locate_template', $template, $template_name, $template_path ); 82 | } else { 83 | return false; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /plugin-name/core/registry/class-controller.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | class Controller { 16 | use Base_Registry; 17 | 18 | /** 19 | * Returns key used to store a particular Controller Object 20 | * 21 | * @param string $controller_class_name Controller Class Name. 22 | * @param string $model_class_name Model Class Name. 23 | * @param string $view_class_name View Class Name. 24 | * @return string 25 | */ 26 | public static function get_key( $controller_class_name, $model_class_name, $view_class_name ) { 27 | return "{$controller_class_name}__{$model_class_name}__{$view_class_name}"; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /plugin-name/core/registry/class-model.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | class Model { 16 | use Base_Registry; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugin-name/core/registry/trait-base-registry.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | trait Base_Registry { 22 | 23 | /** 24 | * Variable that holds all objects in registry. 25 | * 26 | * @var array 27 | */ 28 | protected static $stored_objects = []; 29 | 30 | /** 31 | * Add object to registry 32 | * 33 | * @param string $key Key to be used to map with Object. 34 | * @param mixed $value Object to Store. 35 | * @return void 36 | * @since 1.0.0 37 | */ 38 | public static function set( $key, $value ) { 39 | if ( ! is_string( $key ) ) { 40 | trigger_error( __( 'Key passed to `set` method must be key', Plugin_Name::PLUGIN_ID ), E_USER_ERROR ); // @codingStandardsIgnoreLine. 41 | } 42 | static::$stored_objects[ $key ] = $value; 43 | } 44 | 45 | /** 46 | * Get object from registry 47 | * 48 | * @param string $key Key of the object to restore. 49 | * @return mixed 50 | * @since 1.0.0 51 | */ 52 | public static function get( $key ) { 53 | if ( ! is_string( $key ) ) { 54 | trigger_error( __( 'Key passed to `get` method must be key', Plugin_Name::PLUGIN_ID ), E_USER_ERROR ); // @codingStandardsIgnoreLine. 55 | } 56 | 57 | if ( ! isset( static::$stored_objects[ $key ] ) ) { 58 | return null; 59 | } 60 | 61 | return static::$stored_objects[ $key ]; 62 | } 63 | 64 | /** 65 | * Returns all objects 66 | * 67 | * @return array 68 | * @since 1.0.0 69 | */ 70 | public static function get_all_objects() { 71 | return static::$stored_objects; 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Activator.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Activator 2 | =============== 3 | 4 | Fired during plugin activation. 5 | 6 | This class defines all code necessary to run during the plugin's activation. 7 | 8 | 9 | * Class name: Activator 10 | * Namespace: Plugin_Name\App 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Methods 19 | ------- 20 | 21 | 22 | ### activate 23 | 24 | mixed Plugin_Name\App\Activator::activate() 25 | 26 | Short Description. (use period) 27 | 28 | Long Description. 29 | 30 | * Visibility: **public** 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Controllers-Admin-Admin_Settings.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Controllers\Admin\Admin_Settings 2 | =============== 3 | 4 | Controller class that implements Plugin Admin Settings configurations 5 | 6 | 7 | 8 | 9 | * Class name: Admin_Settings 10 | * Namespace: Plugin_Name\App\Controllers\Admin 11 | * Parent class: [Plugin_Name\App\Controllers\Admin\Base_Controller](Plugin_Name-App-Controllers-Admin-Base_Controller.md) 12 | 13 | 14 | 15 | Constants 16 | ---------- 17 | 18 | 19 | ### SETTINGS_PAGE_SLUG 20 | 21 | const SETTINGS_PAGE_SLUG = \Plugin_Name::PLUGIN_ID 22 | 23 | 24 | 25 | 26 | 27 | ### REQUIRED_CAPABILITY 28 | 29 | const REQUIRED_CAPABILITY = 'manage_options' 30 | 31 | 32 | 33 | 34 | 35 | Properties 36 | ---------- 37 | 38 | 39 | ### $hook_suffix 40 | 41 | private string $hook_suffix = 'settings_page_' . \Plugin_Name::PLUGIN_ID 42 | 43 | Holds suffix for dynamic add_action called on settings page. 44 | 45 | 46 | 47 | * Visibility: **private** 48 | * This property is **static**. 49 | 50 | 51 | ### $model 52 | 53 | protected Object $model 54 | 55 | Holds Model object 56 | 57 | 58 | 59 | * Visibility: **protected** 60 | 61 | 62 | ### $view 63 | 64 | protected Object $view 65 | 66 | Holds View Object 67 | 68 | 69 | 70 | * Visibility: **protected** 71 | 72 | 73 | Methods 74 | ------- 75 | 76 | 77 | ### register_hook_callbacks 78 | 79 | mixed Plugin_Name\App\Controllers\Admin\Base_Controller::register_hook_callbacks() 80 | 81 | Register callbacks for actions and filters. Most of your add_action/add_filter 82 | go into this method. 83 | 84 | NOTE: register_hook_callbacks method is not called automatically. You 85 | as a developer have to call this method where you see fit. For Example, 86 | You may want to call this in constructor, if you feel hooks/filters 87 | callbacks should be registered when the new instance of the class 88 | is created. 89 | 90 | The purpose of this method is to set the convention that first place to 91 | find add_action/add_filter is register_hook_callbacks method. 92 | 93 | * Visibility: **protected** 94 | * This method is **abstract**. 95 | * This method is defined by [Plugin_Name\App\Controllers\Admin\Base_Controller](Plugin_Name-App-Controllers-Admin-Base_Controller.md) 96 | 97 | 98 | 99 | 100 | ### plugin_menu 101 | 102 | mixed Plugin_Name\App\Controllers\Admin\Admin_Settings::plugin_menu() 103 | 104 | Create menu for Plugin inside Settings menu 105 | 106 | 107 | 108 | * Visibility: **public** 109 | 110 | 111 | 112 | 113 | ### enqueue_scripts 114 | 115 | mixed Plugin_Name\App\Controllers\Admin\Admin_Settings::enqueue_scripts() 116 | 117 | Register the JavaScript for the admin area. 118 | 119 | 120 | 121 | * Visibility: **public** 122 | 123 | 124 | 125 | 126 | ### enqueue_styles 127 | 128 | mixed Plugin_Name\App\Controllers\Admin\Admin_Settings::enqueue_styles() 129 | 130 | Register the JavaScript for the admin area. 131 | 132 | 133 | 134 | * Visibility: **public** 135 | 136 | 137 | 138 | 139 | ### markup_settings_page 140 | 141 | mixed Plugin_Name\App\Controllers\Admin\Admin_Settings::markup_settings_page() 142 | 143 | Creates the markup for the Settings page 144 | 145 | 146 | 147 | * Visibility: **public** 148 | 149 | 150 | 151 | 152 | ### register_fields 153 | 154 | mixed Plugin_Name\App\Controllers\Admin\Admin_Settings::register_fields() 155 | 156 | Registers settings sections and fields 157 | 158 | 159 | 160 | * Visibility: **public** 161 | 162 | 163 | 164 | 165 | ### markup_section_headers 166 | 167 | mixed Plugin_Name\App\Controllers\Admin\Admin_Settings::markup_section_headers(array $section) 168 | 169 | Adds the section introduction text to the Settings page 170 | 171 | 172 | 173 | * Visibility: **public** 174 | 175 | 176 | #### Arguments 177 | * $section **array** - <p>Array containing information Section Id, Section 178 | Title & Section Callback.</p> 179 | 180 | 181 | 182 | ### markup_fields 183 | 184 | mixed Plugin_Name\App\Controllers\Admin\Admin_Settings::markup_fields(array $field_args) 185 | 186 | Delivers the markup for settings fields 187 | 188 | 189 | 190 | * Visibility: **public** 191 | 192 | 193 | #### Arguments 194 | * $field_args **array** - <p>Field arguments passed in <code>add_settings_field</code> 195 | function.</p> 196 | 197 | 198 | 199 | ### add_plugin_action_links 200 | 201 | array Plugin_Name\App\Controllers\Admin\Admin_Settings::add_plugin_action_links(array $links) 202 | 203 | Adds links to the plugin's action link section on the Plugins page 204 | 205 | 206 | 207 | * Visibility: **public** 208 | 209 | 210 | #### Arguments 211 | * $links **array** - <p>The links currently mapped to the plugin.</p> 212 | 213 | 214 | 215 | ### get_instance 216 | 217 | object Plugin_Name\Core\Controller::get_instance(mixed $model_class_name, mixed $view_class_name) 218 | 219 | Provides access to a single instance of a module using the singleton pattern 220 | 221 | 222 | 223 | * Visibility: **public** 224 | * This method is **static**. 225 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 226 | 227 | 228 | #### Arguments 229 | * $model_class_name **mixed** - <p>Model Class to be associated with the controller.</p> 230 | * $view_class_name **mixed** - <p>View Class to be associated with the controller.</p> 231 | 232 | 233 | 234 | ### get_model 235 | 236 | object Plugin_Name\Core\Controller::get_model() 237 | 238 | Get model. 239 | 240 | In most of the cases, the model will be set as per routes in defined in routes.php. 241 | So if you are not sure which model class is currently being used, search for the 242 | current controller class name in the routes.php 243 | 244 | * Visibility: **protected** 245 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 246 | 247 | 248 | 249 | 250 | ### get_view 251 | 252 | object Plugin_Name\Core\Controller::get_view() 253 | 254 | Get view 255 | 256 | In most of the cases, the view will be set as per routes in defined in routes.php. 257 | So if you are not sure which view class is currently being used, search for the 258 | current controller class name in the routes.php 259 | 260 | * Visibility: **protected** 261 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 262 | 263 | 264 | 265 | 266 | ### set_model 267 | 268 | void Plugin_Name\Core\Controller::set_model(\Plugin_Name\Core\Model $model) 269 | 270 | Sets the model to be used 271 | 272 | 273 | 274 | * Visibility: **protected** 275 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 276 | 277 | 278 | #### Arguments 279 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model object to be associated with the current controller object.</p> 280 | 281 | 282 | 283 | ### set_view 284 | 285 | void Plugin_Name\Core\Controller::set_view(\Plugin_Name\Core\View $view) 286 | 287 | Sets the view to be used 288 | 289 | 290 | 291 | * Visibility: **protected** 292 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 293 | 294 | 295 | #### Arguments 296 | * $view **[Plugin_Name\Core\View](Plugin_Name-Core-View.md)** - <p>View object to be associated with the current controller object.</p> 297 | 298 | 299 | 300 | ### __construct 301 | 302 | mixed Plugin_Name\Core\Controller::__construct(\Plugin_Name\Core\Model $model, mixed $view) 303 | 304 | Constructor 305 | 306 | 307 | 308 | * Visibility: **protected** 309 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 310 | 311 | 312 | #### Arguments 313 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model object to be used with current controller object.</p> 314 | * $view **mixed** - <p>View object to be used with current controller object. Otherwise false.</p> 315 | 316 | 317 | 318 | ### init 319 | 320 | void Plugin_Name\Core\Controller::init(\Plugin_Name\Core\Model $model, mixed $view) 321 | 322 | Sets Model & View to be used with current controller 323 | 324 | 325 | 326 | * Visibility: **protected** 327 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 328 | 329 | 330 | #### Arguments 331 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model to be associated with this controller.</p> 332 | * $view **mixed** - <p>Either View/its child class object or False.</p> 333 | 334 | 335 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Controllers-Admin-Base_Controller.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Controllers\Admin\Base_Controller 2 | =============== 3 | 4 | Blueprint for Admin related Controllers. All Admin Controllers should extend this Base_Controller 5 | 6 | 7 | 8 | 9 | * Class name: Base_Controller 10 | * Namespace: Plugin_Name\App\Controllers\Admin 11 | * This is an **abstract** class 12 | * Parent class: [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 13 | 14 | 15 | 16 | 17 | 18 | Properties 19 | ---------- 20 | 21 | 22 | ### $model 23 | 24 | protected Object $model 25 | 26 | Holds Model object 27 | 28 | 29 | 30 | * Visibility: **protected** 31 | 32 | 33 | ### $view 34 | 35 | protected Object $view 36 | 37 | Holds View Object 38 | 39 | 40 | 41 | * Visibility: **protected** 42 | 43 | 44 | Methods 45 | ------- 46 | 47 | 48 | ### register_hook_callbacks 49 | 50 | mixed Plugin_Name\App\Controllers\Admin\Base_Controller::register_hook_callbacks() 51 | 52 | Register callbacks for actions and filters. Most of your add_action/add_filter 53 | go into this method. 54 | 55 | NOTE: register_hook_callbacks method is not called automatically. You 56 | as a developer have to call this method where you see fit. For Example, 57 | You may want to call this in constructor, if you feel hooks/filters 58 | callbacks should be registered when the new instance of the class 59 | is created. 60 | 61 | The purpose of this method is to set the convention that first place to 62 | find add_action/add_filter is register_hook_callbacks method. 63 | 64 | * Visibility: **protected** 65 | * This method is **abstract**. 66 | 67 | 68 | 69 | 70 | ### get_instance 71 | 72 | object Plugin_Name\Core\Controller::get_instance(mixed $model_class_name, mixed $view_class_name) 73 | 74 | Provides access to a single instance of a module using the singleton pattern 75 | 76 | 77 | 78 | * Visibility: **public** 79 | * This method is **static**. 80 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 81 | 82 | 83 | #### Arguments 84 | * $model_class_name **mixed** - <p>Model Class to be associated with the controller.</p> 85 | * $view_class_name **mixed** - <p>View Class to be associated with the controller.</p> 86 | 87 | 88 | 89 | ### get_model 90 | 91 | object Plugin_Name\Core\Controller::get_model() 92 | 93 | Get model. 94 | 95 | In most of the cases, the model will be set as per routes in defined in routes.php. 96 | So if you are not sure which model class is currently being used, search for the 97 | current controller class name in the routes.php 98 | 99 | * Visibility: **protected** 100 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 101 | 102 | 103 | 104 | 105 | ### get_view 106 | 107 | object Plugin_Name\Core\Controller::get_view() 108 | 109 | Get view 110 | 111 | In most of the cases, the view will be set as per routes in defined in routes.php. 112 | So if you are not sure which view class is currently being used, search for the 113 | current controller class name in the routes.php 114 | 115 | * Visibility: **protected** 116 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 117 | 118 | 119 | 120 | 121 | ### set_model 122 | 123 | void Plugin_Name\Core\Controller::set_model(\Plugin_Name\Core\Model $model) 124 | 125 | Sets the model to be used 126 | 127 | 128 | 129 | * Visibility: **protected** 130 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 131 | 132 | 133 | #### Arguments 134 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model object to be associated with the current controller object.</p> 135 | 136 | 137 | 138 | ### set_view 139 | 140 | void Plugin_Name\Core\Controller::set_view(\Plugin_Name\Core\View $view) 141 | 142 | Sets the view to be used 143 | 144 | 145 | 146 | * Visibility: **protected** 147 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 148 | 149 | 150 | #### Arguments 151 | * $view **[Plugin_Name\Core\View](Plugin_Name-Core-View.md)** - <p>View object to be associated with the current controller object.</p> 152 | 153 | 154 | 155 | ### __construct 156 | 157 | mixed Plugin_Name\Core\Controller::__construct(\Plugin_Name\Core\Model $model, mixed $view) 158 | 159 | Constructor 160 | 161 | 162 | 163 | * Visibility: **protected** 164 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 165 | 166 | 167 | #### Arguments 168 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model object to be used with current controller object.</p> 169 | * $view **mixed** - <p>View object to be used with current controller object. Otherwise false.</p> 170 | 171 | 172 | 173 | ### init 174 | 175 | void Plugin_Name\Core\Controller::init(\Plugin_Name\Core\Model $model, mixed $view) 176 | 177 | Sets Model & View to be used with current controller 178 | 179 | 180 | 181 | * Visibility: **protected** 182 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 183 | 184 | 185 | #### Arguments 186 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model to be associated with this controller.</p> 187 | * $view **mixed** - <p>Either View/its child class object or False.</p> 188 | 189 | 190 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Controllers-Frontend-Base_Controller.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Controllers\Frontend\Base_Controller 2 | =============== 3 | 4 | Blueprint for Frontend related Controllers. All Frontend Controllers should extend this Base_Controller 5 | 6 | 7 | 8 | 9 | * Class name: Base_Controller 10 | * Namespace: Plugin_Name\App\Controllers\Frontend 11 | * This is an **abstract** class 12 | * Parent class: [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 13 | 14 | 15 | 16 | 17 | 18 | Properties 19 | ---------- 20 | 21 | 22 | ### $model 23 | 24 | protected Object $model 25 | 26 | Holds Model object 27 | 28 | 29 | 30 | * Visibility: **protected** 31 | 32 | 33 | ### $view 34 | 35 | protected Object $view 36 | 37 | Holds View Object 38 | 39 | 40 | 41 | * Visibility: **protected** 42 | 43 | 44 | Methods 45 | ------- 46 | 47 | 48 | ### register_hook_callbacks 49 | 50 | mixed Plugin_Name\App\Controllers\Frontend\Base_Controller::register_hook_callbacks() 51 | 52 | Register callbacks for actions and filters. Most of your add_action/add_filter 53 | go into this method. 54 | 55 | NOTE: register_hook_callbacks method is not called automatically. You 56 | as a developer have to call this method where you see fit. For Example, 57 | You may want to call this in constructor, if you feel hooks/filters 58 | callbacks should be registered when the new instance of the class 59 | is created. 60 | 61 | The purpose of this method is to set the convention that first place to 62 | find add_action/add_filter is register_hook_callbacks method. 63 | 64 | * Visibility: **protected** 65 | * This method is **abstract**. 66 | 67 | 68 | 69 | 70 | ### get_instance 71 | 72 | object Plugin_Name\Core\Controller::get_instance(mixed $model_class_name, mixed $view_class_name) 73 | 74 | Provides access to a single instance of a module using the singleton pattern 75 | 76 | 77 | 78 | * Visibility: **public** 79 | * This method is **static**. 80 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 81 | 82 | 83 | #### Arguments 84 | * $model_class_name **mixed** - <p>Model Class to be associated with the controller.</p> 85 | * $view_class_name **mixed** - <p>View Class to be associated with the controller.</p> 86 | 87 | 88 | 89 | ### get_model 90 | 91 | object Plugin_Name\Core\Controller::get_model() 92 | 93 | Get model. 94 | 95 | In most of the cases, the model will be set as per routes in defined in routes.php. 96 | So if you are not sure which model class is currently being used, search for the 97 | current controller class name in the routes.php 98 | 99 | * Visibility: **protected** 100 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 101 | 102 | 103 | 104 | 105 | ### get_view 106 | 107 | object Plugin_Name\Core\Controller::get_view() 108 | 109 | Get view 110 | 111 | In most of the cases, the view will be set as per routes in defined in routes.php. 112 | So if you are not sure which view class is currently being used, search for the 113 | current controller class name in the routes.php 114 | 115 | * Visibility: **protected** 116 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 117 | 118 | 119 | 120 | 121 | ### set_model 122 | 123 | void Plugin_Name\Core\Controller::set_model(\Plugin_Name\Core\Model $model) 124 | 125 | Sets the model to be used 126 | 127 | 128 | 129 | * Visibility: **protected** 130 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 131 | 132 | 133 | #### Arguments 134 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model object to be associated with the current controller object.</p> 135 | 136 | 137 | 138 | ### set_view 139 | 140 | void Plugin_Name\Core\Controller::set_view(\Plugin_Name\Core\View $view) 141 | 142 | Sets the view to be used 143 | 144 | 145 | 146 | * Visibility: **protected** 147 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 148 | 149 | 150 | #### Arguments 151 | * $view **[Plugin_Name\Core\View](Plugin_Name-Core-View.md)** - <p>View object to be associated with the current controller object.</p> 152 | 153 | 154 | 155 | ### __construct 156 | 157 | mixed Plugin_Name\Core\Controller::__construct(\Plugin_Name\Core\Model $model, mixed $view) 158 | 159 | Constructor 160 | 161 | 162 | 163 | * Visibility: **protected** 164 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 165 | 166 | 167 | #### Arguments 168 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model object to be used with current controller object.</p> 169 | * $view **mixed** - <p>View object to be used with current controller object. Otherwise false.</p> 170 | 171 | 172 | 173 | ### init 174 | 175 | void Plugin_Name\Core\Controller::init(\Plugin_Name\Core\Model $model, mixed $view) 176 | 177 | Sets Model & View to be used with current controller 178 | 179 | 180 | 181 | * Visibility: **protected** 182 | * This method is defined by [Plugin_Name\Core\Controller](Plugin_Name-Core-Controller.md) 183 | 184 | 185 | #### Arguments 186 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model to be associated with this controller.</p> 187 | * $view **mixed** - <p>Either View/its child class object or False.</p> 188 | 189 | 190 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Deactivator.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Deactivator 2 | =============== 3 | 4 | Fired during plugin deactivation. 5 | 6 | This class defines all code necessary to run during the plugin's deactivation. 7 | 8 | 9 | * Class name: Deactivator 10 | * Namespace: Plugin_Name\App 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Methods 19 | ------- 20 | 21 | 22 | ### deactivate 23 | 24 | mixed Plugin_Name\App\Deactivator::deactivate() 25 | 26 | Short Description. (use period) 27 | 28 | Long Description. 29 | 30 | * Visibility: **public** 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Models-Admin-Admin_Settings.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Models\Admin\Admin_Settings 2 | =============== 3 | 4 | Model class that implements Plugin Admin Settings 5 | 6 | 7 | 8 | 9 | * Class name: Admin_Settings 10 | * Namespace: Plugin_Name\App\Models\Admin 11 | * Parent class: [Plugin_Name\App\Models\Admin\Base_Model](Plugin_Name-App-Models-Admin-Base_Model.md) 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Methods 20 | ------- 21 | 22 | 23 | ### __construct 24 | 25 | mixed Plugin_Name\App\Models\Admin\Admin_Settings::__construct() 26 | 27 | Constructor 28 | 29 | 30 | 31 | * Visibility: **protected** 32 | 33 | 34 | 35 | 36 | ### register_hook_callbacks 37 | 38 | mixed Plugin_Name\App\Models\Admin\Base_Model::register_hook_callbacks() 39 | 40 | Register callbacks for actions and filters. Most of your add_action/add_filter 41 | go into this method. 42 | 43 | NOTE: register_hook_callbacks method is not called automatically. You 44 | as a developer have to call this method where you see fit. For Example, 45 | You may want to call this in constructor, if you feel hooks/filters 46 | callbacks should be registered when the new instance of the class 47 | is created. 48 | 49 | The purpose of this method is to set the convention that first place to 50 | find add_action/add_filter is register_hook_callbacks method. 51 | 52 | This method is not marked abstract because it may not be needed in every 53 | model. Making it abstract would enforce every child class to implement 54 | the method. 55 | 56 | If I were you, I would define register_hook_callbacks method in the child 57 | class when it is a 'Model only' route. This is not a rule, it 58 | is just my opinion when I would define this method. 59 | 60 | * Visibility: **protected** 61 | * This method is defined by [Plugin_Name\App\Models\Admin\Base_Model](Plugin_Name-App-Models-Admin-Base_Model.md) 62 | 63 | 64 | 65 | 66 | ### register_settings 67 | 68 | mixed Plugin_Name\App\Models\Admin\Admin_Settings::register_settings() 69 | 70 | Register settings 71 | 72 | 73 | 74 | * Visibility: **public** 75 | 76 | 77 | 78 | 79 | ### sanitize 80 | 81 | array Plugin_Name\App\Models\Admin\Admin_Settings::sanitize(array $input) 82 | 83 | Validates submitted setting values before they get saved to the database. 84 | 85 | 86 | 87 | * Visibility: **public** 88 | 89 | 90 | #### Arguments 91 | * $input **array** - <p>Settings Being Saved.</p> 92 | 93 | 94 | 95 | ### get_plugin_settings_option_key 96 | 97 | string Plugin_Name\App\Models\Admin\Admin_Settings::get_plugin_settings_option_key() 98 | 99 | Returns the option key used to store the settings in database 100 | 101 | 102 | 103 | * Visibility: **public** 104 | 105 | 106 | 107 | 108 | ### get_setting 109 | 110 | array Plugin_Name\App\Models\Admin\Admin_Settings::get_setting(string $setting_name) 111 | 112 | Retrieves all of the settings from the database 113 | 114 | 115 | 116 | * Visibility: **public** 117 | 118 | 119 | #### Arguments 120 | * $setting_name **string** - <p>Setting to be retrieved.</p> 121 | 122 | 123 | 124 | ### get_instance 125 | 126 | object Plugin_Name\Core\Model::get_instance() 127 | 128 | Provides access to a single instance of a module using the singleton pattern 129 | 130 | 131 | 132 | * Visibility: **public** 133 | * This method is **static**. 134 | * This method is defined by [Plugin_Name\Core\Model](Plugin_Name-Core-Model.md) 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Models-Admin-Base_Model.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Models\Admin\Base_Model 2 | =============== 3 | 4 | Blueprint for Admin related Models. All Admin Models should extend this Base_Model 5 | 6 | 7 | 8 | 9 | * Class name: Base_Model 10 | * Namespace: Plugin_Name\App\Models\Admin 11 | * This is an **abstract** class 12 | * Parent class: [Plugin_Name\Core\Model](Plugin_Name-Core-Model.md) 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Methods 21 | ------- 22 | 23 | 24 | ### register_hook_callbacks 25 | 26 | mixed Plugin_Name\App\Models\Admin\Base_Model::register_hook_callbacks() 27 | 28 | Register callbacks for actions and filters. Most of your add_action/add_filter 29 | go into this method. 30 | 31 | NOTE: register_hook_callbacks method is not called automatically. You 32 | as a developer have to call this method where you see fit. For Example, 33 | You may want to call this in constructor, if you feel hooks/filters 34 | callbacks should be registered when the new instance of the class 35 | is created. 36 | 37 | The purpose of this method is to set the convention that first place to 38 | find add_action/add_filter is register_hook_callbacks method. 39 | 40 | This method is not marked abstract because it may not be needed in every 41 | model. Making it abstract would enforce every child class to implement 42 | the method. 43 | 44 | If I were you, I would define register_hook_callbacks method in the child 45 | class when it is a 'Model only' route. This is not a rule, it 46 | is just my opinion when I would define this method. 47 | 48 | * Visibility: **protected** 49 | 50 | 51 | 52 | 53 | ### get_instance 54 | 55 | object Plugin_Name\Core\Model::get_instance() 56 | 57 | Provides access to a single instance of a module using the singleton pattern 58 | 59 | 60 | 61 | * Visibility: **public** 62 | * This method is **static**. 63 | * This method is defined by [Plugin_Name\Core\Model](Plugin_Name-Core-Model.md) 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Models-Frontend-Base_Model.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Models\Frontend\Base_Model 2 | =============== 3 | 4 | Blueprint for Frontend related Models. All Frontend Models should extend this Base_Model 5 | 6 | 7 | 8 | 9 | * Class name: Base_Model 10 | * Namespace: Plugin_Name\App\Models\Frontend 11 | * This is an **abstract** class 12 | * Parent class: [Plugin_Name\Core\Model](Plugin_Name-Core-Model.md) 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Methods 21 | ------- 22 | 23 | 24 | ### register_hook_callbacks 25 | 26 | mixed Plugin_Name\App\Models\Frontend\Base_Model::register_hook_callbacks() 27 | 28 | Register callbacks for actions and filters. Most of your add_action/add_filter 29 | go into this method. 30 | 31 | NOTE: register_hook_callbacks method is not called automatically. You 32 | as a developer have to call this method where you see fit. For Example, 33 | You may want to call this in constructor, if you feel hooks/filters 34 | callbacks should be registered when the new instance of the class 35 | is created. 36 | 37 | The purpose of this method is to set the convention that first place to 38 | find add_action/add_filter is register_hook_callbacks method. 39 | 40 | This method is not marked abstract because it may not be needed in every 41 | model. Making it abstract would enforce every child class to implement 42 | the method. 43 | 44 | If I were you, I would define register_hook_callbacks method in the child 45 | class when it is a 'Model only' route. This is not hard & fast rule, it 46 | is just my opinion when I would define this method. 47 | 48 | * Visibility: **protected** 49 | 50 | 51 | 52 | 53 | ### get_instance 54 | 55 | object Plugin_Name\Core\Model::get_instance() 56 | 57 | Provides access to a single instance of a module using the singleton pattern 58 | 59 | 60 | 61 | * Visibility: **public** 62 | * This method is **static**. 63 | * This method is defined by [Plugin_Name\Core\Model](Plugin_Name-Core-Model.md) 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Models-Settings.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Models\Settings 2 | =============== 3 | 4 | Implements operations related to Plugin Settings. 5 | 6 | 7 | 8 | 9 | * Class name: Settings 10 | * Namespace: Plugin_Name\App\Models 11 | * Parent class: [Plugin_Name\Core\Model](Plugin_Name-Core-Model.md) 12 | 13 | 14 | 15 | Constants 16 | ---------- 17 | 18 | 19 | ### SETTINGS_NAME 20 | 21 | const SETTINGS_NAME = \Plugin_Name::PLUGIN_ID 22 | 23 | 24 | 25 | 26 | 27 | Properties 28 | ---------- 29 | 30 | 31 | ### $settings 32 | 33 | protected array $settings 34 | 35 | Holds all Settings 36 | 37 | 38 | 39 | * Visibility: **protected** 40 | * This property is **static**. 41 | 42 | 43 | Methods 44 | ------- 45 | 46 | 47 | ### get_plugin_settings_option_key 48 | 49 | string Plugin_Name\App\Models\Settings::get_plugin_settings_option_key() 50 | 51 | Returns the Option name/key saved in the database 52 | 53 | 54 | 55 | * Visibility: **public** 56 | * This method is **static**. 57 | 58 | 59 | 60 | 61 | ### get_settings 62 | 63 | array Plugin_Name\App\Models\Settings::get_settings() 64 | 65 | Helper method that retuns all Saved Settings related to Plugin 66 | 67 | 68 | 69 | * Visibility: **public** 70 | * This method is **static**. 71 | 72 | 73 | 74 | 75 | ### get_setting 76 | 77 | mixed Plugin_Name\App\Models\Settings::get_setting(string $setting_name) 78 | 79 | Helper method that returns a individual setting 80 | 81 | 82 | 83 | * Visibility: **public** 84 | * This method is **static**. 85 | 86 | 87 | #### Arguments 88 | * $setting_name **string** - <p>Setting to be retrieved.</p> 89 | 90 | 91 | 92 | ### delete_settings 93 | 94 | void Plugin_Name\App\Models\Settings::delete_settings() 95 | 96 | Helper method to delete all settings related to plugin 97 | 98 | 99 | 100 | * Visibility: **public** 101 | * This method is **static**. 102 | 103 | 104 | 105 | 106 | ### delete_setting 107 | 108 | void Plugin_Name\App\Models\Settings::delete_setting(string $setting_name) 109 | 110 | Helper method to delete a specific setting 111 | 112 | 113 | 114 | * Visibility: **public** 115 | * This method is **static**. 116 | 117 | 118 | #### Arguments 119 | * $setting_name **string** - <p>Setting to be Deleted.</p> 120 | 121 | 122 | 123 | ### update_settings 124 | 125 | void Plugin_Name\App\Models\Settings::update_settings(array $new_settings) 126 | 127 | Helper method to Update Settings 128 | 129 | 130 | 131 | * Visibility: **public** 132 | * This method is **static**. 133 | 134 | 135 | #### Arguments 136 | * $new_settings **array** - <p>New Setting Values to store.</p> 137 | 138 | 139 | 140 | ### update_setting 141 | 142 | void Plugin_Name\App\Models\Settings::update_setting(string $setting_name, mixed $setting_value) 143 | 144 | Helper method Update Single Setting 145 | 146 | Similar to update_settings, this function won't by called anywhere automatically. 147 | This is a custom helper function to delete individual setting. You can 148 | delete this method if you don't want this ability. 149 | 150 | * Visibility: **public** 151 | * This method is **static**. 152 | 153 | 154 | #### Arguments 155 | * $setting_name **string** - <p>Setting to be Updated.</p> 156 | * $setting_value **mixed** - <p>New value to set for that setting.</p> 157 | 158 | 159 | 160 | ### get_instance 161 | 162 | object Plugin_Name\Core\Model::get_instance() 163 | 164 | Provides access to a single instance of a module using the singleton pattern 165 | 166 | 167 | 168 | * Visibility: **public** 169 | * This method is **static**. 170 | * This method is defined by [Plugin_Name\Core\Model](Plugin_Name-Core-Model.md) 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Uninstaller.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Uninstaller 2 | =============== 3 | 4 | Fired during plugin uninstallation. 5 | 6 | This class defines all code necessary to run during the plugin's uninstallation. 7 | 8 | 9 | * Class name: Uninstaller 10 | * Namespace: Plugin_Name\App 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Methods 19 | ------- 20 | 21 | 22 | ### uninstall 23 | 24 | mixed Plugin_Name\App\Uninstaller::uninstall() 25 | 26 | Short Description. (use period) 27 | 28 | Long Description. 29 | 30 | * Visibility: **public** 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-App-Views-Admin-Admin_Settings.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\App\Views\Admin\Admin_Settings 2 | =============== 3 | 4 | View class to load all templates related to Plugin's Admin Settings Page 5 | 6 | 7 | 8 | 9 | * Class name: Admin_Settings 10 | * Namespace: Plugin_Name\App\Views\Admin 11 | * Parent class: [Plugin_Name\Core\View](Plugin_Name-Core-View.md) 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Methods 20 | ------- 21 | 22 | 23 | ### admin_settings_page 24 | 25 | void Plugin_Name\App\Views\Admin\Admin_Settings::admin_settings_page(array $args) 26 | 27 | Prints Settings Page. 28 | 29 | 30 | 31 | * Visibility: **public** 32 | 33 | 34 | #### Arguments 35 | * $args **array** - <p>Arguments passed by <code>markup_settings_page</code> method from <code>Plugin_Name\App\Controllers\Admin\Admin_Settings</code> controller.</p> 36 | 37 | 38 | 39 | ### section_headers 40 | 41 | void Plugin_Name\App\Views\Admin\Admin_Settings::section_headers(array $args) 42 | 43 | Prints Section's Description. 44 | 45 | 46 | 47 | * Visibility: **public** 48 | 49 | 50 | #### Arguments 51 | * $args **array** - <p>Arguments passed by <code>markup_section_headers</code> method from <code>Plugin_Name\App\Controllers\Admin\Admin_Settings</code> controller.</p> 52 | 53 | 54 | 55 | ### markup_fields 56 | 57 | void Plugin_Name\App\Views\Admin\Admin_Settings::markup_fields(array $args) 58 | 59 | Prints text field 60 | 61 | 62 | 63 | * Visibility: **public** 64 | 65 | 66 | #### Arguments 67 | * $args **array** - <p>Arguments passed by <code>markup_fields</code> method from <code>Plugin_Name\App\Controllers\Admin\Admin_Settings</code> controller.</p> 68 | 69 | 70 | 71 | ### render_template 72 | 73 | void Plugin_Name\Core\View::render_template(mixed $template_name, array $args, string $template_path, string $default_path) 74 | 75 | Render Templates 76 | 77 | 78 | 79 | * Visibility: **public** 80 | * This method is **static**. 81 | * This method is defined by [Plugin_Name\Core\View](Plugin_Name-Core-View.md) 82 | 83 | 84 | #### Arguments 85 | * $template_name **mixed** - <p>Template file to render.</p> 86 | * $args **array** - <p>Variables to make available inside template file.</p> 87 | * $template_path **string** - <p>Directory to search for template.</p> 88 | * $default_path **string** - <p>Fallback directory to search for template if not found at $template_path.</p> 89 | 90 | 91 | 92 | ### locate_template 93 | 94 | string Plugin_Name\Core\View::locate_template(mixed $template_name, string $template_path, string $default_path) 95 | 96 | Locate a template and return the path for inclusion. 97 | 98 | This is the load order: 99 | 100 | yourtheme / $template_path / $template_name 101 | yourtheme / $template_name 102 | $default_path / $template_name 103 | 104 | * Visibility: **public** 105 | * This method is **static**. 106 | * This method is defined by [Plugin_Name\Core\View](Plugin_Name-Core-View.md) 107 | 108 | 109 | #### Arguments 110 | * $template_name **mixed** - <p>Template file to locate.</p> 111 | * $template_path **string** - <p>$template_path Directory to search for template.</p> 112 | * $default_path **string** - <p>Fallback directory to search for template if not found at $template_path.</p> 113 | 114 | 115 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-Core-Controller.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\Core\Controller 2 | =============== 3 | 4 | Abstract class to define/implement base methods for all controller classes 5 | 6 | 7 | 8 | 9 | * Class name: Controller 10 | * Namespace: Plugin_Name\Core 11 | * This is an **abstract** class 12 | 13 | 14 | 15 | 16 | 17 | Properties 18 | ---------- 19 | 20 | 21 | ### $model 22 | 23 | protected Object $model 24 | 25 | Holds Model object 26 | 27 | 28 | 29 | * Visibility: **protected** 30 | 31 | 32 | ### $view 33 | 34 | protected Object $view 35 | 36 | Holds View Object 37 | 38 | 39 | 40 | * Visibility: **protected** 41 | 42 | 43 | Methods 44 | ------- 45 | 46 | 47 | ### get_instance 48 | 49 | object Plugin_Name\Core\Controller::get_instance(mixed $model_class_name, mixed $view_class_name) 50 | 51 | Provides access to a single instance of a module using the singleton pattern 52 | 53 | 54 | 55 | * Visibility: **public** 56 | * This method is **static**. 57 | 58 | 59 | #### Arguments 60 | * $model_class_name **mixed** - <p>Model Class to be associated with the controller.</p> 61 | * $view_class_name **mixed** - <p>View Class to be associated with the controller.</p> 62 | 63 | 64 | 65 | ### get_model 66 | 67 | object Plugin_Name\Core\Controller::get_model() 68 | 69 | Get model. 70 | 71 | In most of the cases, the model will be set as per routes in defined in routes.php. 72 | So if you are not sure which model class is currently being used, search for the 73 | current controller class name in the routes.php 74 | 75 | * Visibility: **protected** 76 | 77 | 78 | 79 | 80 | ### get_view 81 | 82 | object Plugin_Name\Core\Controller::get_view() 83 | 84 | Get view 85 | 86 | In most of the cases, the view will be set as per routes in defined in routes.php. 87 | So if you are not sure which view class is currently being used, search for the 88 | current controller class name in the routes.php 89 | 90 | * Visibility: **protected** 91 | 92 | 93 | 94 | 95 | ### set_model 96 | 97 | void Plugin_Name\Core\Controller::set_model(\Plugin_Name\Core\Model $model) 98 | 99 | Sets the model to be used 100 | 101 | 102 | 103 | * Visibility: **protected** 104 | 105 | 106 | #### Arguments 107 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model object to be associated with the current controller object.</p> 108 | 109 | 110 | 111 | ### set_view 112 | 113 | void Plugin_Name\Core\Controller::set_view(\Plugin_Name\Core\View $view) 114 | 115 | Sets the view to be used 116 | 117 | 118 | 119 | * Visibility: **protected** 120 | 121 | 122 | #### Arguments 123 | * $view **[Plugin_Name\Core\View](Plugin_Name-Core-View.md)** - <p>View object to be associated with the current controller object.</p> 124 | 125 | 126 | 127 | ### __construct 128 | 129 | mixed Plugin_Name\Core\Controller::__construct(\Plugin_Name\Core\Model $model, mixed $view) 130 | 131 | Constructor 132 | 133 | 134 | 135 | * Visibility: **protected** 136 | 137 | 138 | #### Arguments 139 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model object to be used with current controller object.</p> 140 | * $view **mixed** - <p>View object to be used with current controller object. Otherwise false.</p> 141 | 142 | 143 | 144 | ### init 145 | 146 | void Plugin_Name\Core\Controller::init(\Plugin_Name\Core\Model $model, mixed $view) 147 | 148 | Sets Model & View to be used with current controller 149 | 150 | 151 | 152 | * Visibility: **protected** 153 | 154 | 155 | #### Arguments 156 | * $model **[Plugin_Name\Core\Model](Plugin_Name-Core-Model.md)** - <p>Model to be associated with this controller.</p> 157 | * $view **mixed** - <p>Either View/its child class object or False.</p> 158 | 159 | 160 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-Core-Model.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\Core\Model 2 | =============== 3 | 4 | Abstract class to define/implement base methods for model classes 5 | 6 | 7 | 8 | 9 | * Class name: Model 10 | * Namespace: Plugin_Name\Core 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Methods 19 | ------- 20 | 21 | 22 | ### get_instance 23 | 24 | object Plugin_Name\Core\Model::get_instance() 25 | 26 | Provides access to a single instance of a module using the singleton pattern 27 | 28 | 29 | 30 | * Visibility: **public** 31 | * This method is **static**. 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-Core-Registry-Controller.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\Core\Registry\Controller 2 | =============== 3 | 4 | Controller Registry 5 | 6 | Maintains the list of all controllers objects 7 | 8 | 9 | * Class name: Controller 10 | * Namespace: Plugin_Name\Core\Registry 11 | 12 | 13 | 14 | 15 | 16 | Properties 17 | ---------- 18 | 19 | 20 | ### $stored_objects 21 | 22 | protected array $stored_objects = array() 23 | 24 | Variable that holds all objects in registry. 25 | 26 | 27 | 28 | * Visibility: **protected** 29 | * This property is **static**. 30 | 31 | 32 | Methods 33 | ------- 34 | 35 | 36 | ### get_key 37 | 38 | string Plugin_Name\Core\Registry\Controller::get_key(string $controller_class_name, string $model_class_name, string $view_class_name) 39 | 40 | Returns key used to store a particular Controller Object 41 | 42 | 43 | 44 | * Visibility: **public** 45 | * This method is **static**. 46 | 47 | 48 | #### Arguments 49 | * $controller_class_name **string** - <p>Controller Class Name.</p> 50 | * $model_class_name **string** - <p>Model Class Name.</p> 51 | * $view_class_name **string** - <p>View Class Name.</p> 52 | 53 | 54 | 55 | ### set 56 | 57 | void Plugin_Name\Core\Registry\Controller::set(string $key, mixed $value) 58 | 59 | Add object to registry 60 | 61 | 62 | 63 | * Visibility: **public** 64 | * This method is **static**. 65 | 66 | 67 | #### Arguments 68 | * $key **string** - <p>Key to be used to map with Object.</p> 69 | * $value **mixed** - <p>Object to Store.</p> 70 | 71 | 72 | 73 | ### get 74 | 75 | mixed Plugin_Name\Core\Registry\Controller::get(string $key) 76 | 77 | Get object from registry 78 | 79 | 80 | 81 | * Visibility: **public** 82 | * This method is **static**. 83 | 84 | 85 | #### Arguments 86 | * $key **string** - <p>Key of the object to restore.</p> 87 | 88 | 89 | 90 | ### get_all_objects 91 | 92 | array Plugin_Name\Core\Registry\Controller::get_all_objects() 93 | 94 | Returns all objects 95 | 96 | 97 | 98 | * Visibility: **public** 99 | * This method is **static**. 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-Core-Registry-Model.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\Core\Registry\Model 2 | =============== 3 | 4 | Model Registry 5 | 6 | Maintains the list of all models objects 7 | 8 | 9 | * Class name: Model 10 | * Namespace: Plugin_Name\Core\Registry 11 | 12 | 13 | 14 | 15 | 16 | Properties 17 | ---------- 18 | 19 | 20 | ### $stored_objects 21 | 22 | protected array $stored_objects = array() 23 | 24 | Variable that holds all objects in registry. 25 | 26 | 27 | 28 | * Visibility: **protected** 29 | * This property is **static**. 30 | 31 | 32 | Methods 33 | ------- 34 | 35 | 36 | ### set 37 | 38 | void Plugin_Name\Core\Registry\Model::set(string $key, mixed $value) 39 | 40 | Add object to registry 41 | 42 | 43 | 44 | * Visibility: **public** 45 | * This method is **static**. 46 | 47 | 48 | #### Arguments 49 | * $key **string** - <p>Key to be used to map with Object.</p> 50 | * $value **mixed** - <p>Object to Store.</p> 51 | 52 | 53 | 54 | ### get 55 | 56 | mixed Plugin_Name\Core\Registry\Model::get(string $key) 57 | 58 | Get object from registry 59 | 60 | 61 | 62 | * Visibility: **public** 63 | * This method is **static**. 64 | 65 | 66 | #### Arguments 67 | * $key **string** - <p>Key of the object to restore.</p> 68 | 69 | 70 | 71 | ### get_all_objects 72 | 73 | array Plugin_Name\Core\Registry\Model::get_all_objects() 74 | 75 | Returns all objects 76 | 77 | 78 | 79 | * Visibility: **public** 80 | * This method is **static**. 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-Core-Route_Type.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\Core\Route_Type 2 | =============== 3 | 4 | Class Responsible for registering Route Types supported by the Application 5 | 6 | 7 | 8 | 9 | * Class name: Route_Type 10 | * Namespace: Plugin_Name\Core 11 | 12 | 13 | 14 | Constants 15 | ---------- 16 | 17 | 18 | ### ANY 19 | 20 | const ANY = 'any' 21 | 22 | 23 | 24 | 25 | 26 | ### ADMIN 27 | 28 | const ADMIN = 'admin' 29 | 30 | 31 | 32 | 33 | 34 | ### ADMIN_WITH_POSSIBLE_AJAX 35 | 36 | const ADMIN_WITH_POSSIBLE_AJAX = 'admin_with_possible_ajax' 37 | 38 | 39 | 40 | 41 | 42 | ### AJAX 43 | 44 | const AJAX = 'ajax' 45 | 46 | 47 | 48 | 49 | 50 | ### CRON 51 | 52 | const CRON = 'cron' 53 | 54 | 55 | 56 | 57 | 58 | ### FRONTEND 59 | 60 | const FRONTEND = 'frontend' 61 | 62 | 63 | 64 | 65 | 66 | ### FRONTEND_WITH_POSSIBLE_AJAX 67 | 68 | const FRONTEND_WITH_POSSIBLE_AJAX = 'frontend_with_possible_ajax' 69 | 70 | 71 | 72 | 73 | 74 | ### LATE_FRONTEND 75 | 76 | const LATE_FRONTEND = 'late_frontend' 77 | 78 | 79 | 80 | 81 | 82 | ### LATE_FRONTEND_WITH_POSSIBLE_AJAX 83 | 84 | const LATE_FRONTEND_WITH_POSSIBLE_AJAX = 'late_frontend_with_possible_ajax' 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-Core-Router.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\Core\Router 2 | =============== 3 | 4 | Class Responsible for registering Routes 5 | 6 | 7 | 8 | 9 | * Class name: Router 10 | * Namespace: Plugin_Name\Core 11 | 12 | 13 | 14 | Constants 15 | ---------- 16 | 17 | 18 | ### REGISTER_LATE_FRONTEND_ROUTES 19 | 20 | const REGISTER_LATE_FRONTEND_ROUTES = true 21 | 22 | 23 | 24 | 25 | 26 | Properties 27 | ---------- 28 | 29 | 30 | ### $models 31 | 32 | private array $models = array() 33 | 34 | Holds List of Models used for 'Model Only' Routes 35 | 36 | 37 | 38 | * Visibility: **private** 39 | * This property is **static**. 40 | 41 | 42 | ### $mvc_components 43 | 44 | private array $mvc_components = array() 45 | 46 | Holds Model, View & Controllers triad for All routes except 'Model Only' Routes 47 | 48 | 49 | 50 | * Visibility: **private** 51 | * This property is **static**. 52 | 53 | 54 | Methods 55 | ------- 56 | 57 | 58 | ### __construct 59 | 60 | mixed Plugin_Name\Core\Router::__construct() 61 | 62 | Constructor 63 | 64 | 65 | 66 | * Visibility: **public** 67 | 68 | 69 | 70 | 71 | ### register_hook_callbacks 72 | 73 | mixed Plugin_Name\Core\Router::register_hook_callbacks() 74 | 75 | Register callbacks for actions and filters 76 | 77 | 78 | 79 | * Visibility: **protected** 80 | 81 | 82 | 83 | 84 | ### register_generic_model_only_routes 85 | 86 | void Plugin_Name\Core\Router::register_generic_model_only_routes() 87 | 88 | Register Generic `Model Only` Routes 89 | 90 | 91 | 92 | * Visibility: **public** 93 | 94 | 95 | 96 | 97 | ### register_late_frontend_model_only_routes 98 | 99 | void Plugin_Name\Core\Router::register_late_frontend_model_only_routes() 100 | 101 | Register Late Frontend `Model Only` Routes 102 | 103 | 104 | 105 | * Visibility: **public** 106 | 107 | 108 | 109 | 110 | ### register_generic_routes 111 | 112 | void Plugin_Name\Core\Router::register_generic_routes() 113 | 114 | Register Generic Routes 115 | 116 | 117 | 118 | * Visibility: **public** 119 | 120 | 121 | 122 | 123 | ### register_late_frontend_routes 124 | 125 | void Plugin_Name\Core\Router::register_late_frontend_routes() 126 | 127 | Register Late Frontend Routes 128 | 129 | 130 | 131 | * Visibility: **public** 132 | 133 | 134 | 135 | 136 | ### generic_route_types 137 | 138 | array Plugin_Name\Core\Router::generic_route_types() 139 | 140 | Returns List of commonly/mostly used Route types 141 | 142 | 143 | 144 | * Visibility: **public** 145 | 146 | 147 | 148 | 149 | ### late_frontend_route_types 150 | 151 | array Plugin_Name\Core\Router::late_frontend_route_types() 152 | 153 | Returns list of Route types belonging to Frontend but registered late 154 | 155 | 156 | 157 | * Visibility: **public** 158 | 159 | 160 | 161 | 162 | ### register_route_of_type 163 | 164 | \Plugin_Name\Core\Router Plugin_Name\Core\Router::register_route_of_type(string $type) 165 | 166 | Type of Route to be registered. Every time a new route needs to be 167 | registered, this function should be called first on `$route` object 168 | 169 | 170 | 171 | * Visibility: **public** 172 | 173 | 174 | #### Arguments 175 | * $type **string** - <p>Type of route to be registered.</p> 176 | 177 | 178 | 179 | ### with_just_model 180 | 181 | mixed Plugin_Name\Core\Router::with_just_model(mixed $model) 182 | 183 | Enqueues a model to be associated with the Model only` Route 184 | 185 | 186 | 187 | * Visibility: **public** 188 | 189 | 190 | #### Arguments 191 | * $model **mixed** - <p>Model to be associated with the Route. Could be String or callback.</p> 192 | 193 | 194 | 195 | ### build_controller_unique_id 196 | 197 | string Plugin_Name\Core\Router::build_controller_unique_id(mixed $controller) 198 | 199 | Generates a Unique id for each controller 200 | 201 | This unique id is used as an array key inside mvc_components array which 202 | is used while enqueueing models and views to associate them with the 203 | controller. 204 | 205 | * Visibility: **public** 206 | 207 | 208 | #### Arguments 209 | * $controller **mixed** - <p>Controller to be associated with the Route. Could be String or callback.</p> 210 | 211 | 212 | 213 | ### with_controller 214 | 215 | object Plugin_Name\Core\Router::with_controller(mixed $controller) 216 | 217 | Enqueues a controller to be associated with the Route 218 | 219 | 220 | 221 | * Visibility: **public** 222 | 223 | 224 | #### Arguments 225 | * $controller **mixed** - <p>Controller to be associated with the Route. Could be String or callback.</p> 226 | 227 | 228 | 229 | ### with_model 230 | 231 | object Plugin_Name\Core\Router::with_model(mixed $model) 232 | 233 | Enqueues a model to be associated with the Route 234 | 235 | The object of this model is passed to controller. 236 | 237 | * Visibility: **public** 238 | 239 | 240 | #### Arguments 241 | * $model **mixed** - <p>Model to be associated with the Route. Could be String or callback.</p> 242 | 243 | 244 | 245 | ### with_view 246 | 247 | object Plugin_Name\Core\Router::with_view(mixed $view) 248 | 249 | Registers view with the Route. The object of this view is passed to controller 250 | 251 | 252 | 253 | * Visibility: **public** 254 | 255 | 256 | #### Arguments 257 | * $view **mixed** - <p>View to be associated with the Route. Could be String or callback.</p> 258 | 259 | 260 | 261 | ### register_routes 262 | 263 | void Plugin_Name\Core\Router::register_routes(boolean $register_late_frontend_routes) 264 | 265 | Registers Enqueued Routes 266 | 267 | 268 | 269 | * Visibility: **private** 270 | 271 | 272 | #### Arguments 273 | * $register_late_frontend_routes **boolean** - <p>Whether to register late frontend routes.</p> 274 | 275 | 276 | 277 | ### dispatch 278 | 279 | void Plugin_Name\Core\Router::dispatch(array $mvc_component, string $route_type) 280 | 281 | Dispatches the route of specified $route_type by creating a controller object 282 | 283 | 284 | 285 | * Visibility: **private** 286 | 287 | 288 | #### Arguments 289 | * $mvc_component **array** - <p>Model-View-Controller triads for all registered routes.</p> 290 | * $route_type **string** - <p>Route Type.</p> 291 | 292 | 293 | 294 | ### register_model_only_routes 295 | 296 | void Plugin_Name\Core\Router::register_model_only_routes(boolean $register_late_frontend_routes) 297 | 298 | Registers `Model Only` Enqueued Routes 299 | 300 | 301 | 302 | * Visibility: **public** 303 | 304 | 305 | #### Arguments 306 | * $register_late_frontend_routes **boolean** - <p>Whether to register late frontend routes.</p> 307 | 308 | 309 | 310 | ### dispatch_only_model 311 | 312 | void Plugin_Name\Core\Router::dispatch_only_model(mixed $model, string $route_type) 313 | 314 | Dispatches the model only route by creating a Model object 315 | 316 | 317 | 318 | * Visibility: **private** 319 | 320 | 321 | #### Arguments 322 | * $model **mixed** - <p>Model to be associated with the Route. Could be String or callback.</p> 323 | * $route_type **string** - <p>Route Type.</p> 324 | 325 | 326 | 327 | ### get_fully_qualified_class_name 328 | 329 | string Plugin_Name\Core\Router::get_fully_qualified_class_name(string $class, string $mvc_component_type, string $route_type) 330 | 331 | Returns the Full Qualified Class Name for given class name 332 | 333 | 334 | 335 | * Visibility: **private** 336 | 337 | 338 | #### Arguments 339 | * $class **string** - <p>Class whose FQCN needs to be found out.</p> 340 | * $mvc_component_type **string** - <p>Could be between 'model', 'view' or 'controller'.</p> 341 | * $route_type **string** - <p>Could be 'admin' or 'frontend'.</p> 342 | 343 | 344 | 345 | ### is_request 346 | 347 | boolean Plugin_Name\Core\Router::is_request(string $route_type) 348 | 349 | Identifies Request Type 350 | 351 | 352 | 353 | * Visibility: **private** 354 | 355 | 356 | #### Arguments 357 | * $route_type **string** - <p>Route Type to identify.</p> 358 | 359 | 360 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-Core-View.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\Core\View 2 | =============== 3 | 4 | Class Responsible for Loading Templates 5 | 6 | 7 | 8 | 9 | * Class name: View 10 | * Namespace: Plugin_Name\Core 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Methods 19 | ------- 20 | 21 | 22 | ### render_template 23 | 24 | void Plugin_Name\Core\View::render_template(mixed $template_name, array $args, string $template_path, string $default_path) 25 | 26 | Render Templates 27 | 28 | 29 | 30 | * Visibility: **public** 31 | * This method is **static**. 32 | 33 | 34 | #### Arguments 35 | * $template_name **mixed** - <p>Template file to render.</p> 36 | * $args **array** - <p>Variables to make available inside template file.</p> 37 | * $template_path **string** - <p>Directory to search for template.</p> 38 | * $default_path **string** - <p>Fallback directory to search for template if not found at $template_path.</p> 39 | 40 | 41 | 42 | ### locate_template 43 | 44 | string Plugin_Name\Core\View::locate_template(mixed $template_name, string $template_path, string $default_path) 45 | 46 | Locate a template and return the path for inclusion. 47 | 48 | This is the load order: 49 | 50 | yourtheme / $template_path / $template_name 51 | yourtheme / $template_name 52 | $default_path / $template_name 53 | 54 | * Visibility: **public** 55 | * This method is **static**. 56 | 57 | 58 | #### Arguments 59 | * $template_name **mixed** - <p>Template file to locate.</p> 60 | * $template_path **string** - <p>$template_path Directory to search for template.</p> 61 | * $default_path **string** - <p>Fallback directory to search for template if not found at $template_path.</p> 62 | 63 | 64 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-Includes-Dependency_Loader.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\Includes\Dependency_Loader 2 | =============== 3 | 4 | Includes all methods required for loading Plugin Dependencies 5 | 6 | 7 | 8 | 9 | * Class name: Dependency_Loader 10 | * Namespace: Plugin_Name\Includes 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Methods 19 | ------- 20 | 21 | 22 | ### load_dependencies 23 | 24 | mixed Plugin_Name\Includes\Dependency_Loader::load_dependencies(string $class) 25 | 26 | Loads all Plugin dependencies 27 | 28 | Converts Class parameter passed to the method into the file path & then 29 | `require_once` that path. It works with Class as well as with Traits. 30 | 31 | * Visibility: **public** 32 | 33 | 34 | #### Arguments 35 | * $class **string** - <p>Class need to be loaded.</p> 36 | 37 | 38 | 39 | ### load_registries 40 | 41 | void Plugin_Name\Includes\Dependency_Loader::load_registries() 42 | 43 | Load All Registry Class Files 44 | 45 | 46 | 47 | * Visibility: **protected** 48 | 49 | 50 | 51 | 52 | ### load_core 53 | 54 | void Plugin_Name\Includes\Dependency_Loader::load_core() 55 | 56 | Load Core MVC Classes 57 | 58 | 59 | 60 | * Visibility: **protected** 61 | 62 | 63 | 64 | 65 | ### autoload_dependencies 66 | 67 | mixed Plugin_Name\Includes\Dependency_Loader::autoload_dependencies() 68 | 69 | Method responsible to call all the dependencies 70 | 71 | 72 | 73 | * Visibility: **protected** 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-Includes-Requirements_Checker.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\Includes\Requirements_Checker 2 | =============== 3 | 4 | Checks whether plugin's requirements are being met or not 5 | 6 | 7 | 8 | 9 | * Class name: Requirements_Checker 10 | * Namespace: Plugin_Name\Includes 11 | 12 | 13 | 14 | 15 | 16 | Properties 17 | ---------- 18 | 19 | 20 | ### $min_php_version 21 | 22 | private string $min_php_version = '5.6' 23 | 24 | Holds minimum php version for plugin if not defined in `requirements.php`. 25 | 26 | 27 | 28 | * Visibility: **private** 29 | 30 | 31 | ### $min_wp_version 32 | 33 | private string $min_wp_version = '4.8' 34 | 35 | Holds minimum wp version for plugin if not defined in `requirements.php`. 36 | 37 | 38 | 39 | * Visibility: **private** 40 | 41 | 42 | ### $is_multisite_compatible 43 | 44 | private boolean $is_multisite_compatible = false 45 | 46 | Holds the information whether plugin is compatible with Multisite or not. 47 | 48 | 49 | 50 | * Visibility: **private** 51 | 52 | 53 | ### $required_plugins 54 | 55 | private array $required_plugins = array() 56 | 57 | Holds list of required plugins to be installed and active for our plugin to work 58 | 59 | 60 | 61 | * Visibility: **private** 62 | 63 | 64 | ### $errors 65 | 66 | private array $errors = array() 67 | 68 | Holds Error messages if dependencies are not met 69 | 70 | 71 | 72 | * Visibility: **private** 73 | 74 | 75 | Methods 76 | ------- 77 | 78 | 79 | ### __construct 80 | 81 | mixed Plugin_Name\Includes\Requirements_Checker::__construct(array $requirements_data) 82 | 83 | Constructor 84 | 85 | 86 | 87 | * Visibility: **public** 88 | 89 | 90 | #### Arguments 91 | * $requirements_data **array** - <p>Requirements Data mentioned in <code>requirements.php</code>.</p> 92 | 93 | 94 | 95 | ### is_php_version_dependency_met 96 | 97 | boolean Plugin_Name\Includes\Requirements_Checker::is_php_version_dependency_met() 98 | 99 | Checks if Installed PHP Version is higher than required PHP Version 100 | 101 | 102 | 103 | * Visibility: **private** 104 | 105 | 106 | 107 | 108 | ### is_wp_version_dependency_met 109 | 110 | boolean Plugin_Name\Includes\Requirements_Checker::is_wp_version_dependency_met() 111 | 112 | Checks if Installed WP Version is higher than required WP Version 113 | 114 | 115 | 116 | * Visibility: **private** 117 | 118 | 119 | 120 | 121 | ### is_wp_multisite_dependency_met 122 | 123 | boolean Plugin_Name\Includes\Requirements_Checker::is_wp_multisite_dependency_met() 124 | 125 | Checks if Multisite Dependencies are met 126 | 127 | 128 | 129 | * Visibility: **private** 130 | 131 | 132 | 133 | 134 | ### is_plugin_active 135 | 136 | boolean Plugin_Name\Includes\Requirements_Checker::is_plugin_active(string $plugin_name, string $plugin_slug) 137 | 138 | Checks whether plugin is active or not 139 | 140 | 141 | 142 | * Visibility: **private** 143 | 144 | 145 | #### Arguments 146 | * $plugin_name **string** - <p>Name of the plugin.</p> 147 | * $plugin_slug **string** - <p>Slug of the plugin.</p> 148 | 149 | 150 | 151 | ### get_plugin_version 152 | 153 | string Plugin_Name\Includes\Requirements_Checker::get_plugin_version(string $plugin_slug) 154 | 155 | Returns the plugin version of passed plugin 156 | 157 | 158 | 159 | * Visibility: **private** 160 | 161 | 162 | #### Arguments 163 | * $plugin_slug **string** - <p>Plugin Slug of whose version needs to be retrieved.</p> 164 | 165 | 166 | 167 | ### is_required_plugin_version_active 168 | 169 | boolean Plugin_Name\Includes\Requirements_Checker::is_required_plugin_version_active(string $plugin_name, string $plugin_slug, string $min_plugin_version) 170 | 171 | Checks whether required version of plugin is active 172 | 173 | 174 | 175 | * Visibility: **private** 176 | 177 | 178 | #### Arguments 179 | * $plugin_name **string** - <p>Plugin Name.</p> 180 | * $plugin_slug **string** - <p>Plugin Slug.</p> 181 | * $min_plugin_version **string** - <p>Minimum version required of the plugin.</p> 182 | 183 | 184 | 185 | ### are_required_plugins_dependency_met 186 | 187 | boolean Plugin_Name\Includes\Requirements_Checker::are_required_plugins_dependency_met() 188 | 189 | Checks whether all required plugins are installed & active with proper versions. 190 | 191 | 192 | 193 | * Visibility: **private** 194 | 195 | 196 | 197 | 198 | ### add_error_notice 199 | 200 | void Plugin_Name\Includes\Requirements_Checker::add_error_notice(string $error_message, string $supportive_information) 201 | 202 | Adds Error message in $errors variable 203 | 204 | 205 | 206 | * Visibility: **private** 207 | 208 | 209 | #### Arguments 210 | * $error_message **string** - <p>Error Message.</p> 211 | * $supportive_information **string** - <p>Supportive Information to be displayed along with Error Message in brackets.</p> 212 | 213 | 214 | 215 | ### requirements_met 216 | 217 | boolean Plugin_Name\Includes\Requirements_Checker::requirements_met() 218 | 219 | Checks if all plugins requirements are met or not 220 | 221 | 222 | 223 | * Visibility: **public** 224 | 225 | 226 | 227 | 228 | ### show_requirements_errors 229 | 230 | mixed Plugin_Name\Includes\Requirements_Checker::show_requirements_errors() 231 | 232 | Prints an error that the system requirements weren't met. 233 | 234 | 235 | 236 | * Visibility: **public** 237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name-Includes-i18n.md: -------------------------------------------------------------------------------- 1 | Plugin_Name\Includes\i18n 2 | =============== 3 | 4 | Define the internationalization functionality 5 | 6 | Loads and defines the internationalization files for this plugin 7 | so that it is ready for translation. 8 | 9 | 10 | * Class name: i18n 11 | * Namespace: Plugin_Name\Includes 12 | 13 | 14 | 15 | 16 | 17 | Properties 18 | ---------- 19 | 20 | 21 | ### $domain 22 | 23 | private string $domain 24 | 25 | The domain specified for this plugin. 26 | 27 | 28 | 29 | * Visibility: **private** 30 | 31 | 32 | Methods 33 | ------- 34 | 35 | 36 | ### load_plugin_textdomain 37 | 38 | mixed Plugin_Name\Includes\i18n::load_plugin_textdomain() 39 | 40 | Load the plugin text domain for translation. 41 | 42 | 43 | 44 | * Visibility: **public** 45 | 46 | 47 | 48 | 49 | ### set_domain 50 | 51 | mixed Plugin_Name\Includes\i18n::set_domain(string $domain) 52 | 53 | Set the domain equal to that of the specified domain. 54 | 55 | 56 | 57 | * Visibility: **public** 58 | 59 | 60 | #### Arguments 61 | * $domain **string** - <p>The domain that represents the locale of this plugin.</p> 62 | 63 | 64 | -------------------------------------------------------------------------------- /plugin-name/docs/Plugin_Name.md: -------------------------------------------------------------------------------- 1 | Plugin_Name 2 | =============== 3 | 4 | The main plugin class 5 | 6 | 7 | 8 | 9 | * Class name: Plugin_Name 10 | * Namespace: 11 | * Parent class: [Plugin_Name\Includes\Dependency_Loader](Plugin_Name-Includes-Dependency_Loader.md) 12 | 13 | 14 | 15 | Constants 16 | ---------- 17 | 18 | 19 | ### PLUGIN_ID 20 | 21 | const PLUGIN_ID = 'plugin-name' 22 | 23 | 24 | 25 | 26 | 27 | ### PLUGIN_NAME 28 | 29 | const PLUGIN_NAME = 'Plugin Name' 30 | 31 | 32 | 33 | 34 | 35 | ### PLUGIN_VERSION 36 | 37 | const PLUGIN_VERSION = '1.0.0' 38 | 39 | 40 | 41 | 42 | 43 | Properties 44 | ---------- 45 | 46 | 47 | ### $instance 48 | 49 | private \Plugin_Name $instance 50 | 51 | Holds instance of this class 52 | 53 | 54 | 55 | * Visibility: **private** 56 | * This property is **static**. 57 | 58 | 59 | ### $plugin_path 60 | 61 | private string $plugin_path 62 | 63 | Main plugin path /wp-content/plugins//. 64 | 65 | 66 | 67 | * Visibility: **private** 68 | * This property is **static**. 69 | 70 | 71 | ### $plugin_url 72 | 73 | private string $plugin_url 74 | 75 | Absolute plugin url /wp-content/plugins//. 76 | 77 | 78 | 79 | * Visibility: **private** 80 | * This property is **static**. 81 | 82 | 83 | Methods 84 | ------- 85 | 86 | 87 | ### __construct 88 | 89 | mixed Plugin_Name::__construct(mixed $router_class_name, mixed $routes) 90 | 91 | Define the core functionality of the plugin. 92 | 93 | Load the dependencies, define the locale, and bootstraps Router. 94 | 95 | * Visibility: **public** 96 | 97 | 98 | #### Arguments 99 | * $router_class_name **mixed** - <p>Name of the Router class to load. Otherwise false.</p> 100 | * $routes **mixed** - <p>File that contains list of all routes. Otherwise false.</p> 101 | 102 | 103 | 104 | ### get_plugin_path 105 | 106 | mixed Plugin_Name::get_plugin_path() 107 | 108 | Get plugin's absolute path. 109 | 110 | 111 | 112 | * Visibility: **public** 113 | * This method is **static**. 114 | 115 | 116 | 117 | 118 | ### get_plugin_url 119 | 120 | mixed Plugin_Name::get_plugin_url() 121 | 122 | Get plugin's absolute url. 123 | 124 | 125 | 126 | * Visibility: **public** 127 | * This method is **static**. 128 | 129 | 130 | 131 | 132 | ### set_locale 133 | 134 | mixed Plugin_Name::set_locale() 135 | 136 | Define the locale for this plugin for internationalization. 137 | 138 | Uses the i18n class in order to set the domain and to register the hook 139 | with WordPress. 140 | 141 | * Visibility: **private** 142 | 143 | 144 | 145 | 146 | ### init_router 147 | 148 | void Plugin_Name::init_router(mixed $router_class_name, mixed $routes) 149 | 150 | Init Router 151 | 152 | 153 | 154 | * Visibility: **private** 155 | 156 | 157 | #### Arguments 158 | * $router_class_name **mixed** - <p>Name of the Router class to load.</p> 159 | * $routes **mixed** - <p>File that contains list of all routes.</p> 160 | 161 | 162 | 163 | ### get_all_controllers 164 | 165 | object Plugin_Name::get_all_controllers() 166 | 167 | Returns all controller objects used for current requests 168 | 169 | 170 | 171 | * Visibility: **private** 172 | 173 | 174 | 175 | 176 | ### get_all_models 177 | 178 | object Plugin_Name::get_all_models() 179 | 180 | Returns all model objecs used for current requests 181 | 182 | 183 | 184 | * Visibility: **private** 185 | 186 | 187 | 188 | 189 | ### get_settings 190 | 191 | array Plugin_Name::get_settings() 192 | 193 | Method that retuns all Saved Settings related to Plugin. 194 | 195 | Only to be used by third party developers. 196 | 197 | * Visibility: **public** 198 | * This method is **static**. 199 | 200 | 201 | 202 | 203 | ### get_setting 204 | 205 | mixed Plugin_Name::get_setting(string $setting_name) 206 | 207 | Method that returns a individual setting 208 | 209 | Only to be used by third party developers. 210 | 211 | * Visibility: **public** 212 | * This method is **static**. 213 | 214 | 215 | #### Arguments 216 | * $setting_name **string** - <p>Setting to be retrieved.</p> 217 | 218 | 219 | 220 | ### load_dependencies 221 | 222 | mixed Plugin_Name\Includes\Dependency_Loader::load_dependencies(string $class) 223 | 224 | Loads all Plugin dependencies 225 | 226 | Converts Class parameter passed to the method into the file path & then 227 | `require_once` that path. It works with Class as well as with Traits. 228 | 229 | * Visibility: **public** 230 | * This method is defined by [Plugin_Name\Includes\Dependency_Loader](Plugin_Name-Includes-Dependency_Loader.md) 231 | 232 | 233 | #### Arguments 234 | * $class **string** - <p>Class need to be loaded.</p> 235 | 236 | 237 | 238 | ### load_registries 239 | 240 | void Plugin_Name\Includes\Dependency_Loader::load_registries() 241 | 242 | Load All Registry Class Files 243 | 244 | 245 | 246 | * Visibility: **protected** 247 | * This method is defined by [Plugin_Name\Includes\Dependency_Loader](Plugin_Name-Includes-Dependency_Loader.md) 248 | 249 | 250 | 251 | 252 | ### load_core 253 | 254 | void Plugin_Name\Includes\Dependency_Loader::load_core() 255 | 256 | Load Core MVC Classes 257 | 258 | 259 | 260 | * Visibility: **protected** 261 | * This method is defined by [Plugin_Name\Includes\Dependency_Loader](Plugin_Name-Includes-Dependency_Loader.md) 262 | 263 | 264 | 265 | 266 | ### autoload_dependencies 267 | 268 | mixed Plugin_Name\Includes\Dependency_Loader::autoload_dependencies() 269 | 270 | Method responsible to call all the dependencies 271 | 272 | 273 | 274 | * Visibility: **protected** 275 | * This method is defined by [Plugin_Name\Includes\Dependency_Loader](Plugin_Name-Includes-Dependency_Loader.md) 276 | 277 | 278 | 279 | -------------------------------------------------------------------------------- /plugin-name/docs/README.md: -------------------------------------------------------------------------------- 1 | API Index 2 | ========= 3 | 4 | * [Plugin_Name](Plugin_Name.md) 5 | * Plugin_Name\Core 6 | * [View](Plugin_Name-Core-View.md) 7 | * Plugin_Name\Core\Registry 8 | * [Controller](Plugin_Name-Core-Registry-Controller.md) 9 | * [Model](Plugin_Name-Core-Registry-Model.md) 10 | * [Route_Type](Plugin_Name-Core-Route_Type.md) 11 | * [Controller](Plugin_Name-Core-Controller.md) 12 | * [Model](Plugin_Name-Core-Model.md) 13 | * [Router](Plugin_Name-Core-Router.md) 14 | * Plugin_Name\App 15 | * [Deactivator](Plugin_Name-App-Deactivator.md) 16 | * Plugin_Name\App\Views 17 | * Plugin_Name\App\Views\Admin 18 | * [Admin_Settings](Plugin_Name-App-Views-Admin-Admin_Settings.md) 19 | * [Uninstaller](Plugin_Name-App-Uninstaller.md) 20 | * [Activator](Plugin_Name-App-Activator.md) 21 | * Plugin_Name\App\Controllers 22 | * Plugin_Name\App\Controllers\Frontend 23 | * [Base_Controller](Plugin_Name-App-Controllers-Frontend-Base_Controller.md) 24 | * Plugin_Name\App\Controllers\Admin 25 | * [Base_Controller](Plugin_Name-App-Controllers-Admin-Base_Controller.md) 26 | * [Admin_Settings](Plugin_Name-App-Controllers-Admin-Admin_Settings.md) 27 | * Plugin_Name\App\Models 28 | * Plugin_Name\App\Models\Frontend 29 | * [Base_Model](Plugin_Name-App-Models-Frontend-Base_Model.md) 30 | * [Settings](Plugin_Name-App-Models-Settings.md) 31 | * Plugin_Name\App\Models\Admin 32 | * [Base_Model](Plugin_Name-App-Models-Admin-Base_Model.md) 33 | * [Admin_Settings](Plugin_Name-App-Models-Admin-Admin_Settings.md) 34 | * Plugin_Name\Includes 35 | * [Dependency_Loader](Plugin_Name-Includes-Dependency_Loader.md) 36 | * [Requirements_Checker](Plugin_Name-Includes-Requirements_Checker.md) 37 | * [i18n](Plugin_Name-Includes-i18n.md) 38 | 39 | -------------------------------------------------------------------------------- /plugin-name/includes/class-dependency-loader.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class Dependency_Loader { 17 | 18 | /** 19 | * Loads all Plugin dependencies 20 | * 21 | * Converts Class parameter passed to the method into the file path & then 22 | * `require_once` that path. It works with Class as well as with Traits. 23 | * 24 | * @param string $class Class need to be loaded. 25 | * @since 1.0.0 26 | */ 27 | public function load_dependencies( $class ) { 28 | $parts = explode( '\\', $class ); 29 | 30 | // Run this autoloader for classes related to this plugin only. 31 | if ( 'Plugin_Name' !== $parts[0] ) { 32 | return; 33 | } 34 | 35 | // Remove 'Plugin_Name' from parts. 36 | array_shift( $parts ); 37 | 38 | $parts = array_map( 39 | function ( $part ) { 40 | return str_replace( '_', '-', strtolower( $part ) ); 41 | }, $parts 42 | ); 43 | 44 | $class_file_name = '/class-' . array_pop( $parts ) . '.php'; 45 | 46 | $file_path = Plugin_Name::get_plugin_path() . implode( '/', $parts ) . $class_file_name; 47 | 48 | if ( \file_exists( $file_path ) ) { 49 | require_once( $file_path ); 50 | return; 51 | } 52 | 53 | $trait_file_name = '/trait-' . array_pop( $parts ) . '.php'; 54 | 55 | $file_path = Plugin_Name::get_plugin_path() . implode( '/', $parts ) . $trait_file_name; 56 | 57 | if ( \file_exists( $file_path ) ) { 58 | require_once( $file_path ); 59 | } 60 | } 61 | 62 | /** 63 | * Load All Registry Class Files 64 | * 65 | * @since 1.0.0 66 | * @return void 67 | */ 68 | protected function load_registries() { 69 | require_once( Plugin_Name::get_plugin_path() . 'core/registry/trait-base-registry.php' ); 70 | require_once( Plugin_Name::get_plugin_path() . 'core/registry/class-controller.php' ); 71 | require_once( Plugin_Name::get_plugin_path() . 'core/registry/class-model.php' ); 72 | } 73 | 74 | /** 75 | * Load Core MVC Classes 76 | * 77 | * @since 1.0.0 78 | * @return void 79 | */ 80 | protected function load_core() { 81 | $this->load_registries(); 82 | foreach ( glob( Plugin_Name::get_plugin_path() . 'core/*.php' ) as $path ) { 83 | require_once $path; 84 | } 85 | } 86 | 87 | /** 88 | * Method responsible to call all the dependencies 89 | * 90 | * @since 1.0.01 91 | */ 92 | protected function autoload_dependencies() { 93 | $this->load_core(); 94 | spl_autoload_register( array( $this, 'load_dependencies' ) ); 95 | } 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /plugin-name/includes/class-i18n.php: -------------------------------------------------------------------------------- 1 | domain, 35 | false, 36 | dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/' 37 | ); 38 | } 39 | 40 | /** 41 | * Set the domain equal to that of the specified domain. 42 | * 43 | * @since 1.0.0.0 44 | * @param string $domain The domain that represents the locale of this plugin. 45 | */ 46 | public function set_domain( $domain ) { 47 | $this->domain = $domain; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /plugin-name/includes/class-plugin-name.php: -------------------------------------------------------------------------------- 1 | /. 33 | * 34 | * @since 1.0.0 35 | * @access private 36 | * @var string $plugin_path Main path. 37 | */ 38 | private static $plugin_path; 39 | 40 | /** 41 | * Absolute plugin url /wp-content/plugins//. 42 | * 43 | * @since 1.0.0 44 | * @access private 45 | * @var string $plugin_url Main path. 46 | */ 47 | private static $plugin_url; 48 | 49 | 50 | /** 51 | * The unique identifier of this plugin. 52 | * 53 | * @since 1.0.0 54 | */ 55 | const PLUGIN_ID = 'plugin-name'; 56 | 57 | /** 58 | * The name identifier of this plugin. 59 | * 60 | * @since 1.0.0 61 | */ 62 | const PLUGIN_NAME = 'Plugin Name'; 63 | 64 | 65 | /** 66 | * The current version of the plugin. 67 | * 68 | * @since 1.0.0 69 | */ 70 | const PLUGIN_VERSION = '1.0.0'; 71 | 72 | /** 73 | * Define the core functionality of the plugin. 74 | * 75 | * Load the dependencies, define the locale, and bootstraps Router. 76 | * 77 | * @param mixed $router_class_name Name of the Router class to load. Otherwise false. 78 | * @param mixed $routes File that contains list of all routes. Otherwise false. 79 | * @since 1.0.0 80 | */ 81 | public function __construct( $router_class_name = false, $routes = false ) { 82 | self::$plugin_path = plugin_dir_path( dirname( __FILE__ ) ); 83 | self::$plugin_url = plugin_dir_url( dirname( __FILE__ ) ); 84 | 85 | $this->autoload_dependencies(); 86 | $this->set_locale(); 87 | 88 | if ( false !== $router_class_name && false !== $routes ) { 89 | $this->init_router( $router_class_name, $routes ); 90 | } 91 | 92 | $this->controllers = $this->get_all_controllers(); 93 | $this->models = $this->get_all_models(); 94 | } 95 | 96 | /** 97 | * Get plugin's absolute path. 98 | * 99 | * @since 1.0.0 100 | */ 101 | public static function get_plugin_path() { 102 | return isset( self::$plugin_path ) ? self::$plugin_path : plugin_dir_path( dirname( __FILE__ ) ); 103 | } 104 | 105 | /** 106 | * Get plugin's absolute url. 107 | * 108 | * @since 1.0.0 109 | */ 110 | public static function get_plugin_url() { 111 | return isset( self::$plugin_url ) ? self::$plugin_url : plugin_dir_url( dirname( __FILE__ ) ); 112 | } 113 | 114 | /** 115 | * Define the locale for this plugin for internationalization. 116 | * 117 | * Uses the i18n class in order to set the domain and to register the hook 118 | * with WordPress. 119 | * 120 | * @since 1.0.0.0 121 | */ 122 | private function set_locale() { 123 | $plugin_i18n = new i18n(); 124 | $plugin_i18n->set_domain( Plugin_Name::PLUGIN_ID ); 125 | 126 | add_action( 'plugins_loaded', array( $plugin_i18n, 'load_plugin_textdomain' ) ); 127 | } 128 | 129 | /** 130 | * Init Router 131 | * 132 | * @param mixed $router_class_name Name of the Router class to load. 133 | * @param mixed $routes File that contains list of all routes. 134 | * @throws \InvalidArgumentException If Router class or Routes file is not found. 135 | * @since 1.0.0 136 | * @return void 137 | */ 138 | private function init_router( $router_class_name, $routes ) { 139 | if ( ! class_exists( $router_class_name ) ) { 140 | throw new \InvalidArgumentException( "Could not load {$router_class_name} class!" ); 141 | } 142 | 143 | if ( ! file_exists( $routes ) ) { 144 | throw new \InvalidArgumentException( "Routes file {$routes} not found! Please pass a valid file." ); 145 | } 146 | 147 | $this->router = $router = new $router_class_name(); // @codingStandardsIgnoreLine. 148 | add_action( 149 | 'plugins_loaded', function() use ( $router, $routes ) { 150 | include_once( $routes ); 151 | } 152 | ); 153 | } 154 | 155 | /** 156 | * Returns all controller objects used for current requests 157 | * 158 | * @since 1.0.0 159 | * @return object 160 | */ 161 | private function get_all_controllers() { 162 | return (object) Controller_Registry::get_all_objects(); 163 | } 164 | 165 | /** 166 | * Returns all model objecs used for current requests 167 | * 168 | * @since 1.0.0 169 | * @return object 170 | */ 171 | private function get_all_models() { 172 | return (object) Model_Registry::get_all_objects(); 173 | } 174 | 175 | /** 176 | * Method that retuns all Saved Settings related to Plugin. 177 | * 178 | * Only to be used by third party developers. 179 | * 180 | * @return array 181 | * @since 1.0.0 182 | */ 183 | public static function get_settings() { 184 | return Settings::get_settings(); 185 | } 186 | 187 | /** 188 | * Method that returns a individual setting 189 | * 190 | * Only to be used by third party developers. 191 | * 192 | * @param string $setting_name Setting to be retrieved. 193 | * @return mixed 194 | * @since 1.0.0 195 | */ 196 | public static function get_setting( $setting_name ) { 197 | return Settings::get_setting( $setting_name ); 198 | } 199 | } 200 | 201 | } 202 | -------------------------------------------------------------------------------- /plugin-name/includes/class-requirements-checker.php: -------------------------------------------------------------------------------- 1 | min_php_version = $requirements_data['min_php_version']; 63 | } 64 | 65 | if ( isset( $requirements_data['min_wp_version'] ) ) { 66 | $this->min_wp_version = $requirements_data['min_wp_version']; 67 | } 68 | 69 | if ( isset( $requirements_data['is_multisite_compatible'] ) ) { 70 | $this->is_multisite_compatible = $requirements_data['is_multisite_compatible']; 71 | } 72 | 73 | if ( isset( $requirements_data['required_plugins'] ) ) { 74 | $this->required_plugins = $requirements_data['required_plugins']; 75 | } 76 | } 77 | 78 | /** 79 | * Checks if Installed PHP Version is higher than required PHP Version 80 | * 81 | * @return boolean 82 | * @since 1.0.0 83 | */ 84 | private function is_php_version_dependency_met() { 85 | $is_required_php_version_installed = version_compare( PHP_VERSION, $this->min_php_version, '>=' ); 86 | 87 | if ( 1 == $is_required_php_version_installed ) { 88 | return true; 89 | } 90 | 91 | $this->add_error_notice( 92 | 'PHP ' . $this->min_php_version . '+ is required', 93 | 'You\'re running version ' . PHP_VERSION 94 | ); 95 | 96 | return false; 97 | } 98 | 99 | /** 100 | * Checks if Installed WP Version is higher than required WP Version 101 | * 102 | * @return boolean 103 | * @since 1.0.0 104 | */ 105 | private function is_wp_version_dependency_met() { 106 | global $wp_version; 107 | $is_required_wp_version_installed = version_compare( $wp_version, $this->min_wp_version, '>=' ); 108 | 109 | if ( 1 == $is_required_wp_version_installed ) { 110 | return true; 111 | } 112 | 113 | $this->add_error_notice( 114 | 'WordPress ' . $this->min_wp_version . '+ is required', 115 | 'You\'re running version ' . $wp_version 116 | ); 117 | 118 | return false; 119 | } 120 | 121 | /** 122 | * Checks if Multisite Dependencies are met 123 | * 124 | * @return boolean 125 | * @since 1.0.0 126 | */ 127 | private function is_wp_multisite_dependency_met() { 128 | $is_wp_multisite_dependency_met = is_multisite() && ( false === $this->is_multisite_compatible ) ? false : true; 129 | 130 | if ( false == $is_wp_multisite_dependency_met ) { 131 | $this->add_error_notice( 132 | 'Your site is set up as a Network (Multisite)', 133 | 'This plugin is not compatible with multisite environment' 134 | ); 135 | } 136 | 137 | return $is_wp_multisite_dependency_met; 138 | } 139 | 140 | /** 141 | * Checks whether plugin is active or not 142 | * 143 | * @param string $plugin_name Name of the plugin. 144 | * @param string $plugin_slug Slug of the plugin. 145 | * @return boolean 146 | * @since 1.0.0 147 | */ 148 | private function is_plugin_active( $plugin_name, $plugin_slug ) { 149 | require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); 150 | 151 | if ( is_plugin_active( $plugin_slug ) ) { 152 | return true; 153 | } 154 | 155 | $this->add_error_notice( 156 | $plugin_name . ' is a required plugin.', 157 | $plugin_name . ' needs to be installed & activated.' 158 | ); 159 | 160 | return false; 161 | } 162 | 163 | /** 164 | * Returns the plugin version of passed plugin 165 | * 166 | * @param string $plugin_slug Plugin Slug of whose version needs to be retrieved. 167 | * @return string Plugin Version 168 | * @since 1.0.0 169 | */ 170 | private function get_plugin_version( $plugin_slug ) { 171 | $plugin_file_path = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $plugin_slug; 172 | 173 | if ( ! file_exists( $plugin_file_path ) ) { 174 | $plugin_file_path = WPMU_PLUGIN_DIR . DIRECTORY_SEPARATOR . $plugin_slug; 175 | } 176 | 177 | $plugin_data = get_plugin_data( $plugin_file_path, false, false ); 178 | 179 | if ( empty( $plugin_data['Version'] ) ) { 180 | return '0.0'; 181 | } 182 | 183 | return $plugin_data['Version']; 184 | } 185 | 186 | /** 187 | * Checks whether required version of plugin is active 188 | * 189 | * @param string $plugin_name Plugin Name. 190 | * @param string $plugin_slug Plugin Slug. 191 | * @param string $min_plugin_version Minimum version required of the plugin. 192 | * @return boolean 193 | * @since 1.0.0 194 | */ 195 | private function is_required_plugin_version_active( $plugin_name, $plugin_slug, $min_plugin_version ) { 196 | $installed_plugin_version = $this->get_plugin_version( $plugin_slug ); 197 | $is_required_plugin_version_active = version_compare( $installed_plugin_version, $min_plugin_version, '>=' ); 198 | 199 | if ( 1 == $is_required_plugin_version_active ) { 200 | return true; 201 | } 202 | 203 | $this->add_error_notice( 204 | "{$plugin_name} {$min_plugin_version}+ is required.", 205 | "{$plugin_name} {$installed_plugin_version} is installed." 206 | ); 207 | 208 | return false; 209 | } 210 | 211 | /** 212 | * Checks whether all required plugins are installed & active with proper versions. 213 | * 214 | * @return boolean 215 | * @since 1.0.0 216 | */ 217 | private function are_required_plugins_dependency_met() { 218 | $plugin_dependency_met = true; 219 | 220 | if ( empty( $this->required_plugins ) ) { 221 | return true; 222 | } 223 | 224 | $installed_plugins = array_filter( 225 | $this->required_plugins, 226 | function( $required_plugin_data, $required_plugin_name ) { 227 | return $this->is_plugin_active( $required_plugin_name, $required_plugin_data['plugin_slug'] ); 228 | }, 229 | ARRAY_FILTER_USE_BOTH 230 | ); 231 | 232 | // If All Plugins are not installed, set plugin_dependency_met flag as false. 233 | if ( count( $installed_plugins ) !== count( $this->required_plugins ) ) { 234 | $plugin_dependency_met = false; 235 | } 236 | 237 | $plugins_installed_with_required_version = array_filter( 238 | $installed_plugins, 239 | function( $required_plugin_data, $required_plugin_name ) { 240 | return $this->is_required_plugin_version_active( $required_plugin_name, $required_plugin_data['plugin_slug'], $required_plugin_data['min_plugin_version'] ); 241 | }, 242 | ARRAY_FILTER_USE_BOTH 243 | ); 244 | 245 | // All Plugins did not met minimum version dependency. 246 | if ( count( $plugins_installed_with_required_version ) !== count( $this->required_plugins ) ) { 247 | $plugin_dependency_met = false; 248 | } 249 | 250 | return $plugin_dependency_met; 251 | } 252 | 253 | 254 | /** 255 | * Adds Error message in $errors variable 256 | * 257 | * @param string $error_message Error Message. 258 | * @param string $supportive_information Supportive Information to be displayed along with Error Message in brackets. 259 | * @return void 260 | * @since 1.0.0 261 | */ 262 | private function add_error_notice( $error_message, $supportive_information ) { 263 | $this->errors[] = (object) [ 264 | 'error_message' => $error_message, 265 | 'supportive_information' => $supportive_information, 266 | ]; 267 | } 268 | 269 | /** 270 | * Checks if all plugins requirements are met or not 271 | * 272 | * @return boolean 273 | * @since 1.0.0 274 | */ 275 | public function requirements_met() { 276 | $requirements_met = true; 277 | 278 | if ( ! $this->is_php_version_dependency_met() ) { 279 | $requirements_met = false; 280 | } 281 | 282 | if ( ! $this->is_wp_version_dependency_met() ) { 283 | $requirements_met = false; 284 | } 285 | 286 | if ( ! $this->is_wp_multisite_dependency_met() ) { 287 | $requirements_met = false; 288 | } 289 | 290 | if ( ! $this->are_required_plugins_dependency_met() ) { 291 | $requirements_met = false; 292 | } 293 | 294 | return $requirements_met; 295 | } 296 | 297 | /** 298 | * Prints an error that the system requirements weren't met. 299 | * 300 | * @since 1.0.0 301 | */ 302 | public function show_requirements_errors() { 303 | $errors = $this->errors; 304 | require_once( dirname( dirname( __FILE__ ) ) . '/app/templates/admin/errors/requirements-error.php' ); 305 | } 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /plugin-name/includes/index.php: -------------------------------------------------------------------------------- 1 | requirements_met() ) { 54 | add_action( 'admin_notices', array( plugin_requirements_checker(), 'show_requirements_errors' ) ); 55 | 56 | // Deactivate plugin immediately if requirements are not met. 57 | require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); 58 | deactivate_plugins( plugin_basename( __FILE__ ) ); 59 | 60 | return; 61 | } 62 | 63 | /** 64 | * The core plugin class that is used to define internationalization, 65 | * admin-specific hooks, and frontend-facing site hooks. 66 | */ 67 | require_once plugin_dir_path( __FILE__ ) . 'includes/class-plugin-name.php'; 68 | 69 | /** 70 | * Begins execution of the plugin. 71 | * 72 | * Since everything within the plugin is registered via hooks, 73 | * then kicking off the plugin from this point in the file does 74 | * not affect the page life cycle. 75 | * 76 | * @since 1.0.0 77 | */ 78 | $router_class_name = apply_filters( 'plugin_name_router_class_name', '\Plugin_Name\Core\Router' ); 79 | $routes = apply_filters( 'plugin_name_routes_file', plugin_dir_path( __FILE__ ) . 'routes.php' ); 80 | $GLOBALS['plugin_name'] = new Plugin_Name( $router_class_name, $routes ); 81 | 82 | register_activation_hook( __FILE__, array( new Plugin_Name\App\Activator(), 'activate' ) ); 83 | register_deactivation_hook( __FILE__, array( new Plugin_Name\App\Deactivator(), 'deactivate' ) ); 84 | } 85 | 86 | run_plugin_name(); 87 | -------------------------------------------------------------------------------- /plugin-name/requirements-config.php: -------------------------------------------------------------------------------- 1 | '5.6', // Minimum PHP Version. 11 | 12 | 'min_wp_version' => '4.8', // Minimum WordPress Version. 13 | 14 | 'is_multisite_compatible' => false, // True if our plugin is Multisite Compatible. 15 | 16 | 'required_plugins' => [ // Plugins on which our plugin is dependent on. 17 | 18 | // Example Config 19 | // 'Hello Dolly' => [ 20 | // 'plugin_slug' => 'hello-dolly/hello.php', 21 | // 'min_plugin_version' => '1.5', 22 | // ], 23 | 24 | ], 25 | 26 | ]; 27 | -------------------------------------------------------------------------------- /plugin-name/routes.php: -------------------------------------------------------------------------------- 1 | register_route_of_type(...)->with_controller(...)->with_model(...)->with_view(...); 44 | * 2. $router->register_route_of_type(...)->with_controller(...)->with_model(...); 45 | * 3. $router->register_route_of_type(...)->with_controller(...)->with_view(...); 46 | * 4. $router->register_route_of_type(...)->with_controller(...); 47 | * 5. $router->register_route_of_type(...)->with_just_model(...); 48 | * 49 | * with_controller, with_model, with_view, with_just_model methods accept either a string or 50 | * a callback. But the callback must return respective Controller/Model or View name. 51 | * 52 | * with_controlller & with_just_model methods supports '@' in the Controller/Model passed to 53 | * them allowing you to call a particular method. That method does not need to be a static 54 | * method. It can be a public method. 55 | */ 56 | 57 | /* 58 | |------------------------------------------------------------------------------------------- 59 | | Simple Example - This example creates a admin route (triggered only when it is a dashboard) 60 | |------------------------------------------------------------------------------------------- 61 | | $router 62 | | ->register_route_of_type( ROUTE_TYPE::ADMIN ) 63 | | >with_controller( 'Admin_Settings' ) // Resolved by Router to 'Plugin_Name\App\Controllers\Admin\Admin_Settings'. 64 | | ->with_model( 'Admin_Settings' ) // Resolved by Router to 'Plugin_Name\App\Models\Admin\Admin_Settings'. 65 | | ->with_view( 'Admin_Settings' ); // Resolved by Router to 'Plugin_Name\App\Views\Admin\Admin_Settings'. 66 | |------------------------------------------------------------------------------------------- 67 | */ 68 | 69 | /* 70 | |------------------------------------------------------------------------------------------- 71 | | Routes with Full Class Names Example. Above route could also be written as :- 72 | |------------------------------------------------------------------------------------------- 73 | | $router 74 | | ->register_route_of_type( ROUTE_TYPE::ADMIN ) 75 | | ->with_controller( 'Plugin_Name\App\Controllers\Admin\Admin_Settings' ) 76 | | ->with_model( 'Plugin_Name\App\Models\Admin\Admin_Settings' ) 77 | | ->with_view( 'Plugin_Name\App\Views\Admin\Admin_Settings' ); 78 | |------------------------------------------------------------------------------------------- 79 | */ 80 | 81 | /* 82 | |------------------------------------------------------------------------------------------- 83 | | '@' Symbol Example :- 84 | | 85 | | Again, @ is supported in with_controller & with_just_model methods only. 86 | |------------------------------------------------------------------------------------------- 87 | | $router 88 | | ->register_route_of_type( ROUTE_TYPE::LATE_FRONTEND ) 89 | | ->with_controller( 'Sample_Shortcode@register_shortcode' ) 90 | | ->with_model( 'Sample_Shortcode' ) 91 | | ->with_view( 'Sample_Shortcode' ); 92 | |------------------------------------------------------------------------------------------- 93 | */ 94 | 95 | /* 96 | |------------------------------------------------------------------------------------------- 97 | | Example of Loading controller if conditions match. Late Frontend Routes are triggerred on 98 | | `wp` hook. Therefore, you should ideally be able to access template related functions 99 | | in the callback passed to `with_controller` method below 100 | |------------------------------------------------------------------------------------------- 101 | | $router 102 | | ->register_route_of_type( ROUTE_TYPE::LATE_FRONTEND ) 103 | | ->with_controller( 104 | | function() { 105 | | 106 | | if ( get_the_ID() == '3367' ) { 107 | | return 'Sample_Shortcode'; 108 | | } 109 | | 110 | | return false; 111 | | } 112 | | ) 113 | | ->with_view( 'Sample_Shortcode' ); 114 | |------------------------------------------------------------------------------------------- 115 | */ 116 | 117 | /* 118 | |------------------------------------------------------------------------------------------- 119 | | If you want to load only model for specific route, you can use with_just_model. 120 | | 121 | | Note: This type of route is referred as `Model Only` route.`Model Only` routes 122 | | don't support Views. This type of route should ideally be used when you have 123 | | to work at data layer but there is nothing to print on the screen. 124 | |------------------------------------------------------------------------------------------- 125 | | $router 126 | | ->register_route_of_type( ROUTE_TYPE::ADMIN ) 127 | | ->with_just_model('Plugin_Name_Model_Admin_Settings'); 128 | |------------------------------------------------------------------------------------------- 129 | */ 130 | 131 | /* That's all, start creating your own routes below this line! Happy coding. */ 132 | 133 | // Route for Settings Page. 134 | $router 135 | ->register_route_of_type( ROUTE_TYPE::ADMIN ) 136 | ->with_controller( 'Admin_Settings@register_hook_callbacks' ) // Resolved by Router to 'Plugin_Name\App\Controllers\Admin\Admin_Settings'. 137 | ->with_model( 'Admin_Settings' ) // Resolved by Router to 'Plugin_Name\App\Models\Admin\Admin_Settings'. 138 | ->with_view( 'Admin_Settings' ); // Resolved by Router to 'Plugin_Name\App\Views\Admin\Admin_Settings'. 139 | -------------------------------------------------------------------------------- /plugin-name/uninstall.php: -------------------------------------------------------------------------------- 1 | uninstall(); 40 | --------------------------------------------------------------------------------