PluginProbe
CSS & JavaScript Toolbox / 8.0.3
CSS & JavaScript Toolbox v8.0.3
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 | controllers/blocks-coupling.php +237 -59 6.08.0.3 View file →
@@ -47,8 +47,15 @@
47 47 * put your comment there...
48 48 *
49 49 * @var mixed
50 50 */
51 + protected static $instance = null;
52 +
53 + /**
54 + * put your comment there...
55 + *
56 + * @var mixed
57 + */
51 58 private $onActionIds = array();
52 59
53 60 /**
54 61 * put your comment there...
@@ -62,11 +69,18 @@
62 69 *
63 70 * @var mixed
64 71 */
65 72 protected $onappendcode = array('parameters' => array('code'));
66 -
73 +
67 74 /**
68 75 * put your comment there...
76 + *
77 + * @var mixed
78 + */
79 + protected $onblockmatched = array('parameters' => array('block'));
80 +
81 + /**
82 + * put your comment there...
69 83 *
70 84 * @var mixed
71 85 */
72 86 protected $oncancelmatching = array('parameters' => array('matched'));
@@ -111,8 +125,15 @@
111 125 *
112 126 * @var mixed
113 127 */
114 128 protected $ongetfilters = array('parameters' => array('filters'));
129 +
130 + /**
131 + * put your comment there...
132 + *
133 + * @var mixed
134 + */
135 + protected $onlinkedtemplates = array('parameters' => array('templates'));
115 136
116 137 /**
117 138 * put your comment there...
118 139 *
@@ -117,8 +138,29 @@
117 138 * put your comment there...
118 139 *
119 140 * @var mixed
120 141 */
142 + protected $onlinkscripts = array('parameters' => array('templates'));
143 +
144 + /**
145 + * put your comment there...
146 + *
147 + * @var mixed
148 + */
149 + protected $onlinkstyles = array('parameters' => array('templates'));
150 +
151 + /**
152 + * put your comment there...
153 + *
154 + * @var mixed
155 + */
156 + protected $onlinktemplate = array('parameters' => array('template'));
157 +
158 + /**
159 + * put your comment there...
160 + *
161 + * @var mixed
162 + */
121 163 protected $onmatchingurls = array('parameters' => array('urls'));
122 164
123 165 /**
124 166 * put your comment there...
@@ -152,11 +194,32 @@
152 194 * put your comment there...
153 195 *
154 196 * @var mixed
155 197 */
198 + protected $onqueuecss = array('parameters' => array('style'));
199 +
200 + /**
201 + * put your comment there...
202 + *
203 + * @var mixed
204 + */
205 + protected $onqueuejavascript = array('parameters' => array('script'));
206 +
207 + /**
208 + * put your comment there...
209 + *
210 + * @var mixed
211 + */
156 212 protected $onsetfilters = array('parameters' => array('filters'));
157 213
158 214 /**
215 + * put your comment there...
216 + *
217 + * @var mixed
218 + */
219 + protected $templates = array();
220 +
221 + /**
159 222 * Initialize controller object.
160 223 *
161 224 * @see CJTController for more details
162 225 * @return void
@@ -161,8 +224,15 @@
161 224 * @see CJTController for more details
162 225 * @return void
163 226 */
164 227 public function __construct() {
228 + // Only one instance is allowed.
229 + if (self::$instance) {
230 + throw new Exception('Trying to instantiate multiple coupling instances!!');
231 + }
232 + // Hold the single instance we've!
233 + self::$instance = $this;
234 + $siteHook = cssJSToolbox::$config->core->siteHook;
165 235 // Initialize controller.
166 236 parent::__construct(false);
167 237 // Import related libraries
168 238 CJTModel::import('block');
@@ -170,9 +240,9 @@
170 240 $this->defaultAction = null;
171 241 // Initialize controller.
172 242 $initCouplingCallback = $this->onassigncouplingcallback(array(&$this, 'initCoupling'));
173 243 add_action('admin_init', $initCouplingCallback);
174 - add_action('wp', $initCouplingCallback);
244 + add_action($siteHook->tag, $initCouplingCallback, $siteHook->priority);
175 245 // Add Shortcode callbacks.
176 246 add_shortcode('cjtoolbox', array(&$this, 'shortcode'));
177 247 }
178 248
@@ -178,9 +248,23 @@
178 248
179 249 /**
180 250 * put your comment there...
181 251 *
252 + * @param mixed $id
182 253 */
254 + public function addOnActionIds($id) {
255 + // Add ID is not exists.
256 + if (!in_array($id, $this->onActionIds)) {
257 + $this->onActionIds[] = $id;
258 + }
259 + // Chaining.
260 + return $this;
261 + }
262 +
263 + /**
264 + * put your comment there...
265 + *
266 + */
183 267 public function getBlocks() {
184 268 // Set request view filters used for querying database.
185 269 $this->setRequestFilters();
186 270 // Get blocks order. NOTE: This is all blocks order not only the queried/target blocks.
@@ -187,8 +271,13 @@
187 271 $blocksOrder = array();
188 272 $metaBoxesOrder = $this->onblocksorder($this->model->getOrder());
189 273 // Get ORDER-INDEX <TO> BLOCK-ID mapping.
190 274 preg_match_all('/cjtoolbox-(\d+)/', $metaBoxesOrder['normal'], $blocksOrder, PREG_SET_ORDER);
275 + /**
276 + * append more to orders produced by CJTBlocksCouplingController::setRequestFilter().
277 + * More to orders may allow other blocks to bein the output (e.g metaboxe blocks).
278 + */
279 + $blocksOrder = array_merge($blocksOrder, $this->getFilters()->moreToOrder);
191 280 // Prepare request URL to match against Links & Expressions.
192 281 $linksRequestURL = self::getRequestURL();
193 282 $expressionsRequestURL = "{$linksRequestURL}?{$_SERVER['QUERY_STRING']}";
194 283 extract($this->onmatchingurls(compact('linksRequestURL', 'expressionsRequestURL')));
@@ -235,12 +324,8 @@
235 324 /// @TODO: Matches may be used later to evaulate variables inside code block.
236 325 if($matchedExpression = @preg_match("/{$expression}/", $expressionsRequestURL)) {
237 326 break;
238 327 }
239 - else if ($matchedExpression === false) { // Error
240 - $message .= "<div style='background-color:red;font-size:20px;'>There are expression error in '{$block->name}' Block!! Expr=({$expression})</div>";
241 - echo($message);
242 - }
243 328 }
244 329 }
245 330 /**
246 331 * Exclude Links & Expressions Blocks that doesn't has a match.
@@ -249,20 +334,33 @@
249 334 if ($this->oncancelmatching(!($matchedExpression || $matchedLink))) {
250 335 continue;
251 336 }
252 337 }
253 - // For every location store blocks code into single string
254 - /** @todo Use method other data:// wrapper, its only available in Hight version of PHP (5.3 or so!) */
255 - $evaluatedCode = CJTPHPCodeEvaluator::getInstance($block)->exec()->getOutput();
256 - /** @todo Include Debuging info only if we're in debuging mode! */
257 - if (1) {
258 - $evaluatedCode = "\n<!-- Block ({$blockId}) START-->\n{$evaluatedCode}\n<!-- Block ({$blockId}) END -->\n";
338 + // Allow extensions to control to prevent block from being in the output
339 + if ($block = $this->onblockmatched($block)) {
340 + // Retrieve block code-files.
341 + $block->code = $this->model->getBlockCode($block->id);
342 + // Import Executable (PHP and HTML) templates.
343 + $block->code = $block->code . $this->model->getExecTemplatesCode($block->id);
344 + // For every location store blocks code into single string
345 + $evaluatedCode = CJTPHPCodeEvaluator::getInstance($block)->exec()->getOutput();
346 + /** @todo Include Debuging info only if we're in debuging mode! */
347 + if (1) {
348 + $evaluatedCode = "\n<!-- Block ({$blockId}) START-->\n{$evaluatedCode}\n<!-- Block ({$blockId}) END -->\n";
349 + }
350 + $this->blocks['code'][$block->location] .= $this->onappendcode($evaluatedCode);
351 + // Store all used Ids in the CORRECT ORDER.
352 + $this->addOnActionIds($blockId);
259 353 }
260 - $this->blocks['code'][$block->location] .= $this->onappendcode($evaluatedCode);
261 - // Store all used Ids in the CORRECT ORDER.
262 - $this->onActionIds[] = $blockId;
263 354 }
264 355 }
356 + $templates = $this->onActionIds ? $this->model->getLinkedTemplates($this->onActionIds) : array();
357 + // Classisfy as we process Scripts and Styles separatly (different hooks!).
358 + foreach ($this->onlinkedtemplates($templates) as $id => $template) {
359 + // Filer template!
360 + extract($this->onlinktemplate(compact('template', 'id')));
361 + $this->templates[$template->type][$id] = $template;
362 + }
265 363 // Return true if there is at least 1 block return within the set.
266 364 return true;
267 365 }
268 366
@@ -281,13 +379,21 @@
281 379 */
282 380 public function getFilters() {
283 381 return $this->ongetfilters($this->filters);
284 382 }
285 -
383 +
286 384 /**
287 385 * put your comment there...
288 386 *
289 387 */
388 + public function getOnActionIds() {
389 + return $this->onActionIds;
390 + }
391 +
392 + /**
393 + * put your comment there...
394 + *
395 + */
290 396 public static function getRequestURL() {
291 397 // URL Protocol.
292 398 $protocol = 'http' . ((isset($_SERVER["HTTPS"]) && ($_SERVER["HTTPS"] == "on")) ? 's' : '') . '://';
293 399 // Host name & port.
@@ -303,8 +409,16 @@
303 409 /**
304 410 * put your comment there...
305 411 *
306 412 */
413 + public function hasOnActionIds() {
414 + return !empty($this->onActionIds);
415 + }
416 +
417 + /**
418 + * put your comment there...
419 + *
420 + */
307 421 public function initCoupling() {
308 422 // For some reasons wp action is fired twice.
309 423 // The wrong call won't has $wp_query object set,
310 424 // but this is only valid at Front end.
@@ -310,17 +424,23 @@
310 424 // but this is only valid at Front end.
311 425 if (!is_admin() && !$GLOBALS['wp_query']) {
312 426 return;
313 427 }
428 + // Get current application hook prefix.
429 + $actionsPrefix = is_admin() ? 'admin' : 'wp';
314 430 // Get cache or get blocks if not cached.
315 431 // If there is no cache or no blocks for output
316 432 // do nothing.
317 433 if ($this->getCached() || $this->getBlocks()) {
318 - $actionsPrefix = is_admin() ? 'admin' : 'wp';
319 434 // Output blocks on various locations!
320 435 add_action("{$actionsPrefix}_head", array(&$this, 'outputBlocks'), 30);
321 436 add_action("{$actionsPrefix}_footer", array(&$this, 'outputBlocks'), 30);
437 + // Links templates & styloes!
438 + add_action("{$actionsPrefix}_enqueue_scripts", array(&$this, 'linkTemplates'), 30);
439 + add_action("{$actionsPrefix}_print_styles", array(&$this, 'linkTemplates'), 30);
322 440 }
441 + // Link style sheet in footer required custom implementation.
442 + add_action("{$actionsPrefix}_print_footer_scripts", array(&$this, 'linkFooterStyleSheets'), 9);
323 443 // Make sure this is executed only once.
324 444 // Sometimes wp hook run on backend and sometimes its not.
325 445 // This method handle both front and backend requests.
326 446 // Simply remove all hooks to ensure its run only one time.
@@ -331,8 +451,71 @@
331 451 /**
332 452 * put your comment there...
333 453 *
334 454 */
455 + public function linkFooterStyleSheets() {
456 + // Initialize.
457 + $styles = array();
458 + // Get queued style sheets!
459 + global $wp_styles;
460 + $queuedStyles =& $wp_styles->queue;
461 + // Process only 'cjt' templates,
462 + foreach ($queuedStyles as $index => $styleName) {
463 + if (strpos($styleName, 'cjt-css-template-') === 0) {
464 + // Get style name src file, prepend to Wordpress absolute path.
465 + $style = $wp_styles->registered[$styleName];
466 + $styles[] = home_url($style->src);
467 + // Stop Wordpress from output <link> tag outside head tag
468 + // as it has no effect.
469 + unset($queuedStyles[$index]);
470 + }
471 + }
472 + // Enqueue Style Sheet loader javascript if there is any
473 + // styles need to be loaded.
474 + if (!empty($styles)) {
475 + // jQuery is dpendency object required by the loader.
476 + wp_enqueue_script('jquery');
477 + // Enqueue footer style sheet loader.
478 + wp_enqueue_script('cjt-coupling-footer-css-loader', cssJSToolbox::getURI('controllers:coupling:js:footer-stylesheet-loader.js'));
479 + // Output Javascript array to be filled with the styles!
480 + $jsStyleSheetsList = json_encode($styles);
481 + require cssJSToolbox::resolvePath('controllers:coupling:html:load-footer-style.html.php');
482 + }
483 + }
484 +
485 + /**
486 + * put your comment there...
487 + *
488 + */
489 + public function linkTemplates() {
490 + $currentFilter = current_filter();
491 + // Derived template Type from Wordpress filter.
492 + $filterFor = explode('_', $currentFilter); $filterFor = array_pop($filterFor);
493 + $type = CJTCouplingModel::$templateTypes[$filterFor];
494 + // Following vars are referenced based on the current type.
495 + $templates = isset($this->templates[$type]) ? $this->templates[$type] : array();
496 + // Filering!
497 + $templates = $this->{"onlink{$filterFor}"}($templates);
498 + /**
499 + * @var WP_Dependencies
500 + */
501 + $queue = $this->model->getQueueObject($filterFor);
502 + // Add templates to the queye.
503 + foreach ($templates as $template) {
504 + // Registery only if not yet registered.
505 + $template = $this->{"onqueue{$type}"}($template);
506 + if (!isset($queue->registered[$template->queueName])) {
507 + $queue->add($template->queueName, "/{$template->file}", null, $template->version);
508 + }
509 + // Always make sure the template is queued.
510 + $queue->enqueue($template->queueName);
511 + }
512 + }
513 +
514 + /**
515 + * put your comment there...
516 + *
517 + */
335 518 public function outputBlocks() {
336 519 // Derived location name from wordpress filter name.
337 520 $currentFilter = current_filter();
338 521 // Map "wp hook location" to "block hook location".
@@ -354,8 +537,9 @@
354 537 // Get request blocks.
355 538 $filters = $this->ondefaultfilters((object) array(
356 539 'pinPoint' => 0x00000000,
357 540 'customPins' => array(),
541 + 'moreToOrder' => array(),
358 542 ));
359 543 if (is_admin()) {
360 544 // Include all backend blocks.
361 545 $filters->pinPoint |= CJTBlockModel::PINS_BACKEND;
@@ -375,8 +559,15 @@
375 559 // Blocks with FRONT-PAGE selected.
376 560 if (is_front_page()) {
377 561 $filters->pinPoint |= CJTBlockModel::PINS_PAGES_FRONT_PAGE;
378 562 }
563 + /**
564 + * In order for metabox block to get in the output we need
565 + * to add metabox order for it.
566 + * @see CJTBlocksCouplingController::getBlocks.
567 + */
568 + $metabox = CJTModel::create('metabox', array($GLOBALS['post']->ID));
569 + $filters->moreToOrder[][1] = $metabox->getMetaboxId();
379 570 } // End is_page()
380 571 else if (is_attachment()) {
381 572 $filters->pinPoint |= CJTBlockModel::PINS_ATTACHMENT;
382 573 }
@@ -405,8 +596,15 @@
405 596 'pins' => $parentCategoriesIds,
406 597 'flag' => CJTBlockModel::PINS_CATEGORIES_CUSTOM_CATEGORY,
407 598 );
408 599 }
600 + /**
601 + * In order for metabox block to get in the output we need
602 + * to add metabox order for it.
603 + * @see CJTBlocksCouplingController::getBlocks.
604 + */
605 + $metabox = CJTModel::create('metabox', array($GLOBALS['post']->ID));
606 + $filters->moreToOrder[][1] = $metabox->getMetaboxId();
409 607 /**
410 608 * @TODO check for recent posts Based on user configuration.
411 609 * Recent posts should be detcted by comparing
412 610 * user condifguration with post date.
@@ -449,53 +647,33 @@
449 647 $this->filters = $this->onsetfilters($filters);
450 648 }
451 649
452 650 /**
651 + * Wordpress do shortcode callback for
652 + * CJT Shortcodes ([cjtoolbox ....])!
653 + *
654 + * This method role is to load the shortcode routines
655 + * in order to handle the request.
656 + *
657 + * It doesn't do anything except deferring the shortcode
658 + * codes from loaded until shortcode is really used!
659 + *
660 + * @param mixed $attributes
661 + */
662 + public function shortcode($attributes, $content) {
663 + // Instantiate Shortcode handler class.
664 + cssJSToolbox::import('controllers:coupling:shortcode:shortcode.php');
665 + $shortcode = new CJT_Controllers_Coupling_Shortcode($attributes, $content);
666 + // Return Shortcode replacement!
667 + return ((string) $shortcode);
668 + }
669 +
670 + /**
453 671 * put your comment there...
454 672 *
455 - * @param mixed $attributes
456 673 */
457 - public function shortcode($attributes) {
458 - // Initialize vars.
459 - $replacement = '';
460 - // Default Class.
461 - if (!$attributes['class']) {
462 - $class = 'block';
463 - }
464 - switch ($class) {
465 - case 'block':
466 - // Get is the default "operation"!
467 - if (!$attributes['op']) {
468 - $attributes['op'] = 'get';
469 - }
470 - switch ($attributes['op']) {
471 - case 'get':
472 - // Import dependecies.
473 - cssJSToolbox::import('framework:db:mysql:xtable.inc.php');
474 - // Output block if 'force="true" or only if it wasn't already in the header/footer!
475 - if ((($attributes['force'] == "true") || !in_array($attributes['id'], $this->onActionIds))) {
476 - // Id is being used!
477 - if ($attributes['force'] != 'true') {
478 - $this->onActionIds[] = (int) $attributes['id'];
479 - }
480 - // Get block code.
481 - $block = CJTxTable::getInstance('block')
482 - ->set('id', $attributes['id'])
483 - ->load();
484 - // Only ACTIVE blocks!
485 - if ($block->get('state') != 'active') {
486 - return;
487 - }
488 - $replacement = $block->get('code');
489 - }
490 - break;
491 - }
492 - break;
493 - default:
494 - $replacement = cssJSToolbox::getText('Shortcode Type is not supported!! Only (block) type is currently available!!!');
495 - break;
496 - }
497 - return $replacement;
674 + public static function & theInstance() {
675 + return self::$instance;
498 676 }
499 677
500 678 } // End class.
501 679