Overview

Packages

  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Datatype
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationMain
    • NavigationTop
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • ArticleForumRightBottom
  • cApiClickableAction
  • cApiClickableQuestionAction
  • cGuiFoldingRow
  • cGuiList
  • cGuiMenu
  • cGuiNavigation
  • cGuiNotification
  • cGuiObjectPager
  • cGuiPage
  • cGuiScrollList
  • cGuiTableForm
  • cGuiTree
  • cPager
  • cTemplate
  • cTree
  • cTreeItem
  • NoteLink
  • NoteList
  • NoteListItem
  • NoteView
  • TODOBackendList
  • TODOLink
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * This file contains the generic page GUI class.
  4:  *
  5:  * @package          Core
  6:  * @subpackage       GUI
  7:  * @version          SVN Revision $Rev:$
  8:  *
  9:  * @author           Mischa Holz
 10:  * @copyright        four for business AG <www.4fb.de>
 11:  * @license          http://www.contenido.org/license/LIZENZ.txt
 12:  * @link             http://www.4fb.de
 13:  * @link             http://www.contenido.org
 14:  */
 15: 
 16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 17: 
 18: /**
 19:  * Generic page GUI class.
 20:  * Manages HTML pages and provides functions for rendering them.
 21:  *
 22:  * @package    Core
 23:  * @subpackage GUI
 24:  */
 25: class cGuiPage {
 26: 
 27:     /**
 28:      * The name of the page.
 29:      * This will be used to load the template, stylesheets and scripts.
 30:      *
 31:      * @var string
 32:      */
 33:     protected $_pagename;
 34: 
 35:     /**
 36:      * The name of the plugin of the current webpage.
 37:      *
 38:      * @var string
 39:      */
 40:     protected $_pluginname;
 41: 
 42:     /**
 43:      * The general page template.
 44:      *
 45:      * @var cTemplate
 46:      */
 47:     protected $_pagetemplate;
 48: 
 49:     /**
 50:      * The template for everything that is inside the body.
 51:      * (Usually template.PAGENAME.html)
 52:      *
 53:      * @var cTemplate
 54:      */
 55:     protected $_contenttemplate;
 56: 
 57:     /**
 58:      * An array of script names (inside /scripts/) which will be included in the
 59:      * final page.
 60:      *
 61:      * @var array
 62:      */
 63:     protected $_scripts;
 64: 
 65:     /**
 66:      * An array of stylesheets (inside /styles/) which will be included in the
 67:      * final page.
 68:      *
 69:      * @var array
 70:      */
 71:     protected $_styles;
 72: 
 73:     /**
 74:      * The script to set the subnavigation.
 75:      * This will be included in the final page.
 76:      *
 77:      * @var string
 78:      */
 79:     protected $_subnav;
 80: 
 81:     /**
 82:      * The script to markup the current submenu item.
 83:      * This will be included in the final page.
 84:      *
 85:      * @var string
 86:      */
 87:     protected $_markscript;
 88: 
 89:     /**
 90:      * An error message which will be used to display an error with the help of
 91:      * cGuiNotification
 92:      *
 93:      * @var string
 94:      */
 95:     protected $_error;
 96: 
 97:     /**
 98:      * A warning which will be used to display an error with the help of
 99:      * cGuiNotification
100:      *
101:      * @var string
102:      */
103:     protected $_warning;
104: 
105:     /**
106:      * An info which will be used to display an error with the help of
107:      * cGuiNotification
108:      *
109:      * @var unknown_type
110:      */
111:     protected $_info;
112: 
113:     /**
114:      * If true, just display the message and don't render the template
115:      *
116:      * @var bool
117:      */
118:     protected $_abort;
119: 
120:     /**
121:      * An array of cHTML objects which will be rendered instead of filling a
122:      * template.
123:      *
124:      * @var array
125:      */
126:     protected $_objects;
127: 
128:     /**
129:      * Array of arrays where each array contains information about a meta tag.
130:      *
131:      * @var array
132:      */
133:     protected $_metaTags;
134: 
135:     /**
136:      * The constructor initializes the class and tries to get the encoding from
137:      * the currently selected language.
138:      * It will also add every script in the form of /scripts/*.PAGENAME.js and
139:      * every stylesheet in the form
140:      * of/styles/*.PAGENAME.css to the page as well as /scripts/PAGENAME.js and
141:      * /styles/PAGENAME.css.
142:      *
143:      * @param string $pagename The name of the page which will be used to load
144:      *        corresponding stylehseets, templates and scripts.
145:      * @param string $pluginname The name of the plugin in which the site is run
146:      * @param string $submenu The number of the submenu which should be
147:      *        highlighted when this page is shown.
148:      */
149:     public function __construct($pagename, $pluginname = "", $submenu = "") {
150:         global $lang, $cfg;
151: 
152:         $this->_pagename = $pagename;
153:         $this->_pluginname = $pluginname;
154:         $this->_pagetemplate = new cTemplate();
155:         $this->_contenttemplate = new cTemplate();
156:         $this->_scripts = array();
157:         $this->_styles = array();
158:         $this->_subnav = "";
159:         $this->_markscript = "";
160:         $this->_error = "";
161:         $this->_warning = "";
162:         $this->_info = "";
163:         $this->_abort = false;
164:         $this->_objects = array();
165:         $this->_metaTags = array();
166: 
167:         // Try to extract the current CONTENIDO language
168:         $clang = new cApiLanguage($lang);
169: 
170:         if ($clang->isLoaded()) {
171:             $this->setEncoding($clang->get("encoding"));
172:         }
173: 
174:         $this->_pagetemplate->set("s", "SUBMENU", $submenu);
175:         $this->_pagetemplate->set("s", "PAGENAME", $pagename);
176: 
177:         if (cFileHandler::exists($cfg['path']['styles'] . $pagename . ".css")) {
178:             $this->addStyle($pagename . ".css");
179:         }
180: 
181:         /** @var $stylefile SplFileInfo */
182:         foreach (new DirectoryIterator($cfg['path']['styles']) as $stylefile) {
183:             if (endsWith($stylefile->getFilename(), "." . $pagename . ".css")) {
184:                 $this->addStyle($stylefile->getFilename());
185:             }
186:         }
187: 
188:         if (cFileHandler::exists($cfg['path']['scripts'] . $pagename . ".js")) {
189:             $this->addScript($pagename . ".js");
190:         }
191: 
192:         /** @var $scriptfile SplFileInfo */
193:         foreach (new DirectoryIterator($cfg['path']['scripts']) as $scriptfile) {
194:             if (endsWith($scriptfile->getFilename(), "." . $pagename . ".js")) {
195:                 $this->addScript($scriptfile->getFilename());
196:             }
197:         }
198:     }
199: 
200:     /**
201:      * Adds a script to the website - path can be absolute, relative to the
202:      * plugin scripts folder and relative to the CONTENIDO scripts folder.
203:      * NOTE: This function will also add inline JavaScript in the form of
204:      * "<script...". However this shouldn't be used.
205:      *
206:      * If the page was constructed in a plugin and the plugin name was given
207:      * in the constructor it will find the JS script in plugins/PLUGINNAME/scripts/
208:      * too.
209:      *
210:      * @param string $script The filename of the script. It has to reside in
211:      *        /scripts/ in order to be found.
212:      */
213:     public function addScript($script) {
214:         $cfg = cRegistry::getConfig();
215:         $backendUrl = cRegistry::getBackendUrl();
216:         $backendPath = cRegistry::getBackendPath();
217: 
218:         if (strpos(trim($script), 'http') === 0 || strpos(trim($script), '<script') === 0 || strpos(trim($script), '//') === 0) {
219:             if (strpos(trim($script), '<script') === 0) {
220:                 cDeprecated("You shouldn't use inline JS for backend pages");
221:             }
222:             // the given script path is absolute
223:             $this->_scripts[] = $script;
224:         } else if (cFileHandler::exists($backendPath . $cfg['path']['plugins'] . $this->_pluginname . '/' . $cfg['path']['scripts'] . $script)) {
225:             // the given script path is relative to the plugin scripts folder
226:             $fullpath = $backendUrl . $cfg['path']['plugins'] . $this->_pluginname . '/' . $cfg['path']['scripts'] . $script;
227:             $this->_scripts[] = $fullpath;
228:         } else if (cFileHandler::exists($backendPath . $cfg['path']['scripts'] . $script)) {
229:             // the given script path is relative to the CONTENIDO scripts folder
230:             $fullpath = $backendUrl . $cfg['path']['scripts'] . $script;
231:             $this->_scripts[] = $fullpath;
232:         }
233:     }
234: 
235:     /**
236:      * Adds a stylesheet to the website - path can be absolute, relative to the
237:      * plugin stylesheets folder and relative to the CONTENIDO stylesheets
238:      * folder.
239:      *
240:      * @param string $stylesheet The filename of the stylesheet. It has to
241:      *        reside in /styles/ in order to be found.
242:      */
243:     public function addStyle($stylesheet) {
244:         $cfg = cRegistry::getConfig();
245:         $backendUrl = cRegistry::getBackendUrl();
246:         $backendPath = cRegistry::getBackendPath();
247: 
248:         if (strpos($stylesheet, 'http') === 0 || strpos($stylesheet, '//') === 0) {
249:             // the given stylesheet path is absolute
250:             $this->_styles[] = $stylesheet;
251:         } else if (cFileHandler::exists($backendPath . $cfg['path']['plugins'] . $this->_pluginname . '/' . $cfg['path']['styles'] . $stylesheet)) {
252:             // the given stylesheet path is relative to the plugin stylesheets
253:             // folder
254:             $fullpath = $backendUrl . $cfg['path']['plugins'] . $this->_pluginname . '/' . $cfg['path']['styles'] . $stylesheet;
255:             $this->_styles[] = $fullpath;
256:         } else if (cFileHandler::exists($backendPath . $cfg['path']['styles'] . $stylesheet)) {
257:             // the given stylesheet path is relative to the CONTENIDO
258:             // stylesheets folder
259:             $fullpath = $backendUrl . $cfg['path']['styles'] . $stylesheet;
260:             $this->_styles[] = $fullpath;
261:         }
262:     }
263: 
264:     /**
265:      * Adds a meta tag to the website.
266:      *
267:      * @param array $meta Associative array with the meta tag attributes
268:      * @throws cInvalidArgumentException if an invalid attribute for the meta
269:      *         tag has been given
270:      * @return void
271:      */
272:     public function addMeta(array $meta) {
273:         $allowedAttributes = array(
274:             'charset',
275:             'content',
276:             'http-equiv',
277:             'name',
278:             'itemprop'
279:         );
280:         foreach ($meta as $key => $value) {
281:             if (!in_array($key, $allowedAttributes)) {
282:                 throw new cInvalidArgumentException('Unallowed attribute for meta tag given - meta tag will be ignored!');
283:             }
284:         }
285:         $this->_metaTags[] = $meta;
286:     }
287: 
288:     /**
289:      * Loads the subnavigation of the current area upon rendering.
290:      *
291:      * @param string $additional Additional parameters the subnavigation might
292:      *        need. These have to look like "key=value&key2=value2..."
293:      * @param string $aarea The area of the subnavigation. If none is given the
294:      *        current area will be loaded
295:      */
296:     public function setSubnav($additional = "", $aarea = "") {
297:         global $area, $sess;
298: 
299:         if ($aarea == "") {
300:             $aarea = $area;
301:         }
302: 
303:         $this->_subnav = '<script type="text/javascript">';
304:         $this->_subnav .= 'parent.frames["right_top"].location.href = "';
305:         $this->_subnav .= $sess->url("main.php?area=" . $aarea . "&frame=3&" . $additional) . '";';
306:         $this->_subnav .= '</script>';
307:     }
308: 
309:     /**
310:      * Adds the reload script for the left_bottom frame to the website
311:      */
312:     public function setReload() {
313:         $this->_scripts[] = "reload.js";
314:     }
315: 
316:     /**
317:      * Sets the markscript
318:      *
319:      * @param string $item The number of the submenu which should be marked.
320:      */
321:     public function setMarkScript($item) {
322:         $this->_markscript = markSubMenuItem($item, true);
323:     }
324: 
325:     /**
326:      * Sets the encoding of the website
327:      *
328:      * @param string $encoding An encoding which should be valid to use in the
329:      *        meta tag
330:      */
331:     public function setEncoding($encoding) {
332:         if (empty($encoding)) {
333:             return;
334:         }
335:         $this->_metaTags[] = array(
336:             'http-equiv' => 'Content-type',
337:             'content' => 'text/html;charset=' . $encoding
338:         );
339:     }
340: 
341:     /**
342:      * Applies a value to a key in the content template.
343:      *
344:      * @param string $type Either "s" or "d" for "static" or "dynamic" values
345:      * @param string $key The key which should be replaced
346:      * @param string $value The value which should replace the key
347:      * @see cTemplate::set()
348:      */
349:     public function set($type, $key, $value) {
350:         $this->_contenttemplate->set($type, $key, $value);
351:     }
352: 
353:     /**
354:      * Calls the next() method on the content template.
355:      *
356:      * @see cTemplate::next()
357:      */
358:     public function next() {
359:         $this->_contenttemplate->next();
360:     }
361: 
362:     /**
363:      * After calling this the page will only display messages and not render the
364:      * content template.
365:      * NOTE: You still have to call render() to actually show any messages
366:      */
367:     public function abortRendering() {
368:         $this->_abort = true;
369:     }
370: 
371:     /**
372:      * Displays an error message and aborts rendering after that
373:      * NOTE: You still have to call render() to actually show any messages
374:      *
375:      * @param string $msg A message
376:      */
377:     public function displayCriticalError($msg) {
378:         $this->_error = $msg;
379:         $this->_abort = true;
380:     }
381: 
382:     /**
383:      * Displays an error but the rendering of the content template will
384:      * continue.
385:      *
386:      * @param string $msg A message
387:      */
388:     public function displayError($msg) {
389:         $this->_error .= $msg . "<br>";
390:     }
391: 
392:     /**
393:      * Displays a warning
394:      *
395:      * @param string $msg The warning
396:      */
397:     public function displayWarning($msg) {
398:         $this->_warning .= $msg . "<br>";
399:     }
400: 
401:     /**
402:      * Displays an info
403:      *
404:      * @param string $msg The info message
405:      */
406:     public function displayInfo($msg) {
407:         $this->_info .= $msg . "<br>";
408:     }
409: 
410:     /**
411:      * Sets an array (or a single object) of cHTML objects which build up the
412:      * site instead of a content template.
413:      * NOTE: All these objects must have a render() method or else they won't be
414:      * shown
415:      *
416:      * @param array|object $objects An array of objects
417:      */
418:     public function setContent($objects) {
419:         if (!is_array($objects)) {
420:             $objects = array(
421:                 $objects
422:             );
423:         }
424:         $this->_objects = $objects;
425:     }
426: 
427:     /**
428:      * Appends all cHTML objects in an array (or a single object) which build up
429:      * the
430:      * site instead of a content template.
431:      * NOTE: All these objects must have a render() method or else they won't be
432:      * shown
433:      *
434:      * @param array|object $objects An array of objects or a single object
435:      */
436:     public function appendContent($objects) {
437:         if (!is_array($objects)) {
438:             $this->_objects[] = $objects;
439:         } else {
440:             $this->_objects = array_merge($this->_objects, $objects);
441:         }
442:     }
443: 
444:     /**
445:      * Example:
446:      * setPluginScript('content_allocation', 'complexlist.js');
447:      * $this->_scripts[] =
448:      * 'http://contenido.local/contenido/plugins/content_allocation/scripts/complexlist.js';
449:      *
450:      * @param unknown_type $plugin
451:      * @param unknown_type $filename
452:      * @return Ambigous <string, mixed>
453:      */
454:     public function setPluginScript($plugin, $filename) {
455:         global $cfg;
456:         $path = $cfg['pica']['script_complexlist'];
457:     }
458: 
459:     public function setStyleDirect($filepath) {
460:         global $cfg;
461:         $path = $cfg['pica']['style_complexlist'];
462:         $this->_pagetemplate->set("s", "SCRIPTS", $path);
463: 
464:         $strstyle = "";
465: 
466:         $strstyle .= "<link href='styles/" . $path . "' type='text/css' rel='stylesheet'>\n";
467: 
468:         $this->_pagetemplate->set("s", "STYLES", $strstyle);
469:         return $this->_pagetemplate->generate($cfg['path']['templates'] . $cfg['templates']['generic_page'], false);
470:     }
471: 
472:     /**
473:      * Renders the page and either prints it or returns it
474:      *
475:      * @param Template|null $template If set, use this content template instead
476:      *        of the default one
477:      * @param bool $return If true, the page will be returned instead of echoed
478:      * @return string void either the webpage or nothing
479:      */
480:     public function render($template = null, $return = false) {
481:         global $cfg, $notification;
482: 
483:         if ($template == null) {
484:             $template = $this->_contenttemplate;
485:         }
486: 
487:         // render the meta tags
488:         $produceXhtml = getEffectiveSetting('generator', 'xhtml', 'false');
489:         $meta = '';
490:         foreach ($this->_metaTags as $metaTag) {
491:             $tag = '<meta';
492:             foreach ($metaTag as $key => $value) {
493:                 $tag .= ' ' . $key . '="' . $value . '"';
494:             }
495:             if ($produceXhtml) {
496:                 $tag .= ' /';
497:             }
498:             $tag .= ">\n";
499:             $meta .= $tag;
500:         }
501:         if (!empty($meta)) {
502:             $this->_pagetemplate->set('s', 'META', $meta);
503:         } else {
504:             $this->_pagetemplate->set('s', 'META', "");
505:         }
506: 
507:         $strscript = $this->_subnav . "\n" . $this->_markscript . "\n";
508:         foreach ($this->_scripts as $script) {
509:             if (strpos($script, "http") === 0 || strpos($script, "//") === 0) {
510:                 $strscript .= '<script type="text/javascript" src="' . $script . '"></script>' . "\n";
511:             } else if (strpos($script, "<script") === false) {
512:                 $strscript .= '<script type="text/javascript" src="scripts/' . $script . '"></script>' . "\n";
513:             } else {
514:                 $strscript .= $script;
515:             }
516:         }
517:         $this->_pagetemplate->set("s", "SCRIPTS", $strscript);
518: 
519:         $strstyle = "";
520:         foreach ($this->_styles as $style) {
521:             if (strpos($style, "http") === 0 || strpos($style, "//") === 0) {
522:                 $strstyle .= '<link href="' . $style . '" type="text/css" rel="stylesheet">' . "\n";
523:             } else {
524:                 $strstyle .= '<link href="styles/' . $style . '" type="text/css" rel="stylesheet">' . "\n";
525:             }
526:         }
527:         $this->_pagetemplate->set("s", "STYLES", $strstyle);
528: 
529:         // get messages from cRegistry
530:         $infoMessages = cRegistry::getInfoMessages();
531:         foreach ($infoMessages as $message) {
532:             $this->displayInfo($message);
533:         }
534: 
535:         $errorMessages = cRegistry::getErrorMessages();
536:         foreach ($errorMessages as $message) {
537:             $this->displayError($message);
538:         }
539: 
540:         $warningMessages = cRegistry::getWarningMessages();
541:         foreach ($warningMessages as $message) {
542:             $this->displayWarning($message);
543:         }
544:         $text = "";
545:         if ($this->_info != "") {
546:             $text .= $notification->returnNotification("info", $this->_info) . "<br>";
547:         }
548:         if ($this->_warning != "") {
549:             $text .= $notification->returnNotification("warning", $this->_warning) . "<br>";
550:         }
551:         if ($this->_error != "") {
552:             $text .= $notification->returnNotification("error", $this->_error) . "<br>";
553:         }
554: 
555:         $file = "";
556:         if ($this->_pluginname == "") {
557:             $file = $cfg['path']['templates'] . "template." . $this->_pagename . ".html";
558:         } else {
559:             $file = $cfg['path']['plugins'] . $this->_pluginname . "/templates/template." . $this->_pagename . ".html";
560:         }
561: 
562:         if (!$this->_abort) {
563:             if (count($this->_objects) == 0) {
564:                 if (cFileHandler::exists($file)) {
565:                     $this->_pagetemplate->set("s", "CONTENT", $text . $template->generate($file, true));
566:                 } else {
567:                     $this->_pagetemplate->set("s", "CONTENT", $text);
568:                 }
569:             } else {
570:                 $str = "";
571:                 foreach ($this->_objects as $obj) {
572:                     if (method_exists($obj, "render")) {
573:                         // Ridiculous workaround because some objects return
574:                         // code if the parameter is true and some return the
575:                         // code if the parameter is false.
576:                         $old_str = $str;
577:                         ob_start(); // We don't want any code outside the body
578:                         // (in case the object outputs directly we
579:                         // will catch this output)
580:                         $str .= $obj->render(false); // We get the code either
581:                         // directly or via the
582:                         // output
583:                         $str .= ob_get_contents();
584:                         if ($old_str == $str) {
585:                             cWarning(__FILE__, __LINE__, "Rendering this object (" . print_r($obj, true) . ") doesn't seem to have any effect.");
586:                         }
587:                         ob_end_clean();
588:                     }
589:                 }
590:                 $this->_pagetemplate->set("s", "CONTENT", $text . $str);
591:             }
592:         } else {
593:             $this->_pagetemplate->set("s", "CONTENT", $text);
594:         }
595: 
596:         return $this->_pagetemplate->generate($cfg['path']['templates'] . $cfg['templates']['generic_page'], $return);
597:     }
598: 
599: }
600: 
CMS CONTENIDO 4.9.0 API documentation generated by ApiGen 2.8.0