page = new YellowPage($this); $this->pages = new YellowPages($this); $this->files = new YellowFiles($this); $this->plugins = new YellowPlugins($this); $this->themes = new YellowThemes($this); $this->config = new YellowConfig($this); $this->text = new YellowText($this); $this->lookup = new YellowLookup($this); $this->toolbox = new YellowToolbox(); $this->config->setDefault("sitename", "Yellow"); $this->config->setDefault("author", "Yellow"); $this->config->setDefault("email", "webmaster"); $this->config->setDefault("language", "en"); $this->config->setDefault("timezone", "UTC"); $this->config->setDefault("theme", "default"); $this->config->setDefault("staticUrl", ""); $this->config->setDefault("staticDefaultFile", "index.html"); $this->config->setDefault("staticErrorFile", "404.html"); $this->config->setDefault("staticDir", "cache/"); $this->config->setDefault("mediaLocation", "/media/"); $this->config->setDefault("downloadLocation", "/media/downloads/"); $this->config->setDefault("imageLocation", "/media/images/"); $this->config->setDefault("pluginLocation", "/media/plugins/"); $this->config->setDefault("themeLocation", "/media/themes/"); $this->config->setDefault("assetLocation", "/media/themes/assets/"); $this->config->setDefault("mediaDir", "media/"); $this->config->setDefault("downloadDir", "media/downloads/"); $this->config->setDefault("imageDir", "media/images/"); $this->config->setDefault("systemDir", "system/"); $this->config->setDefault("configDir", "system/config/"); $this->config->setDefault("pluginDir", "system/plugins/"); $this->config->setDefault("themeDir", "system/themes/"); $this->config->setDefault("assetDir", "system/themes/assets/"); $this->config->setDefault("snippetDir", "system/themes/snippets/"); $this->config->setDefault("templateDir", "system/themes/templates/"); $this->config->setDefault("trashDir", "system/trash/"); $this->config->setDefault("contentDir", "content/"); $this->config->setDefault("contentRootDir", "default/"); $this->config->setDefault("contentHomeDir", "home/"); $this->config->setDefault("contentPagination", "page"); $this->config->setDefault("contentDefaultFile", "page.txt"); $this->config->setDefault("contentExtension", ".txt"); $this->config->setDefault("configExtension", ".ini"); $this->config->setDefault("downloadExtension", ".download"); $this->config->setDefault("uploadExtension", ".upload"); $this->config->setDefault("configFile", "config.ini"); $this->config->setDefault("textFile", "text.ini"); $this->config->setDefault("languageFile", "language-(.*).txt"); $this->config->setDefault("errorFile", "page-error-(.*).txt"); $this->config->setDefault("robotsFile", "robots.txt"); $this->config->setDefault("faviconFile", "favicon.ico"); $this->config->setDefault("serverUrl", ""); $this->config->setDefault("template", "default"); $this->config->setDefault("navigation", "navigation"); $this->config->setDefault("sidebar", "sidebar"); $this->config->setDefault("siteicon", "icon"); $this->config->setDefault("tagline", ""); $this->config->setDefault("parser", "markdown"); $this->config->setDefault("parserSafeMode", "0"); $this->config->setDefault("multiLanguageMode", "0"); $this->config->setDefault("installationMode", "0"); $this->config->setDefault("startupUpdate", "none"); } function __destruct() { $this->shutdown(); } // Handle initialisation function load() { if(defined("DEBUG") && DEBUG>=2) { $serverVersion = $this->toolbox->getServerVersion(); echo "Datenstrom Yellow ".YellowCore::VERSION.", PHP ".PHP_VERSION.", $serverVersion
\n"; } $this->toolbox->timerStart($time); $this->config->load($this->config->get("configDir").$this->config->get("configFile")); $this->lookup->load(); $this->themes->load(); $this->plugins->load(); $this->text->load($this->config->get("pluginDir").$this->config->get("languageFile"), ""); $this->text->load($this->config->get("configDir").$this->config->get("textFile"), $this->config->get("language")); $this->toolbox->timerStop($time); $this->startup(); if(defined("DEBUG") && DEBUG>=2) { $plugins = count($this->plugins->plugins); $themes = count($this->themes->themes); $languages = count($this->text->text); echo "YellowCore::load plugins:$plugins themes:$themes languages:$languages time:$time ms
\n"; } } // Handle request function request() { ob_start(); $statusCode = 0; $this->toolbox->timerStart($time); list($scheme, $address, $base, $location, $fileName) = $this->getRequestInformation(); $this->page->setRequestInformation($scheme, $address, $base, $location, $fileName); foreach($this->plugins->plugins as $key=>$value) { if(method_exists($value["obj"], "onRequest")) { $this->lookup->requestHandler = $key; $statusCode = $value["obj"]->onRequest($scheme, $address, $base, $location, $fileName); if($statusCode!=0) break; } } if($statusCode==0) { $this->lookup->requestHandler = "core"; $statusCode = $this->processRequest($scheme, $address, $base, $location, $fileName, true); } if($this->page->isExisting("pageError")) $statusCode = $this->processRequestError(); $this->toolbox->timerStop($time); ob_end_flush(); if(defined("DEBUG") && DEBUG>=1) { $handler = $this->getRequestHandler(); echo "YellowCore::request status:$statusCode handler:$handler time:$time ms
\n"; } return $statusCode; } // Process request function processRequest($scheme, $address, $base, $location, $fileName, $cacheable) { $statusCode = 0; if(is_readable($fileName)) { if($this->toolbox->isRequestCleanUrl($location)) { $location = $location.$this->getRequestLocationArgsClean(); $location = $this->lookup->normaliseUrl($scheme, $address, $base, $location); $statusCode = $this->sendStatus(303, $location); } } else { if($this->lookup->isRedirectLocation($location)) { $location = $this->lookup->isFileLocation($location) ? "$location/" : "/".$this->getRequestLanguage()."/"; $location = $this->lookup->normaliseUrl($scheme, $address, $base, $location); $statusCode = $this->sendStatus(301, $location); } } if($statusCode==0) { $fileName = $this->lookup->findFileStatic($location, $fileName, $cacheable && !$this->isCommandLine()); if($this->lookup->isContentFile($fileName) || !is_readable($fileName)) { $fileName = $this->readPage($scheme, $address, $base, $location, $fileName, $cacheable, max(is_readable($fileName) ? 200 : 404, $this->page->statusCode), $this->page->get("pageError")); $statusCode = $this->sendPage(); } else { $statusCode = $this->sendFile(200, $fileName, true); } } if(defined("DEBUG") && DEBUG>=1) echo "YellowCore::processRequest file:$fileName
\n"; return $statusCode; } // Process request with error function processRequestError() { ob_clean(); $fileName = $this->readPage($this->page->scheme, $this->page->address, $this->page->base, $this->page->location, $this->page->fileName, $this->page->cacheable, $this->page->statusCode, $this->page->get("pageError")); $statusCode = $this->sendPage(); if(defined("DEBUG") && DEBUG>=1) echo "YellowCore::processRequestError file:$fileName
\n"; return $statusCode; } // Read page function readPage($scheme, $address, $base, $location, $fileName, $cacheable, $statusCode, $pageError) { if($statusCode>=400) { $cacheable = false; $fileName = $this->config->get("configDir").$this->config->get("errorFile"); $fileName = strreplaceu("(.*)", $statusCode, $fileName); $rawData = $this->toolbox->readFile($fileName); if(empty($rawData)) $rawData = "---\nTitle:".$this->toolbox->getHttpStatusFormatted($statusCode, true)."\n---\n"; } else { $rawData = $this->toolbox->readFile($fileName); } $this->page = new YellowPage($this); $this->page->setRequestInformation($scheme, $address, $base, $location, $fileName); $this->page->parseData($rawData, $cacheable, $statusCode, $pageError); $this->text->setLanguage($this->page->get("language")); $this->page->parseContent(); return $fileName; } // Send page response function sendPage() { $this->page->parsePage(); $statusCode = $this->page->statusCode; $lastModifiedFormatted = $this->page->getHeader("Last-Modified"); if($statusCode==200 && $this->page->isCacheable() && $this->toolbox->isRequestNotModified($lastModifiedFormatted)) { $statusCode = 304; @header($this->toolbox->getHttpStatusFormatted($statusCode)); } else { @header($this->toolbox->getHttpStatusFormatted($statusCode)); foreach($this->page->headerData as $key=>$value) @header("$key: $value"); if(!is_null($this->page->outputData)) echo $this->page->outputData; } if(defined("DEBUG") && DEBUG>=1) { foreach($this->page->headerData as $key=>$value) echo "YellowCore::sendPage $key: $value
\n"; $theme = $this->page->get("theme"); $template = $this->page->get("template"); $parser = $this->page->get("parser"); echo "YellowCore::sendPage theme:$theme template:$template parser:$parser
\n"; } return $statusCode; } // Send file response function sendFile($statusCode, $fileName, $cacheable) { $lastModifiedFormatted = $this->toolbox->getHttpDateFormatted($this->toolbox->getFileModified($fileName)); if($statusCode==200 && $cacheable && $this->toolbox->isRequestNotModified($lastModifiedFormatted)) { $statusCode = 304; @header($this->toolbox->getHttpStatusFormatted($statusCode)); } else { @header($this->toolbox->getHttpStatusFormatted($statusCode)); if(!$cacheable) @header("Cache-Control: no-cache, must-revalidate"); @header("Content-Type: ".$this->toolbox->getMimeContentType($fileName)); @header("Last-Modified: ".$lastModifiedFormatted); echo $this->toolbox->readFile($fileName); } return $statusCode; } // Send status response function sendStatus($statusCode, $location = "") { if(!empty($location)) $this->page->clean($statusCode, $location); @header($this->toolbox->getHttpStatusFormatted($statusCode)); foreach($this->page->headerData as $key=>$value) @header("$key: $value"); if(defined("DEBUG") && DEBUG>=1) { foreach($this->page->headerData as $key=>$value) echo "YellowCore::sendStatus $key: $value
\n"; } return $statusCode; } // Handle command function command($args = null) { $statusCode = 0; $this->toolbox->timerStart($time); foreach($this->plugins->plugins as $key=>$value) { if(method_exists($value["obj"], "onCommand")) { $this->lookup->commandHandler = $key; $statusCode = $value["obj"]->onCommand(func_get_args()); if($statusCode!=0) break; } } if($statusCode==0) { $this->lookup->commandHandler = "core"; $statusCode = 400; list($command) = func_get_args(); echo "Yellow $command: Command not found\n"; } $this->toolbox->timerStop($time); if(defined("DEBUG") && DEBUG>=1) { $handler = $this->getCommandHandler(); echo "YellowCore::command status:$statusCode handler:$handler time:$time ms
\n"; } return $statusCode; } // Handle startup function startup() { $tokens = explode(',', $this->config->get("startupUpdate")); foreach($this->plugins->plugins as $key=>$value) { if(method_exists($value["obj"], "onStartup")) $value["obj"]->onStartup(in_array($value["plugin"], $tokens)); } foreach($this->themes->themes as $key=>$value) { if(method_exists($value["obj"], "onStartup")) $value["obj"]->onStartup(in_array($value["theme"], $tokens)); } if($this->config->get("startupUpdate")!="none") { $fileNameConfig = $this->config->get("configDir").$this->config->get("configFile"); $this->config->update($fileNameConfig, array("startupUpdate" => "none")); } } // Handle shutdown function shutdown() { foreach($this->plugins->plugins as $key=>$value) { if(method_exists($value["obj"], "onShutdown")) $value["obj"]->onShutdown(); } foreach($this->themes->themes as $key=>$value) { if(method_exists($value["obj"], "onShutdown")) $value["obj"]->onShutdown(); } } // Parse snippet function snippet($name, $args = null) { $this->lookup->snippetArgs = func_get_args(); $this->page->parseSnippet($name); } // Return snippet arguments function getSnippetArgs() { return $this->lookup->snippetArgs; } // Return request information function getRequestInformation($scheme = "", $address = "", $base = "") { if(empty($scheme) && empty($address) && empty($base)) { $url = $this->config->get("serverUrl"); if(empty($url) || $this->isCommandLine()) $url = $this->toolbox->getServerUrl(); list($scheme, $address, $base) = $this->lookup->getUrlInformation($url); $this->config->set("serverScheme", $scheme); $this->config->set("serverAddress", $address); $this->config->set("serverBase", $base); if(defined("DEBUG") && DEBUG>=3) echo "YellowCore::getRequestInformation $scheme://$address$base
\n"; } $location = substru($this->toolbox->getLocation(), strlenu($base)); if(empty($fileName)) $fileName = $this->lookup->findFileFromSystem($location); if(empty($fileName)) $fileName = $this->lookup->findFileFromMedia($location); if(empty($fileName)) $fileName = $this->lookup->findFileFromLocation($location); return array($scheme, $address, $base, $location, $fileName); } // Return request location function getRequestLocationArgsClean() { return $this->toolbox->getLocationArgsClean($this->config->get("contentPagination")); } // Return request language function getRequestLanguage() { return $this->toolbox->detectBrowserLanguage($this->pages->getLanguages(), $this->config->get("language")); } // Return request handler function getRequestHandler() { return $this->lookup->requestHandler; } // Return command handler function getCommandHandler() { return $this->lookup->commandHandler; } // Check if running at command line function isCommandLine() { return !empty($this->lookup->commandHandler); } } class YellowPage { var $yellow; //access to API var $scheme; //server scheme var $address; //server address var $base; //base location var $location; //page location var $fileName; //content file name var $rawData; //raw data of page var $metaDataOffsetBytes; //meta data offset var $metaData; //meta data var $pageCollection; //page collection var $pageRelations; //page relations var $headerData; //response header var $outputData; //response output var $parser; //content parser var $parserData; //content data of page var $parserSafeMode; //page is parsed in safe mode? (boolean) var $available; //page is available? (boolean) var $visible; //page is visible location? (boolean) var $active; //page is active location? (boolean) var $cacheable; //page is cacheable? (boolean) var $lastModified; //last modification date var $statusCode; //status code function __construct($yellow) { $this->yellow = $yellow; $this->metaData = new YellowDataCollection(); $this->pageCollection = new YellowPageCollection($yellow); $this->pageRelations = array(); $this->headerData = array(); } // Set request information function setRequestInformation($scheme, $address, $base, $location, $fileName) { $this->scheme = $scheme; $this->address = $address; $this->base = $base; $this->location = $location; $this->fileName = $fileName; } // Parse page data function parseData($rawData, $cacheable, $statusCode, $pageError = "") { $this->rawData = $rawData; $this->parser = null; $this->parserData = ""; $this->parserSafeMode = intval($this->yellow->config->get("parserSafeMode")); $this->available = true; $this->visible = $this->yellow->lookup->isVisibleLocation($this->location, $this->fileName); $this->active = $this->yellow->lookup->isActiveLocation($this->location, $this->yellow->page->location); $this->cacheable = $cacheable; $this->lastModified = 0; $this->statusCode = $statusCode; $this->parseMeta($pageError); } // Parse page data update function parseDataUpdate() { if($this->statusCode==0) { $this->rawData = $this->yellow->toolbox->readFile($this->fileName); $this->statusCode = 200; $this->parseMeta(); } } // Parse page meta data function parseMeta($pageError = "") { $this->metaData = new YellowDataCollection(); if(!is_null($this->rawData)) { $this->set("title", $this->yellow->toolbox->createTextTitle($this->location)); $this->set("language", $this->yellow->lookup->findLanguageFromFile($this->fileName, $this->yellow->config->get("language"))); $this->set("modified", date("Y-m-d H:i:s", $this->yellow->toolbox->getFileModified($this->fileName))); $this->parseMetaRaw(array("theme", "template", "sitename", "siteicon", "tagline", "author", "navigation", "sidebar", "parser")); $titleHeader = ($this->location==$this->yellow->pages->getHomeLocation($this->location)) ? $this->get("sitename") : $this->get("title")." - ".$this->get("sitename"); if(!$this->isExisting("titleContent")) $this->set("titleContent", $this->get("title")); if(!$this->isExisting("titleNavigation")) $this->set("titleNavigation", $this->get("title")); if(!$this->isExisting("titleHeader")) $this->set("titleHeader", $titleHeader); if($this->get("status")=="hidden") $this->available = false; $this->set("pageRead", $this->yellow->lookup->normaliseUrl( $this->yellow->config->get("serverScheme"), $this->yellow->config->get("serverAddress"), $this->yellow->config->get("serverBase"), $this->location)); $this->set("pageEdit", $this->yellow->lookup->normaliseUrl( $this->yellow->config->get("serverScheme"), $this->yellow->config->get("serverAddress"), $this->yellow->config->get("serverBase"), rtrim($this->yellow->config->get("editLocation"), '/').$this->location)); } else { $this->set("type", $this->yellow->toolbox->getFileType($this->fileName)); $this->set("modified", date("Y-m-d H:i:s", $this->yellow->toolbox->getFileModified($this->fileName))); } if(!empty($pageError)) $this->set("pageError", $pageError); foreach($this->yellow->plugins->plugins as $key=>$value) { if(method_exists($value["obj"], "onParseMeta")) $value["obj"]->onParseMeta($this); } } // Parse page meta data from raw data function parseMetaRaw($defaultKeys) { foreach($defaultKeys as $key) { $value = $this->yellow->config->get($key); if(!empty($key) && !strempty($value)) $this->set($key, $value); } if(preg_match("/^(\xEF\xBB\xBF)?\-\-\-[\r\n]+(.+?)\-\-\-[\r\n]+/s", $this->rawData, $parts)) { $this->metaDataOffsetBytes = strlenb($parts[0]); foreach(preg_split("/[\r\n]+/", $parts[2]) as $line) { preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); if(!empty($matches[1]) && !strempty($matches[2])) $this->set($matches[1], $matches[2]); } } else if(preg_match("/^(\xEF\xBB\xBF)?([^\r\n]+)[\r\n]+=+[\r\n]+/", $this->rawData, $parts)) { $this->metaDataOffsetBytes = strlenb($parts[0]); $this->set("title", $parts[2]); } } // Parse page content on demand function parseContent($sizeMax = 0) { if(!is_object($this->parser)) { if($this->yellow->plugins->isExisting($this->get("parser"))) { $plugin = $this->yellow->plugins->plugins[$this->get("parser")]; if(method_exists($plugin["obj"], "onParseContentRaw")) { $this->parser = $plugin["obj"]; $this->parserData = $this->getContent(true, $sizeMax); $this->parserData = preg_replace("/@pageRead/i", $this->get("pageRead"), $this->parserData); $this->parserData = preg_replace("/@pageEdit/i", $this->get("pageEdit"), $this->parserData); $this->parserData = $this->parser->onParseContentRaw($this, $this->parserData); foreach($this->yellow->plugins->plugins as $key=>$value) { if(method_exists($value["obj"], "onParseContentText")) { $output = $value["obj"]->onParseContentText($this, $this->parserData); if(!is_null($output)) $this->parserData = $output; } } } } else { $this->parserData = $this->getContent(true, $sizeMax); $this->parserData = preg_replace("/\[yellow error\]/i", $this->get("pageError"), $this->parserData); } if(!$this->isExisting("description")) { $this->set("description", $this->yellow->toolbox->createTextDescription($this->parserData, 150)); } if(!$this->isExisting("keywords")) { $this->set("keywords", $this->yellow->toolbox->createTextKeywords($this->get("title"), 10)); } if(defined("DEBUG") && DEBUG>=3) echo "YellowPage::parseContent location:".$this->location."
\n"; } } // Parse page content block function parseContentBlock($name, $text, $shortcut) { $output = null; foreach($this->yellow->plugins->plugins as $key=>$value) { if(method_exists($value["obj"], "onParseContentBlock")) { $output = $value["obj"]->onParseContentBlock($this, $name, $text, $shortcut); if(!is_null($output)) break; } } if(is_null($output)) { if($name=="yellow" && $shortcut) { $output = "Datenstrom Yellow ".YellowCore::VERSION; if($text=="error") $output = $this->get("pageError"); if($text=="version") { $output = "\n"; $serverVersion = $this->yellow->toolbox->getServerVersion(); $output .= "Datenstrom Yellow ".YellowCore::VERSION.", PHP ".PHP_VERSION.", $serverVersion
\n"; foreach(array_merge($this->yellow->plugins->getData(), $this->yellow->themes->getData()) as $key=>$value) { $output .= htmlspecialchars("$key $value")."
\n"; } $output .= "
\n"; if($this->parserSafeMode) $this->error(500, "Yellow '$text' is not available in safe mode!"); } } } if(defined("DEBUG") && DEBUG>=3 && !empty($name)) echo "YellowPage::parseContentBlock name:$name shortcut:$shortcut
\n"; return $output; } // Parse page function parsePage() { $this->outputData = null; if(!$this->isError()) { foreach($this->yellow->plugins->plugins as $key=>$value) { if(method_exists($value["obj"], "onParsePage")) $value["obj"]->onParsePage(); } } if(is_null($this->outputData)) { ob_start(); $this->parseTemplate($this->get("template")); $this->outputData = ob_get_contents(); ob_end_clean(); } if(!$this->isCacheable()) $this->setHeader("Cache-Control", "no-cache, must-revalidate"); if(!$this->isHeader("Content-Type")) $this->setHeader("Content-Type", "text/html; charset=utf-8"); if(!$this->isHeader("Page-Modified")) $this->setHeader("Page-Modified", $this->getModified(true)); if(!$this->isHeader("Last-Modified")) $this->setHeader("Last-Modified", $this->getLastModified(true)); if(!$this->yellow->text->isLanguage($this->get("language"))) { $this->error(500, "Language '".$this->get("language")."' does not exist!"); } if(!$this->yellow->themes->isExisting($this->get("theme"))) { $this->error(500, "Theme '".$this->get("theme")."' does not exist!"); } if(!is_object($this->parser)) { $this->error(500, "Parser '".$this->get("parser")."' does not exist!"); } if($this->yellow->lookup->isNestedLocation($this->location, $this->fileName, true)) { $this->error(500, "Folder '".dirname($this->fileName)."' may not contain subfolders!"); } if($this->yellow->toolbox->isRequestSelf()) { $serverVersion = $this->yellow->toolbox->getServerVersion(true); $this->error(500, "Rewrite module not working on $serverVersion web server!"); } if($this->yellow->getRequestHandler()=="core" && $this->isExisting("redirect") && $this->statusCode==200) { $location = $this->yellow->lookup->normaliseLocation($this->get("redirect"), $this->location); $location = $this->yellow->lookup->normaliseUrl($this->scheme, $this->address, "", $location); $this->clean(301, $location); } if($this->yellow->getRequestHandler()=="core" && !$this->isAvailable() && $this->statusCode==200) { $this->error(404); } if($this->isExisting("pageClean")) $this->outputData = null; } // Parse template function parseTemplate($name) { $fileNameTemplate = $this->yellow->config->get("templateDir").$this->yellow->lookup->normaliseName($name).".html"; if(is_file($fileNameTemplate)) { $this->setLastModified(filemtime($fileNameTemplate)); global $yellow; require($fileNameTemplate); } else { $this->error(500, "Template '$name' does not exist!"); echo "Template error
\n"; } } // Parse snippet function parseSnippet($name) { $fileNameSnippet = $this->yellow->config->get("snippetDir").$this->yellow->lookup->normaliseName($name).".php"; if(is_file($fileNameSnippet)) { $this->setLastModified(filemtime($fileNameSnippet)); global $yellow; require($fileNameSnippet); } else { $this->error(500, "Snippet '$name' does not exist!"); echo "Snippet error
\n"; } } // Set page meta data function set($key, $value) { $this->metaData[$key] = $value; } // Return page meta data function get($key) { return $this->isExisting($key) ? $this->metaData[$key] : ""; } // Return page meta data, HTML encoded function getHtml($key) { return htmlspecialchars($this->get($key)); } // Return page meta data as language specific date function getDate($key, $format = "") { if(!empty($format)) { $format = $this->yellow->text->get($format); } else { $format = $this->yellow->text->get("dateFormatMedium"); } return $this->yellow->text->getDateFormatted(strtotime($this->get($key)), $format); } // Return page meta data as language specific date, HTML encoded function getDateHtml($key, $format = "") { return htmlspecialchars($this->getDate($key, $format)); } // Return page meta data as custom date function getDateFormatted($key, $format) { return $this->yellow->text->getDateFormatted(strtotime($this->get($key)), $format); } // Return page meta data as custom date, HTML encoded function getDateFormattedHtml($key, $format) { return htmlspecialchars($this->getDateFormatted($key, $format)); } // Return page content, HTML encoded or raw format function getContent($rawFormat = false, $sizeMax = 0) { if($rawFormat) { $this->parseDataUpdate(); $text = substrb($this->rawData, $this->metaDataOffsetBytes); } else { $this->parseContent($sizeMax); $text = $this->parserData; } return $sizeMax ? substrb($text, 0, $sizeMax) : $text; } // Return parent page of current page, null if none function getParent() { $parentLocation = $this->yellow->pages->getParentLocation($this->location); return $this->yellow->pages->find($parentLocation); } // Return top-level page for current page, null if none function getParentTop($homeFailback = true) { $parentTopLocation = $this->yellow->pages->getParentTopLocation($this->location); if(!$this->yellow->pages->find($parentTopLocation) && $homeFailback) { $parentTopLocation = $this->yellow->pages->getHomeLocation($this->location); } return $this->yellow->pages->find($parentTopLocation); } // Return page collection with pages on the same level as current page function getSiblings($showInvisible = false) { $parentLocation = $this->yellow->pages->getParentLocation($this->location); return $this->yellow->pages->getChildren($parentLocation, $showInvisible); } // Return page collection with child pages of current page function getChildren($showInvisible = false) { return $this->yellow->pages->getChildren($this->location, $showInvisible); } // Return page collection with sub pages of current page function getChildrenRecursive($showInvisible = false, $levelMax = 0) { return $this->yellow->pages->getChildrenRecursive($this->location, $showInvisible, $levelMax); } // Set page collection with additional pages for current page function setPages($pages) { $this->pageCollection = $pages; } // Return page collection with additional pages for current page function getPages() { return $this->pageCollection; } // Set related page function setPage($key, $page) { $this->pageRelations[$key] = $page; } // Return related page function getPage($key) { return !is_null($this->pageRelations[$key]) ? $this->pageRelations[$key] : $this; } // Return page base function getBase($multiLanguage = false) { return $multiLanguage ? rtrim($this->base.$this->yellow->pages->getHomeLocation($this->location), '/') : $this->base; } // Return page location function getLocation($absoluteLocation = false) { return $absoluteLocation ? $this->base.$this->location : $this->location; } // Return page URL function getUrl() { return $this->yellow->lookup->normaliseUrl($this->scheme, $this->address, $this->base, $this->location); } // Return page extra HTML data function getExtra($name) { $output = ""; foreach($this->yellow->plugins->plugins as $key=>$value) { if(method_exists($value["obj"], "onExtra")) { $outputPlugin = $value["obj"]->onExtra($name); if(!is_null($outputPlugin)) $output .= $outputPlugin; } } if($name=="header") { if(is_file($this->yellow->config->get("assetDir").$this->get("theme").".css")) { $location = $this->yellow->config->get("serverBase"). $this->yellow->config->get("assetLocation").$this->get("theme").".css"; $output .= "\n"; } if(is_file($this->yellow->config->get("assetDir").$this->get("theme").".js")) { $location = $this->yellow->config->get("serverBase"). $this->yellow->config->get("assetLocation").$this->get("theme").".js"; $output .= "\n"; } if(is_file($this->yellow->config->get("assetDir").$this->get("siteicon").".png")) { $location = $this->yellow->config->get("serverBase"). $this->yellow->config->get("assetLocation").$this->get("siteicon").".png"; $contentType = $this->yellow->toolbox->getMimeContentType($location); $output .= "\n"; $output .= "\n"; } } return $this->normaliseExtra($output); } // Normalise page extra HTML data function normaliseExtra($text) { $outputScript = $outputStylesheet = $outputOther = $locations = array(); foreach($this->yellow->toolbox->getTextLines($text) as $line) { if(preg_match("/^