yellow/system/plugins/core.php

3480 lines
109 KiB
PHP
Raw Normal View History

2013-04-07 18:04:09 +00:00
<?php
2017-02-18 15:08:20 +00:00
// Core plugin, https://github.com/datenstrom/yellow-plugins/tree/master/core
// Copyright (c) 2013-2017 Datenstrom, https://datenstrom.se
2013-04-07 18:04:09 +00:00
// This file may be used and distributed under the terms of the public license.
2015-10-06 12:19:11 +00:00
class YellowCore
2013-04-07 18:04:09 +00:00
{
2017-11-22 10:01:01 +00:00
const VERSION = "0.7.2";
2014-03-21 09:12:56 +00:00
var $page; //current page
var $pages; //pages from file system
2015-04-29 07:26:48 +00:00
var $files; //files from file system
var $plugins; //plugins
2016-03-26 12:27:38 +00:00
var $themes; //themes
2013-07-11 20:33:28 +00:00
var $config; //configuration
2017-07-26 11:23:38 +00:00
var $text; //text
2015-04-29 07:26:48 +00:00
var $lookup; //location and file lookup
2015-01-07 17:02:58 +00:00
var $toolbox; //toolbox with helpers
2013-04-07 18:04:09 +00:00
function __construct()
{
2015-01-19 19:05:51 +00:00
$this->page = new YellowPage($this);
2013-12-01 11:59:07 +00:00
$this->pages = new YellowPages($this);
2015-04-29 07:26:48 +00:00
$this->files = new YellowFiles($this);
$this->plugins = new YellowPlugins($this);
2016-03-26 12:27:38 +00:00
$this->themes = new YellowThemes($this);
2013-12-01 11:59:07 +00:00
$this->config = new YellowConfig($this);
$this->text = new YellowText($this);
2015-04-29 07:26:48 +00:00
$this->lookup = new YellowLookup($this);
2013-12-01 11:59:07 +00:00
$this->toolbox = new YellowToolbox();
2013-04-14 22:41:04 +00:00
$this->config->setDefault("sitename", "Yellow");
$this->config->setDefault("author", "Yellow");
2016-04-20 10:02:42 +00:00
$this->config->setDefault("email", "webmaster");
2015-03-17 20:09:56 +00:00
$this->config->setDefault("language", "en");
2017-02-17 13:52:55 +00:00
$this->config->setDefault("timezone", "UTC");
2014-10-14 14:42:36 +00:00
$this->config->setDefault("theme", "default");
2017-02-17 13:52:55 +00:00
$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/");
2017-10-07 15:35:19 +00:00
$this->config->setDefault("downloadLocation", "/media/downloads/");
2013-05-23 06:24:50 +00:00
$this->config->setDefault("imageLocation", "/media/images/");
2014-01-08 16:58:52 +00:00
$this->config->setDefault("pluginLocation", "/media/plugins/");
2014-10-14 14:42:36 +00:00
$this->config->setDefault("themeLocation", "/media/themes/");
2016-06-15 13:27:01 +00:00
$this->config->setDefault("assetLocation", "/media/themes/assets/");
2017-02-17 13:52:55 +00:00
$this->config->setDefault("mediaDir", "media/");
2017-10-07 15:35:19 +00:00
$this->config->setDefault("downloadDir", "media/downloads/");
2017-02-17 13:52:55 +00:00
$this->config->setDefault("imageDir", "media/images/");
2013-04-07 18:04:09 +00:00
$this->config->setDefault("systemDir", "system/");
$this->config->setDefault("configDir", "system/config/");
$this->config->setDefault("pluginDir", "system/plugins/");
2014-10-14 14:42:36 +00:00
$this->config->setDefault("themeDir", "system/themes/");
2016-06-15 13:27:01 +00:00
$this->config->setDefault("assetDir", "system/themes/assets/");
2015-04-29 07:26:48 +00:00
$this->config->setDefault("snippetDir", "system/themes/snippets/");
$this->config->setDefault("templateDir", "system/themes/templates/");
2016-07-10 18:44:02 +00:00
$this->config->setDefault("trashDir", "system/trash/");
2013-04-07 18:04:09 +00:00
$this->config->setDefault("contentDir", "content/");
$this->config->setDefault("contentRootDir", "default/");
$this->config->setDefault("contentHomeDir", "home/");
2017-02-17 13:52:55 +00:00
$this->config->setDefault("contentPagination", "page");
2013-04-14 22:41:04 +00:00
$this->config->setDefault("contentDefaultFile", "page.txt");
2013-04-07 18:04:09 +00:00
$this->config->setDefault("contentExtension", ".txt");
2013-04-14 22:41:04 +00:00
$this->config->setDefault("configExtension", ".ini");
2016-07-29 22:41:19 +00:00
$this->config->setDefault("downloadExtension", ".download");
2017-10-07 15:35:19 +00:00
$this->config->setDefault("uploadExtension", ".upload");
2013-04-07 18:04:09 +00:00
$this->config->setDefault("configFile", "config.ini");
2017-07-26 11:23:38 +00:00
$this->config->setDefault("textFile", "text.ini");
$this->config->setDefault("languageFile", "language-(.*).txt");
2015-04-29 07:26:48 +00:00
$this->config->setDefault("errorFile", "page-error-(.*).txt");
2015-08-01 17:28:20 +00:00
$this->config->setDefault("robotsFile", "robots.txt");
2016-03-17 14:31:22 +00:00
$this->config->setDefault("faviconFile", "favicon.ico");
2017-07-05 10:25:25 +00:00
$this->config->setDefault("serverUrl", "");
2015-04-29 07:26:48 +00:00
$this->config->setDefault("template", "default");
2015-05-22 17:37:37 +00:00
$this->config->setDefault("navigation", "navigation");
2015-08-28 14:12:19 +00:00
$this->config->setDefault("sidebar", "sidebar");
2016-03-17 14:31:22 +00:00
$this->config->setDefault("siteicon", "icon");
2016-10-01 12:37:59 +00:00
$this->config->setDefault("tagline", "");
2015-04-29 07:26:48 +00:00
$this->config->setDefault("parser", "markdown");
2014-08-29 07:15:49 +00:00
$this->config->setDefault("parserSafeMode", "0");
$this->config->setDefault("multiLanguageMode", "0");
2016-04-08 13:16:07 +00:00
$this->config->setDefault("installationMode", "0");
2017-06-21 15:57:20 +00:00
$this->config->setDefault("startupUpdate", "none");
2017-02-17 13:52:55 +00:00
}
function __destruct()
{
$this->shutdown();
2013-04-14 22:41:04 +00:00
}
2013-06-07 20:01:12 +00:00
2017-01-03 13:11:44 +00:00
// Handle initialisation
2015-08-09 20:17:17 +00:00
function load()
{
2017-01-03 13:11:44 +00:00
if(defined("DEBUG") && DEBUG>=2)
2015-08-09 20:17:17 +00:00
{
2017-02-17 13:52:55 +00:00
$serverVersion = $this->toolbox->getServerVersion();
echo "Datenstrom Yellow ".YellowCore::VERSION.", PHP ".PHP_VERSION.", $serverVersion<br/>\n";
2015-08-09 20:17:17 +00:00
}
2017-07-05 10:25:25 +00:00
$this->toolbox->timerStart($time);
2015-08-09 20:17:17 +00:00
$this->config->load($this->config->get("configDir").$this->config->get("configFile"));
2016-04-04 10:02:11 +00:00
$this->lookup->load();
$this->themes->load();
2017-02-17 13:52:55 +00:00
$this->plugins->load();
2017-07-26 11:23:38 +00:00
$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"));
2017-07-05 10:25:25 +00:00
$this->toolbox->timerStop($time);
2017-02-17 13:52:55 +00:00
$this->startup();
2017-07-05 10:25:25 +00:00
if(defined("DEBUG") && DEBUG>=2)
2017-02-17 13:52:55 +00:00
{
2017-07-05 10:25:25 +00:00
$plugins = count($this->plugins->plugins);
$themes = count($this->themes->themes);
2017-07-26 11:23:38 +00:00
$languages = count($this->text->text);
echo "YellowCore::load plugins:$plugins themes:$themes languages:$languages time:$time ms<br/>\n";
2017-01-03 13:11:44 +00:00
}
2015-08-09 20:17:17 +00:00
}
// Handle request
2015-04-29 07:26:48 +00:00
function request()
2013-04-07 18:04:09 +00:00
{
ob_start();
$statusCode = 0;
2015-04-29 07:26:48 +00:00
$this->toolbox->timerStart($time);
2017-02-17 13:52:55 +00:00
list($scheme, $address, $base, $location, $fileName) = $this->getRequestInformation();
$this->page->setRequestInformation($scheme, $address, $base, $location, $fileName);
2013-04-14 22:41:04 +00:00
foreach($this->plugins->plugins as $key=>$value)
{
2013-04-07 18:04:09 +00:00
if(method_exists($value["obj"], "onRequest"))
2013-04-14 22:41:04 +00:00
{
2017-02-17 13:52:55 +00:00
$this->lookup->requestHandler = $key;
$statusCode = $value["obj"]->onRequest($scheme, $address, $base, $location, $fileName);
2016-07-19 22:12:05 +00:00
if($statusCode!=0) break;
2013-04-14 22:41:04 +00:00
}
}
2016-07-19 22:12:05 +00:00
if($statusCode==0)
{
2017-02-17 13:52:55 +00:00
$this->lookup->requestHandler = "core";
$statusCode = $this->processRequest($scheme, $address, $base, $location, $fileName, true);
}
2016-11-23 23:38:47 +00:00
if($this->page->isExisting("pageError")) $statusCode = $this->processRequestError();
$this->toolbox->timerStop($time);
2015-04-29 07:26:48 +00:00
ob_end_flush();
2016-04-08 13:16:07 +00:00
if(defined("DEBUG") && DEBUG>=1)
{
$handler = $this->getRequestHandler();
2017-02-17 13:52:55 +00:00
echo "YellowCore::request status:$statusCode handler:$handler time:$time ms<br/>\n";
2016-04-08 13:16:07 +00:00
}
2013-07-11 20:33:28 +00:00
return $statusCode;
2013-04-14 22:41:04 +00:00
}
2013-06-27 17:00:03 +00:00
// Process request
2017-02-17 13:52:55 +00:00
function processRequest($scheme, $address, $base, $location, $fileName, $cacheable)
2013-04-14 22:41:04 +00:00
{
2015-04-29 07:26:48 +00:00
$statusCode = 0;
2015-01-19 19:05:51 +00:00
if(is_readable($fileName))
2013-04-14 22:41:04 +00:00
{
2015-01-19 19:05:51 +00:00
if($this->toolbox->isRequestCleanUrl($location))
2013-04-14 22:41:04 +00:00
{
2016-02-20 17:34:06 +00:00
$location = $location.$this->getRequestLocationArgsClean();
2017-02-17 13:52:55 +00:00
$location = $this->lookup->normaliseUrl($scheme, $address, $base, $location);
2017-10-07 15:35:19 +00:00
$statusCode = $this->sendStatus(303, $location);
2013-04-14 22:41:04 +00:00
}
2015-01-19 19:05:51 +00:00
} else {
2017-01-03 13:11:44 +00:00
if($this->lookup->isRedirectLocation($location))
2015-01-19 19:05:51 +00:00
{
2017-01-03 13:11:44 +00:00
$location = $this->lookup->isFileLocation($location) ? "$location/" : "/".$this->getRequestLanguage()."/";
2017-02-17 13:52:55 +00:00
$location = $this->lookup->normaliseUrl($scheme, $address, $base, $location);
2017-10-07 15:35:19 +00:00
$statusCode = $this->sendStatus(301, $location);
2015-04-29 07:26:48 +00:00
}
}
2016-07-19 22:12:05 +00:00
if($statusCode==0)
2015-04-29 07:26:48 +00:00
{
2017-02-17 13:52:55 +00:00
$fileName = $this->lookup->findFileStatic($location, $fileName, $cacheable && !$this->isCommandLine());
2017-01-03 13:11:44 +00:00
if($this->lookup->isContentFile($fileName) || !is_readable($fileName))
2015-04-29 07:26:48 +00:00
{
2017-02-17 13:52:55 +00:00
$fileName = $this->readPage($scheme, $address, $base, $location, $fileName, $cacheable,
2016-04-04 10:02:11 +00:00
max(is_readable($fileName) ? 200 : 404, $this->page->statusCode), $this->page->get("pageError"));
2015-01-19 19:05:51 +00:00
$statusCode = $this->sendPage();
2017-01-03 13:11:44 +00:00
} else {
$statusCode = $this->sendFile(200, $fileName, true);
2015-01-19 19:05:51 +00:00
}
}
2016-04-08 13:16:07 +00:00
if(defined("DEBUG") && DEBUG>=1) echo "YellowCore::processRequest file:$fileName<br/>\n";
2013-04-14 22:41:04 +00:00
return $statusCode;
}
2013-07-11 20:33:28 +00:00
// Process request with error
2015-01-19 19:05:51 +00:00
function processRequestError()
2013-04-14 22:41:04 +00:00
{
ob_clean();
2017-02-17 13:52:55 +00:00
$fileName = $this->readPage($this->page->scheme, $this->page->address, $this->page->base,
2015-01-19 19:05:51 +00:00
$this->page->location, $this->page->fileName, $this->page->cacheable, $this->page->statusCode,
$this->page->get("pageError"));
2013-07-11 20:33:28 +00:00
$statusCode = $this->sendPage();
2016-04-08 13:16:07 +00:00
if(defined("DEBUG") && DEBUG>=1) echo "YellowCore::processRequestError file:$fileName<br/>\n";
2015-01-19 19:05:51 +00:00
return $statusCode;
2013-07-11 20:33:28 +00:00
}
2015-04-29 07:26:48 +00:00
// Read page
2017-02-17 13:52:55 +00:00
function readPage($scheme, $address, $base, $location, $fileName, $cacheable, $statusCode, $pageError)
2013-07-11 20:33:28 +00:00
{
2016-07-19 22:12:05 +00:00
if($statusCode>=400)
2013-07-11 20:33:28 +00:00
{
2017-07-05 10:25:25 +00:00
$cacheable = false;
2015-04-29 07:26:48 +00:00
$fileName = $this->config->get("configDir").$this->config->get("errorFile");
2013-07-11 20:33:28 +00:00
$fileName = strreplaceu("(.*)", $statusCode, $fileName);
2017-07-05 10:25:25 +00:00
$rawData = $this->toolbox->readFile($fileName);
if(empty($rawData)) $rawData = "---\nTitle:".$this->toolbox->getHttpStatusFormatted($statusCode, true)."\n---\n";
} else {
$rawData = $this->toolbox->readFile($fileName);
2013-07-11 20:33:28 +00:00
}
2015-01-19 19:05:51 +00:00
$this->page = new YellowPage($this);
2017-02-17 13:52:55 +00:00
$this->page->setRequestInformation($scheme, $address, $base, $location, $fileName);
2017-07-05 10:25:25 +00:00
$this->page->parseData($rawData, $cacheable, $statusCode, $pageError);
2013-06-27 17:00:03 +00:00
$this->text->setLanguage($this->page->get("language"));
2013-12-11 14:13:38 +00:00
$this->page->parseContent();
2013-06-27 17:00:03 +00:00
return $fileName;
2013-04-14 22:41:04 +00:00
}
// Send page response
2013-07-11 20:33:28 +00:00
function sendPage()
2013-04-14 22:41:04 +00:00
{
2015-04-29 07:26:48 +00:00
$this->page->parsePage();
2015-02-02 12:25:16 +00:00
$statusCode = $this->page->statusCode;
$lastModifiedFormatted = $this->page->getHeader("Last-Modified");
2015-04-29 07:26:48 +00:00
if($statusCode==200 && $this->page->isCacheable() && $this->toolbox->isRequestNotModified($lastModifiedFormatted))
2013-07-11 20:33:28 +00:00
{
2015-02-02 12:25:16 +00:00
$statusCode = 304;
@header($this->toolbox->getHttpStatusFormatted($statusCode));
} else {
2015-04-29 07:26:48 +00:00
@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;
2013-07-11 20:33:28 +00:00
}
if(defined("DEBUG") && DEBUG>=1)
{
2015-10-06 12:19:11 +00:00
foreach($this->page->headerData as $key=>$value) echo "YellowCore::sendPage $key: $value<br/>\n";
2016-03-10 19:44:10 +00:00
$theme = $this->page->get("theme");
$template = $this->page->get("template");
$parser = $this->page->get("parser");
echo "YellowCore::sendPage theme:$theme template:$template parser:$parser<br/>\n";
2013-06-27 17:00:03 +00:00
}
return $statusCode;
}
2015-01-19 19:05:51 +00:00
// Send file response
function sendFile($statusCode, $fileName, $cacheable)
{
2016-08-18 19:57:07 +00:00
$lastModifiedFormatted = $this->toolbox->getHttpDateFormatted($this->toolbox->getFileModified($fileName));
2015-04-29 07:26:48 +00:00
if($statusCode==200 && $cacheable && $this->toolbox->isRequestNotModified($lastModifiedFormatted))
2015-01-19 19:05:51 +00:00
{
$statusCode = 304;
2015-02-02 12:25:16 +00:00
@header($this->toolbox->getHttpStatusFormatted($statusCode));
2015-01-19 19:05:51 +00:00
} else {
2015-02-02 12:25:16 +00:00
@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);
2016-02-20 17:34:06 +00:00
echo $this->toolbox->readFile($fileName);
2015-01-19 19:05:51 +00:00
}
return $statusCode;
}
2013-06-27 17:00:03 +00:00
// Send status response
2015-04-29 07:26:48 +00:00
function sendStatus($statusCode, $location = "")
2013-06-27 17:00:03 +00:00
{
2015-04-29 07:26:48 +00:00
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)
{
2015-10-06 12:19:11 +00:00
foreach($this->page->headerData as $key=>$value) echo "YellowCore::sendStatus $key: $value<br/>\n";
}
2017-10-07 15:35:19 +00:00
return $statusCode;
}
2016-06-27 13:28:10 +00:00
// Handle command
2016-07-19 22:12:05 +00:00
function command($args = null)
2016-06-27 13:28:10 +00:00
{
$statusCode = 0;
$this->toolbox->timerStart($time);
foreach($this->plugins->plugins as $key=>$value)
{
if(method_exists($value["obj"], "onCommand"))
{
2017-02-17 13:52:55 +00:00
$this->lookup->commandHandler = $key;
2016-06-27 13:28:10 +00:00
$statusCode = $value["obj"]->onCommand(func_get_args());
2016-07-19 22:12:05 +00:00
if($statusCode!=0) break;
2016-06-27 13:28:10 +00:00
}
}
2016-07-19 22:12:05 +00:00
if($statusCode==0)
2016-06-27 13:28:10 +00:00
{
2017-02-17 13:52:55 +00:00
$this->lookup->commandHandler = "core";
2016-06-27 13:28:10 +00:00
$statusCode = 400;
2016-07-10 18:44:02 +00:00
list($command) = func_get_args();
2016-06-27 13:28:10 +00:00
echo "Yellow $command: Command not found\n";
}
2016-07-15 16:35:11 +00:00
$this->toolbox->timerStop($time);
2017-02-17 13:52:55 +00:00
if(defined("DEBUG") && DEBUG>=1)
{
$handler = $this->getCommandHandler();
echo "YellowCore::command status:$statusCode handler:$handler time:$time ms<br/>\n";
}
2016-06-27 13:28:10 +00:00
return $statusCode;
}
2017-07-05 10:25:25 +00:00
// 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"));
}
}
2017-02-17 13:52:55 +00:00
// 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();
}
}
2016-02-20 17:34:06 +00:00
// Parse snippet
2016-07-19 22:12:05 +00:00
function snippet($name, $args = null)
2016-02-20 17:34:06 +00:00
{
2017-02-17 13:52:55 +00:00
$this->lookup->snippetArgs = func_get_args();
2016-02-20 17:34:06 +00:00
$this->page->parseSnippet($name);
}
2017-02-17 13:52:55 +00:00
// Return snippet arguments
function getSnippetArgs()
{
return $this->lookup->snippetArgs;
}
// Return request information
2017-02-17 13:52:55 +00:00
function getRequestInformation($scheme = "", $address = "", $base = "")
2013-12-21 13:10:15 +00:00
{
2017-02-17 13:52:55 +00:00
if(empty($scheme) && empty($address) && empty($base))
2015-01-19 19:05:51 +00:00
{
2017-02-17 13:52:55 +00:00
$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<br/>\n";
2015-01-19 19:05:51 +00:00
}
2017-02-17 13:52:55 +00:00
$location = substru($this->toolbox->getLocation(), strlenu($base));
if(empty($fileName)) $fileName = $this->lookup->findFileFromSystem($location);
if(empty($fileName)) $fileName = $this->lookup->findFileFromMedia($location);
2015-04-29 07:26:48 +00:00
if(empty($fileName)) $fileName = $this->lookup->findFileFromLocation($location);
2017-02-17 13:52:55 +00:00
return array($scheme, $address, $base, $location, $fileName);
2013-12-21 13:10:15 +00:00
}
2016-02-20 17:34:06 +00:00
// Return request location
function getRequestLocationArgsClean()
{
return $this->toolbox->getLocationArgsClean($this->config->get("contentPagination"));
}
// Return request language
2017-01-03 13:11:44 +00:00
function getRequestLanguage()
{
2017-01-03 13:11:44 +00:00
return $this->toolbox->detectBrowserLanguage($this->pages->getLanguages(), $this->config->get("language"));
}
// Return request handler
function getRequestHandler()
{
2017-02-17 13:52:55 +00:00
return $this->lookup->requestHandler;
}
// Return command handler
function getCommandHandler()
{
return $this->lookup->commandHandler;
}
2017-02-17 13:52:55 +00:00
// Check if running at command line
function isCommandLine()
2015-05-19 14:15:24 +00:00
{
2017-02-17 13:52:55 +00:00
return !empty($this->lookup->commandHandler);
2015-05-19 14:15:24 +00:00
}
2013-04-07 18:04:09 +00:00
}
2013-05-01 20:16:05 +00:00
2013-12-01 11:59:07 +00:00
class YellowPage
2013-04-07 18:04:09 +00:00
{
2013-07-11 20:33:28 +00:00
var $yellow; //access to API
2017-02-17 13:52:55 +00:00
var $scheme; //server scheme
var $address; //server address
2014-05-15 11:53:54 +00:00
var $base; //base location
2013-07-16 16:56:27 +00:00
var $location; //page location
2013-05-01 20:16:05 +00:00
var $fileName; //content file name
2013-06-27 17:00:03 +00:00
var $rawData; //raw data of page
2013-07-11 20:33:28 +00:00
var $metaDataOffsetBytes; //meta data offset
2013-10-16 21:11:24 +00:00
var $metaData; //meta data
2016-06-10 13:57:11 +00:00
var $pageCollection; //page collection
var $pageRelations; //page relations
2013-10-16 21:11:24 +00:00
var $headerData; //response header
2015-04-29 07:26:48 +00:00
var $outputData; //response output
2013-10-16 21:11:24 +00:00
var $parser; //content parser
2015-04-29 07:26:48 +00:00
var $parserData; //content data of page
2014-08-29 07:15:49 +00:00
var $parserSafeMode; //page is parsed in safe mode? (boolean)
2015-04-29 07:26:48 +00:00
var $available; //page is available? (boolean)
2013-07-11 20:33:28 +00:00
var $visible; //page is visible location? (boolean)
2015-04-29 07:26:48 +00:00
var $active; //page is active location? (boolean)
2013-07-11 20:33:28 +00:00
var $cacheable; //page is cacheable? (boolean)
var $lastModified; //last modification date
2013-10-16 21:11:24 +00:00
var $statusCode; //status code
2015-01-19 19:05:51 +00:00
function __construct($yellow)
2013-04-14 22:41:04 +00:00
{
2013-07-11 20:33:28 +00:00
$this->yellow = $yellow;
2016-06-10 13:57:11 +00:00
$this->metaData = new YellowDataCollection();
$this->pageCollection = new YellowPageCollection($yellow);
2015-08-28 14:12:19 +00:00
$this->pageRelations = array();
2016-06-10 13:57:11 +00:00
$this->headerData = array();
2015-01-19 19:05:51 +00:00
}
// Set request information
2017-02-17 13:52:55 +00:00
function setRequestInformation($scheme, $address, $base, $location, $fileName)
2015-01-19 19:05:51 +00:00
{
2017-02-17 13:52:55 +00:00
$this->scheme = $scheme;
$this->address = $address;
2014-05-15 11:53:54 +00:00
$this->base = $base;
2013-07-16 16:56:27 +00:00
$this->location = $location;
2014-07-25 10:46:58 +00:00
$this->fileName = $fileName;
}
// Parse page data
2015-04-29 07:26:48 +00:00
function parseData($rawData, $cacheable, $statusCode, $pageError = "")
{
2013-07-11 20:33:28 +00:00
$this->rawData = $rawData;
2016-07-19 22:12:05 +00:00
$this->parser = null;
2015-04-29 07:26:48 +00:00
$this->parserData = "";
2015-05-05 16:11:43 +00:00
$this->parserSafeMode = intval($this->yellow->config->get("parserSafeMode"));
2015-04-29 07:26:48 +00:00
$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);
2013-07-11 20:33:28 +00:00
$this->cacheable = $cacheable;
$this->lastModified = 0;
$this->statusCode = $statusCode;
2015-01-19 19:05:51 +00:00
$this->parseMeta($pageError);
2013-04-14 22:41:04 +00:00
}
// Parse page data update
function parseDataUpdate()
{
2016-07-19 22:12:05 +00:00
if($this->statusCode==0)
{
2016-02-20 17:34:06 +00:00
$this->rawData = $this->yellow->toolbox->readFile($this->fileName);
$this->statusCode = 200;
$this->parseMeta();
}
}
2013-07-11 20:33:28 +00:00
// Parse page meta data
2015-01-19 19:05:51 +00:00
function parseMeta($pageError = "")
2013-04-07 18:04:09 +00:00
{
2016-06-10 13:57:11 +00:00
$this->metaData = new YellowDataCollection();
2015-04-29 07:26:48 +00:00
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")));
2015-04-29 07:26:48 +00:00
$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"));
2016-07-19 22:12:05 +00:00
$titleHeader = ($this->location==$this->yellow->pages->getHomeLocation($this->location)) ?
2015-04-29 07:26:48 +00:00
$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"));
2016-10-12 10:03:43 +00:00
if(!$this->isExisting("titleHeader")) $this->set("titleHeader", $titleHeader);
2016-07-19 22:12:05 +00:00
if($this->get("status")=="hidden") $this->available = false;
2015-04-29 07:26:48 +00:00
$this->set("pageRead", $this->yellow->lookup->normaliseUrl(
$this->yellow->config->get("serverScheme"),
2017-02-17 13:52:55 +00:00
$this->yellow->config->get("serverAddress"),
2015-04-29 07:26:48 +00:00
$this->yellow->config->get("serverBase"), $this->location));
$this->set("pageEdit", $this->yellow->lookup->normaliseUrl(
2017-02-17 13:52:55 +00:00
$this->yellow->config->get("serverScheme"),
$this->yellow->config->get("serverAddress"),
2015-04-29 07:26:48 +00:00
$this->yellow->config->get("serverBase"),
rtrim($this->yellow->config->get("editLocation"), '/').$this->location));
2015-04-29 07:26:48 +00:00
} else {
2017-08-09 12:08:02 +00:00
$this->set("type", $this->yellow->toolbox->getFileType($this->fileName));
2015-04-29 07:26:48 +00:00
$this->set("modified", date("Y-m-d H:i:s", $this->yellow->toolbox->getFileModified($this->fileName)));
}
2015-01-19 19:05:51 +00:00
if(!empty($pageError)) $this->set("pageError", $pageError);
2013-09-17 09:18:01 +00:00
foreach($this->yellow->plugins->plugins as $key=>$value)
{
2015-04-29 07:26:48 +00:00
if(method_exists($value["obj"], "onParseMeta")) $value["obj"]->onParseMeta($this);
2013-09-17 09:18:01 +00:00
}
2013-10-16 21:11:24 +00:00
}
// Parse page meta data from raw data
function parseMetaRaw($defaultKeys)
2016-10-01 12:37:59 +00:00
{
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))
2016-10-01 12:37:59 +00:00
{
$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
2016-10-01 12:37:59 +00:00
function parseContent($sizeMax = 0)
2013-05-01 20:16:05 +00:00
{
2013-09-17 09:18:01 +00:00
if(!is_object($this->parser))
2013-05-01 20:16:05 +00:00
{
2013-09-17 09:18:01 +00:00
if($this->yellow->plugins->isExisting($this->get("parser")))
{
2013-12-21 13:10:15 +00:00
$plugin = $this->yellow->plugins->plugins[$this->get("parser")];
2015-04-29 07:26:48 +00:00
if(method_exists($plugin["obj"], "onParseContentRaw"))
2013-12-21 13:10:15 +00:00
{
$this->parser = $plugin["obj"];
2016-10-01 12:37:59 +00:00
$this->parserData = $this->getContent(true, $sizeMax);
2016-02-20 17:34:06 +00:00
$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);
2014-01-08 16:58:52 +00:00
foreach($this->yellow->plugins->plugins as $key=>$value)
{
2015-04-29 07:26:48 +00:00
if(method_exists($value["obj"], "onParseContentText"))
2014-01-08 16:58:52 +00:00
{
2015-04-29 07:26:48 +00:00
$output = $value["obj"]->onParseContentText($this, $this->parserData);
2015-05-21 13:19:56 +00:00
if(!is_null($output)) $this->parserData = $output;
2014-01-08 16:58:52 +00:00
}
}
2014-01-27 11:30:39 +00:00
}
2015-04-29 07:26:48 +00:00
} else {
2016-10-01 12:37:59 +00:00
$this->parserData = $this->getContent(true, $sizeMax);
$this->parserData = preg_replace("/\[yellow error\]/i", $this->get("pageError"), $this->parserData);
2015-04-29 07:26:48 +00:00
}
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));
2013-05-01 20:16:05 +00:00
}
2015-04-29 07:26:48 +00:00
if(defined("DEBUG") && DEBUG>=3) echo "YellowPage::parseContent location:".$this->location."<br/>\n";
2013-05-01 20:16:05 +00:00
}
}
2013-07-11 20:33:28 +00:00
2015-04-29 07:26:48 +00:00
// Parse page content block
2015-06-10 15:13:17 +00:00
function parseContentBlock($name, $text, $shortcut)
2013-08-28 10:01:46 +00:00
{
2016-07-19 22:12:05 +00:00
$output = null;
2013-08-28 10:01:46 +00:00
foreach($this->yellow->plugins->plugins as $key=>$value)
{
2015-04-29 07:26:48 +00:00
if(method_exists($value["obj"], "onParseContentBlock"))
2013-08-28 10:01:46 +00:00
{
2015-06-10 15:13:17 +00:00
$output = $value["obj"]->onParseContentBlock($this, $name, $text, $shortcut);
2013-08-28 10:01:46 +00:00
if(!is_null($output)) break;
}
}
2015-10-21 12:28:56 +00:00
if(is_null($output))
{
2015-12-08 00:01:04 +00:00
if($name=="yellow" && $shortcut)
2015-10-21 12:28:56 +00:00
{
$output = "Datenstrom Yellow ".YellowCore::VERSION;
if($text=="error") $output = $this->get("pageError");
if($text=="version")
2015-10-21 12:28:56 +00:00
{
2016-04-26 10:14:30 +00:00
$output = "<span class=\"".htmlspecialchars($name)."\">\n";
$serverVersion = $this->yellow->toolbox->getServerVersion();
$output .= "Datenstrom Yellow ".YellowCore::VERSION.", PHP ".PHP_VERSION.", $serverVersion<br />\n";
foreach(array_merge($this->yellow->plugins->getData(), $this->yellow->themes->getData()) as $key=>$value)
2015-10-21 12:28:56 +00:00
{
$output .= htmlspecialchars("$key $value")."<br />\n";
2015-10-21 12:28:56 +00:00
}
2016-04-26 10:14:30 +00:00
$output .= "</span>\n";
if($this->parserSafeMode) $this->error(500, "Yellow '$text' is not available in safe mode!");
2015-10-21 12:28:56 +00:00
}
}
}
2015-06-10 15:13:17 +00:00
if(defined("DEBUG") && DEBUG>=3 && !empty($name)) echo "YellowPage::parseContentBlock name:$name shortcut:$shortcut<br/>\n";
2013-08-28 10:01:46 +00:00
return $output;
}
2015-04-29 07:26:48 +00:00
// Parse page
function parsePage()
2015-02-02 12:25:16 +00:00
{
2016-07-19 22:12:05 +00:00
$this->outputData = null;
2015-04-29 07:26:48 +00:00
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();
2015-05-19 14:15:24 +00:00
$this->parseTemplate($this->get("template"));
2015-04-29 07:26:48 +00:00
$this->outputData = ob_get_contents();
ob_end_clean();
}
2015-02-02 12:25:16 +00:00
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");
2016-04-04 10:02:11 +00:00
if(!$this->isHeader("Page-Modified")) $this->setHeader("Page-Modified", $this->getModified(true));
2015-02-02 12:25:16 +00:00
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!");
}
2016-03-26 12:27:38 +00:00
if(!$this->yellow->themes->isExisting($this->get("theme")))
2015-03-17 20:09:56 +00:00
{
$this->error(500, "Theme '".$this->get("theme")."' does not exist!");
}
2015-02-02 12:25:16 +00:00
if(!is_object($this->parser))
{
$this->error(500, "Parser '".$this->get("parser")."' does not exist!");
}
2017-02-17 13:52:55 +00:00
if($this->yellow->lookup->isNestedLocation($this->location, $this->fileName, true))
{
$this->error(500, "Folder '".dirname($this->fileName)."' may not contain subfolders!");
}
2017-12-13 12:51:28 +00:00
if($this->yellow->toolbox->isRequestSelf())
{
$serverVersion = $this->yellow->toolbox->getServerVersion(true);
$this->error(500, "Rewrite module not working on $serverVersion web server!");
}
2015-04-29 07:26:48 +00:00
if($this->yellow->getRequestHandler()=="core" && $this->isExisting("redirect") && $this->statusCode==200)
2015-02-02 12:25:16 +00:00
{
2017-02-17 13:52:55 +00:00
$location = $this->yellow->lookup->normaliseLocation($this->get("redirect"), $this->location);
$location = $this->yellow->lookup->normaliseUrl($this->scheme, $this->address, "", $location);
2015-04-29 07:26:48 +00:00
$this->clean(301, $location);
2015-02-02 12:25:16 +00:00
}
2015-04-29 07:26:48 +00:00
if($this->yellow->getRequestHandler()=="core" && !$this->isAvailable() && $this->statusCode==200)
2015-02-02 13:39:53 +00:00
{
2015-04-29 07:26:48 +00:00
$this->error(404);
2015-02-02 13:39:53 +00:00
}
2016-07-19 22:12:05 +00:00
if($this->isExisting("pageClean")) $this->outputData = null;
}
2015-05-19 14:15:24 +00:00
// Parse template
function parseTemplate($name)
{
2015-05-23 17:24:56 +00:00
$fileNameTemplate = $this->yellow->config->get("templateDir").$this->yellow->lookup->normaliseName($name).".html";
2015-05-19 14:15:24 +00:00
if(is_file($fileNameTemplate))
{
$this->setLastModified(filemtime($fileNameTemplate));
global $yellow;
require($fileNameTemplate);
} else {
$this->error(500, "Template '$name' does not exist!");
echo "Template error<br/>\n";
}
}
// Parse snippet
2015-07-15 11:03:24 +00:00
function parseSnippet($name)
2015-05-19 14:15:24 +00:00
{
2015-05-23 17:24:56 +00:00
$fileNameSnippet = $this->yellow->config->get("snippetDir").$this->yellow->lookup->normaliseName($name).".php";
2015-05-19 14:15:24 +00:00
if(is_file($fileNameSnippet))
{
$this->setLastModified(filemtime($fileNameSnippet));
global $yellow;
require($fileNameSnippet);
} else {
$this->error(500, "Snippet '$name' does not exist!");
echo "Snippet error<br/>\n";
}
}
2013-04-14 22:41:04 +00:00
// Set page meta data
2013-04-07 18:04:09 +00:00
function set($key, $value)
{
$this->metaData[$key] = $value;
}
2014-02-20 15:11:00 +00:00
2013-04-14 22:41:04 +00:00
// Return page meta data
2013-04-07 18:04:09 +00:00
function get($key)
{
return $this->isExisting($key) ? $this->metaData[$key] : "";
2013-04-07 18:04:09 +00:00
}
2013-04-14 22:41:04 +00:00
// Return page meta data, HTML encoded
2013-04-07 18:04:09 +00:00
function getHtml($key)
{
return htmlspecialchars($this->get($key));
}
2015-01-24 22:45:37 +00:00
2015-04-29 07:26:48 +00:00
// Return page meta data as language specific date
function getDate($key, $format = "")
2015-01-24 22:45:37 +00:00
{
if(!empty($format))
2015-02-04 21:58:41 +00:00
{
$format = $this->yellow->text->get($format);
2015-02-04 21:58:41 +00:00
} else {
$format = $this->yellow->text->get("dateFormatMedium");
}
return $this->yellow->text->getDateFormatted(strtotime($this->get($key)), $format);
2015-01-24 22:45:37 +00:00
}
2016-09-01 19:28:03 +00:00
// Return page meta data as language specific date, HTML encoded
function getDateHtml($key, $format = "")
2016-09-01 19:28:03 +00:00
{
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);
2016-09-01 19:28:03 +00:00
}
2015-02-04 21:58:41 +00:00
// Return page meta data as custom date, HTML encoded
function getDateFormattedHtml($key, $format)
{
return htmlspecialchars($this->getDateFormatted($key, $format));
}
2013-10-16 21:11:24 +00:00
// Return page content, HTML encoded or raw format
2016-10-01 12:37:59 +00:00
function getContent($rawFormat = false, $sizeMax = 0)
2013-04-14 22:41:04 +00:00
{
2013-10-16 21:11:24 +00:00
if($rawFormat)
{
$this->parseDataUpdate();
2013-10-16 21:11:24 +00:00
$text = substrb($this->rawData, $this->metaDataOffsetBytes);
} else {
2016-10-01 12:37:59 +00:00
$this->parseContent($sizeMax);
$text = $this->parserData;
2013-10-16 21:11:24 +00:00
}
2016-10-01 12:37:59 +00:00
return $sizeMax ? substrb($text, 0, $sizeMax) : $text;
2013-04-14 22:41:04 +00:00
}
2016-10-01 12:37:59 +00:00
// Return parent page of current page, null if none
2014-02-20 15:11:00 +00:00
function getParent()
{
$parentLocation = $this->yellow->pages->getParentLocation($this->location);
2014-07-25 10:46:58 +00:00
return $this->yellow->pages->find($parentLocation);
2014-02-20 15:11:00 +00:00
}
2016-07-19 22:12:05 +00:00
// Return top-level page for current page, null if none
function getParentTop($homeFailback = true)
2014-02-20 15:11:00 +00:00
{
$parentTopLocation = $this->yellow->pages->getParentTopLocation($this->location);
if(!$this->yellow->pages->find($parentTopLocation) && $homeFailback)
{
$parentTopLocation = $this->yellow->pages->getHomeLocation($this->location);
}
2014-07-25 10:46:58 +00:00
return $this->yellow->pages->find($parentTopLocation);
2014-02-20 15:11:00 +00:00
}
2015-01-07 17:02:58 +00:00
// Return page collection with pages on the same level as current page
2014-02-20 15:11:00 +00:00
function getSiblings($showInvisible = false)
{
$parentLocation = $this->yellow->pages->getParentLocation($this->location);
2015-04-29 07:26:48 +00:00
return $this->yellow->pages->getChildren($parentLocation, $showInvisible);
2014-02-20 15:11:00 +00:00
}
2016-10-01 12:37:59 +00:00
// Return page collection with child pages of current page
2014-02-20 15:11:00 +00:00
function getChildren($showInvisible = false)
{
2015-04-29 07:26:48 +00:00
return $this->yellow->pages->getChildren($this->location, $showInvisible);
}
2017-07-05 10:25:25 +00:00
// Return page collection with sub pages of current page
function getChildrenRecursive($showInvisible = false, $levelMax = 0)
{
return $this->yellow->pages->getChildrenRecursive($this->location, $showInvisible, $levelMax);
}
2015-04-29 07:26:48 +00:00
// Set page collection with additional pages for current page
function setPages($pages)
{
2016-06-10 13:57:11 +00:00
$this->pageCollection = $pages;
2015-04-29 07:26:48 +00:00
}
// Return page collection with additional pages for current page
function getPages()
{
2016-06-10 13:57:11 +00:00
return $this->pageCollection;
2014-02-20 15:11:00 +00:00
}
2015-08-28 14:12:19 +00:00
// Set related page
2015-06-02 22:29:00 +00:00
function setPage($key, $page)
2015-05-30 15:25:27 +00:00
{
2015-08-28 14:12:19 +00:00
$this->pageRelations[$key] = $page;
2015-05-30 15:25:27 +00:00
}
// Return related page
2015-06-02 22:29:00 +00:00
function getPage($key)
2015-05-30 15:25:27 +00:00
{
2015-08-28 14:12:19 +00:00
return !is_null($this->pageRelations[$key]) ? $this->pageRelations[$key] : $this;
2015-05-30 15:25:27 +00:00
}
2017-07-11 12:14:50 +00:00
// Return page base
function getBase($multiLanguage = false)
{
return $multiLanguage ? rtrim($this->base.$this->yellow->pages->getHomeLocation($this->location), '/') : $this->base;
}
2016-06-10 13:57:11 +00:00
// Return page location
2016-09-01 19:28:03 +00:00
function getLocation($absoluteLocation = false)
2013-04-14 22:41:04 +00:00
{
2016-06-10 13:57:11 +00:00
return $absoluteLocation ? $this->base.$this->location : $this->location;
2013-04-14 22:41:04 +00:00
}
2017-02-17 13:52:55 +00:00
// Return page URL
2013-11-29 12:16:14 +00:00
function getUrl()
{
2017-02-17 13:52:55 +00:00
return $this->yellow->lookup->normaliseUrl($this->scheme, $this->address, $this->base, $this->location);
2015-04-29 07:26:48 +00:00
}
// Return page extra HTML data
2015-05-19 14:15:24 +00:00
function getExtra($name)
2015-04-29 07:26:48 +00:00
{
$output = "";
2016-02-22 13:20:57 +00:00
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;
}
}
2016-07-19 22:12:05 +00:00
if($name=="header")
2015-08-01 17:28:20 +00:00
{
2017-02-17 13:52:55 +00:00
if(is_file($this->yellow->config->get("assetDir").$this->get("theme").".css"))
2015-08-01 17:28:20 +00:00
{
$location = $this->yellow->config->get("serverBase").
2017-02-17 13:52:55 +00:00
$this->yellow->config->get("assetLocation").$this->get("theme").".css";
2015-08-01 17:28:20 +00:00
$output .= "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"".htmlspecialchars($location)."\" />\n";
}
2016-06-15 13:27:01 +00:00
if(is_file($this->yellow->config->get("assetDir").$this->get("theme").".js"))
2016-02-22 13:20:57 +00:00
{
$location = $this->yellow->config->get("serverBase").
2016-06-15 13:27:01 +00:00
$this->yellow->config->get("assetLocation").$this->get("theme").".js";
2016-02-22 13:20:57 +00:00
$output .= "<script type=\"text/javascript\" src=\"".htmlspecialchars($location)."\"></script>\n";
}
2016-06-15 13:27:01 +00:00
if(is_file($this->yellow->config->get("assetDir").$this->get("siteicon").".png"))
2015-08-01 17:28:20 +00:00
{
$location = $this->yellow->config->get("serverBase").
2016-06-15 13:27:01 +00:00
$this->yellow->config->get("assetLocation").$this->get("siteicon").".png";
2016-03-17 14:31:22 +00:00
$contentType = $this->yellow->toolbox->getMimeContentType($location);
$output .= "<link rel=\"icon\" type=\"$contentType\" href=\"".htmlspecialchars($location)."\" />\n";
$output .= "<link rel=\"apple-touch-icon\" type=\"$contentType\" href=\"".htmlspecialchars($location)."\" />\n";
2015-08-01 17:28:20 +00:00
}
}
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("/^<script (.*?)src=\"([^\"]+)\"(.*?)><\/script>$/i", $line, $matches))
{
if(is_null($locations[$matches[2]]))
{
$locations[$matches[2]] = $matches[2];
array_push($outputScript, $line);
}
} else if(preg_match("/^<link rel=\"stylesheet\"(.*?)href=\"([^\"]+)\"(.*?)>$/i", $line, $matches)) {
if(is_null($locations[$matches[2]]))
{
$locations[$matches[2]] = $matches[2];
array_push($outputStylesheet, $line);
}
} else {
array_push($outputOther, $line);
}
}
return implode($outputScript).implode($outputStylesheet).implode($outputOther);
2015-04-29 07:26:48 +00:00
}
// Set page response output
function setOutput($output)
{
$this->outputData = $output;
}
// Set page response header
function setHeader($key, $value)
{
$this->headerData[$key] = $value;
}
// Return page response header
function getHeader($key)
{
return $this->isHeader($key) ? $this->headerData[$key] : "";
2013-11-29 12:16:14 +00:00
}
2016-04-04 10:02:11 +00:00
// Return page modification date, Unix time or HTTP format
2013-06-27 17:00:03 +00:00
function getModified($httpFormat = false)
2013-05-01 20:16:05 +00:00
{
$modified = strtotime($this->get("modified"));
2015-01-24 22:45:37 +00:00
return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($modified) : $modified;
2013-05-01 20:16:05 +00:00
}
2015-02-02 12:25:16 +00:00
// Set last modification date, Unix time
function setLastModified($modified)
{
$this->lastModified = max($this->lastModified, $modified);
}
// Return last modification date, Unix time or HTTP format
function getLastModified($httpFormat = false)
{
$modified = max($this->lastModified, $this->getModified(), $this->yellow->config->getModified(),
$this->yellow->text->getModified(), $this->yellow->plugins->getModified());
return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($modified) : $modified;
}
2015-01-24 22:45:37 +00:00
// Return page status code, number or HTTP format
function getStatusCode($httpFormat = false)
{
$statusCode = $this->statusCode;
if($httpFormat)
{
$statusCode = $this->yellow->toolbox->getHttpStatusFormatted($statusCode);
if($this->isExisting("pageError")) $statusCode .= ": ".$this->get("pageError");
}
return $statusCode;
}
2014-02-20 15:11:00 +00:00
// Respond with error page
function error($statusCode, $pageError = "")
{
2014-02-20 15:11:00 +00:00
if(!$this->isExisting("pageError") && $statusCode>0)
{
$this->statusCode = $statusCode;
$this->set("pageError", empty($pageError) ? "Template/snippet error!" : $pageError);
}
2013-05-01 20:16:05 +00:00
}
2014-02-20 15:11:00 +00:00
// Respond with status code, no page content
2015-04-29 07:26:48 +00:00
function clean($statusCode, $location = "")
2013-05-01 20:16:05 +00:00
{
2014-02-20 15:11:00 +00:00
if(!$this->isExisting("pageClean") && $statusCode>0)
{
$this->statusCode = $statusCode;
2015-02-02 12:25:16 +00:00
$this->lastModified = 0;
2014-02-20 15:11:00 +00:00
$this->headerData = array();
2015-04-29 07:26:48 +00:00
if(!empty($location))
{
$this->setHeader("Location", $location);
$this->setHeader("Cache-Control", "no-cache, must-revalidate");
}
2014-02-20 15:11:00 +00:00
$this->set("pageClean", (string)$statusCode);
}
2013-05-01 20:16:05 +00:00
}
2014-02-20 15:11:00 +00:00
2015-04-29 07:26:48 +00:00
// Check if page is available
function isAvailable()
2013-05-01 20:16:05 +00:00
{
2015-04-29 07:26:48 +00:00
return $this->available;
2013-05-01 20:16:05 +00:00
}
2015-04-29 07:26:48 +00:00
// Check if page is visible
function isVisible()
{
2015-04-29 07:26:48 +00:00
return $this->visible;
}
2013-07-11 20:33:28 +00:00
2015-04-29 07:26:48 +00:00
// Check if page is within current request
function isActive()
2013-04-14 22:41:04 +00:00
{
2015-04-29 07:26:48 +00:00
return $this->active;
2013-04-14 22:41:04 +00:00
}
2015-04-29 07:26:48 +00:00
// Check if page is cacheable
function isCacheable()
{
return $this->cacheable;
}
// Check if page with error
function isError()
{
2016-11-23 23:38:47 +00:00
return $this->statusCode>=400;
}
2015-04-29 07:26:48 +00:00
// Check if response header exists
function isHeader($key)
2013-07-11 20:33:28 +00:00
{
2015-04-29 07:26:48 +00:00
return !is_null($this->headerData[$key]);
2013-07-11 20:33:28 +00:00
}
2015-04-29 07:26:48 +00:00
// Check if page meta data exists
function isExisting($key)
2013-04-14 22:41:04 +00:00
{
2015-04-29 07:26:48 +00:00
return !is_null($this->metaData[$key]);
2013-04-14 22:41:04 +00:00
}
2015-08-28 14:12:19 +00:00
// Check if related page exists
function isPage($key)
{
return !is_null($this->pageRelations[$key]);
}
2013-04-07 18:04:09 +00:00
}
2016-06-10 13:57:11 +00:00
class YellowDataCollection extends ArrayObject
{
function __construct()
{
parent::__construct(array());
}
2016-06-10 18:54:51 +00:00
// Return array element
2016-06-10 13:57:11 +00:00
function offsetGet($key)
{
if(is_string($key)) $key = lcfirst($key);
return parent::offsetGet($key);
}
2016-06-10 18:54:51 +00:00
// Set array element
2016-06-10 13:57:11 +00:00
function offsetSet($key, $value)
{
if(is_string($key)) $key = lcfirst($key);
parent::offsetSet($key, $value);
}
2016-06-10 18:54:51 +00:00
// Remove array element
2016-06-10 13:57:11 +00:00
function offsetUnset($key)
{
if(is_string($key)) $key = lcfirst($key);
parent::offsetUnset($key);
}
2016-06-10 18:54:51 +00:00
// Check if array element exists
2016-06-10 13:57:11 +00:00
function offsetExists($key)
{
if(is_string($key)) $key = lcfirst($key);
return parent::offsetExists($key);
}
}
2013-12-01 11:59:07 +00:00
class YellowPageCollection extends ArrayObject
2013-04-07 18:04:09 +00:00
{
2013-07-16 16:56:27 +00:00
var $yellow; //access to API
2014-02-04 14:06:48 +00:00
var $filterValue; //current page filter value
2015-04-29 07:26:48 +00:00
var $paginationNumber; //current page number in pagination
2013-05-01 20:16:05 +00:00
var $paginationCount; //highest page number in pagination
2013-04-14 22:41:04 +00:00
2013-10-16 21:11:24 +00:00
function __construct($yellow)
2013-04-14 22:41:04 +00:00
{
parent::__construct(array());
2013-07-16 16:56:27 +00:00
$this->yellow = $yellow;
}
2013-04-14 22:41:04 +00:00
2013-05-01 20:16:05 +00:00
// Filter page collection by meta data
function filter($key, $value, $exactMatch = true)
2013-04-14 22:41:04 +00:00
{
2017-02-22 20:05:46 +00:00
$array = array();
$value = strreplaceu(' ', '-', strtoloweru($value));
$valueLength = strlenu($value);
$this->filterValue = "";
foreach($this->getArrayCopy() as $page)
2013-04-14 22:41:04 +00:00
{
2017-02-22 20:05:46 +00:00
if($page->isExisting($key))
2013-04-14 22:41:04 +00:00
{
2017-02-22 20:05:46 +00:00
foreach(preg_split("/\s*,\s*/", $page->get($key)) as $pageValue)
2013-05-01 20:16:05 +00:00
{
2017-02-22 20:05:46 +00:00
$pageValueLength = $exactMatch ? strlenu($pageValue) : $valueLength;
if($value==substru(strreplaceu(' ', '-', strtoloweru($pageValue)), 0, $pageValueLength))
2013-05-01 20:16:05 +00:00
{
2017-02-22 20:05:46 +00:00
if(empty($this->filterValue)) $this->filterValue = substru($pageValue, 0, $pageValueLength);
array_push($array, $page);
break;
2013-05-01 20:16:05 +00:00
}
}
2013-04-14 22:41:04 +00:00
}
}
2017-02-22 20:05:46 +00:00
$this->exchangeArray($array);
2013-05-01 20:16:05 +00:00
return $this;
}
2015-05-19 14:15:24 +00:00
// Filter page collection by file name
function match($regex = "/.*/")
{
$array = array();
foreach($this->getArrayCopy() as $page)
{
2015-08-17 20:14:38 +00:00
if(preg_match($regex, $page->fileName)) array_push($array, $page);
2015-05-19 14:15:24 +00:00
}
$this->exchangeArray($array);
return $this;
}
// Sort page collection by meta data
function sort($key, $ascendingOrder = true)
{
2017-03-21 15:48:31 +00:00
$array = $this->getArrayCopy();
foreach($array as $page) $page->set("sortindex", ++$i);
$callback = function($a, $b) use ($key, $ascendingOrder)
{
2017-03-21 15:48:31 +00:00
$result = $ascendingOrder ?
strnatcasecmp($a->get($key), $b->get($key)) :
strnatcasecmp($b->get($key), $a->get($key));
2017-03-21 15:48:31 +00:00
return $result==0 ? $a->get("sortindex") - $b->get("sortindex") : $result;
};
usort($array, $callback);
$this->exchangeArray($array);
return $this;
}
2015-05-30 15:25:27 +00:00
// Sort page collection by meta data similarity
function similar($page, $ascendingOrder = false)
{
$location = $page->location;
2015-06-02 22:29:00 +00:00
$keywords = $this->yellow->toolbox->createTextKeywords($page->get("title"));
$keywords .= ",".$page->get("tag").",".$page->get("author");
2017-02-22 20:05:46 +00:00
$tokens = array_unique(array_filter(preg_split("/\s*,\s*/", $keywords), "strlen"));
2015-05-30 15:25:27 +00:00
if(!empty($tokens))
{
$array = array();
foreach($this->getArrayCopy() as $page)
{
$searchScore = 0;
foreach($tokens as $token)
{
if(stristr($page->get("title"), $token)) $searchScore += 10;
if(stristr($page->get("tag"), $token)) $searchScore += 5;
if(stristr($page->get("author"), $token)) $searchScore += 2;
}
2016-07-19 22:12:05 +00:00
if($page->location!=$location)
2015-05-30 15:25:27 +00:00
{
$page->set("searchscore", $searchScore);
array_push($array, $page);
}
}
$this->exchangeArray($array);
2017-03-21 15:48:31 +00:00
$this->sort("modified", $ascendingOrder)->sort("searchscore", $ascendingOrder);
2015-05-30 15:25:27 +00:00
}
return $this;
}
2013-05-01 20:16:05 +00:00
2013-07-16 16:56:27 +00:00
// Merge page collection
function merge($input)
{
$this->exchangeArray(array_merge($this->getArrayCopy(), (array)$input));
return $this;
}
2013-09-17 09:18:01 +00:00
// Append to end of page collection
function append($page)
{
parent::append($page);
return $this;
}
// Prepend to start of page collection
function prepend($page)
{
$array = $this->getArrayCopy();
array_unshift($array, $page);
$this->exchangeArray($array);
return $this;
}
// Limit the number of pages in page collection
function limit($pagesMax)
{
$this->exchangeArray(array_slice($this->getArrayCopy(), 0, $pagesMax));
return $this;
}
2013-05-01 20:16:05 +00:00
// Reverse page collection
function reverse()
2013-05-01 20:16:05 +00:00
{
$this->exchangeArray(array_reverse($this->getArrayCopy()));
return $this;
}
2015-01-07 17:02:58 +00:00
// Randomize page collection
function shuffle()
{
$array = $this->getArrayCopy();
shuffle($array);
$this->exchangeArray($array);
return $this;
}
2013-05-01 20:16:05 +00:00
// Paginate page collection
function pagination($limit, $reverse = true)
{
2015-04-29 07:26:48 +00:00
$this->paginationNumber = 1;
2013-05-01 20:16:05 +00:00
$this->paginationCount = ceil($this->count() / $limit);
2015-04-29 07:26:48 +00:00
$pagination = $this->yellow->config->get("contentPagination");
if(isset($_REQUEST[$pagination])) $this->paginationNumber = intval($_REQUEST[$pagination]);
2016-07-19 22:12:05 +00:00
if($this->paginationNumber>$this->paginationCount) $this->paginationNumber = 0;
if($this->paginationNumber>=1)
{
2015-04-29 07:26:48 +00:00
$array = $this->getArrayCopy();
if($reverse) $array = array_reverse($array);
$this->exchangeArray(array_slice($array, ($this->paginationNumber - 1) * $limit, $limit));
}
2013-05-01 20:16:05 +00:00
return $this;
}
// Return current page number in pagination
2015-04-29 07:26:48 +00:00
function getPaginationNumber()
2013-05-01 20:16:05 +00:00
{
2015-04-29 07:26:48 +00:00
return $this->paginationNumber;
2013-05-01 20:16:05 +00:00
}
// Return highest page number in pagination
function getPaginationCount()
{
return $this->paginationCount;
2013-04-14 22:41:04 +00:00
}
2016-11-22 14:36:09 +00:00
// Return location for a page in pagination
function getPaginationLocation($absoluteLocation = true, $pageNumber = 1)
2013-04-14 22:41:04 +00:00
{
2013-05-01 20:16:05 +00:00
if($pageNumber>=1 && $pageNumber<=$this->paginationCount)
2013-04-14 22:41:04 +00:00
{
$pagination = $this->yellow->config->get("contentPagination");
2016-11-22 14:36:09 +00:00
$location = $this->yellow->page->getLocation($absoluteLocation);
$locationArgs = $this->yellow->toolbox->getLocationArgsNew(
$pageNumber>1 ? "$pagination:$pageNumber" : "$pagination:", $pagination);
2013-04-14 22:41:04 +00:00
}
2013-12-21 13:10:15 +00:00
return $location.$locationArgs;
2013-04-14 22:41:04 +00:00
}
2016-11-22 14:36:09 +00:00
// Return location for previous page in pagination
function getPaginationPrevious($absoluteLocation = true)
2013-05-01 20:16:05 +00:00
{
2016-11-22 14:36:09 +00:00
$pageNumber = $this->paginationNumber-1;
return $this->getPaginationLocation($absoluteLocation, $pageNumber);
2013-05-01 20:16:05 +00:00
}
2016-11-22 14:36:09 +00:00
// Return location for next page in pagination
function getPaginationNext($absoluteLocation = true)
2013-05-01 20:16:05 +00:00
{
2016-11-22 14:36:09 +00:00
$pageNumber = $this->paginationNumber+1;
return $this->getPaginationLocation($absoluteLocation, $pageNumber);
}
// Return current page number in collection
function getPageNumber($page)
{
$pageNumber = 0;
foreach($this->getIterator() as $key=>$value)
{
if($page->getLocation()==$value->getLocation()) { $pageNumber = $key+1; break; }
}
return $pageNumber;
}
// Return page in collection, null if none
function getPage($pageNumber = 1)
{
return ($pageNumber>=1 && $pageNumber<=$this->count()) ? $this->offsetGet($pageNumber-1) : null;
}
// Return previous page in collection, null if none
function getPagePrevious($page)
{
$pageNumber = $this->getPageNumber($page)-1;
return $this->getPage($pageNumber);
}
// Return next page in collection, null if none
function getPageNext($page)
{
$pageNumber = $this->getPageNumber($page)+1;
return $this->getPage($pageNumber);
2013-05-01 20:16:05 +00:00
}
2013-06-27 17:00:03 +00:00
2014-02-04 14:06:48 +00:00
// Return current page filter
function getFilter()
{
return $this->filterValue;
}
2015-02-02 12:25:16 +00:00
// Return page collection modification date, Unix time or HTTP format
2013-06-27 17:00:03 +00:00
function getModified($httpFormat = false)
{
$modified = 0;
foreach($this->getIterator() as $page) $modified = max($modified, $page->getModified());
2015-01-24 22:45:37 +00:00
return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($modified) : $modified;
2013-06-27 17:00:03 +00:00
}
2015-04-29 07:26:48 +00:00
// Check if there is a pagination
2013-05-01 20:16:05 +00:00
function isPagination()
{
2016-07-19 22:12:05 +00:00
return $this->paginationCount>1;
2013-05-01 20:16:05 +00:00
}
}
2013-12-01 11:59:07 +00:00
class YellowPages
2013-04-07 18:04:09 +00:00
{
var $yellow; //access to API
var $pages; //scanned pages
2013-05-01 20:16:05 +00:00
2013-07-16 16:56:27 +00:00
function __construct($yellow)
2013-04-14 22:41:04 +00:00
{
2013-07-11 20:33:28 +00:00
$this->yellow = $yellow;
2013-11-29 12:16:14 +00:00
$this->pages = array();
2013-05-01 20:16:05 +00:00
}
2013-09-17 09:18:01 +00:00
2015-04-29 07:26:48 +00:00
// Scan file system on demand
function scanLocation($location)
{
if(is_null($this->pages[$location]))
{
if(defined("DEBUG") && DEBUG>=2) echo "YellowPages::scanLocation location:$location<br/>\n";
$this->pages[$location] = array();
2017-02-17 13:52:55 +00:00
$scheme = $this->yellow->page->scheme;
$address = $this->yellow->page->address;
2015-04-29 07:26:48 +00:00
$base = $this->yellow->page->base;
if(empty($location))
{
$rootLocations = $this->yellow->lookup->findRootLocations();
foreach($rootLocations as $rootLocation)
{
list($rootLocation, $fileName) = explode(' ', $rootLocation, 2);
$page = new YellowPage($this->yellow);
2017-02-17 13:52:55 +00:00
$page->setRequestInformation($scheme, $address, $base, $rootLocation, $fileName);
2015-04-29 07:26:48 +00:00
$page->parseData("", false, 0);
array_push($this->pages[$location], $page);
}
} else {
$fileNames = $this->yellow->lookup->findChildrenFromLocation($location);
foreach($fileNames as $fileName)
{
$page = new YellowPage($this->yellow);
2017-02-17 13:52:55 +00:00
$page->setRequestInformation($scheme, $address, $base,
2015-04-29 07:26:48 +00:00
$this->yellow->lookup->findLocationFromFile($fileName), $fileName);
2016-02-20 17:34:06 +00:00
$page->parseData($this->yellow->toolbox->readFile($fileName, 4096), false, 0);
2016-07-19 22:12:05 +00:00
if(strlenb($page->rawData)<4096) $page->statusCode = 200;
2015-04-29 07:26:48 +00:00
array_push($this->pages[$location], $page);
}
}
}
return $this->pages[$location];
}
2016-07-19 22:12:05 +00:00
// Return page from file system, null if not found
2015-04-29 07:26:48 +00:00
function find($location, $absoluteLocation = false)
{
if($absoluteLocation) $location = substru($location, strlenu($this->yellow->page->base));
foreach($this->scanLocation($this->getParentLocation($location)) as $page)
{
2016-07-19 22:12:05 +00:00
if($page->location==$location)
2015-04-29 07:26:48 +00:00
{
if(!$this->yellow->lookup->isRootLocation($page->location)) { $found = true; break; }
}
}
2016-07-19 22:12:05 +00:00
return $found ? $page : null;
2015-04-29 07:26:48 +00:00
}
// Return page collection with all pages
2015-05-06 07:19:31 +00:00
function index($showInvisible = false, $multiLanguage = false, $levelMax = 0)
2013-07-16 16:56:27 +00:00
{
2015-05-06 07:19:31 +00:00
$rootLocation = $multiLanguage ? "" : $this->getRootLocation($this->yellow->page->location);
2015-04-29 07:26:48 +00:00
return $this->getChildrenRecursive($rootLocation, $showInvisible, $levelMax);
2013-07-16 16:56:27 +00:00
}
2013-05-01 20:16:05 +00:00
// Return page collection with top-level navigation
function top($showInvisible = false)
2013-05-01 20:16:05 +00:00
{
$rootLocation = $this->getRootLocation($this->yellow->page->location);
return $this->getChildren($rootLocation, $showInvisible);
2013-05-01 20:16:05 +00:00
}
2013-09-17 09:18:01 +00:00
// Return page collection with path ancestry
function path($location, $absoluteLocation = false)
{
2014-07-25 10:46:58 +00:00
$pages = new YellowPageCollection($this->yellow);
2015-04-29 07:26:48 +00:00
if($absoluteLocation) $location = substru($location, strlenu($this->yellow->page->base));
if($page = $this->find($location))
2013-09-17 09:18:01 +00:00
{
2014-07-25 10:46:58 +00:00
$pages->prepend($page);
for(; $parent = $page->getParent(); $page=$parent) $pages->prepend($parent);
$home = $this->find($this->getHomeLocation($page->location));
if($home && $home->location!=$page->location) $pages->prepend($home);
2013-09-17 09:18:01 +00:00
}
return $pages;
}
// Return page collection with multiple languages
function multi($location, $absoluteLocation = false, $showInvisible = false)
{
$pages = new YellowPageCollection($this->yellow);
if($absoluteLocation) $location = substru($location, strlenu($this->yellow->page->base));
2015-04-29 07:26:48 +00:00
$locationEnd = substru($location, strlenu($this->getRootLocation($location)) - 4);
foreach($this->scanLocation("") as $page)
{
2015-04-29 07:26:48 +00:00
if($content = $this->find(substru($page->location, 4).$locationEnd))
{
2015-04-29 07:26:48 +00:00
if($content->isAvailable() && ($content->isVisible() || $showInvisible))
{
if(!$this->yellow->lookup->isRootLocation($content->location)) $pages->append($content);
}
}
}
return $pages;
}
2015-04-29 07:26:48 +00:00
// Return page collection that's empty
function clean()
2013-07-16 16:56:27 +00:00
{
2014-07-25 10:46:58 +00:00
return new YellowPageCollection($this->yellow);
2013-07-16 16:56:27 +00:00
}
2013-05-01 20:16:05 +00:00
2016-02-20 17:34:06 +00:00
// Return languages in multi language mode
2015-04-29 07:26:48 +00:00
function getLanguages($showInvisible = false)
{
2015-04-29 07:26:48 +00:00
$languages = array();
foreach($this->scanLocation("") as $page)
{
2015-04-29 07:26:48 +00:00
if($page->isAvailable() && ($page->isVisible() || $showInvisible))
{
array_push($languages, $page->get("language"));
}
}
2015-04-29 07:26:48 +00:00
return $languages;
}
2015-04-29 07:26:48 +00:00
// Return child pages
function getChildren($location, $showInvisible = false)
2013-05-01 20:16:05 +00:00
{
2013-12-01 11:59:07 +00:00
$pages = new YellowPageCollection($this->yellow);
2015-04-29 07:26:48 +00:00
foreach($this->scanLocation($location) as $page)
{
2015-04-29 07:26:48 +00:00
if($page->isAvailable() && ($page->isVisible() || $showInvisible))
{
if(!$this->yellow->lookup->isRootLocation($page->location) && is_readable($page->fileName)) $pages->append($page);
}
}
2013-05-01 20:16:05 +00:00
return $pages;
2013-04-14 22:41:04 +00:00
}
2013-07-16 16:56:27 +00:00
// Return sub pages
2015-04-29 07:26:48 +00:00
function getChildrenRecursive($location, $showInvisible = false, $levelMax = 0)
2013-04-14 22:41:04 +00:00
{
2013-07-16 16:56:27 +00:00
--$levelMax;
2013-12-01 11:59:07 +00:00
$pages = new YellowPageCollection($this->yellow);
2015-04-29 07:26:48 +00:00
foreach($this->scanLocation($location) as $page)
2013-07-16 16:56:27 +00:00
{
2015-04-29 07:26:48 +00:00
if($page->isAvailable() && ($page->isVisible() || $showInvisible))
2013-07-16 16:56:27 +00:00
{
if(!$this->yellow->lookup->isRootLocation($page->location) && is_readable($page->fileName)) $pages->append($page);
2015-04-29 07:26:48 +00:00
if(!$this->yellow->lookup->isFileLocation($page->location) && $levelMax!=0)
2013-07-16 16:56:27 +00:00
{
2015-04-29 07:26:48 +00:00
$pages->merge($this->getChildrenRecursive($page->location, $showInvisible, $levelMax));
2013-07-16 16:56:27 +00:00
}
}
}
return $pages;
2013-05-01 20:16:05 +00:00
}
2015-04-29 07:26:48 +00:00
// Return root location
function getRootLocation($location)
2013-05-01 20:16:05 +00:00
{
2015-04-29 07:26:48 +00:00
$rootLocation = "root/";
if($this->yellow->config->get("multiLanguageMode"))
2013-05-01 20:16:05 +00:00
{
2015-04-29 07:26:48 +00:00
foreach($this->scanLocation("") as $page)
{
$token = substru($page->location, 4);
if($token!="/" && substru($location, 0, strlenu($token))==$token) { $rootLocation = "root$token"; break; }
}
}
return $rootLocation;
}
// Return home location
function getHomeLocation($location)
{
return substru($this->getRootLocation($location), 4);
}
2013-07-16 16:56:27 +00:00
// Return parent location
2013-05-01 20:16:05 +00:00
function getParentLocation($location)
{
2015-04-29 07:26:48 +00:00
$token = rtrim(substru($this->getRootLocation($location), 4), '/');
if(preg_match("#^($token.*\/).+?$#", $location, $matches))
{
if($matches[1]!="$token/" || $this->yellow->lookup->isFileLocation($location)) $parentLocation = $matches[1];
}
if(empty($parentLocation)) $parentLocation = "root$token/";
return $parentLocation;
}
// Return top-level location
function getParentTopLocation($location)
{
$token = rtrim(substru($this->getRootLocation($location), 4), '/');
if(preg_match("#^($token.+?\/)#", $location, $matches)) $parentTopLocation = $matches[1];
if(empty($parentTopLocation)) $parentTopLocation = "$token/";
return $parentTopLocation;
}
}
class YellowFiles
{
var $yellow; //access to API
var $files; //scanned files
function __construct($yellow)
{
$this->yellow = $yellow;
$this->files = array();
}
// Scan file system on demand
function scanLocation($location)
{
if(is_null($this->files[$location]))
{
if(defined("DEBUG") && DEBUG>=2) echo "YellowFiles::scanLocation location:$location<br/>\n";
$this->files[$location] = array();
2017-02-17 13:52:55 +00:00
$scheme = $this->yellow->page->scheme;
$address = $this->yellow->page->address;
2015-08-01 17:28:20 +00:00
$base = $this->yellow->config->get("serverBase");
2015-04-29 07:26:48 +00:00
if(empty($location))
{
$fileNames = array($this->yellow->config->get("mediaDir"));
} else {
$fileNames = array();
$path = substru($location, 1);
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/.*/", true, true, true) as $entry)
{
array_push($fileNames, $entry."/");
}
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/.*/", true, false, true) as $entry)
{
array_push($fileNames, $entry);
}
}
foreach($fileNames as $fileName)
{
$file = new YellowPage($this->yellow);
2017-02-17 13:52:55 +00:00
$file->setRequestInformation($scheme, $address, $base, "/".$fileName, $fileName);
2016-07-19 22:12:05 +00:00
$file->parseData(null, false, 0);
2015-04-29 07:26:48 +00:00
array_push($this->files[$location], $file);
}
}
return $this->files[$location];
}
2016-07-19 22:12:05 +00:00
// Return page with media file information, null if not found
2015-04-29 07:26:48 +00:00
function find($location, $absoluteLocation = false)
{
2017-02-17 13:52:55 +00:00
if($absoluteLocation) $location = substru($location, strlenu($this->yellow->config->get("serverBase")));
2015-04-29 07:26:48 +00:00
foreach($this->scanLocation($this->getParentLocation($location)) as $file)
{
2016-09-07 14:48:26 +00:00
if($file->location==$location)
{
if($this->yellow->lookup->isFileLocation($file->location)) { $found = true; break; }
}
2015-04-29 07:26:48 +00:00
}
2016-07-19 22:12:05 +00:00
return $found ? $file : null;
2015-04-29 07:26:48 +00:00
}
// Return page collection with all media files
2015-05-06 07:19:31 +00:00
function index($showInvisible = false, $multiPass = false, $levelMax = 0)
2015-04-29 07:26:48 +00:00
{
return $this->getChildrenRecursive("", $showInvisible, $levelMax);
}
// Return page collection that's empty
function clean()
{
return new YellowPageCollection($this->yellow);
}
// Return child files
function getChildren($location, $showInvisible = false)
{
$files = new YellowPageCollection($this->yellow);
foreach($this->scanLocation($location) as $file)
{
if($file->isAvailable() && ($file->isVisible() || $showInvisible))
{
2016-09-07 14:48:26 +00:00
if($this->yellow->lookup->isFileLocation($file->location)) $files->append($file);
2015-04-29 07:26:48 +00:00
}
}
return $files;
}
// Return sub files
2015-04-29 07:26:48 +00:00
function getChildrenRecursive($location, $showInvisible = false, $levelMax = 0)
{
--$levelMax;
$files = new YellowPageCollection($this->yellow);
foreach($this->scanLocation($location) as $file)
{
if($file->isAvailable() && ($file->isVisible() || $showInvisible))
{
2016-09-07 14:48:26 +00:00
if($this->yellow->lookup->isFileLocation($file->location)) $files->append($file);
2015-04-29 07:26:48 +00:00
if(!$this->yellow->lookup->isFileLocation($file->location) && $levelMax!=0)
{
$files->merge($this->getChildrenRecursive($file->location, $showInvisible, $levelMax));
}
}
}
return $files;
}
// Return home location
function getHomeLocation($location)
{
2017-02-17 13:52:55 +00:00
return $this->yellow->config->get("mediaLocation");
2015-04-29 07:26:48 +00:00
}
// Return parent location
function getParentLocation($location)
{
2017-02-17 13:52:55 +00:00
$token = rtrim($this->yellow->config->get("mediaLocation"), '/');
2015-04-29 07:26:48 +00:00
if(preg_match("#^($token.*\/).+?$#", $location, $matches))
{
2015-04-29 07:26:48 +00:00
if($matches[1]!="$token/" || $this->yellow->lookup->isFileLocation($location)) $parentLocation = $matches[1];
}
2015-04-29 07:26:48 +00:00
if(empty($parentLocation)) $parentLocation = "";
2013-05-01 20:16:05 +00:00
return $parentLocation;
}
// Return top-level location
function getParentTopLocation($location)
{
2017-02-17 13:52:55 +00:00
$token = rtrim($this->yellow->config->get("mediaLocation"), '/');
2015-04-29 07:26:48 +00:00
if(preg_match("#^($token.+?\/)#", $location, $matches)) $parentTopLocation = $matches[1];
if(empty($parentTopLocation)) $parentTopLocation = "$token/";
return $parentTopLocation;
}
2013-05-01 20:16:05 +00:00
}
2015-04-29 07:26:48 +00:00
class YellowPlugins
{
var $yellow; //access to API
var $modified; //plugin modification date
2016-03-26 12:27:38 +00:00
var $plugins; //registered plugins
2015-04-29 07:26:48 +00:00
function __construct($yellow)
{
$this->yellow = $yellow;
$this->modified = 0;
2016-03-26 12:27:38 +00:00
$this->plugins = array();
2015-04-29 07:26:48 +00:00
}
// Load plugins
2017-02-17 13:52:55 +00:00
function load($path = "")
2015-04-29 07:26:48 +00:00
{
if(count($this->yellow->config->config)==0) //TODO: remove later, backwards compability for old version
{
$this->yellow->load();
return;
}
2017-02-17 13:52:55 +00:00
$path = empty($path) ? $this->yellow->config->get("pluginDir") : $path;
2015-04-29 07:26:48 +00:00
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.php$/", true, false) as $entry)
{
2017-02-17 13:52:55 +00:00
if(defined("DEBUG") && DEBUG>=3) echo "YellowPlugins::load file:$entry<br/>\n";
2015-04-29 07:26:48 +00:00
$this->modified = max($this->modified, filemtime($entry));
global $yellow;
require_once($entry);
}
2016-07-15 16:35:11 +00:00
$callback = function($a, $b)
{
return $a["priority"] - $b["priority"];
};
uasort($this->plugins, $callback);
2015-04-29 07:26:48 +00:00
foreach($this->plugins as $key=>$value)
{
2016-06-14 15:10:09 +00:00
$this->plugins[$key]["obj"] = new $value["plugin"];
2015-04-29 07:26:48 +00:00
if(method_exists($this->plugins[$key]["obj"], "onLoad")) $this->plugins[$key]["obj"]->onLoad($yellow);
}
}
// Register plugin
2016-07-15 16:35:11 +00:00
function register($name, $plugin, $version, $priority = 0)
2015-04-29 07:26:48 +00:00
{
if(!$this->isExisting($name))
{
2016-07-19 22:12:05 +00:00
if($priority==0) $priority = count($this->plugins) + 10;
2015-04-29 07:26:48 +00:00
$this->plugins[$name] = array();
2016-06-14 15:10:09 +00:00
$this->plugins[$name]["plugin"] = $plugin;
2015-04-29 07:26:48 +00:00
$this->plugins[$name]["version"] = $version;
2016-07-15 16:35:11 +00:00
$this->plugins[$name]["priority"] = $priority;
2015-04-29 07:26:48 +00:00
}
}
// Return plugin
function get($name)
{
return $this->plugins[$name]["obj"];
}
2015-10-08 14:52:01 +00:00
// Return plugin version
function getData()
{
2016-06-14 15:10:09 +00:00
$data = array();
2016-07-19 22:12:05 +00:00
$data["YellowCore"] = YellowCore::VERSION;
2017-02-17 13:52:55 +00:00
foreach($this->plugins as $key=>$value)
{
if(empty($value["plugin"]) || empty($value["version"])) continue;
$data[$value["plugin"]] = $value["version"];
}
2017-11-30 23:31:43 +00:00
uksort($data, "strnatcasecmp");
2016-06-14 15:10:09 +00:00
return $data;
2015-10-08 14:52:01 +00:00
}
// Return plugin modification date, Unix time or HTTP format
2015-04-29 07:26:48 +00:00
function getModified($httpFormat = false)
{
return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($this->modified) : $this->modified;
}
// Check if plugin exists
function isExisting($name)
{
return !is_null($this->plugins[$name]);
}
}
2016-03-26 12:27:38 +00:00
class YellowThemes
{
var $yellow; //access to API
var $modified; //theme modification date
var $themes; //themes
function __construct($yellow)
{
$this->yellow = $yellow;
$this->modified = 0;
$this->themes = array();
}
// Load themes
2017-02-17 13:52:55 +00:00
function load($path = "")
2016-03-26 12:27:38 +00:00
{
2017-02-17 13:52:55 +00:00
$path = empty($path) ? $this->yellow->config->get("assetDir") : $path;
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.php$/", true, false) as $entry)
{
if(defined("DEBUG") && DEBUG>=3) echo "YellowThemes::load file:$entry<br/>\n";
$this->modified = max($this->modified, filemtime($entry));
global $yellow;
require_once($entry);
}
2016-04-04 10:02:11 +00:00
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.css$/", true, false) as $entry)
2016-03-26 12:27:38 +00:00
{
2017-02-17 13:52:55 +00:00
if(defined("DEBUG") && DEBUG>=3) echo "YellowThemes::load file:$entry<br/>\n";
2016-03-26 12:27:38 +00:00
$this->modified = max($this->modified, filemtime($entry));
2017-02-17 13:52:55 +00:00
$name = $this->yellow->lookup->normaliseName(basename($entry), true, true);
$this->register($name, "", "");
}
$callback = function($a, $b)
{
return $a["priority"] - $b["priority"];
};
uasort($this->themes, $callback);
foreach($this->themes as $key=>$value)
{
$this->themes[$key]["obj"] = empty($value["theme"]) ? new stdClass : new $value["theme"];
if(method_exists($this->themes[$key]["obj"], "onLoad")) $this->themes[$key]["obj"]->onLoad($yellow);
}
}
// Register theme
function register($name, $theme, $version, $priority = 0)
{
if(!$this->isExisting($name))
{
if($priority==0) $priority = count($this->themes) + 10;
$this->themes[$name] = array();
$this->themes[$name]["theme"] = $theme;
$this->themes[$name]["version"] = $version;
$this->themes[$name]["priority"] = $priority;
2016-03-26 12:27:38 +00:00
}
}
// Return theme
function get($name)
{
return $this->theme[$name]["obj"];
}
2016-03-26 12:27:38 +00:00
// Return theme version
function getData()
{
2016-06-14 15:10:09 +00:00
$data = array();
2017-02-17 13:52:55 +00:00
foreach($this->themes as $key=>$value)
{
if(empty($value["theme"]) || empty($value["version"])) continue;
$data[$value["theme"]] = $value["version"];
}
2017-11-30 23:31:43 +00:00
uksort($data, "strnatcasecmp");
2016-06-14 15:10:09 +00:00
return $data;
2016-03-26 12:27:38 +00:00
}
// Return theme modification date, Unix time or HTTP format
function getModified($httpFormat = false)
{
return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($this->modified) : $this->modified;
}
// Check if theme exists
function isExisting($name)
{
return !is_null($this->themes[$name]);
}
}
2013-12-01 11:59:07 +00:00
class YellowConfig
2013-11-29 12:16:14 +00:00
{
var $yellow; //access to API
2015-01-24 22:45:37 +00:00
var $modified; //configuration modification date
2013-11-29 12:16:14 +00:00
var $config; //configuration
var $configDefaults; //configuration defaults
function __construct($yellow)
{
$this->yellow = $yellow;
$this->modified = 0;
2016-06-10 13:57:11 +00:00
$this->config = new YellowDataCollection();
$this->configDefaults = new YellowDataCollection();
2013-11-29 12:16:14 +00:00
}
// Load configuration from file
function load($fileName)
{
2016-02-20 17:34:06 +00:00
if(defined("DEBUG") && DEBUG>=2) echo "YellowConfig::load file:$fileName<br/>\n";
2016-08-18 19:57:07 +00:00
$this->modified = $this->yellow->toolbox->getFileModified($fileName);
2016-02-20 17:34:06 +00:00
$fileData = $this->yellow->toolbox->readFile($fileName);
foreach($this->yellow->toolbox->getTextLines($fileData) as $line)
2013-11-29 12:16:14 +00:00
{
2016-02-20 17:34:06 +00:00
if(preg_match("/^\#/", $line)) continue;
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if(!empty($matches[1]) && !strempty($matches[2]))
2013-11-29 12:16:14 +00:00
{
2016-06-10 13:57:11 +00:00
$this->set($matches[1], $matches[2]);
if(defined("DEBUG") && DEBUG>=3) echo "YellowConfig::load $matches[1]:$matches[2]<br/>\n";
2013-11-29 12:16:14 +00:00
}
}
}
2016-04-08 13:16:07 +00:00
// Update configuration in file
function update($fileName, $config)
{
2017-07-05 10:25:25 +00:00
$configNew = new YellowDataCollection();
2016-04-08 13:16:07 +00:00
foreach($config as $key=>$value)
{
2017-07-05 10:25:25 +00:00
if(!empty($key) && !strempty($value))
{
$this->set($key, $value);
$configNew[$key] = $value;
}
2016-04-08 13:16:07 +00:00
}
$this->modified = time();
$fileData = $this->yellow->toolbox->readFile($fileName);
foreach($this->yellow->toolbox->getTextLines($fileData) as $line)
{
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
2017-07-05 10:25:25 +00:00
if(!empty($matches[1]) && !is_null($configNew[$matches[1]]))
2016-04-08 13:16:07 +00:00
{
2017-07-05 10:25:25 +00:00
$fileDataNew .= "$matches[1]: ".$configNew[$matches[1]]."\n";
unset($configNew[$matches[1]]);
2016-04-08 13:16:07 +00:00
} else {
$fileDataNew .= $line;
}
}
2017-07-05 10:25:25 +00:00
foreach($configNew as $key=>$value)
2016-04-08 13:16:07 +00:00
{
$fileDataNew .= ucfirst($key).": $value\n";
2016-04-08 13:16:07 +00:00
}
return $this->yellow->toolbox->createFile($fileName, $fileDataNew);
}
2013-11-29 12:16:14 +00:00
// Set default configuration
function setDefault($key, $value)
{
$this->configDefaults[$key] = $value;
}
// Set configuration
function set($key, $value)
{
$this->config[$key] = $value;
}
// Return configuration
function get($key)
{
2014-12-21 23:53:51 +00:00
if(!is_null($this->config[$key]))
{
$value = $this->config[$key];
} else {
$value = !is_null($this->configDefaults[$key]) ? $this->configDefaults[$key] : "";
}
return $value;
2013-11-29 12:16:14 +00:00
}
// Return configuration, HTML encoded
function getHtml($key)
{
return htmlspecialchars($this->get($key));
}
// Return configuration strings
2014-08-19 21:44:22 +00:00
function getData($filterStart = "", $filterEnd = "")
2013-11-29 12:16:14 +00:00
{
$config = array();
2014-08-19 21:44:22 +00:00
if(empty($filterStart) && empty($filterEnd))
2013-11-29 12:16:14 +00:00
{
2016-06-10 13:57:11 +00:00
$config = array_merge($this->configDefaults->getArrayCopy(), $this->config->getArrayCopy());
2013-11-29 12:16:14 +00:00
} else {
2016-06-10 13:57:11 +00:00
foreach(array_merge($this->configDefaults->getArrayCopy(), $this->config->getArrayCopy()) as $key=>$value)
2013-11-29 12:16:14 +00:00
{
2014-08-19 21:44:22 +00:00
if(!empty($filterStart) && substru($key, 0, strlenu($filterStart))==$filterStart) $config[$key] = $value;
if(!empty($filterEnd) && substru($key, -strlenu($filterEnd))==$filterEnd) $config[$key] = $value;
2013-11-29 12:16:14 +00:00
}
}
return $config;
}
2015-01-24 22:45:37 +00:00
// Return configuration modification date, Unix time or HTTP format
2013-11-29 12:16:14 +00:00
function getModified($httpFormat = false)
{
2015-01-24 22:45:37 +00:00
return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($this->modified) : $this->modified;
2013-11-29 12:16:14 +00:00
}
// Check if configuration exists
function isExisting($key)
{
return !is_null($this->config[$key]);
}
}
2013-12-01 11:59:07 +00:00
class YellowText
2013-11-29 12:16:14 +00:00
{
var $yellow; //access to API
2015-01-24 22:45:37 +00:00
var $modified; //text modification date
2017-07-26 11:23:38 +00:00
var $text; //text
2013-11-29 12:16:14 +00:00
var $language; //current language
function __construct($yellow)
{
$this->yellow = $yellow;
$this->modified = 0;
2016-06-10 13:57:11 +00:00
$this->text = new YellowDataCollection();
2013-11-29 12:16:14 +00:00
}
// Load text strings from file
2017-07-26 11:23:38 +00:00
function load($fileName, $languageDefault)
2013-11-29 12:16:14 +00:00
{
$path = dirname($fileName);
2014-06-27 09:36:30 +00:00
$regex = "/^".basename($fileName)."$/";
2013-11-29 12:16:14 +00:00
foreach($this->yellow->toolbox->getDirectoryEntries($path, $regex, true, false) as $entry)
{
2016-02-20 17:34:06 +00:00
if(defined("DEBUG") && DEBUG>=2) echo "YellowText::load file:$entry<br/>\n";
2017-07-26 11:23:38 +00:00
$language = $languageDefault;
2016-02-20 17:34:06 +00:00
$this->modified = max($this->modified, filemtime($entry));
$fileData = $this->yellow->toolbox->readFile($entry);
foreach($this->yellow->toolbox->getTextLines($fileData) as $line)
2013-11-29 12:16:14 +00:00
{
2016-02-20 17:34:06 +00:00
if(preg_match("/^\#/", $line)) continue;
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
2016-07-10 18:44:02 +00:00
if(lcfirst($matches[1])=="language" && !strempty($matches[2])) $language = $matches[2];
2016-02-20 17:34:06 +00:00
if(!empty($language) && !empty($matches[1]) && !strempty($matches[2]))
2013-11-29 12:16:14 +00:00
{
2016-06-10 13:57:11 +00:00
$this->setText($matches[1], $matches[2], $language);
if(defined("DEBUG") && DEBUG>=3) echo "YellowText::load $matches[1]:$matches[2]<br/>\n";
2013-11-29 12:16:14 +00:00
}
}
}
}
// Set current language
function setLanguage($language)
{
$this->language = $language;
}
// Set text string for specific language
2013-12-11 14:13:38 +00:00
function setText($key, $value, $language)
2013-11-29 12:16:14 +00:00
{
2016-06-10 13:57:11 +00:00
if(is_null($this->text[$language])) $this->text[$language] = new YellowDataCollection();
2013-11-29 12:16:14 +00:00
$this->text[$language][$key] = $value;
}
// Return text string
function get($key)
{
2015-01-09 13:23:41 +00:00
return $this->getText($key, $this->language);
2013-11-29 12:16:14 +00:00
}
// Return text string, HTML encoded
function getHtml($key)
{
2015-01-09 13:23:41 +00:00
return htmlspecialchars($this->getText($key, $this->language));
2013-11-29 12:16:14 +00:00
}
2016-09-01 19:28:03 +00:00
// Return text string for specific language
function getText($key, $language)
{
return $this->isExisting($key, $language) ? $this->text[$language][$key] : "[$key]";
}
// Return text string for specific language, HTML encoded
function getTextHtml($key, $language)
{
return htmlspecialchars($this->getText($key, $language));
}
2013-12-11 14:13:38 +00:00
// Return text strings
function getData($filterStart = "", $language = "")
2013-11-29 12:16:14 +00:00
{
$text = array();
2013-12-11 14:13:38 +00:00
if(empty($language)) $language = $this->language;
2015-01-09 13:23:41 +00:00
if($this->isLanguage($language))
2013-11-29 12:16:14 +00:00
{
if(empty($filterStart))
{
$text = $this->text[$language];
} else {
foreach($this->text[$language] as $key=>$value)
{
2016-07-19 22:12:05 +00:00
if(substru($key, 0, strlenu($filterStart))==$filterStart) $text[$key] = $value;
2013-11-29 12:16:14 +00:00
}
}
}
return $text;
}
// Return human readable date, custom date
2015-02-04 21:58:41 +00:00
function getDateFormatted($timestamp, $format)
{
2017-02-22 20:05:46 +00:00
$dateMonths = preg_split("/\s*,\s*/", $this->get("dateMonths"));
$dateWeekdays = preg_split("/\s*,\s*/", $this->get("dateWeekdays"));
2015-02-04 21:58:41 +00:00
$month = $dateMonths[date('n', $timestamp) - 1];
$weekday = $dateWeekdays[date('N', $timestamp) - 1];
2017-07-26 11:23:38 +00:00
$timeZone = $this->yellow->config->get("timezone");
$timeZoneHelper = new DateTime(null, new DateTimeZone($timeZone));
$timeZoneOffset = $timeZoneHelper->getOffset();
$timeZoneAbbreviation = "GMT".($timeZoneOffset<0 ? "-" : "+").abs(intval($timeZoneOffset/3600));
2015-02-04 21:58:41 +00:00
$format = preg_replace("/(?<!\\\)F/", addcslashes($month, 'A..Za..z'), $format);
$format = preg_replace("/(?<!\\\)M/", addcslashes(substru($month, 0, 3), 'A..Za..z'), $format);
$format = preg_replace("/(?<!\\\)D/", addcslashes(substru($weekday, 0, 3), 'A..Za..z'), $format);
$format = preg_replace("/(?<!\\\)l/", addcslashes($weekday, 'A..Za..z'), $format);
2017-07-26 11:23:38 +00:00
$format = preg_replace("/(?<!\\\)T/", addcslashes($timeZoneAbbreviation, 'A..Za..z'), $format);
2015-02-04 21:58:41 +00:00
return date($format, $timestamp);
}
2016-02-20 17:34:06 +00:00
// Return languages
function getLanguages()
{
$languages = array();
foreach($this->text as $key=>$value) array_push($languages, $key);
return $languages;
}
2015-01-24 22:45:37 +00:00
// Return text modification date, Unix time or HTTP format
2013-11-29 12:16:14 +00:00
function getModified($httpFormat = false)
{
2015-01-24 22:45:37 +00:00
return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($this->modified) : $this->modified;
2013-11-29 12:16:14 +00:00
}
2015-01-09 13:23:41 +00:00
2015-02-04 21:58:41 +00:00
// Normalise date into known format
function normaliseDate($text)
{
if(preg_match("/^\d+\-\d+$/", $text))
{
$output = $this->getDateFormatted(strtotime($text), $this->get("dateFormatShort"));
} else if(preg_match("/^\d+\-\d+\-\d+$/", $text)) {
$output = $this->getDateFormatted(strtotime($text), $this->get("dateFormatMedium"));
} else if(preg_match("/^\d+\-\d+\-\d+ \d+\:\d+$/", $text)) {
$output = $this->getDateFormatted(strtotime($text), $this->get("dateFormatLong"));
} else {
$output = $text;
}
return $output;
}
2015-01-09 13:23:41 +00:00
// Check if language exists
function isLanguage($language)
2013-11-29 12:16:14 +00:00
{
2015-01-09 13:23:41 +00:00
return !is_null($this->text[$language]);
2013-11-29 12:16:14 +00:00
}
// Check if text string exists
2015-01-09 13:23:41 +00:00
function isExisting($key, $language = "")
2013-11-29 12:16:14 +00:00
{
2015-01-09 13:23:41 +00:00
if(empty($language)) $language = $this->language;
return !is_null($this->text[$language]) && !is_null($this->text[$language][$key]);
2013-11-29 12:16:14 +00:00
}
}
2015-01-07 17:02:58 +00:00
2015-04-29 07:26:48 +00:00
class YellowLookup
{
var $yellow; //access to API
2017-02-17 13:52:55 +00:00
var $requestHandler; //request handler name
var $commandHandler; //command handler name
var $snippetArgs; //snippet arguments
2015-04-29 07:26:48 +00:00
function __construct($yellow)
2015-01-07 17:02:58 +00:00
{
2015-04-29 07:26:48 +00:00
$this->yellow = $yellow;
2015-01-07 17:02:58 +00:00
}
2016-04-04 10:02:11 +00:00
// Load file system information
function load()
{
2016-06-30 15:51:56 +00:00
list($pathRoot, $pathHome) = $this->detectFileSystem();
2016-04-04 10:02:11 +00:00
$this->yellow->config->set("contentRootDir", $pathRoot);
$this->yellow->config->set("contentHomeDir", $pathHome);
2017-02-17 13:52:55 +00:00
date_default_timezone_set($this->yellow->config->get("timezone"));
2016-04-04 10:02:11 +00:00
}
2015-01-07 17:02:58 +00:00
2016-06-30 15:51:56 +00:00
// Detect file system
function detectFileSystem()
{
$path = $this->yellow->config->get("contentDir");
$pathRoot = $this->yellow->config->get("contentRootDir");
$pathHome = $this->yellow->config->get("contentHomeDir");
if(!$this->yellow->config->get("multiLanguageMode")) $pathRoot = "";
if(!empty($pathRoot))
{
$token = $root = rtrim($pathRoot, '/');
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/.*/", true, true, false) as $entry)
{
if(empty($firstRoot)) { $firstRoot = $token = $entry; }
if($this->normaliseToken($entry)==$root) { $token = $entry; break; }
2016-06-30 15:51:56 +00:00
}
$pathRoot = $this->normaliseToken($token)."/";
2016-06-30 15:51:56 +00:00
$path .= "$firstRoot/";
}
if(!empty($pathHome))
{
$token = $home = rtrim($pathHome, '/');
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/.*/", true, true, false) as $entry)
{
if(empty($firstHome)) { $firstHome = $token = $entry; }
if($this->normaliseToken($entry)==$home) { $token = $entry; break; }
2016-06-30 15:51:56 +00:00
}
$pathHome = $this->normaliseToken($token)."/";
2016-06-30 15:51:56 +00:00
}
2017-01-03 13:11:44 +00:00
return array($pathRoot, $pathHome);
2016-06-30 15:51:56 +00:00
}
2015-04-29 07:26:48 +00:00
// Return root locations
function findRootLocations($includePath = true)
2015-01-07 17:02:58 +00:00
{
2015-04-29 07:26:48 +00:00
$locations = array();
$pathBase = $this->yellow->config->get("contentDir");
$pathRoot = $this->yellow->config->get("contentRootDir");
if(!empty($pathRoot))
2015-01-07 17:02:58 +00:00
{
2015-04-29 07:26:48 +00:00
foreach($this->yellow->toolbox->getDirectoryEntries($pathBase, "/.*/", true, true, false) as $entry)
{
$token = $this->normaliseToken($entry)."/";
2016-07-19 22:12:05 +00:00
if($token==$pathRoot) $token = "";
2015-04-29 07:26:48 +00:00
array_push($locations, $includePath ? "root/$token $pathBase$entry/" : "root/$token");
if(defined("DEBUG") && DEBUG>=2) echo "YellowLookup::findRootLocations root/$token<br/>\n";
}
} else {
array_push($locations, $includePath ? "root/ $pathBase" : "root/");
2015-01-07 17:02:58 +00:00
}
2015-04-29 07:26:48 +00:00
return $locations;
2015-01-07 17:02:58 +00:00
}
2015-04-29 07:26:48 +00:00
// Return location from file path
function findLocationFromFile($fileName)
2015-01-07 17:02:58 +00:00
{
2015-04-29 07:26:48 +00:00
$location = "/";
$pathBase = $this->yellow->config->get("contentDir");
$pathRoot = $this->yellow->config->get("contentRootDir");
$pathHome = $this->yellow->config->get("contentHomeDir");
$fileDefault = $this->yellow->config->get("contentDefaultFile");
$fileExtension = $this->yellow->config->get("contentExtension");
2016-07-19 22:12:05 +00:00
if(substru($fileName, 0, strlenu($pathBase))==$pathBase)
2015-01-07 17:02:58 +00:00
{
2015-04-29 07:26:48 +00:00
$fileName = substru($fileName, strlenu($pathBase));
$tokens = explode('/', $fileName);
if(!empty($pathRoot))
{
$token = $this->normaliseToken($tokens[0]).'/';
2015-04-29 07:26:48 +00:00
if($token!=$pathRoot) $location .= $token;
array_shift($tokens);
}
for($i=0; $i<count($tokens)-1; ++$i)
{
$token = $this->normaliseToken($tokens[$i]).'/';
2015-04-29 07:26:48 +00:00
if($i || $token!=$pathHome) $location .= $token;
}
$token = $this->normaliseToken($tokens[$i], $fileExtension);
$fileFolder = $this->normaliseToken($tokens[$i-1], $fileExtension);
if($token!=$fileDefault && $token!=$fileFolder) $location .= $this->normaliseToken($tokens[$i], $fileExtension, true);
2015-04-29 07:26:48 +00:00
$extension = ($pos = strrposu($fileName, '.')) ? substru($fileName, $pos) : "";
2016-07-19 22:12:05 +00:00
if($extension!=$fileExtension) $invalid = true;
2015-04-29 07:26:48 +00:00
} else {
$invalid = true;
2015-01-07 17:02:58 +00:00
}
2015-04-29 07:26:48 +00:00
if(defined("DEBUG") && DEBUG>=2)
2014-05-15 11:53:54 +00:00
{
2015-04-29 07:26:48 +00:00
$debug = ($invalid ? "INVALID" : $location)." <- $pathBase$fileName";
echo "YellowLookup::findLocationFromFile $debug<br/>\n";
2014-05-15 11:53:54 +00:00
}
2015-04-29 07:26:48 +00:00
return $invalid ? "" : $location;
2013-06-07 20:01:12 +00:00
}
2015-04-29 07:26:48 +00:00
// Return file path from location
function findFileFromLocation($location, $directory = false)
2013-06-07 20:01:12 +00:00
{
2015-07-08 09:21:07 +00:00
$path = $this->yellow->config->get("contentDir");
2015-04-29 07:26:48 +00:00
$pathRoot = $this->yellow->config->get("contentRootDir");
$pathHome = $this->yellow->config->get("contentHomeDir");
$fileDefault = $this->yellow->config->get("contentDefaultFile");
$fileExtension = $this->yellow->config->get("contentExtension");
$tokens = explode('/', $location);
if($this->isRootLocation($location))
2013-12-21 13:10:15 +00:00
{
2015-04-29 07:26:48 +00:00
if(!empty($pathRoot))
2013-12-21 13:10:15 +00:00
{
2016-07-19 22:12:05 +00:00
$token = (count($tokens)>2) ? $tokens[1] : rtrim($pathRoot, '/');
$path .= $this->findFileDirectory($path, $token, "", true, true, $found, $invalid);
2015-04-29 07:26:48 +00:00
}
} else {
if(!empty($pathRoot))
{
2016-07-19 22:12:05 +00:00
if(count($tokens)>2)
2013-12-21 13:10:15 +00:00
{
if($this->normaliseToken($tokens[1])==$this->normaliseToken(rtrim($pathRoot, '/'))) $invalid = true;
$path .= $this->findFileDirectory($path, $tokens[1], "", true, false, $found, $invalid);
2015-04-29 07:26:48 +00:00
if($found) array_shift($tokens);
2013-12-21 13:10:15 +00:00
}
if(!$found) $path .= $this->findFileDirectory($path, rtrim($pathRoot, '/'), "", true, true, $found, $invalid);
2015-04-29 07:26:48 +00:00
2013-12-21 13:10:15 +00:00
}
2016-07-19 22:12:05 +00:00
if(count($tokens)>2)
2013-12-21 13:10:15 +00:00
{
if($this->normaliseToken($tokens[1])==$this->normaliseToken(rtrim($pathHome, '/'))) $invalid = true;
2015-04-29 07:26:48 +00:00
for($i=1; $i<count($tokens)-1; ++$i)
2013-12-21 13:10:15 +00:00
{
$path .= $this->findFileDirectory($path, $tokens[$i], "", true, true, $found, $invalid);
2013-12-21 13:10:15 +00:00
}
2015-04-29 07:26:48 +00:00
} else {
$i = 1;
$tokens[0] = rtrim($pathHome, '/');
$path .= $this->findFileDirectory($path, $tokens[0], "", true, true, $found, $invalid);
2013-12-21 13:10:15 +00:00
}
2015-04-29 07:26:48 +00:00
if(!$directory)
2013-05-01 20:16:05 +00:00
{
if(!strempty($tokens[$i]))
2013-05-01 20:16:05 +00:00
{
2015-04-29 07:26:48 +00:00
$token = $tokens[$i].$fileExtension;
2015-10-21 12:28:56 +00:00
$fileFolder = $tokens[$i-1].$fileExtension;
2015-04-29 07:26:48 +00:00
if($token==$fileDefault || $token==$fileFolder) $invalid = true;
$path .= $this->findFileDirectory($path, $token, $fileExtension, false, true, $found, $invalid);
2015-04-29 07:26:48 +00:00
} else {
2015-10-21 12:28:56 +00:00
$path .= $this->findFileDefault($path, $fileDefault, $fileExtension, false);
2015-04-29 07:26:48 +00:00
}
if(defined("DEBUG") && DEBUG>=2)
{
$debug = "$location -> ".($invalid ? "INVALID" : $path);
echo "YellowLookup::findFileFromLocation $debug<br/>\n";
2013-05-01 20:16:05 +00:00
}
}
}
2015-04-29 07:26:48 +00:00
return $invalid ? "" : $path;
2013-10-16 21:11:24 +00:00
}
2015-04-29 07:26:48 +00:00
// Return file or directory that matches token
function findFileDirectory($path, $token, $fileExtension, $directory, $default, &$found, &$invalid)
2013-10-16 21:11:24 +00:00
{
if($this->normaliseToken($token, $fileExtension)!=$token) $invalid = true;
2015-04-29 07:26:48 +00:00
if(!$invalid)
2013-05-01 20:16:05 +00:00
{
2015-04-29 07:26:48 +00:00
$regex = "/^[\d\-\_\.]*".strreplaceu('-', '.', $token)."$/";
foreach($this->yellow->toolbox->getDirectoryEntries($path, $regex, false, $directory, false) as $entry)
2013-10-16 21:11:24 +00:00
{
if($this->normaliseToken($entry, $fileExtension)==$token) { $token = $entry; $found = true; break; }
2013-10-16 21:11:24 +00:00
}
2013-05-01 20:16:05 +00:00
}
2015-04-29 07:26:48 +00:00
if($directory) $token .= '/';
return ($default || $found) ? $token : "";
2014-05-15 11:53:54 +00:00
}
2015-04-29 07:26:48 +00:00
// Return default file in directory
2015-10-21 12:28:56 +00:00
function findFileDefault($path, $fileDefault, $fileExtension, $includePath = true)
2014-01-27 11:30:39 +00:00
{
2015-04-29 07:26:48 +00:00
$token = $fileDefault;
if(!is_file($path."/".$fileDefault))
{
$fileFolder = $this->normaliseToken(basename($path), $fileExtension);
2015-04-29 07:26:48 +00:00
$regex = "/^[\d\-\_\.]*($fileDefault|$fileFolder)$/";
foreach($this->yellow->toolbox->getDirectoryEntries($path, $regex, true, false, false) as $entry)
{
if($this->normaliseToken($entry, $fileExtension)==$fileDefault) { $token = $entry; break; }
if($this->normaliseToken($entry, $fileExtension)==$fileFolder) { $token = $entry; break; }
2015-04-29 07:26:48 +00:00
}
}
2015-10-21 12:28:56 +00:00
return $includePath ? "$path/$token" : $token;
2014-01-27 11:30:39 +00:00
}
// Return new file
function findFileNew($location, $filePrefix = "")
{
$fileName = $this->findFileFromLocation($location);
if(!empty($filePrefix) && !empty($fileName))
{
preg_match("/^([\d\-\_\.]*)(.*)$/", $filePrefix, $matches);
$filePrefix = empty($matches[1]) ? "" : $matches[1].'-';
$fileText = $this->normaliseName(basename($fileName), true, true);
if(preg_match("/^[\d\-\_\.]*$/", $fileText) && !empty($filePrefix)) $filePrefix = "";
$fileName = dirname($fileName)."/".$filePrefix.$fileText.$this->yellow->config->get("contentExtension");
}
if(!is_dir(dirname($fileName)))
{
$tokens = explode('/', $fileName);
for($i=0; $i<count($tokens)-1; ++$i)
{
if(!is_dir($path.$tokens[$i]))
{
if(!preg_match("/^[\d\-\_\.]+(.*)$/", $tokens[$i]))
{
$number = 1;
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/^[\d\-\_\.]+(.*)$/", true, true, false) as $entry)
{
if($number!=1 && $number!=intval($entry)) break;
$number = intval($entry)+1;
}
$tokens[$i] = "$number-".$tokens[$i];
}
$tokens[$i] = $this->normaliseName($tokens[$i], false, false, true);
}
$path .= $tokens[$i]."/";
}
$fileName = $path.$tokens[$i];
}
return $fileName;
}
// Return static file if possible
function findFileStatic($location, $fileName, $cacheable)
{
if($cacheable)
{
$location .= $this->yellow->toolbox->getLocationArgs();
$fileNameStatic = rtrim($this->yellow->config->get("staticDir"), '/').$location;
if(!$this->isFileLocation($location)) $fileNameStatic .= $this->yellow->config->get("staticDefaultFile");
if(is_readable($fileNameStatic)) $fileName = $fileNameStatic;
}
return $fileName;
}
2015-04-29 07:26:48 +00:00
// Return children from location
function findChildrenFromLocation($location)
{
2015-04-29 07:26:48 +00:00
$fileNames = array();
$fileDefault = $this->yellow->config->get("contentDefaultFile");
$fileExtension = $this->yellow->config->get("contentExtension");
if(!$this->isFileLocation($location))
{
$path = $this->findFileFromLocation($location, true);
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/.*/", true, true, false) as $entry)
{
2015-10-21 12:28:56 +00:00
$token = $this->findFileDefault($path.$entry, $fileDefault, $fileExtension, false);
2015-04-29 07:26:48 +00:00
array_push($fileNames, $path.$entry."/".$token);
}
if(!$this->isRootLocation($location))
{
$fileFolder = $this->normaliseToken(basename($path), $fileExtension);
2015-04-29 07:26:48 +00:00
$regex = "/^.*\\".$fileExtension."$/";
foreach($this->yellow->toolbox->getDirectoryEntries($path, $regex, true, false, false) as $entry)
{
if($this->normaliseToken($entry, $fileExtension)==$fileDefault) continue;
if($this->normaliseToken($entry, $fileExtension)==$fileFolder) continue;
2015-04-29 07:26:48 +00:00
array_push($fileNames, $path.$entry);
}
}
}
return $fileNames;
}
2013-12-21 13:10:15 +00:00
2015-04-29 07:26:48 +00:00
// Return language from file path
function findLanguageFromFile($fileName, $languageDefault)
{
2015-04-29 07:26:48 +00:00
$language = $languageDefault;
$pathBase = $this->yellow->config->get("contentDir");
$pathRoot = $this->yellow->config->get("contentRootDir");
if(!empty($pathRoot))
{
$fileName = substru($fileName, strlenu($pathBase));
if(preg_match("/^(.+?)\//", $fileName, $matches)) $name = $this->normaliseToken($matches[1]);
2016-07-19 22:12:05 +00:00
if(strlenu($name)==2) $language = $name;
2015-04-29 07:26:48 +00:00
}
return $language;
}
// Return file path from media location
2017-02-17 13:52:55 +00:00
function findFileFromMedia($location)
{
if($this->isFileLocation($location))
{
$mediaLocationLength = strlenu($this->yellow->config->get("mediaLocation"));
if(substru($location, 0, $mediaLocationLength)==$this->yellow->config->get("mediaLocation"))
{
$fileName = $this->yellow->config->get("mediaDir").substru($location, 7);
}
}
return $fileName;
}
// Return file path from system location
2017-02-17 13:52:55 +00:00
function findFileFromSystem($location)
{
2017-06-26 13:19:49 +00:00
if(preg_match("/\.(css|gif|ico|js|jpg|png|svg|txt|woff|woff2)$/", $location))
2017-02-17 13:52:55 +00:00
{
$pluginLocationLength = strlenu($this->yellow->config->get("pluginLocation"));
$themeLocationLength = strlenu($this->yellow->config->get("themeLocation"));
if(substru($location, 0, $pluginLocationLength)==$this->yellow->config->get("pluginLocation")) {
$fileName = $this->yellow->config->get("pluginDir").substru($location, $pluginLocationLength);
} else if(substru($location, 0, $themeLocationLength)==$this->yellow->config->get("themeLocation")) {
$fileName = $this->yellow->config->get("themeDir").substru($location, $themeLocationLength);
} else if($location=="/".$this->yellow->config->get("robotsFile")) {
$fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("robotsFile");
} else if($location=="/".$this->yellow->config->get("faviconFile")) {
$fileName = $this->yellow->config->get("assetDir").$this->yellow->config->get("siteicon").".png";
}
}
return $fileName;
}
// Normalise file/directory token
function normaliseToken($text, $fileExtension = "", $removeExtension = false)
2017-02-17 13:52:55 +00:00
{
if(!empty($fileExtension)) $text = ($pos = strrposu($text, '.')) ? substru($text, 0, $pos) : $text;
if(preg_match("/^[\d\-\_\.]+(.*)$/", $text, $matches) && !empty($matches[1])) $text = $matches[1];
return preg_replace("/[^\pL\d\-\_]/u", "-", $text).($removeExtension ? "" : $fileExtension);
2017-02-17 13:52:55 +00:00
}
// Normalise name
function normaliseName($text, $removePrefix = false, $removeExtension = false, $filterStrict = false)
2013-04-14 22:41:04 +00:00
{
2015-04-29 07:26:48 +00:00
if($removeExtension) $text = ($pos = strrposu($text, '.')) ? substru($text, 0, $pos) : $text;
if($removePrefix && preg_match("/^[\d\-\_\.]+(.*)$/", $text, $matches) && !empty($matches[1])) $text = $matches[1];
if($filterStrict) $text = strtoloweru($text);
return preg_replace("/[^\pL\d\-\_]/u", "-", $text);
2013-07-11 20:33:28 +00:00
}
2017-02-17 13:52:55 +00:00
// Normalise array, make keys with same upper/lower case
function normaliseUpperLower($input)
{
$array = array();
foreach($input as $key=>$value)
{
if(empty($key) || strempty($value)) continue;
$keySearch = strtoloweru($key);
foreach($array as $keyNew=>$valueNew) if(strtoloweru($keyNew)==$keySearch) { $key = $keyNew; break; }
$array[$key] += $value;
}
return $array;
}
2015-04-29 07:26:48 +00:00
// Normalise location, make absolute location
2017-02-17 13:52:55 +00:00
function normaliseLocation($location, $pageLocation, $filterStrict = true)
2013-04-14 22:41:04 +00:00
{
2015-04-29 07:26:48 +00:00
if(!preg_match("/^\w+:/", trim(html_entity_decode($location, ENT_QUOTES, "UTF-8"))))
2013-04-14 22:41:04 +00:00
{
2017-02-17 13:52:55 +00:00
$pageBase = $this->yellow->page->base;
$mediaBase = $this->yellow->config->get("serverBase").$this->yellow->config->get("mediaLocation");
if(preg_match("/^\#/", $location))
2015-04-29 07:26:48 +00:00
{
2017-02-17 13:52:55 +00:00
$location = $pageBase.$pageLocation.$location;
} else if(!preg_match("/^\//", $location)) {
$location = $this->getDirectoryLocation($pageBase.$pageLocation).$location;
} else if(!preg_match("#^($pageBase|$mediaBase)#", $location)) {
$location = $pageBase.$location;
2015-04-29 07:26:48 +00:00
}
2018-02-26 09:33:42 +00:00
$location = strreplaceu("/./", "/", $location);
2017-02-17 13:52:55 +00:00
$location = strreplaceu(':', $this->yellow->toolbox->getLocationArgsSeparator(), $location);
2013-04-14 22:41:04 +00:00
} else {
2015-04-29 07:26:48 +00:00
if($filterStrict && !preg_match("/^(http|https|ftp|mailto):/", $location)) $location = "error-xss-filter";
2013-04-14 22:41:04 +00:00
}
2015-04-29 07:26:48 +00:00
return $location;
2013-04-14 22:41:04 +00:00
}
2015-04-29 07:26:48 +00:00
// Normalise URL, make absolute URL
2017-02-17 13:52:55 +00:00
function normaliseUrl($scheme, $address, $base, $location, $filterStrict = true)
2013-04-14 22:41:04 +00:00
{
2015-04-29 07:26:48 +00:00
if(!preg_match("/^\w+:/", $location))
2013-04-14 22:41:04 +00:00
{
2017-02-17 13:52:55 +00:00
$url = "$scheme://$address$base$location";
2014-09-02 11:14:34 +00:00
} else {
2017-02-17 13:52:55 +00:00
if($filterStrict && !preg_match("/^(http|https|ftp|mailto):/", $location)) $location = "error-xss-filter";
2015-04-29 07:26:48 +00:00
$url = $location;
2013-04-14 22:41:04 +00:00
}
2015-04-29 07:26:48 +00:00
return $url;
2013-04-14 22:41:04 +00:00
}
2017-02-17 13:52:55 +00:00
// Return URL information
function getUrlInformation($url)
{
if(preg_match("#^(\w+)://([^/]+)(.*)$#", rtrim($url, '/'), $matches))
{
$scheme = $matches[1];
$address = $matches[2];
$base = $matches[3];
}
return array($scheme, $address, $base);
}
2015-04-29 07:26:48 +00:00
// Return directory location
function getDirectoryLocation($location)
{
return ($pos = strrposu($location, '/')) ? substru($location, 0, $pos+1) : "/";
}
2015-04-29 07:26:48 +00:00
// Check if location is specifying root
function isRootLocation($location)
{
2016-07-19 22:12:05 +00:00
return $location[0]!="/";
}
2015-04-29 07:26:48 +00:00
// Check if location is specifying file or directory
function isFileLocation($location)
{
2016-07-19 22:12:05 +00:00
return substru($location, -1, 1)!="/";
}
2017-01-03 13:11:44 +00:00
// Check if location can be redirected into directory
function isRedirectLocation($location)
{
$redirect = false;
if($this->isFileLocation($location))
{
$redirect = is_dir($this->findFileFromLocation("$location/", true));
} else if($location=="/") {
$redirect = $this->yellow->config->get("multiLanguageMode");
}
return $redirect;
}
// Check if location contains nested directories
2017-02-17 13:52:55 +00:00
function isNestedLocation($location, $fileName, $checkHomeLocation = false)
2017-01-03 13:11:44 +00:00
{
$nested = false;
if(!$checkHomeLocation || $location==$this->yellow->pages->getHomeLocation($location))
{
2017-02-17 13:52:55 +00:00
$path = dirname($fileName);
2017-01-03 13:11:44 +00:00
if(count($this->yellow->toolbox->getDirectoryEntries($path, "/.*/", true, true, false))) $nested = true;
}
return $nested;
}
2015-04-29 07:26:48 +00:00
// Check if location is visible
function isVisibleLocation($location, $fileName)
{
2015-04-29 07:26:48 +00:00
$visible = true;
$pathBase = $this->yellow->config->get("contentDir");
2016-07-19 22:12:05 +00:00
if(substru($fileName, 0, strlenu($pathBase))==$pathBase)
{
2014-09-02 11:14:34 +00:00
$fileName = substru($fileName, strlenu($pathBase));
$tokens = explode('/', $fileName);
for($i=0; $i<count($tokens)-1; ++$i)
{
2015-04-29 07:26:48 +00:00
if(!preg_match("/^[\d\-\_\.]+(.*)$/", $tokens[$i])) { $visible = false; break; }
2014-09-02 11:14:34 +00:00
}
} else {
2015-04-29 07:26:48 +00:00
$visible = false;
}
2015-04-29 07:26:48 +00:00
return $visible;
}
// Check if location is within current request
function isActiveLocation($location, $currentLocation)
{
2015-06-02 22:29:00 +00:00
if($this->isFileLocation($location))
{
2015-06-02 22:29:00 +00:00
$active = $currentLocation==$location;
2015-04-29 07:26:48 +00:00
} else {
2016-07-19 22:12:05 +00:00
if($location==$this->yellow->pages->getHomeLocation($location))
2015-06-02 22:29:00 +00:00
{
$active = $this->getDirectoryLocation($currentLocation)==$location;
} else {
$active = substru($currentLocation, 0, strlenu($location))==$location;
}
}
2015-04-29 07:26:48 +00:00
return $active;
}
2016-07-10 18:44:02 +00:00
// Check if file is valid
function isValidFile($fileName)
{
$contentDirLength = strlenu($this->yellow->config->get("contentDir"));
$mediaDirLength = strlenu($this->yellow->config->get("mediaDir"));
$systemDirLength = strlenu($this->yellow->config->get("systemDir"));
2016-07-19 22:12:05 +00:00
return substru($fileName, 0, $contentDirLength)==$this->yellow->config->get("contentDir") ||
substru($fileName, 0, $mediaDirLength)==$this->yellow->config->get("mediaDir") ||
substru($fileName, 0, $systemDirLength)==$this->yellow->config->get("systemDir");
2016-07-10 18:44:02 +00:00
}
2017-01-03 13:11:44 +00:00
// Check if content file
function isContentFile($fileName)
{
$contentDirLength = strlenu($this->yellow->config->get("contentDir"));
return substru($fileName, 0, $contentDirLength)==$this->yellow->config->get("contentDir");
}
// Check if media file
function isMediaFile($fileName)
{
$mediaDirLength = strlenu($this->yellow->config->get("mediaDir"));
return substru($fileName, 0, $mediaDirLength)==$this->yellow->config->get("mediaDir");
}
// Check if system file
function isSystemFile($fileName)
{
$systemDirLength = strlenu($this->yellow->config->get("systemDir"));
return substru($fileName, 0, $systemDirLength)==$this->yellow->config->get("systemDir");
}
2015-04-29 07:26:48 +00:00
}
class YellowToolbox
{
2017-02-17 13:52:55 +00:00
// Return server version from current HTTP request
2017-12-13 12:51:28 +00:00
function getServerVersion($shortFormat = false)
2015-08-01 17:28:20 +00:00
{
2017-02-17 13:52:55 +00:00
$serverVersion = strtoupperu(PHP_SAPI)." ".PHP_OS;
if(preg_match("/^(\S+)/", $_SERVER["SERVER_SOFTWARE"], $matches)) $serverVersion = $matches[1]." ".PHP_OS;
2017-12-13 12:51:28 +00:00
if($shortFormat && preg_match("/^(\pL+)/u", $serverVersion, $matches)) $serverVersion = $matches[1];
2017-02-17 13:52:55 +00:00
return $serverVersion;
2015-08-01 17:28:20 +00:00
}
2017-01-03 13:11:44 +00:00
// Return server URL from current HTTP request
function getServerUrl()
{
2017-02-17 13:52:55 +00:00
$scheme = $this->getScheme();
$address = $this->getAddress();
$base = $this->getBase();
return "$scheme://$address$base/";
2017-01-03 13:11:44 +00:00
}
2017-02-17 13:52:55 +00:00
// Return scheme from current HTTP request
function getScheme()
2015-04-29 07:26:48 +00:00
{
2017-02-17 13:52:55 +00:00
$scheme = "";
2015-04-29 07:26:48 +00:00
if(preg_match("/^HTTP\//", $_SERVER["SERVER_PROTOCOL"]))
2013-04-14 22:41:04 +00:00
{
2015-04-29 07:26:48 +00:00
$secure = isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"]!="off";
2017-02-17 13:52:55 +00:00
$scheme = $secure ? "https" : "http";
2015-04-29 07:26:48 +00:00
}
2017-02-17 13:52:55 +00:00
return $scheme;
2015-04-29 07:26:48 +00:00
}
2017-02-17 13:52:55 +00:00
// Return address from current HTTP request
function getAddress()
2015-04-29 07:26:48 +00:00
{
2017-02-17 13:52:55 +00:00
$address = $_SERVER["SERVER_NAME"];
$port = $_SERVER["SERVER_PORT"];
if($port!=80 && $port!=443) $address .= ":$port";
return $address;
2015-04-29 07:26:48 +00:00
}
2017-02-17 13:52:55 +00:00
// Return base from current HTTP request
function getBase()
2015-04-29 07:26:48 +00:00
{
2017-02-17 13:52:55 +00:00
$base = "";
if(preg_match("/^(.*)\/.*\.php$/", $_SERVER["SCRIPT_NAME"], $matches)) $base = $matches[1];
2017-02-17 13:52:55 +00:00
return $base;
2015-04-29 07:26:48 +00:00
}
// Return location from current HTTP request
2016-02-20 17:34:06 +00:00
function getLocation($filterStrict = true)
2015-04-29 07:26:48 +00:00
{
2016-02-20 17:34:06 +00:00
$location = $_SERVER["REQUEST_URI"];
$location = rawurldecode(($pos = strposu($location, '?')) ? substru($location, 0, $pos) : $location);
if($filterStrict)
2015-04-29 07:26:48 +00:00
{
2016-07-10 18:44:02 +00:00
$location = $this->normaliseTokens($location, true);
2016-02-20 17:34:06 +00:00
$separator = $this->getLocationArgsSeparator();
if(preg_match("/^(.*?\/)([^\/]+$separator.*)$/", $location, $matches))
{
2016-02-20 17:34:06 +00:00
$_SERVER["LOCATION"] = $location = $matches[1];
$_SERVER["LOCATION_ARGS"] = $matches[2];
foreach(explode('/', $matches[2]) as $token)
{
2016-02-20 17:34:06 +00:00
preg_match("/^(.*?)$separator(.*)$/", $token, $matches);
if(!empty($matches[1]) && !strempty($matches[2]))
{
$matches[1] = strreplaceu(array("\x1c", "\x1d", "\x1e"), array('/', ':', '='), $matches[1]);
$matches[2] = strreplaceu(array("\x1c", "\x1d", "\x1e"), array('/', ':', '='), $matches[2]);
$_REQUEST[$matches[1]] = $matches[2];
}
}
2016-02-20 17:34:06 +00:00
} else {
$_SERVER["LOCATION"] = $location;
$_SERVER["LOCATION_ARGS"] = "";
}
2016-02-20 17:34:06 +00:00
}
2015-04-29 07:26:48 +00:00
return $location;
2013-04-14 22:41:04 +00:00
}
2015-01-19 19:05:51 +00:00
2015-04-29 07:26:48 +00:00
// Return location arguments from current HTTP request
function getLocationArgs()
2015-01-19 19:05:51 +00:00
{
2015-04-29 07:26:48 +00:00
return $_SERVER["LOCATION_ARGS"];
2015-01-19 19:05:51 +00:00
}
2015-04-29 07:26:48 +00:00
2016-02-20 17:34:06 +00:00
// Return location arguments from current HTTP request, modify existing arguments
2015-04-29 07:26:48 +00:00
function getLocationArgsNew($arg, $pagination)
2014-10-19 19:22:47 +00:00
{
2016-02-20 17:34:06 +00:00
$separator = $this->getLocationArgsSeparator();
2015-04-29 07:26:48 +00:00
preg_match("/^(.*?):(.*)$/", $arg, $args);
foreach(explode('/', $_SERVER["LOCATION_ARGS"]) as $token)
2014-10-19 19:22:47 +00:00
{
2016-02-20 17:34:06 +00:00
preg_match("/^(.*?)$separator(.*)$/", $token, $matches);
2016-07-19 22:12:05 +00:00
if($matches[1]==$args[1]) { $matches[2] = $args[2]; $found = true; }
2015-04-29 07:26:48 +00:00
if(!empty($matches[1]) && !strempty($matches[2]))
2014-10-19 19:22:47 +00:00
{
2015-04-29 07:26:48 +00:00
if(!empty($locationArgs)) $locationArgs .= '/';
$locationArgs .= "$matches[1]:$matches[2]";
2014-10-19 19:22:47 +00:00
}
}
2015-04-29 07:26:48 +00:00
if(!$found && !empty($args[1]) && !strempty($args[2]))
2014-10-19 19:22:47 +00:00
{
2015-04-29 07:26:48 +00:00
if(!empty($locationArgs)) $locationArgs .= '/';
$locationArgs .= "$args[1]:$args[2]";
2014-10-19 19:22:47 +00:00
}
2015-04-29 07:26:48 +00:00
if(!empty($locationArgs))
{
$locationArgs = $this->normaliseArgs($locationArgs, false, false);
2016-02-20 17:34:06 +00:00
if(!$this->isLocationArgsPagination($locationArgs, $pagination)) $locationArgs .= '/';
2015-04-29 07:26:48 +00:00
}
return $locationArgs;
2014-10-19 19:22:47 +00:00
}
2013-04-14 22:41:04 +00:00
2016-02-20 17:34:06 +00:00
// Return location arguments from current HTTP request, convert form parameters
function getLocationArgsClean($pagination)
2013-04-14 22:41:04 +00:00
{
2015-04-29 07:26:48 +00:00
foreach(array_merge($_GET, $_POST) as $key=>$value)
{
2015-04-29 07:26:48 +00:00
if(!empty($key) && !strempty($value))
{
2015-04-29 07:26:48 +00:00
if(!empty($locationArgs)) $locationArgs .= '/';
2016-02-20 17:34:06 +00:00
$key = strreplaceu(array('/', ':', '='), array("\x1c", "\x1d", "\x1e"), $key);
$value = strreplaceu(array('/', ':', '='), array("\x1c", "\x1d", "\x1e"), $value);
2015-04-29 07:26:48 +00:00
$locationArgs .= "$key:$value";
}
}
2015-04-29 07:26:48 +00:00
if(!empty($locationArgs))
2015-02-03 13:00:01 +00:00
{
2015-04-29 07:26:48 +00:00
$locationArgs = $this->normaliseArgs($locationArgs, false, false);
2016-02-20 17:34:06 +00:00
if(!$this->isLocationArgsPagination($locationArgs, $pagination)) $locationArgs .= '/';
2015-02-03 13:00:01 +00:00
}
2015-04-29 07:26:48 +00:00
return $locationArgs;
2015-02-03 13:00:01 +00:00
}
2016-02-20 17:34:06 +00:00
// Return location arguments separator
function getLocationArgsSeparator()
{
2016-07-19 22:12:05 +00:00
return (strtoupperu(substru(PHP_OS, 0, 3))!="WIN") ? ':' : '=';
2016-02-20 17:34:06 +00:00
}
2014-02-04 14:06:48 +00:00
2017-03-02 14:31:49 +00:00
// Check if there are location arguments in current HTTP request
2016-03-19 23:17:01 +00:00
function isLocationArgs($location = "")
{
2016-03-19 23:17:01 +00:00
$location = empty($location) ? $_SERVER["LOCATION"].$_SERVER["LOCATION_ARGS"] : $location;
2016-02-20 17:34:06 +00:00
$separator = $this->getLocationArgsSeparator();
return preg_match("/[^\/]+$separator.*$/", $location);
}
2017-03-02 14:31:49 +00:00
// Check if there are pagination arguments in current HTTP request
2015-04-29 07:26:48 +00:00
function isLocationArgsPagination($location, $pagination)
{
2016-02-20 17:34:06 +00:00
$separator = $this->getLocationArgsSeparator();
return preg_match("/^(.*\/)?$pagination$separator.*$/", $location);
}
2015-04-29 07:26:48 +00:00
2015-12-14 23:22:49 +00:00
// Check if script location is requested
function isRequestSelf()
{
return substru($_SERVER["REQUEST_URI"], -10, 10)=="yellow.php";
2015-12-14 23:22:49 +00:00
}
2015-04-29 07:26:48 +00:00
// Check if clean URL is requested
function isRequestCleanUrl($location)
{
2015-04-29 07:26:48 +00:00
return (isset($_GET["clean-url"]) || isset($_POST["clean-url"])) && substru($location, -1, 1)=="/";
}
2015-04-29 07:26:48 +00:00
// Check if unmodified since last HTTP request
function isRequestNotModified($lastModifiedFormatted)
{
2015-04-29 07:26:48 +00:00
return isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && $_SERVER["HTTP_IF_MODIFIED_SINCE"]==$lastModifiedFormatted;
}
2014-08-25 13:05:22 +00:00
2016-07-10 18:44:02 +00:00
// Normalise path or location, take care of relative path tokens
function normaliseTokens($text, $prependSlash = false)
{
$textFiltered = "";
if($prependSlash && $text[0]!='/') $textFiltered .= '/';
for($pos=0; $pos<strlenb($text); ++$pos)
{
if($text[$pos]=='/' || $pos==0)
{
2016-07-19 22:12:05 +00:00
if($text[$pos+1]=='/') continue;
if($text[$pos+1]=='.')
2016-07-10 18:44:02 +00:00
{
2016-07-19 22:12:05 +00:00
$posNew = $pos+1; while($text[$posNew]=='.') ++$posNew;
2016-07-10 18:44:02 +00:00
if($text[$posNew]=='/' || $text[$posNew]=='')
{
$pos = $posNew-1;
continue;
}
}
}
$textFiltered .= $text[$pos];
}
return $textFiltered;
}
2014-08-25 13:05:22 +00:00
// Normalise location arguments
function normaliseArgs($text, $appendSlash = true, $filterStrict = true)
{
if($appendSlash) $text .= '/';
if($filterStrict) $text = strreplaceu(' ', '-', strtoloweru($text));
2016-02-20 17:34:06 +00:00
$text = strreplaceu(':', $this->getLocationArgsSeparator(), $text);
return strreplaceu(array('%2F','%3A','%3D'), array('/',':','='), rawurlencode($text));
2014-08-25 13:05:22 +00:00
}
2014-02-04 14:06:48 +00:00
// Normalise text into UTF-8 NFC
function normaliseUnicode($text)
{
if(PHP_OS=="Darwin" && !mb_check_encoding($text, "ASCII"))
{
$utf8nfc = preg_match("//u", $text) && !preg_match('/[^\x00-\x{2FF}]/u', $text);
if(!$utf8nfc) $text = iconv("UTF-8-MAC", "UTF-8", $text);
}
return $text;
}
2017-02-17 13:52:55 +00:00
// Return timezone
function getTimezone()
2015-02-04 21:58:41 +00:00
{
2017-02-17 13:52:55 +00:00
$timezone = @date_default_timezone_get();
if(PHP_OS=="Darwin" && $timezone=="UTC")
2015-02-04 21:58:41 +00:00
{
2017-02-17 13:52:55 +00:00
if(preg_match("#zoneinfo/(.*)#", @readlink("/etc/localtime"), $matches)) $timezone = $matches[1];
2015-02-04 21:58:41 +00:00
}
2017-02-17 13:52:55 +00:00
return $timezone;
2015-02-04 21:58:41 +00:00
}
2013-04-14 22:41:04 +00:00
// Return human readable HTTP server status
2016-04-04 10:02:11 +00:00
function getHttpStatusFormatted($statusCode, $shortFormat = false)
2013-04-14 22:41:04 +00:00
{
switch($statusCode)
{
2016-04-04 10:02:11 +00:00
case 0: $text = "No data"; break;
case 200: $text = "OK"; break;
case 301: $text = "Moved permanently"; break;
case 302: $text = "Moved temporarily"; break;
case 303: $text = "Reload please"; break;
case 304: $text = "Not modified"; break;
case 400: $text = "Bad request"; break;
case 403: $text = "Forbidden"; break;
case 404: $text = "Not found"; break;
2017-07-05 10:25:25 +00:00
case 430: $text = "Login failed"; break;
case 434: $text = "Not existing"; break;
2016-04-04 10:02:11 +00:00
case 500: $text = "Server error"; break;
case 503: $text = "Service unavailable"; break;
default: $text = "Error $statusCode";
2013-04-14 22:41:04 +00:00
}
2016-04-04 10:02:11 +00:00
$serverProtocol = $_SERVER["SERVER_PROTOCOL"];
if(!preg_match("/^HTTP\//", $serverProtocol)) $serverProtocol = "HTTP/1.1";
return $shortFormat ? $text : "$serverProtocol $statusCode $text";
2013-04-14 22:41:04 +00:00
}
2013-06-27 17:00:03 +00:00
2015-01-24 22:45:37 +00:00
// Return human readable HTTP date
function getHttpDateFormatted($timestamp)
2013-06-27 17:00:03 +00:00
{
return gmdate("D, d M Y H:i:s", $timestamp)." GMT";
}
2015-01-19 19:05:51 +00:00
// Return MIME content type
function getMimeContentType($fileName)
{
2017-08-09 12:08:02 +00:00
$contentType = "";
$contentTypes = array(
2015-01-19 19:05:51 +00:00
"css" => "text/css",
2017-06-26 13:19:49 +00:00
"gif" => "image/gif",
2017-01-03 13:11:44 +00:00
"html" => "text/html; charset=utf-8",
2015-08-01 17:28:20 +00:00
"ico" => "image/x-icon",
2015-01-19 19:05:51 +00:00
"js" => "application/javascript",
"jpg" => "image/jpeg",
"png" => "image/png",
2016-08-18 19:57:07 +00:00
"svg" => "image/svg+xml",
2015-01-19 19:05:51 +00:00
"txt" => "text/plain",
2015-04-29 07:26:48 +00:00
"woff" => "application/font-woff",
"woff2" => "application/font-woff2",
2015-04-29 07:26:48 +00:00
"xml" => "text/xml; charset=utf-8");
2017-08-09 12:08:02 +00:00
$fileType = $this->getFileType($fileName);
if(empty($fileType))
2017-01-03 13:11:44 +00:00
{
2017-08-09 12:08:02 +00:00
$contentType = $contentTypes["html"];
} else if(array_key_exists($fileType, $contentTypes)) {
$contentType = $contentTypes[$fileType];
2017-01-03 13:11:44 +00:00
}
2015-01-19 19:05:51 +00:00
return $contentType;
}
2013-04-14 22:41:04 +00:00
// Return number of bytes
function getNumberBytes($string)
{
$bytes = intval($string);
switch(strtoupperu(substru($string, -1)))
{
case 'G': $bytes *= 1024*1024*1024; break;
case 'M': $bytes *= 1024*1024; break;
case 'K': $bytes *= 1024; break;
}
return $bytes;
}
2013-04-14 22:41:04 +00:00
// Return files and directories
function getDirectoryEntries($path, $regex = "/.*/", $sort = true, $directories = true, $includePath = true)
2013-04-14 22:41:04 +00:00
{
$entries = array();
$dirHandle = @opendir($path);
if($dirHandle)
{
$path = rtrim($path, '/');
2016-07-19 22:12:05 +00:00
while(($entry = readdir($dirHandle))!==false)
2013-04-14 22:41:04 +00:00
{
2016-07-19 22:12:05 +00:00
if(substru($entry, 0, 1)==".") continue;
2014-02-04 14:06:48 +00:00
$entry = $this->normaliseUnicode($entry);
2013-04-14 22:41:04 +00:00
if(preg_match($regex, $entry))
{
if($directories)
{
if(is_dir("$path/$entry")) array_push($entries, $includePath ? "$path/$entry" : $entry);
2013-04-14 22:41:04 +00:00
} else {
if(is_file("$path/$entry")) array_push($entries, $includePath ? "$path/$entry" : $entry);
2013-04-14 22:41:04 +00:00
}
}
}
2016-07-15 16:35:11 +00:00
if($sort) natcasesort($entries);
2013-04-14 22:41:04 +00:00
closedir($dirHandle);
}
return $entries;
}
// Return files and directories recursively
function getDirectoryEntriesRecursive($path, $regex = "/.*/", $sort = true, $directories = true, $levelMax = 0)
{
--$levelMax;
$entries = $this->getDirectoryEntries($path, $regex, $sort, $directories);
2016-07-19 22:12:05 +00:00
if($levelMax!=0)
{
2013-12-21 13:10:15 +00:00
foreach($this->getDirectoryEntries($path, "/.*/", $sort, true) as $entry)
{
$entries = array_merge($entries, $this->getDirectoryEntriesRecursive($entry, $regex, $sort, $directories, $levelMax));
}
}
return $entries;
}
2014-07-25 10:46:58 +00:00
2016-02-04 14:02:53 +00:00
// Read file, empty string if not found
function readFile($fileName, $sizeMax = 0)
{
$fileData = "";
$fileHandle = @fopen($fileName, "rb");
if($fileHandle)
{
2016-08-13 10:30:07 +00:00
clearstatcache(true, $fileName);
2017-01-03 13:11:44 +00:00
$fileSize = $sizeMax ? $sizeMax : filesize($fileName);
if($fileSize) $fileData = fread($fileHandle, $fileSize);
2016-02-04 14:02:53 +00:00
fclose($fileHandle);
}
return $fileData;
}
// Create file
2013-12-21 13:10:15 +00:00
function createFile($fileName, $fileData, $mkdir = false)
{
$ok = false;
if($mkdir)
{
$path = dirname($fileName);
if(!empty($path) && !is_dir($path)) @mkdir($path, 0777, true);
}
2016-02-20 17:34:06 +00:00
$fileHandle = @fopen($fileName, "wb");
if($fileHandle)
{
2016-08-13 10:30:07 +00:00
clearstatcache(true, $fileName);
2016-02-22 13:20:57 +00:00
if(flock($fileHandle, LOCK_EX))
{
ftruncate($fileHandle, 0);
fwrite($fileHandle, $fileData);
flock($fileHandle, LOCK_UN);
}
fclose($fileHandle);
$ok = true;
}
return $ok;
}
// Copy file
2017-10-07 15:35:19 +00:00
function copyFile($fileNameSource, $fileNameDestination, $mkdir = false)
{
2016-08-13 10:30:07 +00:00
clearstatcache();
if($mkdir)
{
2017-10-07 15:35:19 +00:00
$path = dirname($fileNameDestination);
if(!empty($path) && !is_dir($path)) @mkdir($path, 0777, true);
}
2017-10-07 15:35:19 +00:00
return @copy($fileNameSource, $fileNameDestination);
}
// Rename file
2017-10-07 15:35:19 +00:00
function renameFile($fileNameSource, $fileNameDestination, $mkdir = false)
{
2016-08-13 10:30:07 +00:00
clearstatcache();
if($mkdir)
{
2017-10-07 15:35:19 +00:00
$path = dirname($fileNameDestination);
if(!empty($path) && !is_dir($path)) @mkdir($path, 0777, true);
}
2017-10-07 15:35:19 +00:00
return @rename($fileNameSource, $fileNameDestination);
}
// Merge file
function mergeFile($fileNameSource, $fileNameDestination)
{
$ok = false;
clearstatcache();
$fileHandleSource = @fopen($fileNameSource, "rb");
if($fileHandleSource)
{
$fileHandleDestination = @fopen($fileNameDestination, "ab");
if($fileHandleDestination)
{
while(true)
{
$dataBufferChunk = fread($fileHandleSource, 1024*64);
fwrite($fileHandleDestination, $dataBufferChunk);
if(feof($fileHandleSource) || $dataBufferChunk===false) break;
}
fclose($fileHandleDestination);
$ok = true;
}
fclose($fileHandleSource);
if($ok) @unlink($fileNameSource);
}
return $ok;
}
2014-06-27 09:36:30 +00:00
2014-07-25 10:46:58 +00:00
// Delete file
2016-07-10 18:44:02 +00:00
function deleteFile($fileName, $pathTrash = "")
2014-07-25 10:46:58 +00:00
{
2016-08-13 10:30:07 +00:00
clearstatcache();
2016-07-10 18:44:02 +00:00
if(empty($pathTrash))
{
$ok = @unlink($fileName);
} else {
2016-08-07 10:51:23 +00:00
if(!is_dir($pathTrash)) @mkdir($pathTrash, 0777, true);
2017-10-07 15:35:19 +00:00
$fileNameDestination = $pathTrash;
$fileNameDestination .= pathinfo($fileName, PATHINFO_FILENAME);
$fileNameDestination .= "-".str_replace(array(" ", ":"), "-", date("Y-m-d H:i:s", filemtime($fileName)));
$fileNameDestination .= ".".pathinfo($fileName, PATHINFO_EXTENSION);
$ok = @rename($fileName, $fileNameDestination);
2016-08-07 10:51:23 +00:00
}
return $ok;
}
// Delete directory
function deleteDirectory($path, $pathTrash = "")
{
2016-08-13 10:30:07 +00:00
clearstatcache();
2016-08-07 10:51:23 +00:00
if(empty($pathTrash))
{
$iterator = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file)
{
if($file->isDir())
{
@rmdir($file->getRealPath());
} else {
@unlink($file->getRealPath());
}
}
$ok = @rmdir($path);
} else {
if(!is_dir($pathTrash)) @mkdir($pathTrash, 0777, true);
2017-10-07 15:35:19 +00:00
$pathDestination = $pathTrash;
$pathDestination .= basename($path);
$pathDestination .= "-".str_replace(array(" ", ":"), "-", date("Y-m-d H:i:s", filemtime($path)));
$ok = @rename($path, $pathDestination);
2016-07-10 18:44:02 +00:00
}
return $ok;
2014-07-25 10:46:58 +00:00
}
2015-04-29 07:26:48 +00:00
2016-08-22 09:54:13 +00:00
// Set file modification date, Unix time
function modifyFile($fileName, $modified)
2016-08-18 19:57:07 +00:00
{
2016-08-22 09:54:13 +00:00
clearstatcache(true, $fileName);
return @touch($fileName, $modified);
2016-08-18 19:57:07 +00:00
}
// Return file modification date, Unix time
function getFileModified($fileName)
{
return is_file($fileName) ? filemtime($fileName) : 0;
}
2017-08-09 12:08:02 +00:00
// Return file type
function getFileType($fileName)
2016-08-22 09:54:13 +00:00
{
return strtoloweru(($pos = strrposu($fileName, '.')) ? substru($fileName, $pos+1) : "");
}
// Return lines from text string, including newline
2015-04-29 07:26:48 +00:00
function getTextLines($text)
{
$lines = array();
2016-04-27 22:32:37 +00:00
$split = preg_split("/(\R)/u", $text, -1, PREG_SPLIT_DELIM_CAPTURE);
2015-04-29 07:26:48 +00:00
for($i=0; $i<count($split)-1; $i+=2) array_push($lines, $split[$i].$split[$i+1]);
2017-07-05 10:25:25 +00:00
if($split[$i]!="") array_push($lines, $split[$i]."\n");
2015-04-29 07:26:48 +00:00
return $lines;
}
2017-01-03 13:11:44 +00:00
// Return arguments from text string, space separated
2014-06-27 09:36:30 +00:00
function getTextArgs($text, $optional = "-")
{
2015-05-19 14:15:24 +00:00
$text = preg_replace("/\s+/s", " ", trim($text));
$tokens = str_getcsv($text, ' ', '"');
2016-07-19 22:12:05 +00:00
foreach($tokens as $key=>$value) if($value==$optional) $tokens[$key] = "";
2014-06-27 09:36:30 +00:00
return $tokens;
}
2013-05-01 20:16:05 +00:00
// Create description from text string
2017-01-25 21:31:17 +00:00
function createTextDescription($text, $lengthMax = 0, $removeHtml = true, $endMarker = "", $endMarkerText = "")
2013-04-14 22:41:04 +00:00
{
2015-08-01 17:28:20 +00:00
if(preg_match("/^<h1>.*?<\/h1>(.*)$/si", $text, $matches)) $text = $matches[1];
2017-01-25 21:31:17 +00:00
if($lengthMax==0) $lengthMax = strlenu($text);
2013-05-01 20:16:05 +00:00
if($removeHtml)
2013-04-14 22:41:04 +00:00
{
2013-05-01 20:16:05 +00:00
while(true)
2013-04-14 22:41:04 +00:00
{
2013-09-17 09:18:01 +00:00
$elementFound = preg_match("/<\s*?([\/!]?\w*)(.*?)\s*?\>/s", $text, $matches, PREG_OFFSET_CAPTURE, $offsetBytes);
2013-05-01 20:16:05 +00:00
$element = $matches[0][0];
$elementName = $matches[1][0];
2013-09-17 09:18:01 +00:00
$elementText = $matches[2][0];
2013-05-01 20:16:05 +00:00
$elementOffsetBytes = $elementFound ? $matches[0][1] : strlenb($text);
$string = html_entity_decode(substrb($text, $offsetBytes, $elementOffsetBytes - $offsetBytes), ENT_QUOTES, "UTF-8");
if(preg_match("/^(blockquote|br|div|h\d|hr|li|ol|p|pre|ul)/i", $elementName)) $string .= ' ';
if(preg_match("/^\/(code|pre)/i", $elementName)) $string = preg_replace("/^(\d+\n){2,}$/", "", $string);
2013-05-01 20:16:05 +00:00
$string = preg_replace("/\s+/s", " ", $string);
2013-11-29 12:16:14 +00:00
if(substru($string, 0, 1)==" " && (empty($output) || substru($output, -1)==' ')) $string = substru($string, 1);
2013-05-01 20:16:05 +00:00
$length = strlenu($string);
2016-07-19 22:12:05 +00:00
$output .= substru($string, 0, $length<$lengthMax ? $length : $lengthMax-1);
2013-05-01 20:16:05 +00:00
$lengthMax -= $length;
2013-09-17 09:18:01 +00:00
if(!empty($element) && $element==$endMarker) { $lengthMax = 0; $endMarkerFound = true; }
2013-05-01 20:16:05 +00:00
if($lengthMax<=0 || !$elementFound) break;
$offsetBytes = $elementOffsetBytes + strlenb($element);
2013-04-14 22:41:04 +00:00
}
2013-05-01 20:16:05 +00:00
$output = rtrim($output);
2016-07-19 22:12:05 +00:00
if($lengthMax<=0) $output .= $endMarkerFound ? $endMarkerText : "";
2013-05-01 20:16:05 +00:00
} else {
$elementsOpen = array();
while(true)
2013-04-14 22:41:04 +00:00
{
2013-09-17 09:18:01 +00:00
$elementFound = preg_match("/&.*?\;|<\s*?([\/!]?\w*)(.*?)\s*?\>/s", $text, $matches, PREG_OFFSET_CAPTURE, $offsetBytes);
2013-05-01 20:16:05 +00:00
$element = $matches[0][0];
$elementName = $matches[1][0];
$elementText = $matches[2][0];
2013-05-01 20:16:05 +00:00
$elementOffsetBytes = $elementFound ? $matches[0][1] : strlenb($text);
$string = substrb($text, $offsetBytes, $elementOffsetBytes - $offsetBytes);
$length = strlenu($string);
2016-07-19 22:12:05 +00:00
$output .= substru($string, 0, $length<$lengthMax ? $length : $lengthMax-1);
2013-05-01 20:16:05 +00:00
$lengthMax -= $length + ($element[0]=='&' ? 1 : 0);
2013-09-17 09:18:01 +00:00
if(!empty($element) && $element==$endMarker) { $lengthMax = 0; $endMarkerFound = true; }
2013-05-01 20:16:05 +00:00
if($lengthMax<=0 || !$elementFound) break;
if(!empty($elementName) && substru($elementText, -1)!='/' &&
2013-09-17 09:18:01 +00:00
!preg_match("/^(area|br|col|hr|img|input|col|param|!)/i", $elementName))
2013-05-01 20:16:05 +00:00
{
2016-07-19 22:12:05 +00:00
if($elementName[0]!='/')
2013-05-01 20:16:05 +00:00
{
array_push($elementsOpen, $elementName);
2013-05-01 20:16:05 +00:00
} else {
array_pop($elementsOpen);
}
}
$output .= $element;
$offsetBytes = $elementOffsetBytes + strlenb($element);
2013-04-14 22:41:04 +00:00
}
2013-05-01 20:16:05 +00:00
$output = rtrim($output);
2013-12-21 13:10:15 +00:00
for($i=count($elementsOpen)-1; $i>=0; --$i)
{
if(!preg_match("/^(dl|ol|ul|table|tbody|thead|tfoot|tr)/i", $elementsOpen[$i])) break;
$output .= "</".$elementsOpen[$i].">";
}
2016-07-19 22:12:05 +00:00
if($lengthMax<=0) $output .= $endMarkerFound ? $endMarkerText : "";
2013-12-21 13:10:15 +00:00
for(; $i>=0; --$i) $output .= "</".$elementsOpen[$i].">";
2013-04-14 22:41:04 +00:00
}
2013-05-01 20:16:05 +00:00
return $output;
2013-04-14 22:41:04 +00:00
}
2013-12-21 13:10:15 +00:00
2013-04-14 22:41:04 +00:00
// Create keywords from text string
2015-06-02 22:29:00 +00:00
function createTextKeywords($text, $keywordsMax = 0)
2013-04-14 22:41:04 +00:00
{
2015-08-01 17:28:20 +00:00
$tokens = array_unique(preg_split("/[,\s\(\)\+\-]/", strtoloweru($text)));
2016-07-19 22:12:05 +00:00
foreach($tokens as $key=>$value) if(strlenu($value)<3) unset($tokens[$key]);
2015-06-02 22:29:00 +00:00
if($keywordsMax) $tokens = array_slice($tokens, 0, $keywordsMax);
return implode(", ", $tokens);
2013-04-14 22:41:04 +00:00
}
// Create title from text string
2013-10-16 21:11:24 +00:00
function createTextTitle($text)
2013-04-14 22:41:04 +00:00
{
2014-07-25 10:46:58 +00:00
if(preg_match("/^.*\/([\w\-]+)/", $text, $matches)) $text = strreplaceu('-', ' ', ucfirst($matches[1]));
2013-04-14 22:41:04 +00:00
return $text;
}
2013-04-07 18:04:09 +00:00
// Create random text for cryptography
function createSalt($length, $bcryptFormat = false)
{
$dataBuffer = $salt = "";
$dataBufferSize = $bcryptFormat ? intval(ceil($length/4) * 3) : intval(ceil($length/2));
2017-06-26 13:19:49 +00:00
if(empty($dataBuffer) && function_exists("random_bytes"))
{
$dataBuffer = @random_bytes($dataBufferSize);
}
if(empty($dataBuffer) && function_exists("mcrypt_create_iv"))
{
$dataBuffer = @mcrypt_create_iv($dataBufferSize, MCRYPT_DEV_URANDOM);
}
if(empty($dataBuffer) && function_exists("openssl_random_pseudo_bytes"))
{
$dataBuffer = @openssl_random_pseudo_bytes($dataBufferSize);
}
2016-07-19 22:12:05 +00:00
if(strlenb($dataBuffer)==$dataBufferSize)
{
if($bcryptFormat)
{
$salt = substrb(base64_encode($dataBuffer), 0, $length);
$base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
$bcrypt64Chars = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
$salt = strtr($salt, $base64Chars, $bcrypt64Chars);
} else {
$salt = substrb(bin2hex($dataBuffer), 0, $length);
}
}
return $salt;
}
// Create hash with random salt, bcrypt or sha256
function createHash($text, $algorithm, $cost = 0)
{
$hash = "";
switch($algorithm)
{
case "bcrypt": $prefix = sprintf("$2y$%02d$", $cost);
$salt = $this->createSalt(22, true);
$hash = crypt($text, $prefix.$salt);
if(empty($salt) || strlenb($hash)!=60) $hash = "";
break;
case "sha256": $prefix = "$5y$";
$salt = $this->createSalt(32);
$hash = "$prefix$salt".hash("sha256", $salt.$text);
if(empty($salt) || strlenb($hash)!=100) $hash = "";
break;
}
return $hash;
}
// Verify that text matches hash
function verifyHash($text, $algorithm, $hash)
{
$hashCalculated = "";
switch($algorithm)
{
2015-04-29 07:26:48 +00:00
case "bcrypt": if(substrb($hash, 0, 4)=="$2y$" || substrb($hash, 0, 4)=="$2a$")
{
$hashCalculated = crypt($text, $hash);
}
break;
2016-07-19 22:12:05 +00:00
case "sha256": if(substrb($hash, 0, 4)=="$5y$")
{
$prefix = substrb($hash, 0, 4);
$salt = substrb($hash, 4, 32);
$hashCalculated = "$prefix$salt".hash("sha256", $salt.$text);
}
break;
}
$ok = !empty($hashCalculated) && strlenb($hashCalculated)==strlenb($hash);
2016-07-19 22:12:05 +00:00
if($ok) for($i=0; $i<strlenb($hashCalculated); ++$i) $ok &= $hashCalculated[$i]==$hash[$i];
return $ok;
}
// Return meta data from raw data
function getMetaData($rawData, $key)
{
$value = "";
if(preg_match("/^(\xEF\xBB\xBF)?\-\-\-[\r\n]+(.+?)\-\-\-[\r\n]+(.*)$/s", $rawData, $parts))
{
$key = lcfirst($key);
foreach($this->getTextLines($parts[2]) as $line)
{
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if(lcfirst($matches[1])==$key && !strempty($matches[2])) { $value = $matches[2]; break; }
}
}
return $value;
}
// Set meta data in raw data
function setMetaData($rawData, $key, $value)
{
if(preg_match("/^(\xEF\xBB\xBF)?\-\-\-[\r\n]+(.+?)\-\-\-[\r\n]+(.*)$/s", $rawData, $parts))
{
$key = lcfirst($key);
foreach($this->getTextLines($parts[2]) as $line)
{
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if(lcfirst($matches[1])==$key)
{
$rawDataNew .= "$matches[1]: $value\n";
$found = true;
} else {
$rawDataNew .= $line;
}
}
if(!$found) $rawDataNew .= ucfirst($key).": $value\n";
$rawDataNew = $parts[1]."---\n".$rawDataNew."---\n".$parts[3];
} else {
$rawDataNew = $rawData;
}
return $rawDataNew;
}
// Detect web browser language
function detectBrowserLanguage($languages, $languageDefault)
{
$language = $languageDefault;
if(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
{
2017-02-22 20:05:46 +00:00
foreach(preg_split("/\s*,\s*/", $_SERVER["HTTP_ACCEPT_LANGUAGE"]) as $string)
{
$tokens = explode(';', $string);
if(in_array($tokens[0], $languages)) { $language = $tokens[0]; break; }
}
}
return $language;
}
2017-06-26 13:19:49 +00:00
// Detect image dimensions and type for gif/jpg/png/svg
2014-06-27 09:36:30 +00:00
function detectImageInfo($fileName)
{
$width = $height = 0;
2014-06-27 09:36:30 +00:00
$type = "";
$fileHandle = @fopen($fileName, "rb");
if($fileHandle)
{
2017-06-26 13:19:49 +00:00
if(substru(strtoloweru($fileName), -3)=="gif")
{
2017-06-26 13:19:49 +00:00
$dataSignature = fread($fileHandle, 6);
$dataHeader = fread($fileHandle, 7);
if(!feof($fileHandle) && ($dataSignature=="GIF87a" || $dataSignature=="GIF89a"))
{
$width = (ord($dataHeader[1])<<8) + ord($dataHeader[0]);
$height = (ord($dataHeader[3])<<8) + ord($dataHeader[2]);
$type = "gif";
}
} else if(substru(strtoloweru($fileName), -3)=="jpg") {
2014-10-27 14:25:57 +00:00
$dataBufferSizeMax = filesize($fileName);
$dataBufferSize = min($dataBufferSizeMax, 4096);
2017-01-03 13:11:44 +00:00
if($dataBufferSize) $dataBuffer = fread($fileHandle, $dataBufferSize);
$dataSignature = substrb($dataBuffer, 0, 4);
if(!feof($fileHandle) && ($dataSignature=="\xff\xd8\xff\xe0" || $dataSignature=="\xff\xd8\xff\xe1"))
{
for($pos=2; $pos+8<$dataBufferSize; $pos+=$length)
{
2016-07-19 22:12:05 +00:00
if($dataBuffer[$pos]!="\xff") break;
if($dataBuffer[$pos+1]=="\xc0" || $dataBuffer[$pos+1]=="\xc2")
{
$width = (ord($dataBuffer[$pos+7])<<8) + ord($dataBuffer[$pos+8]);
$height = (ord($dataBuffer[$pos+5])<<8) + ord($dataBuffer[$pos+6]);
2014-06-27 09:36:30 +00:00
$type = "jpg";
break;
}
$length = (ord($dataBuffer[$pos+2])<<8) + ord($dataBuffer[$pos+3]) + 2;
2016-07-19 22:12:05 +00:00
while($pos+$length+8>=$dataBufferSize)
2014-10-27 14:25:57 +00:00
{
2016-07-19 22:12:05 +00:00
if($dataBufferSize==$dataBufferSizeMax) break;
2014-10-27 14:25:57 +00:00
$dataBufferDiff = min($dataBufferSizeMax, $dataBufferSize*2) - $dataBufferSize;
$dataBufferSize += $dataBufferDiff;
2017-01-03 13:11:44 +00:00
$dataBufferChunk = fread($fileHandle, $dataBufferDiff);
2017-10-07 15:35:19 +00:00
if(feof($fileHandle) || $dataBufferChunk===false) { $dataBufferSize = 0; break; }
2017-01-03 13:11:44 +00:00
$dataBuffer .= $dataBufferChunk;
2014-10-27 14:25:57 +00:00
}
}
}
2016-08-18 19:57:07 +00:00
} else if(substru(strtoloweru($fileName), -3)=="png") {
$dataSignature = fread($fileHandle, 8);
$dataHeader = fread($fileHandle, 16);
if(!feof($fileHandle) && $dataSignature=="\x89PNG\r\n\x1a\n")
{
$width = (ord($dataHeader[10])<<8) + ord($dataHeader[11]);
$height = (ord($dataHeader[14])<<8) + ord($dataHeader[15]);
$type = "png";
}
} else if(substru(strtoloweru($fileName), -3)=="svg") {
$dataBufferSizeMax = filesize($fileName);
$dataBufferSize = min($dataBufferSizeMax, 4096);
2017-01-03 13:11:44 +00:00
if($dataBufferSize) $dataBuffer = fread($fileHandle, $dataBufferSize);
2016-08-18 19:57:07 +00:00
$dataSignature = substrb($dataBuffer, 0, 5);
if(!feof($fileHandle) && $dataSignature=="\x3csvg\x20")
{
$dataBuffer = ($pos = strposu($dataBuffer, '>')) ? substru($dataBuffer, 0, $pos) : $dataBuffer;
if(preg_match("/ width=\"(\d+)\"/", $dataBuffer, $matches)) $width = $matches[1];
if(preg_match("/ height=\"(\d+)\"/", $dataBuffer, $matches)) $height = $matches[1];
$type = "svg";
}
}
fclose($fileHandle);
}
2014-06-27 09:36:30 +00:00
return array($width, $height, $type);
}
2013-04-14 22:41:04 +00:00
// Start timer
2013-10-16 21:11:24 +00:00
function timerStart(&$time)
2013-04-14 22:41:04 +00:00
{
$time = microtime(true);
}
// Stop timer and calculate elapsed time in milliseconds
2013-10-16 21:11:24 +00:00
function timerStop(&$time)
2013-04-14 22:41:04 +00:00
{
$time = intval((microtime(true)-$time) * 1000);
}
2013-04-07 18:04:09 +00:00
}
// Unicode support for PHP
2013-05-01 20:16:05 +00:00
mb_internal_encoding("UTF-8");
2013-10-16 21:11:24 +00:00
function strempty($string) { return is_null($string) || $string===""; }
2016-02-04 14:02:53 +00:00
function strencode($string) { return addcslashes($string, "\'\"\\\/"); }
2013-05-01 20:16:05 +00:00
function strreplaceu() { return call_user_func_array("str_replace", func_get_args()); }
function strtoloweru() { return call_user_func_array("mb_strtolower", func_get_args()); }
function strtoupperu() { return call_user_func_array("mb_strtoupper", func_get_args()); }
function strlenu() { return call_user_func_array("mb_strlen", func_get_args()); }
2013-05-01 20:16:05 +00:00
function strlenb() { return call_user_func_array("strlen", func_get_args()); }
function strposu() { return call_user_func_array("mb_strpos", func_get_args()); }
2013-05-01 20:16:05 +00:00
function strposb() { return call_user_func_array("strpos", func_get_args()); }
function strrposu() { return call_user_func_array("mb_strrpos", func_get_args()); }
function strrposb() { return call_user_func_array("strrpos", func_get_args()); }
function substru() { return call_user_func_array("mb_substr", func_get_args()); }
2013-05-01 20:16:05 +00:00
function substrb() { return call_user_func_array("substr", func_get_args()); }
2013-06-07 20:01:12 +00:00
// Error reporting for PHP
2013-06-07 20:01:12 +00:00
error_reporting(E_ALL ^ E_NOTICE);
?>