1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14: 
 15: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 16: 
 17:  18:  19:  20:  21:  22:  23: 
 24: class cGuiPage {
 25: 
 26:      27:  28:  29:  30:  31: 
 32:     protected $_pageName;
 33: 
 34:      35:  36:  37:  38: 
 39:     protected $_pluginName;
 40: 
 41:      42:  43:  44:  45: 
 46:     protected $_pageTemplate;
 47: 
 48:      49:  50:  51:  52:  53: 
 54:     protected $_contentTemplate;
 55: 
 56:      57:  58:  59:  60:  61: 
 62:     protected $_scripts;
 63: 
 64:      65:  66:  67:  68:  69: 
 70:     protected $_styles;
 71: 
 72:      73:  74:  75:  76:  77: 
 78:     protected $_subnav;
 79: 
 80:      81:  82:  83:  84:  85: 
 86:     protected $_markScript;
 87: 
 88:      89:  90:  91:  92:  93: 
 94:     protected $_error;
 95: 
 96:      97:  98:  99: 100: 101: 
102:     protected $_warning;
103: 
104:     105: 106: 107: 108: 109: 
110:     protected $_info;
111: 
112:     113: 114: 115: 116: 
117:     protected $_abort;
118: 
119:     120: 121: 122: 123: 124: 
125:     protected $_objects;
126: 
127:     128: 129: 130: 131: 
132:     protected $_metaTags;
133: 
134:     135: 136: 137: 138: 
139:     protected $_bodyClassNames;
140: 
141:     142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 
155:     156: 157: 158: 159: 
160:     const filesDirectory = 'includes/';
161: 
162:     public function __construct($pageName, $pluginName = '', $subMenu = '') {
163:         global $lang, $cfg, $sess;
164: 
165:         $this->_pageName = $pageName;
166:         $this->_pluginName = $pluginName;
167:         $this->_pageTemplate = new cTemplate();
168:         $this->_contentTemplate = new cTemplate();
169:         $this->_scripts = array();
170:         $this->_styles = array();
171:         $this->_subnav = '';
172:         $this->_markScript = '';
173:         $this->_error = '';
174:         $this->_warning = '';
175:         $this->_info = '';
176:         $this->_abort = false;
177:         $this->_objects = array();
178:         $this->_metaTags = array();
179:         $this->_bodyClassNames = array();
180: 
181:         
182:         $clang = new cApiLanguage($lang);
183: 
184:         if ($clang->isLoaded()) {
185:             $this->setEncoding($clang->get('encoding'));
186:         }
187: 
188:         $this->_pageTemplate->set('s', 'SUBMENU', $subMenu);
189:         $this->_pageTemplate->set('s', 'PAGENAME', $pageName);
190:         $pageid = str_replace('.', '_', $pageName);
191:         $this->_pageTemplate->set('s', 'PAGENAME', $pageName);
192:         $this->_pageTemplate->set('s', 'PAGEID', $pageid);
193: 
194:         $this->addBodyClassName('page_generic');
195:         $this->addBodyClassName('page_' . $pageid);
196: 
197:         if (cFileHandler::exists($cfg['path']['styles_includes'] . $pageName . '.css')) {
198:             $this->addStyle(cGuiPage::filesDirectory . $pageName . '.css');
199:         }
200: 
201:         202: 203: 204: 
205:         foreach (new DirectoryIterator($cfg['path']['styles_includes']) as $stylefile) {
206:             if (cString::endsWith($stylefile->getFilename(), '.' . $pageName . '.css')) {
207:                 $this->addStyle(cGuiPage::filesDirectory . $stylefile->getFilename());
208:             }
209:         }
210: 
211:         if (cFileHandler::exists($cfg['path']['scripts_includes'] . $pageName . '.js')) {
212:             $this->addScript(cGuiPage::filesDirectory . $pageName . '.js');
213:         }
214: 
215:         216: 217: 218: 
219:         foreach (new DirectoryIterator($cfg['path']['scripts_includes']) as $scriptfile) {
220:             if (cString::endsWith($scriptfile->getFilename(), '.' . $pageName . '.js')) {
221:                 $this->addScript(cGuiPage::filesDirectory . $scriptfile->getFilename());
222:             }
223:         }
224:     }
225: 
226:     227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 
240:     public function addScript($script) {
241:         $script = trim($script);
242:         if (empty($script)) {
243:             return;
244:         }
245: 
246:         $cfg = cRegistry::getConfig();
247:         $backendUrl = cRegistry::getBackendUrl();
248:         $backendPath = cRegistry::getBackendPath();
249:         $filePathName = $this->_getRealFilePathName($script);
250: 
251:         if (strpos(trim($script), 'http') === 0 || strpos(trim($script), '<script') === 0 || strpos(trim($script), '//') === 0) {
252:             if (strpos(trim($script), '<script') === 0) {
253:                 cDeprecated("You shouldn't use inline JS for backend pages");
254:             }
255:             
256:             $this->_scripts[] = $script;
257:         } else if (!empty($this->_pluginName) && cFileHandler::exists($backendPath . $cfg['path']['plugins'] . $this->_pluginName . '/' . $cfg['path']['scripts'] . $filePathName)) {
258:             
259:             $fullpath = $backendUrl . $cfg['path']['plugins'] . $this->_pluginName . '/' . $cfg['path']['scripts'] . $script;
260:             $this->_scripts[] = $fullpath;
261:         } else if (cFileHandler::exists($backendPath . $cfg['path']['scripts'] . $filePathName)) {
262:             
263:             $fullpath = $backendUrl . $cfg['path']['scripts'] . $script;
264: 
265:             $this->_scripts[] = $fullpath;
266:         }
267:     }
268: 
269:     270: 271: 272: 273: 274: 275: 276: 
277:     public function addStyle($stylesheet) {
278:         $stylesheet = trim($stylesheet);
279:         if (empty($stylesheet)) {
280:             return;
281:         }
282: 
283:         $cfg = cRegistry::getConfig();
284:         $backendUrl = cRegistry::getBackendUrl();
285:         $backendPath = cRegistry::getBackendPath();
286:         $filePathName = $this->_getRealFilePathName($stylesheet);
287: 
288:         if (strpos($stylesheet, 'http') === 0 || strpos($stylesheet, '//') === 0) {
289:             
290:             $this->_styles[] = $stylesheet;
291:         } else if (!empty($this->_pluginName) && cFileHandler::exists($backendPath . $cfg['path']['plugins'] . $this->_pluginName . '/' . $cfg['path']['styles'] . $filePathName)) {
292:             
293:             
294:             $fullpath = $backendUrl . $cfg['path']['plugins'] . $this->_pluginName . '/' . $cfg['path']['styles'] . $stylesheet;
295:             $this->_styles[] = $fullpath;
296:         } else if (cFileHandler::exists($backendPath . $cfg['path']['styles'] . $filePathName)) {
297:             
298:             
299:             $fullpath = $backendUrl . $cfg['path']['styles'] . $stylesheet;
300:             $this->_styles[] = $fullpath;
301:         }
302:     }
303: 
304:     305: 306: 307: 308: 309: 310: 
311:     public function addMeta(array $meta) {
312:         $allowedAttributes = array(
313:             'charset',
314:             'content',
315:             'http-equiv',
316:             'name',
317:             'itemprop'
318:         );
319:         foreach ($meta as $key => $value) {
320:             if (!in_array($key, $allowedAttributes)) {
321:                 throw new cInvalidArgumentException('Unallowed attribute for meta tag given - meta tag will be ignored!');
322:             }
323:         }
324:         $this->_metaTags[] = $meta;
325:     }
326: 
327:     328: 329: 330: 331: 
332:     public function addBodyClassName($className) {
333:         if (!in_array($className, $this->_bodyClassNames)) {
334:             $this->_bodyClassNames[] = $className;
335:         }
336:     }
337: 
338:     339: 340: 341: 342: 343: 344: 345: 
346:     public function setSubnav($additional = '', $aarea = '') {
347:         global $area, $sess;
348: 
349:         if ($aarea == '') {
350:             $aarea = $area;
351:         }
352: 
353:         $this->_subnav = '
354:         <script type="text/javascript">
355:         Con.getFrame("right_top").location.href = "' . $sess->url("main.php?area={$aarea}&frame=3&{$additional}") . '";
356:         </script>
357:         ';
358:     }
359: 
360:     361: 362: 
363:     public function setReload() {
364:         $this->_scripts[] = 'reload.js';
365:     }
366: 
367:     368: 369: 370: 371: 
372:     public function setMarkScript($item) {
373:         $this->_markScript = markSubMenuItem($item, true);
374:     }
375: 
376:     377: 378: 379: 380: 381: 
382:     public function setEncoding($encoding) {
383:         if (empty($encoding)) {
384:             return;
385:         }
386:         $this->_metaTags[] = array(
387:             'http-equiv' => 'Content-type',
388:             'content' => 'text/html;charset=' . $encoding
389:         );
390:     }
391: 
392:     393: 394: 395: 396: 397: 398: 399: 
400:     public function set($type, $key, $value) {
401:         $this->_contentTemplate->set($type, $key, $value);
402:     }
403: 
404:     405: 406: 407: 408: 
409:     public function next() {
410:         $this->_contentTemplate->next();
411:     }
412: 
413:     414: 415: 416: 417: 
418:     public function abortRendering() {
419:         $this->_abort = true;
420:     }
421: 
422:     423: 424: 425: 426: 427: 
428:     public function displayCriticalError($msg) {
429:         $this->_error = $msg;
430:         $this->_abort = true;
431:     }
432: 
433:     434: 435: 436: 437: 438: 
439:     public function displayError($msg) {
440:         $this->_error .= $msg . '<br>';
441:     }
442: 
443:     444: 445: 446: 447: 
448:     public function displayWarning($msg) {
449:         $this->_warning .= $msg . '<br>';
450:     }
451: 
452:     453: 454: 455: 456: 
457:     public function displayInfo($msg) {
458:         $this->_info .= $msg . '<br>';
459:     }
460: 
461:     462: 463: 464: 465: 466: 467: 468: 
469:     public function setContent($objects) {
470:         if (!is_array($objects)) {
471:             $objects = array(
472:                 $objects
473:             );
474:         }
475:         $this->_objects = $objects;
476:     }
477: 
478:     479: 480: 481: 482: 483: 484: 485: 486: 
487:     public function appendContent($objects) {
488:         if (!is_array($objects)) {
489:             $this->_objects[] = $objects;
490:         } else {
491:             $this->_objects = array_merge($this->_objects, $objects);
492:         }
493:     }
494: 
495:     496: 497: 498: 499: 500: 501: 502: 503: 504: 
505:     public function setPluginScript($plugin, $filename) {
506:         global $cfg;
507:         $path = $cfg['pica']['script_complexlist'];
508:     }
509: 
510:     public function setStyleDirect($filepath) {
511:         global $cfg;
512:         $path = $cfg['pica']['style_complexlist'];
513:         $this->_pageTemplate->set('s', 'SCRIPTS', $path);
514: 
515:         $strstyle = '';
516: 
517:         $strstyle .= "<link href='styles/" . $path . "' type='text/css' rel='stylesheet'>\n";
518: 
519:         $this->_pageTemplate->set('s', 'STYLES', $strstyle);
520:         return $this->_pageTemplate->generate($cfg['path']['templates'] . $cfg['templates']['generic_page'], false);
521:     }
522: 
523:     524: 525: 526: 527: 528: 529: 530: 
531:     public function render($template = NULL, $return = false) {
532:         global $cfg;
533: 
534:         if ($template == NULL) {
535:             $template = $this->_contentTemplate;
536:         }
537: 
538:         
539:         $this->_renderMetaTags();
540:         $this->_renderScripts();
541:         $this->_renderStyles();
542: 
543:         
544:         $this->_pageTemplate->set('s', 'PAGECLASS', implode(' ', $this->_bodyClassNames));
545: 
546:         
547:         $text = $this->_renderContentMessages();
548: 
549:         if (!$this->_abort) {
550:             if (count($this->_objects) == 0) {
551:                 $output = $this->_renderTemplate($template);
552:             } else {
553:                 $output = $this->_renderObjects();
554:             }
555:             $this->_pageTemplate->set('s', 'CONTENT', $text . $output);
556:         } else {
557:             $this->_pageTemplate->set('s', 'CONTENT', $text);
558:         }
559: 
560:         return $this->_pageTemplate->generate($cfg['path']['templates'] . $cfg['templates']['generic_page'], $return);
561:     }
562: 
563:     564: 565: 
566:     protected function _renderMetaTags() {
567:         
568:         
569:         
570:         $produceXhtml = false;
571:         $meta = '';
572:         foreach ($this->_metaTags as $metaTag) {
573:             $tag = '<meta';
574:             foreach ($metaTag as $key => $value) {
575:                 $tag .= ' ' . $key . '="' . $value . '"';
576:             }
577:             if ($produceXhtml) {
578:                 $tag .= ' /';
579:             }
580:             $tag .= ">\n";
581:             $meta .= $tag;
582:         }
583:         if (!empty($meta)) {
584:             $this->_pageTemplate->set('s', 'META', $meta);
585:         } else {
586:             $this->_pageTemplate->set('s', 'META', '');
587:         }
588:     }
589: 
590:     591: 592: 
593:     protected function _renderScripts() {
594:         $strscript = $this->_subnav . "\n" . $this->_markScript . "\n";
595:         foreach ($this->_scripts as $script) {
596:             if (strpos($script, 'http') === 0 || strpos($script, '//') === 0) {
597:                 $strscript .= '<script type="text/javascript" src="' . $script . '"></script>' . "\n";
598:             } else if (strpos($script, '<script') === false) {
599:                 $strscript .= '<script type="text/javascript" src="scripts/' . $script . '"></script>' . "\n";
600:             } else {
601:                 $strscript .= $script;
602:             }
603:         }
604:         $this->_pageTemplate->set('s', 'SCRIPTS', $strscript);
605:     }
606: 
607:     608: 609: 
610:     protected function _renderStyles() {
611:         $strstyle = '';
612:         foreach ($this->_styles as $style) {
613:             if (strpos($style, 'http') === 0 || strpos($style, '//') === 0) {
614:                 $strstyle .= '<link href="' . $style . '" type="text/css" rel="stylesheet">' . "\n";
615:             } else {
616:                 $strstyle .= '<link href="styles/' . $style . '" type="text/css" rel="stylesheet">' . "\n";
617:             }
618:         }
619:         $this->_pageTemplate->set('s', 'STYLES', $strstyle);
620:     }
621: 
622:     623: 624: 625: 626: 627: 628: 
629:     protected function _renderContentMessages() {
630:         global $notification;
631: 
632:         
633:         $infoMessages = cRegistry::getInfoMessages();
634:         foreach ($infoMessages as $message) {
635:             $this->displayInfo($message);
636:         }
637: 
638:         $errorMessages = cRegistry::getErrorMessages();
639:         foreach ($errorMessages as $message) {
640:             $this->displayError($message);
641:         }
642: 
643:         $warningMessages = cRegistry::getWarningMessages();
644:         foreach ($warningMessages as $message) {
645:             $this->displayWarning($message);
646:         }
647: 
648:         $text = '';
649:         if ($this->_info != '') {
650:             $text .= $notification->returnNotification('info', $this->_info) . '<br>';
651:         }
652:         if ($this->_warning != '') {
653:             $text .= $notification->returnNotification('warning', $this->_warning) . '<br>';
654:         }
655:         if ($this->_error != '') {
656:             $text .= $notification->returnNotification('error', $this->_error) . '<br>';
657:         }
658: 
659:         return $text;
660:     }
661: 
662:     663: 664: 665: 666: 667: 
668:     protected function _renderObjects() {
669:         $output = '';
670: 
671:         foreach ($this->_objects as $obj) {
672:             if (!method_exists($obj, 'render')) {
673:                 continue;
674:             }
675: 
676:             
677:             
678:             
679:             $oldOutput = $output;
680:             ob_start(); 
681:                         
682:                         
683:             $output .= $obj->render(false);
684:             
685:             $output .= ob_get_contents();
686:             if ($oldOutput == $output) {
687:                 cWarning(__FILE__, __LINE__, "Rendering this object (" . print_r($obj, true) . ") doesn't seem to have any effect.");
688:             }
689:             ob_end_clean();
690:         }
691: 
692:         return $output;
693:     }
694: 
695:     696: 697: 698: 699: 700: 
701:     protected function _renderTemplate($template) {
702:         $cfg = cRegistry::getConfig();
703: 
704:         $file = '';
705:         if ($this->_pluginName == '') {
706:             $file = $cfg['path']['templates'] . 'template.' . $this->_pageName . '.html';
707:         } else {
708:             $file = $cfg['path']['plugins'] . $this->_pluginName . '/templates/template.' . $this->_pageName . '.html';
709:         }
710: 
711:         if (cFileHandler::exists($file)) {
712:             $output = $template->generate($file, true);
713:         } else {
714:             $output = '';
715:         }
716: 
717:         return $output;
718:     }
719: 
720:     721: 722: 723: 724: 725: 726: 727: 728: 729: 
730:     protected function _getRealFilePathName($file) {
731:         $tmp = explode('?', $file);
732:         return $tmp[0];
733:     }
734: 
735: }