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