PluginProbe
CSS & JavaScript Toolbox / 8.3.1
CSS & JavaScript Toolbox v8.3.1
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 / controllers / blocks-coupling.php

blocks-coupling.php in CSS & JavaScript Toolbox 8.3.1, at controllers/blocks-coupling.php

831 lines 21.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @version $ Id; blocks-coupling.php 21-03-2012 03:22:10 Ahmed Said $
4 */
5
6 // Disallow direct access.
7 defined('ABSPATH') or die("Access denied");
8
9 /**
10 * Applying Code blocks for the curren request.
11 *
12 * This controller is always loaded.
13 *
14 * The class resposibility is to output the code blocks
15 * tha associated with current request.
16 *
17 * @author Ahmed Said
18 * @version 6
19 */
20 class CJTBlocksCouplingController extends CJTController {
21
22 /**
23 * put your comment there...
24 *
25 * @var mixed
26 */
27 protected $blocks = array(
28 'code' => array('header' => '', 'footer' => ''),
29 'scripts' => array('header' => array(), 'footer' => array()),
30 );
31
32 /**
33 * put your comment there...
34 *
35 * @var mixed
36 */
37 protected $controllerInfo = array('model' => 'coupling');
38
39 /**
40 * put your comment there...
41 *
42 * @var mixed
43 */
44 protected $filters = null;
45
46 /**
47 * put your comment there...
48 *
49 * @var mixed
50 */
51 protected static $instance = null;
52
53 /**
54 * put your comment there...
55 *
56 * @var mixed
57 */
58 private $onActionIds = array();
59
60 /**
61 * put your comment there...
62 *
63 * @var mixed
64 */
65 protected $onassigncouplingcallback = array('parameters' => array('callback'));
66
67 /**
68 * put your comment there...
69 *
70 * @var mixed
71 */
72 protected $onappendcode = array('parameters' => array('code'));
73
74 /**
75 * put your comment there...
76 *
77 * @var mixed
78 */
79 protected $onblockmatched = array('parameters' => array('block'));
80
81 /**
82 * put your comment there...
83 *
84 * @var mixed
85 */
86 protected $oncancelmatching = array('parameters' => array('matched'));
87
88 /**
89 * put your comment there...
90 *
91 * @var mixed
92 */
93 protected $ondefaultfilters = array('parameters' => array('filters'));
94
95 /**
96 * put your comment there...
97 *
98 * @var mixed
99 */
100 protected $ondo = array('parameters' => array('data', 'method', 'condition'));
101
102 /**
103 * put your comment there...
104 *
105 * @var mixed
106 */
107 protected $onblocksorder = array('parameters' => array('order'));
108
109 /**
110 * put your comment there...
111 *
112 * @var mixed
113 */
114 protected $onevalcodeblock = array( 'parameters' => array( 'keep', 'block' ) );
115
116 /**
117 * put your comment there...
118 *
119 * @var mixed
120 */
121 protected $ongetblocks = array('parameters' => array('blocks'));
122
123 /**
124 * put your comment there...
125 *
126 * @var mixed
127 */
128 protected $ongetcache = array('parameters' => array('cache'));
129
130 /**
131 * put your comment there...
132 *
133 * @var mixed
134 */
135 protected $ongetfilters = array('parameters' => array('filters'));
136
137 /**
138 * put your comment there...
139 *
140 * @var mixed
141 */
142 protected $onlinkedtemplates = array('parameters' => array('templates'));
143
144 /**
145 * put your comment there...
146 *
147 * @var mixed
148 */
149 protected $onlinkscripts = array('parameters' => array('templates'));
150
151 /**
152 * put your comment there...
153 *
154 * @var mixed
155 */
156 protected $onlinkstyles = array('parameters' => array('templates'));
157
158 /**
159 * put your comment there...
160 *
161 * @var mixed
162 */
163 protected $onlinktemplate = array('parameters' => array('template'));
164
165 /**
166 * put your comment there...
167 *
168 * @var mixed
169 */
170 protected $onmatchingurls = array('parameters' => array('urls'));
171
172 /**
173 * put your comment there...
174 *
175 * @var mixed
176 */
177 protected $onnoblocks = array('hookType' => CJTWordpressEvents::HOOK_ACTION);
178
179 /**
180 * put your comment there...
181 *
182 * @var mixed
183 */
184 protected $onoutput = array('parameters' => array('code', 'location'));
185
186 /**
187 * put your comment there...
188 *
189 * @var mixed
190 */
191 protected $onprocess = array('hookType' => CJTWordpressEvents::HOOK_ACTION);
192
193 /**
194 * put your comment there...
195 *
196 * @var mixed
197 */
198 protected $onprocessblock = array('parameters' => array('block'));
199
200 /**
201 * put your comment there...
202 *
203 * @var mixed
204 */
205 protected $onqueuecss = array('parameters' => array('style'));
206
207 /**
208 * put your comment there...
209 *
210 * @var mixed
211 */
212 protected $onqueuejavascript = array('parameters' => array('script'));
213
214 /**
215 * put your comment there...
216 *
217 * @var mixed
218 */
219 protected $onsetfilters = array('parameters' => array('filters'));
220
221 /**
222 * put your comment there...
223 *
224 * @var mixed
225 */
226 protected $templates = array();
227
228 /**
229 * Initialize controller object.
230 *
231 * @see CJTController for more details
232 * @return void
233 */
234 public function __construct() {
235 // Only one instance is allowed.
236 if (self::$instance) {
237 throw new Exception('Trying to instantiate multiple coupling instances!!');
238 }
239 // Hold the single instance we've!
240 self::$instance = $this;
241 $siteHook = cssJSToolbox::$config->core->siteHook;
242 // Initialize controller.
243 parent::__construct(false);
244 // Import related libraries
245 CJTModel::import('block');
246 // Not default action needed.
247 $this->defaultAction = null;
248 // Initialize controller.
249 $initCouplingCallback = $this->onassigncouplingcallback(array(&$this, 'initCoupling'));
250 add_action('admin_init', $initCouplingCallback);
251 add_action($siteHook->tag, $initCouplingCallback, $siteHook->priority);
252 // Add Shortcode callbacks.
253 add_shortcode('cjtoolbox', array(&$this, 'shortcode'));
254 }
255
256 /**
257 * put your comment there...
258 *
259 * @param mixed $id
260 */
261 public function addOnActionIds($id) {
262 // Add ID is not exists.
263 if (!in_array($id, $this->onActionIds)) {
264 $this->onActionIds[] = $id;
265 }
266 // Chaining.
267 return $this;
268 }
269
270 /**
271 * put your comment there...
272 *
273 */
274 public function getBlocks()
275 {
276 // Set request view filters used for querying database.
277 $this->setRequestFilters();
278
279 // Get blocks order. NOTE: This is all blocks order not only the queried/target blocks.
280 $blocksOrder = array();
281 $metaBoxesOrder = $this->onblocksorder( $this->model->getOrder() );
282
283 // Get ORDER-INDEX <TO> BLOCK-ID mapping.
284 preg_match_all( '/cjtoolbox-(\d+)/', $metaBoxesOrder[ 'normal' ], $blocksOrder, PREG_SET_ORDER );
285
286 /**
287 * append more to orders produced by CJTBlocksCouplingController::setRequestFilter().
288 * More to orders may allow other blocks to bein the output (e.g metaboxe blocks).
289 */
290 $blocksOrder = array_merge( $blocksOrder, $this->getFilters()->moreToOrder );
291
292 // Prepare request URL to match against Links & Expressions.
293 $linksRequestURL = self::getRequestURL();
294 $expressionsRequestURL = "{$linksRequestURL}?{$_SERVER['QUERY_STRING']}";
295
296 extract( $this->onmatchingurls( compact( 'linksRequestURL', 'expressionsRequestURL' ) ) );
297
298 // Get all blocks including (Links & Expressions Blocks).
299 $blocks = $this->ongetblocks(
300
301 $this->model->getPinsBlocks(
302
303 CJTBlockModel::PINS_LINK_EXPRESSION,
304
305 $this->getFilters()->pinPoint,
306
307 $this->getFilters()->customPins,
308
309 $this->getFilters()
310
311 )
312
313 );
314
315
316 if ( empty( $blocks ) )
317 {
318 $this->onnoblocks();
319
320 return false;
321
322 }
323
324 // Import related libraries.
325 cssJSToolbox::import( 'framework:php:evaluator:evaluator.inc.php' );
326
327 /**
328 * Iterator over all blocks by using they order.
329 * For each block get code and scripts.
330 */
331 $this->onprocess();
332
333 foreach ( $blocksOrder as $blockOrder )
334 {
335 $blockId = (int) $blockOrder[1];
336
337 // As mentioned above. Orders is for all blocks not just those queried from db.
338 if ( isset($blocks[ $blockId ] ) )
339 {
340
341 $block = $this->onprocessblock( $blocks[ $blockId ] );
342
343 /**
344 * Process Links & Expressions blocks.
345 * For better performace check only those with links and expressions flags.
346 */
347 if ( $block->blocksGroup & CJTBlockModel::PINS_LINK_EXPRESSION )
348 {
349 /**
350 * Initiliaze $matchedLink and $matchedExpression inside IF statment.
351 * Those variables need to refresh state at each block.
352 * If there is no link or expression flags, they will be FALSE.
353 * Otherwise they'll get the correct value inside each statement.
354 */
355 /// Check if there is a matched link.
356 if ( $matchedLink = ( $block->blocksGroup & CJTBlockModel::PINS_LINKS ) )
357 {
358 $links = explode( "\n", trim( $block->links ) );
359 $matchedLink = in_array( $linksRequestURL, $links );
360 }
361
362 /// Check if there is a matched expression.
363 if ( $matchedExpression = ( $block->blocksGroup & CJTBlockModel::PINS_EXPRESSIONS ) )
364 {
365 $expressions = explode("\n", $block->expressions);
366
367 foreach ( $expressions as $expression )
368 {
369 /// @TODO: Matches may be used later to evaulate variables inside code block.
370 if( $matchedExpression = @ preg_match( "/{$expression}/", $expressionsRequestURL ) )
371 {
372 break;
373 }
374
375 }
376
377 }
378
379 /**
380 * Exclude Links & Expressions Blocks that doesn't has a match.
381 * If there is no matched link or expression then exclude block.
382 */
383 if ( $this->oncancelmatching( ! ( $matchedExpression || $matchedLink ) ) )
384 {
385 continue;
386 }
387
388 }
389 // Allow extensions to control to prevent block from being in the output
390 if ( $block = $this->onblockmatched( $block ) )
391 {
392 // Retrieve block code-files.
393 $block->code = $this->model->getBlockCode( $block->id );
394
395 // Import Executable (PHP and HTML) templates.
396 $block->code = $block->code . $this->model->getExecTemplatesCode( $block->id );
397
398 // For every location store blocks code into single string
399
400 if ( ! $evaluatedCode = $this->onevalcodeblock( false, $block ) )
401 {
402 $evaluatedCode = CJTPHPCodeEvaluator::getInstance( $block )->exec()->getOutput();
403 }
404
405 /** @todo Include Debuging info only if we're in debuging mode! */
406 if ( 1 ) {
407 $evaluatedCode = "\n<!-- Block ({$blockId}) START-->\n{$evaluatedCode}\n<!-- Block ({$blockId}) END -->\n";
408 }
409
410 $this->blocks[ 'code' ][ $block->location ] .= $this->onappendcode( $evaluatedCode );
411
412 // Store all used Ids in the CORRECT ORDER.
413 $this->addOnActionIds( $blockId );
414 }
415
416 }
417
418 }
419
420 $templates = $this->onActionIds ?
421 $this->model->getLinkedTemplates( $this->onActionIds ) :
422 array();
423
424 // Classisfy as we process Scripts and Styles separatly (different hooks!).
425 foreach ( $this->onlinkedtemplates( $templates ) as $id => $template )
426 {
427 // Filer template!
428 extract( $this->onlinktemplate( compact( 'template', 'id' ) ) );
429
430 $this->templates[ $template->type ][ $id ] = $template;
431 }
432
433
434 return true;
435 }
436
437 /**
438 * put your comment there...
439 *
440 */
441 public function getCached() {
442 // Cache is not implemented yet might be supported by extenal Extensions!
443 return $this->ongetcache(false);
444 }
445
446 /**
447 * put your comment there...
448 *
449 */
450 public function getFilters() {
451 return $this->ongetfilters($this->filters);
452 }
453
454 /**
455 * put your comment there...
456 *
457 */
458 public function getOnActionIds() {
459 return $this->onActionIds;
460 }
461
462 /**
463 * put your comment there...
464 *
465 */
466 public static function getRequestURL() {
467 // URL Protocol.
468 $protocol = 'http' . ((isset($_SERVER["HTTPS"]) && ($_SERVER["HTTPS"] == "on")) ? 's' : '') . '://';
469 // Host name & port.
470 $host = $_SERVER['HTTP_HOST'];
471 $port = ($_SERVER["SERVER_PORT"] != "80") ? ":{$_SERVER["SERVER_PORT"]}" : '';
472 // Request URI.
473 $requestURI = $_SERVER['REQUEST_URI'];
474 // Final URL.
475 $url = "{$protocol}{$host}{$port}{$requestURI}";
476 return $url;
477 }
478
479 /**
480 * put your comment there...
481 *
482 */
483 public function hasOnActionIds() {
484 return !empty($this->onActionIds);
485 }
486
487 /**
488 * put your comment there...
489 *
490 */
491 public function initCoupling() {
492 // For some reasons wp action is fired twice.
493 // The wrong call won't has $wp_query object set,
494 // but this is only valid at Front end.
495 if (!is_admin() && !$GLOBALS['wp_query']) {
496 return;
497 }
498 // Get current application hook prefix.
499 $actionsPrefix = is_admin() ? 'admin' : 'wp';
500 // Get cache or get blocks if not cached.
501 // If there is no cache or no blocks for output
502 // do nothing.
503 if ($this->getCached() || $this->getBlocks()) {
504 // Output blocks on various locations!
505 add_action("{$actionsPrefix}_head", array(&$this, 'outputBlocks'), 30);
506 add_action("{$actionsPrefix}_footer", array(&$this, 'outputBlocks'), 30);
507 // Links templates & styloes!
508 add_action("{$actionsPrefix}_enqueue_scripts", array(&$this, 'linkTemplates'), 30);
509 add_action("{$actionsPrefix}_print_styles", array(&$this, 'linkTemplates'), 30);
510 }
511 // Link style sheet in footer required custom implementation.
512 add_action("{$actionsPrefix}_print_footer_scripts", array(&$this, 'linkFooterStyleSheets'), 9);
513 // Make sure this is executed only once.
514 // Sometimes wp hook run on backend and sometimes its not.
515 // This method handle both front and backend requests.
516 // Simply remove all hooks to ensure its run only one time.
517 remove_action('wp', array(&$this, 'initCoupling'));
518 remove_action('admin_init', array(&$this, 'initCoupling'));
519 }
520
521 /**
522 * put your comment there...
523 *
524 */
525 public function linkFooterStyleSheets() {
526 // Initialize.
527 $styles = array();
528 // Get queued style sheets!
529 global $wp_styles;
530 $queuedStyles =& $wp_styles->queue;
531 // Process only 'cjt' templates,
532 foreach ($queuedStyles as $index => $styleName) {
533 if (strpos($styleName, 'cjt-css-template-') === 0) {
534 // Get style name src file, prepend to Wordpress absolute path.
535 $style = $wp_styles->registered[$styleName];
536 $styles[] = home_url($style->src);
537 // Stop Wordpress from output <link> tag outside head tag
538 // as it has no effect.
539 unset($queuedStyles[$index]);
540 }
541 }
542 // Enqueue Style Sheet loader javascript if there is any
543 // styles need to be loaded.
544 if (!empty($styles)) {
545 // jQuery is dpendency object required by the loader.
546 wp_enqueue_script('jquery');
547 // Enqueue footer style sheet loader.
548 wp_enqueue_script('cjt-coupling-footer-css-loader', cssJSToolbox::getURI('controllers:coupling:js:footer-stylesheet-loader.js'));
549 // Output Javascript array to be filled with the styles!
550 $jsStyleSheetsList = json_encode($styles);
551 require cssJSToolbox::resolvePath('controllers:coupling:html:load-footer-style.html.php');
552 }
553 }
554
555 /**
556 * put your comment there...
557 *
558 */
559 public function linkTemplates() {
560 $currentFilter = current_filter();
561 // Derived template Type from Wordpress filter.
562 $filterFor = explode('_', $currentFilter); $filterFor = array_pop($filterFor);
563 $type = CJTCouplingModel::$templateTypes[$filterFor];
564 // Following vars are referenced based on the current type.
565 $templates = isset($this->templates[$type]) ? $this->templates[$type] : array();
566 // Filering!
567 $templates = $this->{"onlink{$filterFor}"}($templates);
568 /**
569 * @var WP_Dependencies
570 */
571 $queue = $this->model->getQueueObject($filterFor);
572 // Add templates to the queye.
573 foreach ($templates as $template) {
574 // Registery only if not yet registered.
575 $template = $this->{"onqueue{$type}"}($template);
576 if (!isset($queue->registered[$template->queueName])) {
577 $queue->add($template->queueName, "/{$template->file}", null, $template->version);
578 }
579 // Always make sure the template is queued.
580 $queue->enqueue($template->queueName);
581 }
582 }
583
584 /**
585 * put your comment there...
586 *
587 */
588 public function outputBlocks() {
589 // Derived location name from wordpress filter name.
590 $currentFilter = current_filter();
591 // Map "wp hook location" to "block hook location".
592 $locationsMap = array('head' => 'header', 'footer' => 'footer');
593 // This hook is used across both ends, front and back ends.
594 // Remove application prefix (wp_ or admin_).
595 // Remining is head or footer.
596 $location = str_replace(array('wp_', 'admin_'), '', $currentFilter);
597 // Map to block location.
598 $location = $locationsMap[$location];
599 echo $this->onoutput($this->blocks['code'][$location], $location);
600 }
601
602 /**
603 * put your comment there...
604 *
605 */
606 protected function setRequestFilters()
607 {
608 // Get request blocks.
609 $filters = $this->ondefaultfilters( ( object ) array
610 (
611
612 'pinPoint' => 0x00000000,
613
614 'customPins' => array(),
615
616 'moreToOrder' => array(),
617
618 'currentObject' => null,
619
620 'currentCustomPin' => 0,
621
622 'params' => array(),
623
624 ) );
625
626 if ( is_admin() )
627 {
628 // Include all backend blocks.
629 $filters->pinPoint |= CJTBlockModel::PINS_BACKEND;
630 }
631 else
632 {
633 $filters->pinPoint |= CJTBlockModel::PINS_FRONTEND;
634
635 // Pages.
636 if ( is_page() )
637 {
638 // Blocks with ALL PAGES selected.
639 $filters->pinPoint |= CJTBlockModel::PINS_PAGES_ALL_PAGES;
640
641 $filters->currentObject = $GLOBALS[ 'post' ];
642 $filters->currentCustomPin = CJTBlockModel::PINS_PAGES_CUSTOM_PAGE;
643
644 // Blocks with PAGE-ID selected.
645 $filters->customPins[ ] = array
646 (
647 'pin' => 'pages',
648
649 'pins' => array( $filters->currentObject->ID ),
650
651 'flag' => CJTBlockModel::PINS_PAGES_CUSTOM_PAGE,
652
653 );
654
655 // Blocks with FRONT-PAGE selected.
656 if ( is_front_page() )
657 {
658 $filters->pinPoint |= CJTBlockModel::PINS_PAGES_FRONT_PAGE;
659 }
660
661 /**
662 * In order for metabox block to get in the output we need
663 * to add metabox order for it.
664 * @see CJTBlocksCouplingController::getBlocks.
665 */
666 $metabox = CJTModel::create( 'metabox', array( $filters->currentObject->ID ) );
667
668 $filters->moreToOrder[ ][ 1 ] = $metabox->getMetaboxId();
669
670 } // End is_page()
671
672 else if ( is_attachment() )
673 {
674 $filters->pinPoint |= CJTBlockModel::PINS_ATTACHMENT;
675 }
676 // Posts.
677 else if ( is_single() )
678 {
679 // Blocks with ALL POSTS & ALL CATEGORIES selected.
680 $filters->pinPoint |= CJTBlockModel::PINS_POSTS_ALL_POSTS | CJTBlockModel::PINS_CATEGORIES_ALL_CATEGORIES;
681
682 $filters->currentObject = $GLOBALS[ 'post' ];
683 $filters->currentCustomPin = CJTBlockModel::PINS_POSTS_CUSTOM_POST;
684
685 // Blocks with POST-ID selected.
686
687 $filters->customPins[ ] = array
688 (
689
690 'pin' => 'posts',
691
692 'pins' => array( $filters->currentObject->ID ),
693
694 'flag' => CJTBlockModel::PINS_POSTS_CUSTOM_POST,
695
696 );
697
698 // Include POST PARENT CATRGORIES blocks.
699 $parentCategoriesIds = wp_get_post_categories( $filters->currentObject->ID, array( 'fields' => 'ids' ) );
700
701 /**
702 * Custom-Posts just added "ON THE RUN/FLY"
703 * Need simple fix by confirming that the post is belong to
704 * specific category or not.
705 * Custom posts NOW unlike Posts, it doesn't inherit parent
706 * taxonomis Code Blocks!!
707 */
708 if ( ! empty( $parentCategoriesIds ) )
709 {
710
711 $filters->params[ 'hasCategories' ] = true;
712 $filters->params[ 'parentCategories' ] = $parentCategoriesIds;
713
714 $filters->customPins[ ] = array
715 (
716
717 'pin' => 'categories',
718
719 'pins' => $parentCategoriesIds,
720
721 'flag' => CJTBlockModel::PINS_CATEGORIES_CUSTOM_CATEGORY,
722
723 );
724
725 }
726
727 /**
728 * In order for metabox block to get in the output we need
729 * to add metabox order for it.
730 * @see CJTBlocksCouplingController::getBlocks.
731 */
732 $metabox = CJTModel::create( 'metabox', array( $filters->currentObject->ID ) );
733
734 $filters->moreToOrder[][ 1 ] = $metabox->getMetaboxId();
735
736 /**
737 * @TODO check for recent posts Based on user configuration.
738 * Recent posts should be detcted by comparing
739 * user condifguration with post date.
740 */
741 if ( 0 ) {
742
743 }
744 } // End is_single()
745
746 // Categories.
747 else if( is_category() )
748 {
749 // Blocks with ALL CATEGORIES selected.
750 $filters->pinPoint |= CJTBlockModel::PINS_CATEGORIES_ALL_CATEGORIES;
751
752 $filters->currentObject = get_queried_object();
753 $filters->currentCustomPin = CJTBlockModel::PINS_CATEGORIES_CUSTOM_CATEGORY;
754
755 // Blocks with CATEGORY-ID selected.
756 $filters->customPins[] = array
757 (
758 'pin' => 'categories',
759
760 'pins' => array( $filters->currentObject->term_id ),
761
762 'flag' => CJTBlockModel::PINS_CATEGORIES_CUSTOM_CATEGORY,
763
764 );
765
766 } // End is_category()
767
768 // Blocks with BLOG-INDEX selected.
769 else if ( is_home() )
770 {
771 $filters->pinPoint |= CJTBlockModel::PINS_POSTS_BLOG_INDEX;
772 }
773 else if ( is_search() )
774 {
775 $filters->pinPoint |= CJTBlockModel::PINS_SEARCH;
776 }
777 else if ( is_tag() )
778 {
779 $filters->pinPoint |= CJTBlockModel::PINS_TAG;
780 }
781 else if ( is_author() )
782 {
783 $filters->pinPoint |= CJTBlockModel::PINS_AUTHOR;
784 }
785 else if ( is_archive() )
786 {
787 $filters->pinPoint |= CJTBlockModel::PINS_ARCHIVE;
788 }
789 else if ( is_404() )
790 {
791 $filters->pinPoint |= CJTBlockModel::PINS_404_ERROR;
792 }
793
794 }
795
796 $this->filters = $this->onsetfilters( $filters );
797
798 }
799
800 /**
801 * Wordpress do shortcode callback for
802 * CJT Shortcodes ([cjtoolbox ....])!
803 *
804 * This method role is to load the shortcode routines
805 * in order to handle the request.
806 *
807 * It doesn't do anything except deferring the shortcode
808 * codes from loaded until shortcode is really used!
809 *
810 * @param mixed $attributes
811 */
812 public function shortcode($attributes, $content) {
813 // Instantiate Shortcode handler class.
814 cssJSToolbox::import('controllers:coupling:shortcode:shortcode.php');
815 $shortcode = new CJT_Controllers_Coupling_Shortcode($attributes, $content);
816 // Return Shortcode replacement!
817 return ((string) $shortcode);
818 }
819
820 /**
821 * put your comment there...
822 *
823 */
824 public static function & theInstance() {
825 return self::$instance;
826 }
827
828 } // End class.
829
830 // Hookable!
831 CJTBlocksCouplingController::define('CJTBlocksCouplingController', array('hookType' => CJTWordpressEvents::HOOK_FILTER));