├── LICENSE
├── README.md
├── application
├── .htaccess
├── config
│ ├── autoload.php
│ ├── config.php
│ └── plugins.php
├── controllers
│ └── Plugins.php
├── helpers
│ └── plugin_helper.php
├── libraries
│ ├── Plugins_lib.php
│ ├── abstract.plugins.php
│ └── trait.plugins.php
├── models
│ ├── Plugins_model.php
│ └── index.html
└── views
│ ├── plugin_list.php
│ └── plugin_settings.php
├── plugin_database.sql
└── plugins
└── hello_world
├── hello_world.php
└── views
└── settings.php
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 J
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > :warning: **Deprecation warning**: I wrote this a very long time ago and no longer use CI - Or any PHP framework for that matter. I stay away from PHP like the plague. But since people seem to continue to star/watch it, I'll leave it up here.
2 | >
3 | > Someone please steal this and make it better.
4 |
5 |
6 | # CI3_Plugin_System
7 | Plugin system for CodeIgniter 3
8 |
9 | Ill add more info to the readme later, but for now, just drop the helper/model/library where they go, import the table in the .sql file, and look at the application/controllers/Plugins.php for some info, and look at the plugins/hello_world/hello_world.php for a very basic demo.
10 |
--------------------------------------------------------------------------------
/application/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Require all denied
3 |
4 |
5 | Deny from all
6 |
--------------------------------------------------------------------------------
/application/config/autoload.php:
--------------------------------------------------------------------------------
1 | 'ua');
61 | */
62 |
63 | $autoload['libraries'] = array('database','Plugins_lib');
64 |
65 |
66 | /*
67 | | -------------------------------------------------------------------
68 | | Auto-load Drivers
69 | | -------------------------------------------------------------------
70 | | These classes are located in the system/libraries folder or in your
71 | | application/libraries folder within their own subdirectory. They
72 | | offer multiple interchangeable driver options.
73 | |
74 | | Prototype:
75 | |
76 | | $autoload['drivers'] = array('cache');
77 | */
78 |
79 | $autoload['drivers'] = array();
80 |
81 |
82 | /*
83 | | -------------------------------------------------------------------
84 | | Auto-load Helper Files
85 | | -------------------------------------------------------------------
86 | | Prototype:
87 | |
88 | | $autoload['helper'] = array('url', 'file');
89 | */
90 |
91 | $autoload['helper'] = array('plugin');
92 |
93 |
94 | /*
95 | | -------------------------------------------------------------------
96 | | Auto-load Config files
97 | | -------------------------------------------------------------------
98 | | Prototype:
99 | |
100 | | $autoload['config'] = array('config1', 'config2');
101 | |
102 | | NOTE: This item is intended for use ONLY if you have created custom
103 | | config files. Otherwise, leave it blank.
104 | |
105 | */
106 |
107 | $autoload['config'] = array('plugins');
108 |
109 |
110 | /*
111 | | -------------------------------------------------------------------
112 | | Auto-load Language files
113 | | -------------------------------------------------------------------
114 | | Prototype:
115 | |
116 | | $autoload['language'] = array('lang1', 'lang2');
117 | |
118 | | NOTE: Do not include the "_lang" part of your file. For example
119 | | "codeigniter_lang.php" would be referenced as array('codeigniter');
120 | |
121 | */
122 |
123 | $autoload['language'] = array();
124 |
125 |
126 | /*
127 | | -------------------------------------------------------------------
128 | | Auto-load Models
129 | | -------------------------------------------------------------------
130 | | Prototype:
131 | |
132 | | $autoload['model'] = array('first_model', 'second_model');
133 | |
134 | | You can also supply an alternative model name to be assigned
135 | | in the controller:
136 | |
137 | | $autoload['model'] = array('first_model' => 'first');
138 | */
139 |
140 | $autoload['model'] = array('Plugins_model');
141 |
--------------------------------------------------------------------------------
/application/config/config.php:
--------------------------------------------------------------------------------
1 | ]+$/i
152 | |
153 | | DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
154 | |
155 | */
156 | $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
157 |
158 |
159 | /*
160 | |--------------------------------------------------------------------------
161 | | Enable Query Strings
162 | |--------------------------------------------------------------------------
163 | |
164 | | By default CodeIgniter uses search-engine friendly segment based URLs:
165 | | example.com/who/what/where/
166 | |
167 | | By default CodeIgniter enables access to the $_GET array. If for some
168 | | reason you would like to disable it, set 'allow_get_array' to FALSE.
169 | |
170 | | You can optionally enable standard query string based URLs:
171 | | example.com?who=me&what=something&where=here
172 | |
173 | | Options are: TRUE or FALSE (boolean)
174 | |
175 | | The other items let you set the query string 'words' that will
176 | | invoke your controllers and its functions:
177 | | example.com/index.php?c=controller&m=function
178 | |
179 | | Please note that some of the helpers won't work as expected when
180 | | this feature is enabled, since CodeIgniter is designed primarily to
181 | | use segment based URLs.
182 | |
183 | */
184 | $config['allow_get_array'] = TRUE;
185 | $config['enable_query_strings'] = FALSE;
186 | $config['controller_trigger'] = 'c';
187 | $config['function_trigger'] = 'm';
188 | $config['directory_trigger'] = 'd';
189 |
190 | /*
191 | |--------------------------------------------------------------------------
192 | | Error Logging Threshold
193 | |--------------------------------------------------------------------------
194 | |
195 | | If you have enabled error logging, you can set an error threshold to
196 | | determine what gets logged. Threshold options are:
197 | | You can enable error logging by setting a threshold over zero. The
198 | | threshold determines what gets logged. Threshold options are:
199 | |
200 | | 0 = Disables logging, Error logging TURNED OFF
201 | | 1 = Error Messages (including PHP errors)
202 | | 2 = Debug Messages
203 | | 3 = Informational Messages
204 | | 4 = All Messages
205 | |
206 | | You can also pass an array with threshold levels to show individual error types
207 | |
208 | | array(2) = Debug Messages, without Error Messages
209 | |
210 | | For a live site you'll usually only enable Errors (1) to be logged otherwise
211 | | your log files will fill up very fast.
212 | |
213 | */
214 | $config['log_threshold'] = 0;
215 |
216 | /*
217 | |--------------------------------------------------------------------------
218 | | Error Logging Directory Path
219 | |--------------------------------------------------------------------------
220 | |
221 | | Leave this BLANK unless you would like to set something other than the default
222 | | application/logs/ directory. Use a full server path with trailing slash.
223 | |
224 | */
225 | $config['log_path'] = '';
226 |
227 | /*
228 | |--------------------------------------------------------------------------
229 | | Log File Extension
230 | |--------------------------------------------------------------------------
231 | |
232 | | The default filename extension for log files. The default 'php' allows for
233 | | protecting the log files via basic scripting, when they are to be stored
234 | | under a publicly accessible directory.
235 | |
236 | | Note: Leaving it blank will default to 'php'.
237 | |
238 | */
239 | $config['log_file_extension'] = '';
240 |
241 | /*
242 | |--------------------------------------------------------------------------
243 | | Log File Permissions
244 | |--------------------------------------------------------------------------
245 | |
246 | | The file system permissions to be applied on newly created log files.
247 | |
248 | | IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal
249 | | integer notation (i.e. 0700, 0644, etc.)
250 | */
251 | $config['log_file_permissions'] = 0644;
252 |
253 | /*
254 | |--------------------------------------------------------------------------
255 | | Date Format for Logs
256 | |--------------------------------------------------------------------------
257 | |
258 | | Each item that is logged has an associated date. You can use PHP date
259 | | codes to set your own date formatting
260 | |
261 | */
262 | $config['log_date_format'] = 'Y-m-d H:i:s';
263 |
264 | /*
265 | |--------------------------------------------------------------------------
266 | | Error Views Directory Path
267 | |--------------------------------------------------------------------------
268 | |
269 | | Leave this BLANK unless you would like to set something other than the default
270 | | application/views/errors/ directory. Use a full server path with trailing slash.
271 | |
272 | */
273 | $config['error_views_path'] = '';
274 |
275 | /*
276 | |--------------------------------------------------------------------------
277 | | Cache Directory Path
278 | |--------------------------------------------------------------------------
279 | |
280 | | Leave this BLANK unless you would like to set something other than the default
281 | | application/cache/ directory. Use a full server path with trailing slash.
282 | |
283 | */
284 | $config['cache_path'] = '';
285 |
286 | /*
287 | |--------------------------------------------------------------------------
288 | | Cache Include Query String
289 | |--------------------------------------------------------------------------
290 | |
291 | | Set this to TRUE if you want to use different cache files depending on the
292 | | URL query string. Please be aware this might result in numerous cache files.
293 | |
294 | */
295 | $config['cache_query_string'] = FALSE;
296 |
297 | /*
298 | |--------------------------------------------------------------------------
299 | | Encryption Key
300 | |--------------------------------------------------------------------------
301 | |
302 | | If you use the Encryption class, you must set an encryption key.
303 | | See the user guide for more info.
304 | |
305 | | http://codeigniter.com/user_guide/libraries/encryption.html
306 | |
307 | */
308 | $config['encryption_key'] = '';
309 |
310 | /*
311 | |--------------------------------------------------------------------------
312 | | Session Variables
313 | |--------------------------------------------------------------------------
314 | |
315 | | 'sess_driver'
316 | |
317 | | The storage driver to use: files, database, redis, memcached
318 | |
319 | | 'sess_cookie_name'
320 | |
321 | | The session cookie name, must contain only [0-9a-z_-] characters
322 | |
323 | | 'sess_expiration'
324 | |
325 | | The number of SECONDS you want the session to last.
326 | | Setting to 0 (zero) means expire when the browser is closed.
327 | |
328 | | 'sess_save_path'
329 | |
330 | | The location to save sessions to, driver dependant.
331 | |
332 | | For the 'files' driver, it's a path to a writable directory.
333 | | WARNING: Only absolute paths are supported!
334 | |
335 | | For the 'database' driver, it's a table name.
336 | | Please read up the manual for the format with other session drivers.
337 | |
338 | | IMPORTANT: You are REQUIRED to set a valid save path!
339 | |
340 | | 'sess_match_ip'
341 | |
342 | | Whether to match the user's IP address when reading the session data.
343 | |
344 | | 'sess_time_to_update'
345 | |
346 | | How many seconds between CI regenerating the session ID.
347 | |
348 | | 'sess_regenerate_destroy'
349 | |
350 | | Whether to destroy session data associated with the old session ID
351 | | when auto-regenerating the session ID. When set to FALSE, the data
352 | | will be later deleted by the garbage collector.
353 | |
354 | | Other session cookie settings are shared with the rest of the application,
355 | | except for 'cookie_prefix' and 'cookie_httponly', which are ignored here.
356 | |
357 | */
358 | $config['sess_driver'] = 'files';
359 | $config['sess_cookie_name'] = 'ci_session';
360 | $config['sess_expiration'] = 7200;
361 | $config['sess_save_path'] = NULL;
362 | $config['sess_match_ip'] = FALSE;
363 | $config['sess_time_to_update'] = 300;
364 | $config['sess_regenerate_destroy'] = FALSE;
365 |
366 | /*
367 | |--------------------------------------------------------------------------
368 | | Cookie Related Variables
369 | |--------------------------------------------------------------------------
370 | |
371 | | 'cookie_prefix' = Set a cookie name prefix if you need to avoid collisions
372 | | 'cookie_domain' = Set to .your-domain.com for site-wide cookies
373 | | 'cookie_path' = Typically will be a forward slash
374 | | 'cookie_secure' = Cookie will only be set if a secure HTTPS connection exists.
375 | | 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript)
376 | |
377 | | Note: These settings (with the exception of 'cookie_prefix' and
378 | | 'cookie_httponly') will also affect sessions.
379 | |
380 | */
381 | $config['cookie_prefix'] = '';
382 | $config['cookie_domain'] = '';
383 | $config['cookie_path'] = '/';
384 | $config['cookie_secure'] = FALSE;
385 | $config['cookie_httponly'] = FALSE;
386 |
387 | /*
388 | |--------------------------------------------------------------------------
389 | | Standardize newlines
390 | |--------------------------------------------------------------------------
391 | |
392 | | Determines whether to standardize newline characters in input data,
393 | | meaning to replace \r\n, \r, \n occurences with the PHP_EOL value.
394 | |
395 | | This is particularly useful for portability between UNIX-based OSes,
396 | | (usually \n) and Windows (\r\n).
397 | |
398 | */
399 | $config['standardize_newlines'] = FALSE;
400 |
401 | /*
402 | |--------------------------------------------------------------------------
403 | | Global XSS Filtering
404 | |--------------------------------------------------------------------------
405 | |
406 | | Determines whether the XSS filter is always active when GET, POST or
407 | | COOKIE data is encountered
408 | |
409 | | WARNING: This feature is DEPRECATED and currently available only
410 | | for backwards compatibility purposes!
411 | |
412 | */
413 | $config['global_xss_filtering'] = FALSE;
414 |
415 | /*
416 | |--------------------------------------------------------------------------
417 | | Cross Site Request Forgery
418 | |--------------------------------------------------------------------------
419 | | Enables a CSRF cookie token to be set. When set to TRUE, token will be
420 | | checked on a submitted form. If you are accepting user data, it is strongly
421 | | recommended CSRF protection be enabled.
422 | |
423 | | 'csrf_token_name' = The token name
424 | | 'csrf_cookie_name' = The cookie name
425 | | 'csrf_expire' = The number in seconds the token should expire.
426 | | 'csrf_regenerate' = Regenerate token on every submission
427 | | 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks
428 | */
429 | $config['csrf_protection'] = FALSE;
430 | $config['csrf_token_name'] = 'csrf_test_name';
431 | $config['csrf_cookie_name'] = 'csrf_cookie_name';
432 | $config['csrf_expire'] = 7200;
433 | $config['csrf_regenerate'] = TRUE;
434 | $config['csrf_exclude_uris'] = array();
435 |
436 | /*
437 | |--------------------------------------------------------------------------
438 | | Output Compression
439 | |--------------------------------------------------------------------------
440 | |
441 | | Enables Gzip output compression for faster page loads. When enabled,
442 | | the output class will test whether your server supports Gzip.
443 | | Even if it does, however, not all browsers support compression
444 | | so enable only if you are reasonably sure your visitors can handle it.
445 | |
446 | | Only used if zlib.output_compression is turned off in your php.ini.
447 | | Please do not use it together with httpd-level output compression.
448 | |
449 | | VERY IMPORTANT: If you are getting a blank page when compression is enabled it
450 | | means you are prematurely outputting something to your browser. It could
451 | | even be a line of whitespace at the end of one of your scripts. For
452 | | compression to work, nothing can be sent before the output buffer is called
453 | | by the output class. Do not 'echo' any values with compression enabled.
454 | |
455 | */
456 | $config['compress_output'] = FALSE;
457 |
458 | /*
459 | |--------------------------------------------------------------------------
460 | | Master Time Reference
461 | |--------------------------------------------------------------------------
462 | |
463 | | Options are 'local' or any PHP supported timezone. This preference tells
464 | | the system whether to use your server's local time as the master 'now'
465 | | reference, or convert it to the configured one timezone. See the 'date
466 | | helper' page of the user guide for information regarding date handling.
467 | |
468 | */
469 | $config['time_reference'] = 'local';
470 |
471 | /*
472 | |--------------------------------------------------------------------------
473 | | Rewrite PHP Short Tags
474 | |--------------------------------------------------------------------------
475 | |
476 | | If your PHP installation does not have short tag support enabled CI
477 | | can rewrite the tags on-the-fly, enabling you to utilize that syntax
478 | | in your view files. Options are TRUE or FALSE (boolean)
479 | |
480 | */
481 | $config['rewrite_short_tags'] = FALSE;
482 |
483 |
484 | /*
485 | |--------------------------------------------------------------------------
486 | | Reverse Proxy IPs
487 | |--------------------------------------------------------------------------
488 | |
489 | | If your server is behind a reverse proxy, you must whitelist the proxy
490 | | IP addresses from which CodeIgniter should trust headers such as
491 | | HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify
492 | | the visitor's IP address.
493 | |
494 | | You can use both an array or a comma-separated list of proxy addresses,
495 | | as well as specifying whole subnets. Here are a few examples:
496 | |
497 | | Comma-separated: '10.0.1.200,192.168.5.0/24'
498 | | Array: array('10.0.1.200', '192.168.5.0/24')
499 | */
500 | $config['proxy_ips'] = '';
501 |
--------------------------------------------------------------------------------
/application/config/plugins.php:
--------------------------------------------------------------------------------
1 | /plugins/)
11 | */
12 | $config['plugin_dir'] = FCPATH . 'plugins/';
13 |
14 | require_once( APPPATH . 'libraries/abstract.plugins.php' );
15 | require_once( APPPATH . 'libraries/trait.plugins.php' );
--------------------------------------------------------------------------------
/application/controllers/Plugins.php:
--------------------------------------------------------------------------------
1 | _plugins = $this->Plugins_model->get_plugins();
13 |
14 | $this->plugins_lib->update_all_plugin_headers();
15 | }
16 |
17 | public function index()
18 | {
19 |
20 | $data = array();
21 |
22 | $data['plugins'] = $this->Plugins_model->get_plugins();
23 |
24 | $this->load->view('plugin_list', $data);
25 | }
26 |
27 | public function config()
28 | {
29 | $data = array();
30 |
31 | if( ! $plugin = $this->input->get('plugin'))
32 | {
33 | redirect('/');
34 | }
35 | elseif( ! isset($this->_plugins[$plugin]))
36 | {
37 | die("Unknown plugin {$plugin}");
38 | }
39 | elseif($this->_plugins[$plugin]->status != 1)
40 | {
41 | die("The plugin {$plugin} isn't enabled");
42 | }
43 | else
44 | {
45 | $data['plugin'] = $plugin;
46 |
47 | // Just some random stuff to send to the data, not needed unless the plugin
48 | // controller requires it
49 | $plugin_data = array('some' => 'data');
50 |
51 | if( ! $data['plugin_content'] = $this->plugins_lib->view_controller($plugin, $plugin_data))
52 | {
53 | die('No controller for this plugin');
54 | }
55 | }
56 |
57 |
58 | $this->load->view('plugin_settings', $data);
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/application/helpers/plugin_helper.php:
--------------------------------------------------------------------------------
1 | update_all_plugin_headers();
16 | }
17 | }
18 |
19 | // ------------------------------------------------------------------------
20 |
21 | if( ! function_exists('update_plugin_headers'))
22 | {
23 | /**
24 | * Shortcut to Plugins_lib::update_plugin_headers()
25 | *
26 | * Updates the plugin headers for a specified plugin based on the plugins .php file comments
27 | *
28 | * @param string $plugin Plugin system name
29 | *
30 | * @since 0.1.0
31 | * @return bool
32 | */
33 | function update_plugin_headers( $plugin )
34 | {
35 | return Plugins_lib::$instance->update_plugin_headers( $plugin );
36 | }
37 | }
38 |
39 | // ------------------------------------------------------------------------
40 |
41 | if( ! function_exists('install_plugin'))
42 | {
43 | /**
44 | * Shortcut to Plugins_lib::install_plugin()
45 | *
46 | * Executes whatevers in the plugins install method
47 | *
48 | * @param string $plugin Plugin system name
49 | *
50 | * @since 0.1.0
51 | * @return bool
52 | */
53 | function install_plugin( $plugin, $data = NULL )
54 | {
55 | return Plugins_lib::$instance->install_plugin( $plugin, $data );
56 | }
57 | }
58 |
59 | // ------------------------------------------------------------------------
60 |
61 | if( ! function_exists('enable_plugin'))
62 | {
63 | /**
64 | * Shortcut to Plugins_lib::enable_plugin()
65 | *
66 | * Enable a specified plugin by setting the database status value to 1
67 | *
68 | * @param string $plugin Plugin system name
69 | * @param mixed $data Any data that should be handed down to the plugins activation method (optional)
70 | *
71 | * @since 0.1.0
72 | * @return bool
73 | */
74 | function enable_plugin( $plugin, $data = NULL )
75 | {
76 | return Plugins_lib::$instance->enable_plugin( $plugin, $data );
77 | }
78 | }
79 |
80 | // ------------------------------------------------------------------------
81 |
82 | if( ! function_exists('disable_plugin'))
83 | {
84 | /**
85 | * Shortcut to Plugins_lib::disable_plugin()
86 | *
87 | * Disable a specified plugin by setting the database status value to 0
88 | *
89 | * @param string $plugin Plugin system name
90 | * @param mixed $data Any data that should be handed down to the plugins deactivate method (optional)
91 | *
92 | * @since 0.1.0
93 | * @return bool
94 | */
95 | function disable_plugin( $plugin, $data = NULL )
96 | {
97 | return Plugins_lib::$instance->disable_plugin( $plugin, $data );
98 | }
99 | }
100 |
101 | // ------------------------------------------------------------------------
102 |
103 | if( ! function_exists('plugin_details'))
104 | {
105 | /**
106 | * Shortcut to Plugins_lib::plugin_details()
107 | *
108 | * Return the details of a plugin from the plugins database table
109 | *
110 | * @param string $plugin Plugin system name
111 | *
112 | * @since 0.1.0
113 | * @return array
114 | */
115 | function plugin_details( $plugin )
116 | {
117 | return Plugins_lib::$instance->plugin_details( $plugin );
118 | }
119 | }
120 |
121 | // ------------------------------------------------------------------------
122 |
123 | if( ! function_exists('get_messages'))
124 | {
125 | /**
126 | * Shortcut to Plugins_lib::get_messages()
127 | *
128 | * Gets all the plugin messages thus far (errors, debug messages, warnings)
129 | *
130 | * @param string $type Specific type to retrieve, if NULL, all are returned
131 | *
132 | * @since 0.1.0
133 | * @return array
134 | */
135 | function get_messages( $type = NULL )
136 | {
137 | return Plugins_lib::$instance->get_messages( $type );
138 | }
139 | }
140 |
141 | // ------------------------------------------------------------------------
142 |
143 | if( ! function_exists('print_messages'))
144 | {
145 | /**
146 | * Shortcut to Plugins_lib::print_messages()
147 | *
148 | * Displays all the plugin messages thus far (errors, debug messages, warnings)
149 | *
150 | * @param string $type Specific type to retrieve, if NULL, all are printed
151 | *
152 | * @since 0.1.0
153 | * @return array
154 | */
155 | function print_messages( $type = NULL )
156 | {
157 | return Plugins_lib::$instance->print_messages( $type );
158 | }
159 | }
160 |
161 | // ------------------------------------------------------------------------
162 |
163 | if( ! function_exists('get_orphaned_plugins'))
164 | {
165 | /**
166 | * Shortcut to Plugins_lib::get_orphaned_plugins()
167 | *
168 | * See if there are any plugins in the plugins directory that arent in the database
169 | *
170 | * @since 0.1.0
171 | * @return array
172 | */
173 | function get_orphaned_plugins()
174 | {
175 | return Plugins_lib::$instance->get_orphaned_plugins();
176 | }
177 | }
178 |
179 | // ------------------------------------------------------------------------
180 |
181 | if( ! function_exists('add_action'))
182 | {
183 | /**
184 | * Shortcut to Plugins_lib::add_action()
185 | *
186 | * Add an action - a function that will fire off when a tag/action is executed (NOT
187 | * the same as add_filter - which will return a value
188 | *
189 | * @param string $tag Tag/Action thats being executed
190 | * @param string|array $function Either a single function (string), or a class and method (array)
191 | * @param int $priority Priority of this action
192 | *
193 | * @since 0.1.0
194 | * @return boolean
195 | */
196 | function add_action( $tag, $function, $priority = 10 )
197 | {
198 | return Plugins_lib::$instance->add_action( $tag, $function, $priority );
199 | }
200 | }
201 |
202 | // ------------------------------------------------------------------------
203 |
204 | if( ! function_exists('add_filter'))
205 | {
206 | /**
207 | * Shortcut to Plugins_lib::add_filter()
208 | *
209 | * Add a filter - a function that can be used to effect/parse/filter out some content (NOT
210 | * the same as add_action - which will just fire off a function
211 | *
212 | * @param string $tag Tag/Action thats being executed
213 | * @param string|array $function Either a single function (string), or a class and method (array)
214 | * @param int $priority Priority of this action
215 | *
216 | * @since 0.1.0
217 | * @return boolean
218 | */
219 | function add_filter( $tag, $function, $priority = 10 )
220 | {
221 | return Plugins_lib::$instance->add_filter( $tag, $function, $priority );
222 | }
223 | }
224 |
225 | // ------------------------------------------------------------------------
226 |
227 | if( ! function_exists('get_actions'))
228 | {
229 | /**
230 | * Shortcut to Plugins_lib::get_actions()
231 | *
232 | * Retrieve all actions/filters that are assigned to actions/tags
233 | *
234 | * @since 0.1.0
235 | * @return array
236 | */
237 | function get_actions()
238 | {
239 | return Plugins_lib::$instance->get_actions();
240 | }
241 | }
242 |
243 | // ------------------------------------------------------------------------
244 |
245 | if( ! function_exists('retrieve_plugins'))
246 | {
247 | /**
248 | * Shortcut to Plugins_lib::retrieve_plugins()
249 | *
250 | * Retrieve all plugins
251 | *
252 | * @since 0.1.0
253 | * @return array
254 | */
255 | function retrieve_plugins()
256 | {
257 | return Plugins_lib::$instance->retrieve_plugins();
258 | }
259 | }
260 |
261 | // ------------------------------------------------------------------------
262 |
263 | if( ! function_exists('do_action'))
264 | {
265 | /**
266 | * Shortcut to Plugins_lib::do_action()
267 | *
268 | * Execute all plugin functions tied to a specific tag
269 | *
270 | * @param string $tag Tag to execute
271 | * @param mixed $args Arguments to hand to plugin (Can be anything)
272 | *
273 | * @since 0.1.0
274 | * @return mixed
275 | */
276 | function do_action( $tag, array $args = NULL )
277 | {
278 | //log_message('error',"Doing $tag " . ($args ? "With args: " . serialize($args) : "With no args"));
279 | return Plugins_lib::$instance->do_action( $tag, $args );
280 | }
281 | }
282 |
283 | // ------------------------------------------------------------------------
284 |
285 | if( ! function_exists('remove_action'))
286 | {
287 | /**
288 | * Shortcut to Plugins_lib::remove_action()
289 | *
290 | * Remove a specific plugin function assigned to execute on a specific tag at a specific priority
291 | *
292 | * @param string $tag Tag to clear actions from
293 | * @param string|array $function Function or object/method to remove from tag
294 | * @param int $priority Priority to clear
295 | *
296 | * @since 0.1.0
297 | * @return boolean
298 | */
299 | function remove_action( $tag, $function, $priority = 10 )
300 | {
301 | return Plugins_lib::$instance->remove_action( $tag, $function, $priority );
302 | }
303 | }
304 |
305 | // ------------------------------------------------------------------------
306 |
307 | if( ! function_exists('current_action'))
308 | {
309 | /**
310 | * Shortcut to Plugins_lib::current_action()
311 | *
312 | * Get the current plugin action being executed
313 | *
314 | * @since 0.1.0
315 | * @return string
316 | */
317 | function current_action()
318 | {
319 | return Plugins_lib::$instance->current_action();
320 | }
321 | }
322 |
323 | // ------------------------------------------------------------------------
324 |
325 | if( ! function_exists('has_run'))
326 | {
327 | /**
328 | * Shortcut to Plugins_lib::has_run()
329 | *
330 | * See if an action has run or not
331 | *
332 | * @param string $action Tag/action to check
333 | *
334 | * @since 0.1.0
335 | * @return boolean
336 | */
337 | function has_run( $action = NULL )
338 | {
339 | return Plugins_lib::$instance->has_run( $action );
340 | }
341 | }
342 |
343 | // ------------------------------------------------------------------------
344 |
345 | if( ! function_exists('doing_action'))
346 | {
347 | /**
348 | * Shortcut to Plugins_lib::doing_action()
349 | *
350 | * If no action is specified, then the current action being executed will be returned, if
351 | * an action is specified, then TRUE/FALSE will be returned based on if the action is
352 | * being executed or not
353 | *
354 | * @oaran string $action Action to check
355 | * @since 0.1.0
356 | * @return boolean|string
357 | */
358 | function doing_action( $action = NULL )
359 | {
360 | return Plugins_lib::$instance->doing_action( $action );
361 | }
362 | }
363 |
364 | // ------------------------------------------------------------------------
365 |
366 | if( ! function_exists('did_action'))
367 | {
368 | /**
369 | * Shortcut to Plugins_lib::did_action()
370 | *
371 | * Check if an action/tag has been executed or not
372 | *
373 | * @param string $tag Tag/action to check
374 | *
375 | * @since 0.1.0
376 | * @return boolean
377 | */
378 | function did_action( $tag )
379 | {
380 | return Plugins_lib::$instance->did_action( $tag );
381 | }
382 | }
383 |
--------------------------------------------------------------------------------
/application/libraries/Plugins_lib.php:
--------------------------------------------------------------------------------
1 | load->model('Plugins_model');
132 |
133 | // Load the plugins helper
134 | static::$CI->load->helper('plugin');
135 |
136 | // Set a shorter handle for the plugins model
137 | static::$PM = static::$CI->Plugins_model;
138 |
139 | static::$messages = array(
140 | 'error' => [],
141 | 'debug' => [],
142 | 'warn' => []
143 | );
144 |
145 | // Set plugin path
146 | $this->set_plugin_dir();
147 |
148 | // Get all activated plugins
149 | $this->get_plugins();
150 |
151 | // Include plugins
152 | $this->include_enabled_plugins();
153 |
154 | // Load them
155 | $this->load_enabled_plugins();
156 | }
157 |
158 | // ------------------------------------------------------------------------
159 |
160 | /**
161 | * Set Plugin Directory
162 | *
163 | * Set the plugins directory that contains all the plugin folders, at the local
164 | * private property: static::$plugin_path
165 | *
166 | * @param str $dir Directory, an ending slash is appended if not found, and any
167 | * accidental double slashes are replaced with single slashes
168 | * @access private
169 | */
170 | private function set_plugin_dir()
171 | {
172 | if($path = static::$CI->config->item('plugin_path'))
173 | {
174 | $this->_debug("Plugin path set to {$path} via config setting");
175 | }
176 | elseif(defined('PLUGIN_DIR'))
177 | {
178 | $this->_debug("Plugin path set to ".PLUGIN_DIR."via constant PLUGIN_DIR");
179 |
180 | $path = PLUGIN_DIR;
181 | }
182 | else
183 | {
184 | $path = FCPATH . 'plugins/';
185 |
186 | $this->_debug("Plugin path defaulted to {$path}");
187 |
188 | $this->_warn("No plugin path specified in CI settings or PLUGIN_DIR constant, defaulting to {$path}");
189 | }
190 |
191 | // Make sure it ends in /
192 | if( preg_match('%/$%', $path) === FALSE )
193 | {
194 | $path = "{$path}/";
195 | }
196 |
197 | static::$plugin_path = str_replace('//','/',$path);
198 | }
199 |
200 | // ------------------------------------------------------------------------
201 |
202 | /**
203 | * View Controller
204 | *
205 | * View the controller from the plugin.
206 | *
207 | * @param string $plugin Systen name of plugin
208 | * @param mixed $plugin_data Any data to hand down to the plugin (Anything
209 | * processed from the controller, etc)
210 | * @access public
211 | * @since 0.1.0
212 | * @return string Whatever content is returned from the plugins controller (which
213 | * is usually HTML from the settings form)
214 | */
215 | public function view_controller($plugin, $plugin_data = NULL)
216 | {
217 | if( ! isset(static::$plugins[$plugin]))
218 | {
219 | log_message('error',"The plugin {$plugin} was not found");
220 |
221 | return FALSE;
222 | }
223 | elseif( ! method_exists(static::$plugins[$plugin]['handler'], 'controller'))
224 | {
225 | $this->_error('error','Plugin Error',"The plugin {$plugin} does not have a controller", TRUE);
226 |
227 | return FALSE;
228 | }
229 |
230 | return call_user_func(array(static::$plugins[$plugin]['handler'], 'controller'), $plugin_data);
231 | }
232 |
233 | // ------------------------------------------------------------------------
234 |
235 | /**
236 | * Plugin Error Collector
237 | *
238 | * Push an error message into the messages array
239 | *
240 | * @param string $message Message to push
241 | * @access private
242 | */
243 | private function _error($message)
244 | {
245 | //log_message('error', 'PLUGIN-ERROR: ' . $message);
246 |
247 | array_push(static::$messages['error'], $message);
248 | }
249 |
250 | // ------------------------------------------------------------------------
251 |
252 | /**
253 | * Plugin Debug Collector
254 | *
255 | * Push a debug message into the messages array
256 | *
257 | * @param string $message Message to push
258 | * @access private
259 | */
260 | private function _debug($message)
261 | {
262 | //log_message('debug', 'PLUGIN-DEBUG: ' . $message);
263 |
264 | array_push(static::$messages['debug'], $message);
265 | }
266 |
267 | // ------------------------------------------------------------------------
268 |
269 | /**
270 | * Plugin Warn Collector
271 | *
272 | * Push a warn message into the messages array
273 | *
274 | * @param string $message Message to push
275 | * @access private
276 | */
277 | private function _warn($message)
278 | {
279 | //log_message('error', 'PLUGIN-WARN: ' . $message);
280 |
281 | array_push(static::$messages['warn'], $message);
282 | }
283 |
284 | // ------------------------------------------------------------------------
285 |
286 | /**
287 | * Enable Plugin
288 | *
289 | * Enable a plugin by setting the plugins.status to 1 in the plugins table
290 | *
291 | * @oaram string $plugin Plugin Name
292 | * @param mixed $data Any data that should be handed down to the plugins deactivate method (optional)
293 | * @access public
294 | * @since 0.1.0
295 | * @return bool
296 | */
297 | public function enable_plugin($plugin, $data = NULL)
298 | {
299 | // Run the plugins activation method to run anything required by the plugin
300 | call_user_func(array(static::$plugins[$plugin]['handler'], 'activate'), $data);
301 |
302 | // Enable it in the database
303 | return static::$PM->set_status($plugin, 1);
304 | }
305 |
306 | // ------------------------------------------------------------------------
307 |
308 | /**
309 | * Disable Plugin
310 | *
311 | * Disable a plugin by setting the plugins.status to 0 in the plugins table
312 | *
313 | * @oaram string $plugin Plugin Name
314 | * @param mixed $data Any data that should be handed down to the plugins activate method (optional)
315 | * @access public
316 | * @since 0.1.0
317 | * @return bool
318 | */
319 | public function disable_plugin($plugin, $data = NULL)
320 | {
321 | // Run the plugins deactivation method to run anything required by the plugin
322 | call_user_func(array(static::$plugins[$plugin]['handler'], 'deactivate'), $data);
323 |
324 | // Disable it in the database
325 | return static::$PM->set_status($plugin, 0);
326 | }
327 |
328 | // ------------------------------------------------------------------------
329 |
330 | /**
331 | * Install Plugin
332 | *
333 | * Install a plugin by adding it to the database and executing any installation code thats in
334 | * the plugins install method
335 | *
336 | * @param string $plugin Plugins system name (Folder name)
337 | * @access public
338 | * @param boolean
339 | */
340 | public function install_plugin($plugin, $data = NULL)
341 | {
342 | // System name for folder and file
343 | $system_name = strtolower($plugin);
344 |
345 | // Class name is just system name with ucfirst
346 | $class_name = ucfirst($system_name);
347 |
348 | // Path to plugins main file
349 | $plugin_path = static::$plugin_path . "{$system_name}/{$system_name}.php";
350 |
351 | // If the plugins class hasnt been loaded...
352 | if( ! class_exists($class_name))
353 | {
354 | // Make sure a valid plugin file by the same name as the folder exists
355 | if (file_exists($plugin_path))
356 | {
357 | if( ! include_once $plugin_path)
358 | {
359 | $this->_error("Failed to install {$plugin}, there was an error loading the plugin file {$plugin_path}, is it readable?");
360 | }
361 | else
362 | {
363 | $this->_debug("Successfully loaded the plugin file {$plugin_path}");
364 | }
365 | }
366 | else
367 | {
368 | $this->_error("Failed to install {$plugin}, unable to find the file {$plugin_path}");
369 | }
370 | }
371 |
372 | // Execute the plugin installation
373 | return call_user_func("{$class_name}::install", $data);
374 | }
375 |
376 | // ------------------------------------------------------------------------
377 |
378 | /**
379 | * Plugin Details
380 | *
381 | * Retrieve the details of a plugin from the database
382 | *
383 | * @param string $plugin Plugin system name
384 | * @access public
385 | * @since 0.1.0
386 | * @return object|bool
387 | */
388 | public function plugin_details($plugin)
389 | {
390 | return static::$PM->get_plugin($plugin);
391 | }
392 |
393 | // ------------------------------------------------------------------------
394 |
395 | /**
396 | * Get Enabled Plugins
397 | *
398 | * Retrieve the enabled plugins from the database and load them into the enabled_plugins
399 | * array. This does not initiate the plugins, thats done in a different method
400 | *
401 | * @access private
402 | */
403 | private function get_plugins()
404 | {
405 | // Fetch all plugins
406 | if( ! $plugins = static::$PM->get_plugins())
407 | {
408 | return FALSE;
409 | }
410 |
411 | // Load the plugins
412 | foreach($plugins as $p)
413 | {
414 | if( ! isset( static::$plugins[ $p->system_name ] ) )
415 | {
416 | $this->_debug( "Adding plugin {$p->system_name}" );
417 |
418 | static::$plugins[$p->system_name] = array(
419 | 'data' => $p->data
420 | );
421 |
422 | // If its enabled, add it to $enabled_plugins referencing the plugin in $plugins
423 | if($p->status == '1')
424 | {
425 | $this->_debug( "Enabling plugin {$p->system_name}" );
426 |
427 | static::$enabled_plugins[ $p->system_name ] = &static::$plugins[$p->system_name];
428 | }
429 | }
430 | }
431 | }
432 |
433 | // ------------------------------------------------------------------------
434 |
435 | /**
436 | * Print Plugins
437 | *
438 | * Retrieve all plugin information from the database
439 | *
440 | * @access public
441 | * @since 0.1.0
442 | * @return array
443 | */
444 | public function retrieve_plugins()
445 | {
446 | return static::$PM->get_plugins();
447 | }
448 |
449 | // ------------------------------------------------------------------------
450 |
451 | /**
452 | * Include Enabled Plugins
453 | *
454 | * Iterate through the enabled_plugins property array and include the actual plugin files
455 | *
456 | * @access private
457 | */
458 | private function include_enabled_plugins()
459 | {
460 | if(empty(static::$enabled_plugins))
461 | {
462 | $this->_error("Unable to include enabled plugin files, enabled plugins not retrieved");
463 |
464 | return FALSE;
465 | }
466 |
467 | foreach(static::$enabled_plugins as $name => $p)
468 | {
469 | $plugin_path = static::$plugin_path . "{$name}/{$name}.php";
470 |
471 | // Make sure a valid plugin file by the same name as the folder exists
472 | if (file_exists($plugin_path))
473 | {
474 | if( ! include_once $plugin_path)
475 | {
476 | $this->_error("There was an error loading the plugin file {$plugin_path}");
477 | }
478 | else
479 | {
480 | $this->_debug("Successfully loaded the plugin file {$plugin_path}");
481 | }
482 | }
483 | else
484 | {
485 | $this->_error("Failed to include the plugin {$name}, unable to find the file {$plugin_path}");
486 | }
487 | }
488 | }
489 |
490 | // ------------------------------------------------------------------------
491 |
492 | /**
493 | * Load Enabled Plugins
494 | *
495 | * Load the enabled plugins into objects, store the objects into the loaded plugins array
496 | *
497 | * @access private
498 | */
499 | private function load_enabled_plugins()
500 | {
501 | if(static::$enabled_plugins)
502 | {
503 | foreach( static::$enabled_plugins as $name => $p )
504 | {
505 | new $name;
506 | }
507 | }
508 | }
509 |
510 | // ------------------------------------------------------------------------
511 |
512 | /**
513 | * Add Action
514 | *
515 | * Assign a function to be executed by a certain tag. An action will just fire off a function
516 | * when the tag is called, a filter will parse data and return the modified data
517 | *
518 | * @param string $tag Tag to add filter to
519 | * @param string|array $function Either a string (function), or an array (Object, method)
520 | * @param integer $priority Priority
521 | * @param string $type Either action or filter
522 | * @access public
523 | * @since 0.1.0
524 | * @return boolean
525 | */
526 | public function add_action($tag, $function, $priority = 10, $type = 'action')
527 | {
528 | if(is_array($function))
529 | {
530 | if(count($function) < 2)
531 | {
532 | // If its an array of one element, then just add the first element
533 | $function = $function[0];
534 | }
535 | elseif( ! is_object($function[0]))
536 | {
537 | $this->_error("Failing to add method '" . implode('::', $function) . "'' as {$type} to tag {$tag}, an array was given, first element was not an object");
538 |
539 | return FALSE;
540 | }
541 | elseif( ! method_exists($function[0], $function[1]))
542 | {
543 | $this->_error("Failing to add method '" . get_class($function[0]) . "::{$function[1]}' as {$type} to tag {$tag}, the method does not exist");
544 |
545 | return FALSE;
546 | }
547 | }
548 |
549 | // Execute is_array again, since the above could have converted it to an array
550 | if( ! is_array($function))
551 | {
552 | if( ! function_exists($function))
553 | {
554 | $this->_error("Failing to add function {$function} as {$type} to tag {$tag}, the function does not exist");
555 |
556 | return FALSE;
557 | }
558 | }
559 |
560 | if( ! in_array($type, ['action','filter']))
561 | {
562 | $this->_error("Unknown type '{$type}', must be 'filter' or 'action'");
563 |
564 | return FALSE;
565 | }
566 |
567 | static::$actions[$tag][$priority][] = array(
568 | 'function' => $function,
569 | 'type' => $type
570 | );
571 |
572 | return TRUE;
573 | }
574 |
575 | // ------------------------------------------------------------------------
576 |
577 | /**
578 | * Add Filter
579 | *
580 | * Just a wrapper for add_function except adds it as type 'filter'. Filters will
581 | * take in data and perform an action on it, then return it, actions will just
582 | * fire off a function
583 | *
584 | * @param string $tag Tag to add filter to
585 | * @param string|array $function Either a string (function), or an array (Object, method)
586 | * @param integer $priority Priority
587 | * @access public
588 | * @since 0.1.0
589 | * @return boolean
590 | */
591 | public function add_filter($tag, $function, $priority = 10)
592 | {
593 | return $this->add_action($tag, $function, $priority, 'filter');
594 | }
595 |
596 | // ------------------------------------------------------------------------
597 |
598 | /**
599 | * Get Actions
600 | *
601 | * Get actions....
602 | *
603 | * @access public
604 | * @since 0.1.0
605 | * @return array
606 | */
607 | public function get_actions()
608 | {
609 | foreach(static::$actions as $k => $a)
610 | ksort(static::$actions[$k]);
611 |
612 | return static::$actions;
613 | }
614 |
615 | // ------------------------------------------------------------------------
616 |
617 | /**
618 | * Do Action
619 | *
620 | * Execute a specific action, pass optional arguments to it
621 | * @param string $tag Tag to execute
622 | * @param null $args Arguments to hand to functions assigned to tag
623 | * @access public
624 | * @since 0.1.0
625 | * @return mixed Returns whatever the type of $args is
626 | */
627 | public function do_action($tag, array $args = NULL)
628 | {
629 | static::$current_action = $tag;
630 |
631 | array_push(static::$run_actions, $tag);
632 |
633 | if( ! isset(static::$actions[$tag]))
634 | {
635 | $this->_debug("No actions found for tag {$tag}");
636 |
637 | return $args;
638 | }
639 |
640 | ksort(static::$actions[$tag]);
641 |
642 | //die('
' . print_r(static::$actions, TRUE));
643 |
644 | foreach(static::$actions[$tag] as $actions)
645 | {
646 | foreach($actions as $a)
647 | {
648 | // Make sure the function or method exists
649 | if(is_array($a['function']))
650 | {
651 | // Methods are setup as an array, [0] is the object/class, [1] is the method
652 | if( ! method_exists($a['function'][0], $a['function'][1]))
653 | {
654 | $this->_error("Unable to execute method '" . get_class($a['function'][0]) . "::{$a['function'][1]}' for action {$tag}, the method doesn't exist");
655 |
656 | return $args;
657 | }
658 | }
659 | else
660 | {
661 | // Strings are just functions
662 | if( ! function_exists($a['function']))
663 | {
664 | $this->_error("Unable to execute function '{$a['function']}' for action {$tag}, the function doesn't exist");
665 |
666 | return $args;
667 | }
668 | }
669 |
670 | // Actions
671 | if($a['type'] == 'action')
672 | {
673 | // No arguments/null
674 | if( ! $args)
675 | {
676 | call_user_func( $a['function'] );
677 | }
678 | else
679 | {
680 | call_user_func_array( $a['function'], $args );
681 | }
682 | }
683 | // Filters
684 | else
685 | {
686 | // No arguments/null
687 | if( ! $args)
688 | {
689 | $args = call_user_func( $a['function'] );
690 | }
691 | else
692 | {
693 | $args = call_user_func_array( $a['function'], $args );
694 | }
695 | }
696 | }
697 | }
698 |
699 | static::$current_action = NULL;
700 |
701 | // Be polite, return it as you found it
702 | settype($args, gettype($args));
703 |
704 | return $args;
705 | }
706 |
707 | // ------------------------------------------------------------------------
708 |
709 | /**
710 | * Remove Action
711 | *
712 | * Remove a function from an action
713 | *
714 | * @param string $tag Tag to check in
715 | * @param mixed $function Function to be removed
716 | * @param integer $priority Priority to check for function
717 | * @access public
718 | * @since 0.1.0
719 | * @return boolean
720 | */
721 | public function remove_action($tag, $function, $priority = 10)
722 | {
723 | if (isset(static::$actions[$tag][$priority][$function]))
724 | {
725 | // Remove the action hook from our hooks array
726 | unset(static::$actions[$tag][$priority][$function]);
727 | }
728 |
729 | return TRUE;
730 |
731 | }
732 |
733 | // ------------------------------------------------------------------------
734 |
735 | /**
736 | * Current Action
737 | *
738 | * Set the currently running action
739 | *
740 | * @access public
741 | * @since 0.1.0
742 | * @return string
743 | */
744 | public function current_action()
745 | {
746 | return static::$current_action;
747 | }
748 |
749 | // ------------------------------------------------------------------------
750 |
751 | /**
752 | * Has Run
753 | *
754 | * See if a particular action has ran yet
755 | *
756 | * @param string $action Action to check for
757 | * @access public
758 | * @since 0.1.0
759 | * @return boolean
760 | */
761 | public function has_run($action)
762 | {
763 | if (isset(static::$run_actions[$action]))
764 | {
765 | return true;
766 | }
767 | else
768 | {
769 | return false;
770 | }
771 | }
772 |
773 | // ------------------------------------------------------------------------
774 |
775 | /**
776 | * Update Plugin Headers
777 | *
778 | * Parse a given plugins PHP file for the header information in the comments, and update the database info
779 | * accordingly
780 | *
781 | * @param string $plugin Plugin System Name to check
782 | * @access public
783 | * @todo Try to retrieve only the top X lines of the file, not the whole file
784 | * @since 0.1.0
785 | * @return TRUE Always true
786 | */
787 | public function update_plugin_headers($plugin)
788 | {
789 | if (isset(static::$plugins[$plugin]))
790 | {
791 | $arr = array();
792 |
793 | $plugin_data = file_get_contents(static::$plugin_path.$plugin."/".$plugin.".php"); // Load the plugin we want
794 |
795 | preg_match ('|Plugin Name:(.*)$|mi', $plugin_data, $name);
796 | preg_match ('|Plugin URI:(.*)$|mi', $plugin_data, $uri);
797 | preg_match ('|Version:(.*)|i', $plugin_data, $version);
798 | preg_match ('|Description:(.*)$|mi', $plugin_data, $description);
799 | preg_match ('|Author:(.*)$|mi', $plugin_data, $author_name);
800 | preg_match ('|Author URI:(.*)$|mi', $plugin_data, $author_uri);
801 |
802 | if (isset($name[1]))
803 | {
804 | $arr['name'] = trim($name[1]);
805 | }
806 |
807 | if (isset($uri[1]))
808 | {
809 | $arr['uri'] = trim($uri[1]);
810 | }
811 |
812 | if (isset($version[1]))
813 | {
814 | $arr['version'] = trim($version[1]);
815 | }
816 |
817 | if (isset($description[1]))
818 | {
819 | $arr['description'] = trim($description[1]);
820 | }
821 |
822 | if (isset($author_name[1]))
823 | {
824 | $arr['author'] = trim($author_name[1]);
825 | }
826 |
827 | if (isset($author_uri[1]))
828 | {
829 | $arr['author_uri'] = trim($author_uri[1]);
830 | }
831 |
832 | if(empty($arr))
833 | {
834 | $this->_warn("Skipping header update for {$plugin}, no headers matched");
835 | }
836 | elseif(self::$PM->update_plugin_info($plugin, $arr))
837 | {
838 | $this->_debug("Updated plugin headers for {$plugin}: " . serialize($arr));
839 | }
840 | else
841 | {
842 | $this->_error("Failed to update plugin headers for {$plugin}: " . serialize($arr));
843 | }
844 | }
845 |
846 | return TRUE;
847 | }
848 |
849 | // ------------------------------------------------------------------------
850 |
851 | /**
852 | * Update All Plugin Headers
853 | *
854 | * Execute self::update_plugin_headers for each plugin found in static::$plugins
855 | *
856 | * @access public
857 | * @since 0.1.0
858 | * @return boolean
859 | */
860 | public function update_all_plugin_headers()
861 | {
862 | if(empty(static::$plugins))
863 | {
864 | $this->_warn("No plugins to update headers for");
865 |
866 | return TRUE;
867 | }
868 |
869 | foreach(static::$plugins as $name => $plugin)
870 | {
871 | $this->_debug("Updating plugin headers for {$name}");
872 |
873 | if( ! $this->update_plugin_headers($name))
874 | {
875 | return FALSE;
876 | }
877 | }
878 |
879 | return TRUE;
880 | }
881 |
882 | // ------------------------------------------------------------------------
883 |
884 | /**
885 | * Doing Action
886 | *
887 | * If the param is NULL, then this will return what action is being executed,
888 | * if an action is supplied, then it will return boolean based on if that action
889 | * is being executed or not
890 | *
891 | * @param null $action Action to check for
892 | */
893 | public function doing_action($action = NULL)
894 | {
895 | if(is_null($action))
896 | {
897 | return static::$current_action;
898 | }
899 | else
900 | {
901 | return $action === static::$current_action;
902 | }
903 | }
904 |
905 | // ------------------------------------------------------------------------
906 |
907 | /**
908 | * Did Action
909 | *
910 | * Returns if a tag has been fired or not
911 | *
912 | * @param $tag
913 | */
914 | public function did_action($tag)
915 | {
916 | return in_array($tag, static::$run_actions);
917 | }
918 |
919 | // ------------------------------------------------------------------------
920 |
921 | /**
922 | * Get Orphaned Plugins
923 | *
924 | * Look in the plugin directory for any folders that do not have an associated entry
925 | * in the plugins table
926 | *
927 | * @access public
928 | * @since 0.1.0
929 | * @return array|bool If no orphaned plugins are found, return false
930 | */
931 | public function get_orphaned_plugins()
932 | {
933 | $files = scandir(static::$plugin_path);
934 |
935 | $plugins = static::$PM->get_plugins();
936 |
937 | $orphaned = array();
938 |
939 | foreach($files as $f)
940 | {
941 | // Skip directories
942 | if(in_array($f, ['.','..'])) continue;
943 |
944 | if( ! isset($plugins[$f]))
945 | {
946 | array_push($orphaned, $f);
947 | }
948 | }
949 |
950 | return (count($orphaned) > 0 ? $orphaned : FALSE);
951 | }
952 |
953 | // ------------------------------------------------------------------------
954 |
955 | /**
956 | * Get Messages
957 | *
958 | * Get all messages, or a specific type of message
959 | *
960 | * @param string $type Type of error to retrieve (error, debug, warn)
961 | * @access public
962 | * @since 0.1.0
963 | * @return array|bool
964 | */
965 | public function get_messages($type = NULL)
966 | {
967 | if( ! $type)
968 | {
969 | return static::$messages;
970 | }
971 | elseif( ! isset(static::$messages[ strtolower($type) ]))
972 | {
973 | $this->_error("Failed to retrieve error type '{$type}', no such type found. Use 'error', 'warn' or 'debug'");
974 |
975 | return FALSE;
976 | }
977 |
978 | return static::$messages[strtolower($type)];
979 | }
980 |
981 | // ------------------------------------------------------------------------
982 |
983 | /**
984 | * Print Messages
985 | *
986 | * Print all messages, or messages of a certain type
987 | *
988 | * @param string $type Type of error to display (error, debug, warn)
989 | * @access public
990 | * @since 0.1.0
991 | * @return array|bool
992 | */
993 | public function print_messages($type = NULL)
994 | {
995 | if($type)
996 | {
997 | if(@empty(static::$messages[ strtolower($type) ]) || ! isset(static::$messages[ strtolower($type) ]))
998 | {
999 | echo "{$type} IS EMPTY\n";
1000 | return TRUE;
1001 | }
1002 |
1003 | echo "Plugin Messages - " . ucfirst($type) . "
\n";
1004 |
1005 | echo "\n";
1006 |
1007 | foreach(static::$messages[ strtolower($type) ] as $m)
1008 | {
1009 | echo "- $m
\n";
1010 | }
1011 |
1012 | echo "
\n\n";
1013 |
1014 | return TRUE;
1015 | }
1016 |
1017 | foreach(static::$messages as $type => $messages)
1018 | {
1019 | if(@empty($messages))
1020 | {
1021 | echo "{$type} IS EMPTY\n";
1022 | continue;
1023 | }
1024 |
1025 | echo "Plugin Messages - " . ucfirst($type) . "
\n";
1026 |
1027 | echo "\n";
1028 |
1029 | foreach($messages as $m)
1030 | {
1031 | echo "- $m
\n";
1032 | }
1033 |
1034 | echo "
\n\n";
1035 | }
1036 |
1037 | return TRUE;
1038 | }
1039 | }
--------------------------------------------------------------------------------
/application/libraries/abstract.plugins.php:
--------------------------------------------------------------------------------
1 | input->get($index, $xss_clean);
61 | }
62 |
63 | // ------------------------------------------------------------------------
64 |
65 | /**
66 | * Fetch an item from the POST array
67 | *
68 | * Shortcut to Loader::post()
69 | *
70 | * @param mixed $index Index for item to be fetched from $_POST
71 | * @param bool $xss_clean Whether to apply XSS filtering
72 | * @access protected
73 | * @since 0.1.0
74 | * @return mixed
75 | */
76 | protected function post($index = NULL, $xss_clean = NULL)
77 | {
78 | return parent::$CI->input->post($index, $xss_clean);
79 | }
80 |
81 | // ------------------------------------------------------------------------
82 |
83 | /**
84 | * Fetch an item from POST data with fallback to GET
85 | *
86 | * Shortcut to Loader::post_get()
87 | *
88 | * @param string $index Index for item to be fetched from $_POST or $_GET
89 | * @param bool $xss_clean Whether to apply XSS filtering
90 | * @access protected
91 | * @since 0.1.0
92 | * @return mixed
93 | */
94 | protected function post_get($index, $xss_clean = NULL)
95 | {
96 | return parent::$CI->input->post_get($index, $xss_clean);
97 | }
98 |
99 | // ------------------------------------------------------------------------
100 |
101 | /**
102 | * Fetch an item from GET data with fallback to POST
103 | *
104 | * Shortcut to Loader::get_post()
105 | *
106 | * @param string $index Index for item to be fetched from $_GET or $_POST
107 | * @param bool $xss_clean Whether to apply XSS filtering
108 | * @access protected
109 | * @since 0.1.0
110 | * @return mixed
111 | */
112 | protected function get_post($index, $xss_clean = NULL)
113 | {
114 | return parent::$CI->input->get_post($index, $xss_clean);
115 | }
116 |
117 | // ------------------------------------------------------------------------
118 |
119 | /**
120 | * Plugin View
121 | *
122 | * Load a plugin view via Loader::plugin_view()
123 | *
124 | * @param str $view Plugin view to load, must exist in the /views/ folder of the plugins root directory
125 | * @param array $data Data to load into view.
126 | * @access protected
127 | * @since 0.1.0
128 | * @return str String value of processed view
129 | */
130 | protected function view($view, array $data = array())
131 | {
132 | $backtrace = debug_backtrace();
133 |
134 | if( ! isset($backtrace[1]['class']))
135 | {
136 | return FALSE;
137 | }
138 |
139 | // The strtolower version of the class name should be the plugin folder name
140 | $class = strtolower($backtrace[1]['class']);
141 |
142 | return parent::$CI->load->plugin_view($class, $view, $data, TRUE);
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/application/models/Plugins_model.php:
--------------------------------------------------------------------------------
1 | db;
63 | }
64 |
65 | // ------------------------------------------------------------------------
66 |
67 | /**
68 | * Get Plugins
69 | *
70 | * Get all plugins, return an array of the plugins from the database, with the system_name
71 | * as the keys
72 | *
73 | * @access public
74 | * @since 0.1.0
75 | * @return array|bool
76 | */
77 | public function get_plugins()
78 | {
79 | $query = static::$db->get('plugins');
80 |
81 | if( ! $result = $query->result())
82 | {
83 | log_message('error','Error retrieving plugins from database');
84 |
85 | return FALSE;
86 | }
87 |
88 | $return = array();
89 |
90 | foreach($result as $r)
91 | {
92 | if( ! empty($r->data))
93 | {
94 | $r->data = unserialize($r->data);
95 | }
96 |
97 | $return[$r->system_name] = $r;
98 | }
99 |
100 | return $return;
101 | }
102 |
103 | // ------------------------------------------------------------------------
104 |
105 | /**
106 | * Update Plugin Info
107 | *
108 | * Update the plugin information in the database. This is typically executed by the
109 | * Plugins_lib::update_headers() which parses the comments of the plugin for the info
110 | *
111 | * @param str $plugin The system_name of the plugin
112 | * @param array $settings New settings for plugin
113 | * @access public
114 | * @since 0.1.0
115 | * @return bool
116 | */
117 | public function update_plugin_info($plugin, array $settings)
118 | {
119 | return static::$db->where('system_name', $plugin)->update('plugins', $settings);
120 | }
121 |
122 | // ------------------------------------------------------------------------
123 |
124 | /**
125 | * Set Status
126 | *
127 | * Enable/Disable plugin
128 | *
129 | * @param string $plugin Plugin system name
130 | * @param bool $status Status to set plugin as
131 | * @access public
132 | * @since 0.1.0
133 | * @return bool
134 | */
135 | public function set_status($plugin, $status)
136 | {
137 | log_message("error","PLUGIN: $plugin; STATUS: $status");
138 |
139 | if( ! static::$db
140 | ->where('system_name', $plugin)
141 | ->update('plugins', ['status' => $status]))
142 | {
143 | return FALSE;
144 | }
145 |
146 | return TRUE;
147 | }
148 |
149 | // ------------------------------------------------------------------------
150 |
151 | /**
152 | * Get Plugin
153 | *
154 | * Retrieve the data from the database for a single plugin by the plugin system name
155 | *
156 | * @param string $plugin Plugin System Name
157 | * @access public
158 | * @since 0.1.0
159 | * @return bool|object
160 | */
161 | public function get_plugin($plugin)
162 | {
163 | $query = static::$db->get_where('plugins', ['system_name' => $plugin]);
164 |
165 | $result = $query->result();
166 |
167 | return ( ! @empty($result[0]) ? $result[0] : FALSE);
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/application/models/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/views/plugin_list.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Plugin |
5 | Status |
6 | URI |
7 | Version |
8 | Description |
9 | Author |
10 | Data |
11 |
12 |
13 |
14 | $p): ?>
15 |
16 | system_name . '">' . $p->name . ''; ?> |
17 | status ? 'Enabled' : 'Disabled'); ?> |
18 | uri . '" target="_blank">' . $p->uri . ''; ?> |
19 | version; ?> |
20 | description; ?> |
21 | author_uri . '" target="_blank">' . $p->author . ''; ?> |
22 | data ? print_r(unserialize($p->data), TRUE) : 'No Data'); ?> |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/application/views/plugin_settings.php:
--------------------------------------------------------------------------------
1 | Settings for
2 |
3 |
--------------------------------------------------------------------------------
/plugin_database.sql:
--------------------------------------------------------------------------------
1 | -- MySQL dump 10.13 Distrib 5.5.42, for osx10.6 (i386)
2 | --
3 | -- Host: localhost Database: citest
4 | -- ------------------------------------------------------
5 | -- Server version 5.5.42
6 |
7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
10 | /*!40101 SET NAMES utf8 */;
11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
12 | /*!40103 SET TIME_ZONE='+00:00' */;
13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
17 |
18 | --
19 | -- Table structure for table `citest_table1`
20 | --
21 |
22 | DROP TABLE IF EXISTS `citest_table1`;
23 | /*!40101 SET @saved_cs_client = @@character_set_client */;
24 | /*!40101 SET character_set_client = utf8 */;
25 | CREATE TABLE `citest_table1` (
26 | `id` int(11) NOT NULL AUTO_INCREMENT,
27 | `first_name` varchar(100) DEFAULT NULL,
28 | PRIMARY KEY (`id`)
29 | ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
30 | /*!40101 SET character_set_client = @saved_cs_client */;
31 |
32 | --
33 | -- Dumping data for table `citest_table1`
34 | --
35 |
36 | LOCK TABLES `citest_table1` WRITE;
37 | /*!40000 ALTER TABLE `citest_table1` DISABLE KEYS */;
38 | INSERT INTO `citest_table1` VALUES (1,'Justin'),(2,'Amanda');
39 | /*!40000 ALTER TABLE `citest_table1` ENABLE KEYS */;
40 | UNLOCK TABLES;
41 |
42 | --
43 | -- Table structure for table `citest_table2`
44 | --
45 |
46 | DROP TABLE IF EXISTS `citest_table2`;
47 | /*!40101 SET @saved_cs_client = @@character_set_client */;
48 | /*!40101 SET character_set_client = utf8 */;
49 | CREATE TABLE `citest_table2` (
50 | `id` int(11) NOT NULL AUTO_INCREMENT,
51 | `last_name` varchar(100) NOT NULL,
52 | PRIMARY KEY (`id`)
53 | ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
54 | /*!40101 SET character_set_client = @saved_cs_client */;
55 |
56 | --
57 | -- Dumping data for table `citest_table2`
58 | --
59 |
60 | LOCK TABLES `citest_table2` WRITE;
61 | /*!40000 ALTER TABLE `citest_table2` DISABLE KEYS */;
62 | INSERT INTO `citest_table2` VALUES (1,'Hyland'),(2,'Trueba');
63 | /*!40000 ALTER TABLE `citest_table2` ENABLE KEYS */;
64 | UNLOCK TABLES;
65 |
66 | --
67 | -- Table structure for table `plugins`
68 | --
69 |
70 | DROP TABLE IF EXISTS `plugins`;
71 | /*!40101 SET @saved_cs_client = @@character_set_client */;
72 | /*!40101 SET character_set_client = utf8 */;
73 | CREATE TABLE `plugins` (
74 | `plugin_id` int(11) NOT NULL AUTO_INCREMENT,
75 | `system_name` varchar(150) NOT NULL,
76 | `name` varchar(150) NOT NULL,
77 | `status` tinyint(1) NOT NULL DEFAULT '1',
78 | `uri` varchar(255) DEFAULT NULL,
79 | `version` varchar(10) NOT NULL,
80 | `description` varchar(255) DEFAULT NULL,
81 | `author` varchar(50) DEFAULT NULL,
82 | `author_uri` varchar(255) DEFAULT NULL,
83 | `data` longtext,
84 | PRIMARY KEY (`plugin_id`)
85 | ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
86 | /*!40101 SET character_set_client = @saved_cs_client */;
87 |
88 | --
89 | -- Dumping data for table `plugins`
90 | --
91 |
92 | LOCK TABLES `plugins` WRITE;
93 | /*!40000 ALTER TABLE `plugins` DISABLE KEYS */;
94 | INSERT INTO `plugins` VALUES (1,'hello_world','Hello World',1,'https://github.com/jhyland87/CI3_Plugin_System','1.0','Apply colors to asset table cells or rows depending on values','Justin Hyland','http://justinhyland.com',NULL);
95 | /*!40000 ALTER TABLE `plugins` ENABLE KEYS */;
96 | UNLOCK TABLES;
97 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
98 |
99 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
100 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
101 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
102 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
103 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
104 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
105 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
106 |
107 | -- Dump completed on 2015-09-25 13:36:16
108 |
--------------------------------------------------------------------------------
/plugins/hello_world/hello_world.php:
--------------------------------------------------------------------------------
1 | {$foo}..
";
39 | }
40 |
41 |
42 | $content .= '
';
46 |
47 | return $content;
48 | }
49 |
50 |
51 | // Just an example filter to alter the values of an array
52 | public function alter_name($data)
53 | {
54 | array_walk($data, function(&$item, $key){
55 | if(strtolower($item) === 'jane')
56 | $item = 'john';
57 |
58 | $item = ucfirst($item);
59 | });
60 |
61 | return $data;
62 | }
63 |
64 | // Example plugin action, just logs.. stuff
65 | public function log_stuff($prefix, $data)
66 | {
67 |
68 | log_message('info', "[{$prefix}] " . __METHOD__ . ": Logging stuff - " . ((is_array($data) || is_object($data)) ? serialize($data) : $data));
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/plugins/hello_world/views/settings.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | Result:
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------