PluginProbe
CSS & JavaScript Toolbox / 11.5
CSS & JavaScript Toolbox v11.5
trunk 0.3 0.8 10 10.1 11 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 11.9.1 12 12.0 12.0.1 12.0.3 12.0.4 12.0.5 12.0.6 12.0.7 6.0 6.0.11 All 60 releases
css-javascript-toolbox / framework / extensions / extensions.class.php

extensions.class.php in CSS & JavaScript Toolbox 11.5, at framework/extensions/extensions.class.php

464 lines 13.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 *
4 */
5
6 // Disallow direct access.
7 defined('ABSPATH') or die("Access denied");
8
9 /**
10 *
11 */
12 class CJTExtensions extends CJTHookableClass {
13
14 /**
15 *
16 */
17 const CACHE_OPTION_NAME = 'cjt_extensions';
18
19 /**
20 *
21 */
22 const LOAD_METHOD = 'getInvolved';
23
24 /**
25 *
26 */
27 const PREFIXS = 'cjte-,css-javascript-toolbox-';
28
29 /**
30 * put your comment there...
31 *
32 * @var mixed
33 */
34 protected $defDocs;
35
36 /**
37 * put your comment there...
38 *
39 * @var mixed
40 */
41 protected $extensions;
42
43 /**
44 * put your comment there...
45 *
46 * @var mixed
47 */
48 protected $file2Classmap;
49
50 /**
51 * put your comment there...
52 *
53 * @var mixed
54 */
55 protected $incompatibilies;
56
57 /**
58 * put your comment there...
59 *
60 * @var mixed
61 */
62 protected $incompatibleAddons = array();
63
64
65 /**
66 * put your comment there...
67 *
68 * @var mixed
69 */
70 protected $loadMethod;
71
72 /**
73 * put your comment there...
74 *
75 * @var mixed
76 */
77 protected $onautoload = array('parameters' => array('file', 'class'));
78
79 /**
80 * put your comment there...
81 *
82 * @var mixed
83 */
84 protected $onbindevent = array('parameters' => array('event', 'callback'));
85
86 /**
87 * put your comment there...
88 *
89 * @var mixed
90 */
91 protected $ondetectextension = array('parameters' => array('extension'));
92
93 /**
94 * put your comment there...
95 *
96 * @var mixed
97 */
98 protected $ongetactiveplugins = array('parameters' => array('plugins'));
99
100 /**
101 * put your comment there...
102 *
103 * @var mixed
104 */
105 protected $onload = array('parameters' => array('params'));
106
107 /**
108 * put your comment there...
109 *
110 * @var mixed
111 */
112 protected $onloadcallback = array('parameters' => array('callback'));
113
114 /**
115 * put your comment there...
116 *
117 * @var mixed
118 */
119 protected $onloaddefinition = array('parameters' => array('definition'));
120
121 /***
122 * put your comment there...
123 *
124 * @var mixed
125 */
126 protected $ontregisterautoload = array('parameters' => array('callback'));
127
128 /**
129 * put your comment there...
130 *
131 * @var mixed
132 */
133 protected $onreloadcacheparameters = array('parameters' => array('params'));
134
135 /**
136 * put your comment there...
137 *
138 * @var mixed
139 */
140 protected $onloaded = array(
141 'hookType' => CJTWordpressEvents::HOOK_ACTION,
142 'parameters' => array('class', 'extension', 'definition', 'result')
143 );
144
145 /**
146 * put your comment there...
147 *
148 * @var mixed
149 */
150 protected $prefix;
151
152 /**
153 * put your comment there...
154 *
155 * @param mixed $className
156 */
157 public function _autoload($className) {
158
159 // Load only classed defined on the list!
160 if (isset($this->extensions[$className])) {
161 $classFile = $this->onautoload($this->extensions[$className]['runtime']['classFile'], $className);
162 // Import class file!
163 require_once $classFile;
164 }
165 }
166
167 /**
168 * put your comment there...
169 *
170 * @param mixed $prefix
171 * @param mixed $loadMethod
172 * @return CJTExtensions
173 */
174 public function __construct($prefix = self::PREFIXS, $loadMethod = self::LOAD_METHOD) {
175 // Hookable!
176 parent::__construct();
177
178 // Initialize incomapiblt addons meta data
179 $this->incompatibleAddons = array(
180
181 'css-javascript-toolbox-plus' => array(
182 '9.4',
183 '<',
184 'Aborted',
185
186 function() {
187
188 ob_start();
189
190 require CJTOOLBOX_PATH . DIRECTORY_SEPARATOR . 'includes' .
191 DIRECTORY_SEPARATOR . 'html' . DIRECTORY_SEPARATOR .
192 'incompatible_cjtplus_version.html.php';
193
194 $content = ob_get_clean();
195
196 return $content;
197 }
198
199 ),
200
201 );
202
203 // Initializing!
204 $this->prefix = explode( ',', $prefix );
205 $this->loadMethod = $loadMethod;
206 }
207
208 /**
209 * put your comment there...
210 *
211 */
212 public function __destruct() {
213 spl_autoload_unregister(array($this, '_autoload'));
214 }
215
216 /**
217 * put your comment there...
218 *
219 * @param mixed $reload
220 * @return CJTExtensions
221 */
222 public function & getExtensions($reload = false) {
223 // Get cached extensions or cache then if not yest cached!
224 extract($this->onreloadcacheparameters(compact('reload')));
225 if ($reload || (!($extensions = $this->extensions) && !($extensions = get_option(self::CACHE_OPTION_NAME, array())))) {
226 //Resting!
227 $this->file2Classmap = array();
228 $extensions = array();
229 # Get all active plugins
230 $activePlugins = wp_get_active_and_valid_plugins();
231 # Get Network plugins
232 if (is_multisite()) {
233 $activePlugins = array_merge(wp_get_active_network_plugins(), $activePlugins);
234 }
235 // filter all installed Plugins to fetch all out Extensions!
236 $activePlugins = $this->ongetactiveplugins($activePlugins);
237 foreach ($activePlugins as $file) {
238 $pluginDir = dirname($file);
239 $pluginName = basename($pluginDir);
240 // Any plugin with our prefix is a CJT extension!
241 if ( ( strpos( $pluginName, $this->prefix[0] ) === 0 ) ||
242 ( strpos( $pluginName, $this->prefix[1] ) === 0 ) ) {
243 // CJT Extsnsion must has the definition XML file!
244 // First try for Edition-Specific file
245 // if not exists try the generic one.
246 $xmlFile = "{$pluginDir}/{$pluginName}.xml";
247 if (file_exists($xmlFile)) {
248 // Get Plugin primary data!
249 $extension = array();
250 $extension['pluginFile'] = $file;
251 $extension['file'] = basename($file);
252 $extension['defFile'] = basename($pluginDir) . DIRECTORY_SEPARATOR . basename($xmlFile);
253 // Its useful to use ABS path only at runtime as it might changed as host might get moved.
254 $extension['dir'] = basename($pluginDir);
255 $extension['name'] = $pluginName;
256 // Cache XML file.
257 $extension['definition']['raw'] = file_get_contents($xmlFile);
258 // Filer!
259 $extension = $this->ondetectextension($extension);
260 // Read Basic XML Definition!
261 $definitionXML = $this->onloaddefinition(new SimpleXMLElement($extension['definition']['raw']));
262 $attrs = $definitionXML->attributes();
263 $extension['defDoc'] = $definitionXML;
264 $extension['definition']['primary']['loadMethod'] = (string) $attrs->loadMethod;
265 $extension['definition']['primary']['requiredLicense'] = (string) $definitionXML->license;
266 $className = ((string) $attrs->class);
267 // Add to list!
268 $extensions[$className] = $extension;
269 // Map Plugin FILE-2-CLASS name!
270 $this->file2Classmap["{$extension['dir']}/{$extension['file']}"] = $className;
271 }
272 }
273 }
274 }
275 $this->extensions = $this->onload($extensions);
276 // Chaining
277 return $this->extensions;
278 }
279
280 /**
281 * put your comment there...
282 *
283 */
284 public function load() {
285
286 // Initialize.
287 $frameworkVersion = new CJT_Framework_Version_Version(CJTPlugin::FW_Version);
288
289 // Auto load CJT extensions files when requested.
290 spl_autoload_register($this->ontregisterautoload(array($this, '_autoload')));
291
292 // Load all CJT extensions!
293 foreach ($this->getExtensions() as $class => $extension) {
294 // Filters!
295 extract($this->onload($extension, compact('class', 'extension')));
296 // Build Extension plugin path
297 $pluginPath = WP_PLUGIN_DIR . "/{$extension['name']}";
298 // Set runtime variables.
299 $this->extensions[$class]['runtime']['classFile'] = "{$pluginPath}/{$extension['name']}.class.php";
300 // Load definition.
301 $definitionXML = $extension['defDoc'];
302 // Extensions below version 1.0 use static classes
303 // while version 1.0 and up use objects
304 if (((string) $definitionXML->attributes()->version) == '1.0') {
305 // Instantiate extension object
306 $extensionObject = new $class($extension);
307 // Hold extension object
308 $extension['exObject'] = $extensionObject;
309 // Obejct callback
310 $callback = array($extensionObject, $this->loadMethod);
311 }
312 else {
313 # Static callback
314 $callback = array($class, $this->loadMethod);
315 }
316 // Callback filter
317 $callback = $this->onloadcallback($callback);
318 // If auto load is speicifd then import class file and bind events.
319 if ($extension['definition']['primary']['loadMethod'] == 'auto') {
320
321 // Don't load Incompatible extensions/addons
322 if (isset($this->incompatibleAddons[$extension['name']])) {
323
324 require_once ABSPATH . DIRECTORY_SEPARATOR . 'wp-admin' .
325 DIRECTORY_SEPARATOR . 'includes' .
326 DIRECTORY_SEPARATOR . 'plugin.php';
327
328 $incomapatibleAddon = $this->incompatibleAddons[$extension['name']];
329 $addonVersion = get_plugin_data($extension['pluginFile'], false, false)['Version'];
330 $currentVersion = get_plugin_data( CJTOOLBOX_PLUGIN_FILE )['Version'];
331
332 // Only show notice if addon version is less than 11.
333 if ( $addonVersion < 11) {
334
335 $extension['incompatibleMessage']['flag'] = $incomapatibleAddon[2];
336 $extension['incompatibleMessage']['msg'] = $incomapatibleAddon[3];
337
338 $this->incompatibilies[$pluginPath] = $extension;
339
340 continue;
341 }
342
343 }
344
345 // If frameworkVersion is not provided assume its 0 (Older version)
346 // before frameworkversion chech even supported.
347 // otherwise compare it with current frameworkversion
348 // If the version MAJOR is different current
349 // then its incompatible.
350 $extensionVer = new CJT_Framework_Version_Version((int) ((string) $definitionXML->attributes()->requireFrameworkVersion));
351 if ($frameworkVersion->getMajor() < $extensionVer->getMajor()) {
352 // Detects which requird updates CJT or the Extension itself.
353 $extension['incompatibleMessage']['msg'] = cssJSToolbox::getText('Extension is required CJT Framework Version higher than currently installed, CJT need to get updated!!!');
354 $extension['incompatibleMessage']['flag'] = cssJSToolbox::getText('Aborted');
355 // Add to incomaptibility list.
356 $this->incompatibilies[$pluginPath] = $extension;
357 }
358 else {
359 # Detect extensions required old Framework
360 if ($frameworkVersion->getMajor() > $extensionVer->getMajor()) {
361 $extension['incompatibleMessage']['msg'] = cssJSToolbox::getText('Extension is required old CJT Framework Version than the installed. This extension might need to get update. Please check if this extension is currently behaving correctly!!!');
362 $extension['incompatibleMessage']['flag'] = cssJSToolbox::getText('Ignored');
363 // Add to incomaptibility list.
364 $this->incompatibilies[$pluginPath] = $extension;
365 }
366 // Bind events for compatible extensions.
367 foreach ($definitionXML->getInvolved->event as $event) {
368 // filter!
369 extract($this->onbindevent(compact('event', 'callback')));
370 // Bind!
371 CJTPlugin::on((string) $event->attributes()->type, $callback);
372 }
373 }
374 }
375 else { // If manual load specified just
376 if (class_exists($class)) { // Make sure the class is loaded!
377 $this->onloaded($class, $extension, $definitionXML, call_user_func($callback));
378 }
379 }
380 }
381 if (!empty($this->incompatibilies)) {
382 // Hook for processing incomaptible extensions.
383 add_action('admin_notices', array(& $this, 'processIncompatibles'));
384 }
385 }
386
387 /**
388 * put your comment there...
389 *
390 * @param mixed $pluginName
391 */
392 public function & getDefDoc($pluginName) {
393 # Find if cached or create it
394 if (!isset($this->defDocs[$pluginName])) {
395 // Add CJT Def doc to def docs list
396 $pluginXMLFile = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $pluginName . DIRECTORY_SEPARATOR . "{$pluginName}.xml";
397 // Extension might removed while its license key still in the database
398 // Make sure the extension still exists
399 if (file_exists($pluginXMLFile)) {
400 $this->defDocs[$pluginName] = new SimpleXMLElement(file_get_contents($pluginXMLFile));
401 }
402 else {
403 # Return null when extension is absent!
404 $this->defDocs[$pluginName] = null;
405 }
406 }
407 return $this->defDocs[$pluginName];
408 }
409
410 /**
411 * put your comment there...
412 *
413 */
414 public function & getFiles2ClassesMap() {
415 return $this->file2Classmap;
416 }
417
418 /**
419 * put your comment there...
420 *
421 * @TODO: REMOVE HTML-MARKUP. CJT PLUGIN NEVER WRITE MARKUP IMIXED WITH HTML. ITS VERY BAD PROGRAMMING PRACTICE. THIS WILL BE REMOVED NEXT TIME AS WE IN RUSH!!!
422 */
423 public function processIncompatibles() {
424 global $current_screen;
425
426 // Proces only if in CJT page.
427 if (!preg_match('/\/plugins\.php|page\=cjtoolbox/', $_SERVER['REQUEST_URI'])) {
428 return;
429 }
430 // INitialize.
431 $message = cssJSToolbox::getText('CJT detects incompatible installed extensions, listed below with status message for every extension:');
432 $list = '';
433 // For every compatible extension add
434 // an list item with details
435 // if there is an update available or provide
436 // a direct link to CJT website if no upgrade is available.
437 // Upgrade wont be available in case no license key is activated!
438 foreach ($this->incompatibilies as $class => $extension) {
439 // Show details.
440 $pluginInfo = get_plugin_data($extension['pluginFile']);
441 // List item Markup
442 $list .= is_callable($extension['incompatibleMessage']['msg']) ?
443 "<li style='list-style-type:none'>{$extension['incompatibleMessage']['msg']()}</li>" :
444 "<li><a target='_blank' href='{$pluginInfo['PluginURI']}'>{$pluginInfo['Name']}</a> (Status: {$extension['incompatibleMessage']['flag']}, Message: {$extension['incompatibleMessage']['msg']})</li>\n";
445 }
446
447 $noticeClasses = 'cjt-incomaptible-extensions-notice notice notice-error';
448
449 if ( $current_screen->id !== 'toplevel_page_cjtoolbox' ) {
450 $noticeClasses .= ' is-dismissible';
451 }
452
453 // Output full message.
454 // TODO: BAD PRACTICE1!!!!! NEVER MIX HTML WITH PHP, JUST TEMPORARY1!!!
455 echo "<div class='$noticeClasses' style='font-size:14px;font-weight:bold;margin-top: 20px;'>
456 <ul style='list-style-type: circle;font-size: 12px;'>{$list}</ul>
457 </div>";
458 }
459
460 } // End class.
461
462
463 // Hookable!
464 CJTExtensions::define('CJTExtensions', array('hookType' => CJTWordpressEvents::HOOK_FILTER));