diff --git a/.htaccess b/.htaccess
index c3d4405..699247f 100644
--- a/.htaccess
+++ b/.htaccess
@@ -13,5 +13,5 @@ RewriteRule ^(cache|content|system)/ error [L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^[^\.]+$ - [T=text/html,L]
-ErrorDocument 404 /error404.html
+ErrorDocument 404 /error.html
diff --git a/README.md b/README.md
index 30f1478..1f36a6a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-Yellow 0.5.2
+Yellow 0.5.3
============
[](http://datenstrom.se/yellow)
@@ -9,11 +9,8 @@ How do I install this?
1. [Download Yellow and unzip it](https://github.com/datenstrom/yellow/archive/master.zip).
2. Copy all files to your web hosting.
3. Open your website in a web browser.
-
-How do I get started?
----------------------
-Start by editing your website. Just give it a try.
-For more information see [Yellow documentation](https://github.com/datenstrom/yellow/wiki).
+
+Installing is unzipping one file and you are ready to go. [Learn more](https://github.com/datenstrom/yellow/wiki).
License
-------
diff --git a/system/config/config.ini b/system/config/config.ini
index c6cd784..2b2812f 100644
--- a/system/config/config.ini
+++ b/system/config/config.ini
@@ -3,8 +3,7 @@
sitename = Yellow
author = Yellow
language = en
-theme = default
-template = default
+theme = flatsite
// timeZone = UTC
// serverScheme = http
@@ -18,14 +17,14 @@ systemDir = system/
configDir = system/config/
coreDir = system/core/
pluginDir = system/plugins/
-snippetDir = system/snippets/
-templateDir = system/templates/
themeDir = system/themes/
+snippetDir = system/themes/snippets/
+templateDir = system/themes/templates/
mediaDir = media/
imageDir = media/images/
staticDir = cache/
staticDefaultFile = index.html
-staticErrorFile = error404.html
+staticErrorFile = error.html
contentDir = content/
contentRootDir = default/
contentHomeDir = home/
@@ -33,18 +32,19 @@ contentDefaultFile = page.txt
contentPagination = page
contentExtension = .txt
configExtension = .ini
-errorPageFile = error(.*).txt
-newPageFile = new(.*).txt
-textStringFile = language(.*).ini
+textFile = language-(.*).ini
+errorFile = page-error-(.*).txt
robotsTextFile = robots.txt
-parser = markdownextra
+template = default
+parser = markdown
parserSafeMode = 0
multiLanguageMode = 0
+commandlineIgnoreLocation =
+commandlineSystemFile = .htaccess
webinterfaceLocation = /edit/
webinterfaceServerScheme = http
webinterfaceUserHashAlgorithm = bcrypt
webinterfaceUserHashCost = 10
webinterfaceUserFile = user.ini
-webinterfaceFilePrefix = published
-commandlineIgnoreLocation =
-commandlineSystemFile = .htaccess
+webinterfaceNewFile = page-new-(.*).txt
+webinterfaceMetaFilePrefix = published
diff --git a/system/config/error401.txt b/system/config/page-error-401.txt
similarity index 100%
rename from system/config/error401.txt
rename to system/config/page-error-401.txt
diff --git a/system/config/error404.txt b/system/config/page-error-404.txt
similarity index 100%
rename from system/config/error404.txt
rename to system/config/page-error-404.txt
diff --git a/system/config/error424.txt b/system/config/page-error-424.txt
similarity index 100%
rename from system/config/error424.txt
rename to system/config/page-error-424.txt
diff --git a/system/config/error500.txt b/system/config/page-error-500.txt
similarity index 100%
rename from system/config/error500.txt
rename to system/config/page-error-500.txt
diff --git a/system/config/newpage.txt b/system/config/page-new-default.txt
similarity index 100%
rename from system/config/newpage.txt
rename to system/config/page-new-default.txt
diff --git a/system/core/core-commandline.php b/system/core/core-commandline.php
index ee49798..6919d26 100755
--- a/system/core/core-commandline.php
+++ b/system/core/core-commandline.php
@@ -1,20 +1,20 @@
yellow = $yellow;
@@ -22,15 +22,6 @@ class YellowCommandline
$this->yellow->config->setDefault("commandlineSystemFile", ".htaccess");
}
- // Handle command help
- function onCommandHelp()
- {
- $help .= "version\n";
- $help .= "build [DIRECTORY LOCATION]\n";
- $help .= "clean [DIRECTORY LOCATION]\n";
- return $help;
- }
-
// Handle command
function onCommand($args)
{
@@ -51,6 +42,15 @@ class YellowCommandline
return $statusCode;
}
+ // Handle command help
+ function onCommandHelp()
+ {
+ $help .= "version\n";
+ $help .= "build [DIRECTORY LOCATION]\n";
+ $help .= "clean [DIRECTORY LOCATION]\n";
+ return $help;
+ }
+
// Show available commands
function helpCommand()
{
@@ -93,34 +93,38 @@ class YellowCommandline
return $statusCode;
}
- // Build static directories and files
+ // Build static pages and files
function buildStatic($path, $location)
{
$this->yellow->toolbox->timerStart($time);
$path = rtrim(empty($path) ? $this->yellow->config->get("staticDir") : $path, '/');
$this->content = $this->media = $this->system = $this->error = $statusCode = 0;
- $this->locationsArguments = $this->locationsPagination = array();
+ $this->locationsArgs = $this->locationsArgsPagination = array();
if(empty($location))
{
$statusCode = $this->cleanStatic($path, $location);
foreach($this->getStaticLocations() as $location)
{
- $statusCode = max($statusCode, $this->buildStaticRequest($path, $location, true));
+ $statusCode = max($statusCode, $this->buildStaticPage($path, $location, true));
}
- foreach($this->locationsArguments as $location)
+ foreach($this->locationsArgs as $location)
{
- $statusCode = max($statusCode, $this->buildStaticRequest($path, $location, true));
+ $statusCode = max($statusCode, $this->buildStaticPage($path, $location, true));
}
- foreach($this->locationsPagination as $location)
+ foreach($this->locationsArgsPagination as $location)
{
+ if(substru($location, -1) != ':')
+ {
+ $statusCode = max($statusCode, $this->buildStaticPage($path, $location, false, true));
+ }
for($pageNumber=2; $pageNumber<=999; ++$pageNumber)
{
- $statusCodeLocation = $this->buildStaticRequest($path, $location.$pageNumber, false, true);
+ $statusCodeLocation = $this->buildStaticPage($path, $location.$pageNumber, false, true);
$statusCode = max($statusCode, $statusCodeLocation);
if($statusCodeLocation == 0) break;
}
}
- $statusCode = max($statusCode, $this->buildStaticError($path, 404));
+ $statusCode = max($statusCode, $this->buildStaticPage($path, "/error", false, false, true));
foreach($this->getStaticFilesMedia($path) as $fileNameSource=>$fileNameDest)
{
$statusCode = max($statusCode, $this->buildStaticFile($fileNameSource, $fileNameDest, true));
@@ -130,66 +134,33 @@ class YellowCommandline
$statusCode = max($statusCode, $this->buildStaticFile($fileNameSource, $fileNameDest, false));
}
} else {
- $statusCode = $this->buildStaticRequest($path, $location);
+ $statusCode = $this->buildStaticPage($path, $location);
}
$this->yellow->toolbox->timerStop($time);
if(defined("DEBUG") && DEBUG>=1) echo "YellowCommandline::buildStatic time:$time ms\n";
return $statusCode;
}
- // Build static request
- function buildStaticRequest($path, $location, $analyse = false, $probe = false)
+ // Build static page
+ function buildStaticPage($path, $location, $analyse = false, $probe = false, $error = false)
{
ob_start();
$_SERVER["SERVER_PROTOCOL"] = "HTTP/1.1";
$_SERVER["SERVER_NAME"] = $this->yellow->config->get("serverName");
$_SERVER["REQUEST_URI"] = $this->yellow->config->get("serverBase").$location;
- $_SERVER["SCRIPT_NAME"] = $this->yellow->config->get("serverBase")."yellow.php";
+ $_SERVER["SCRIPT_NAME"] = $this->yellow->config->get("serverBase")."/yellow.php";
$_REQUEST = array();
$statusCode = $this->yellow->request();
- if($statusCode < 400)
+ if($statusCode<400 || $error)
{
- $fileName = $this->yellow->toolbox->findStaticFileFromLocation($location, $path,
- $this->yellow->config->get("staticDefaultFile"));
$fileData = ob_get_contents();
$modified = strtotime($this->yellow->page->getHeader("Last-Modified"));
- if(!$this->yellow->toolbox->createFile($fileName, $fileData, true) ||
- !$this->yellow->toolbox->modifyFile($fileName, $modified))
+ if($statusCode>=301 && $statusCode<=303)
{
- $statusCode = 500;
- $this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
+ $fileData = $this->getStaticRedirect($this->yellow->page->getHeader("Location"));
+ $modified = time();
}
- }
- ob_end_clean();
- if($statusCode==200 && $analyse) $this->analyseStaticContent($fileData);
- if($statusCode==404 && $probe) $statusCode = 0;
- if($statusCode != 0) ++$this->content;
- if($statusCode >= 400)
- {
- ++$this->error;
- echo "ERROR building content location '$location', ".$this->yellow->page->getStatusCode(true)."\n";
- }
- if(defined("DEBUG") && DEBUG>=3) echo $fileData;
- if(defined("DEBUG") && DEBUG>=1) echo "YellowCommandline::buildStaticRequest status:$statusCode location:$location\n";
- return $statusCode;
- }
-
- // Build static error
- function buildStaticError($path, $statusCodeRequest)
- {
- ob_start();
- $_SERVER["SERVER_PROTOCOL"] = "HTTP/1.1";
- $_SERVER["SERVER_NAME"] = $this->yellow->config->get("serverName");
- $_SERVER["REQUEST_URI"] = $this->yellow->config->get("serverBase")."/";
- $_SERVER["SCRIPT_NAME"] = $this->yellow->config->get("serverBase")."yellow.php";
- $_REQUEST = array();
- $fileName = "$path/".$this->yellow->config->get("staticErrorFile");
- $statusCode = $this->yellow->request($statusCodeRequest);
- if($statusCode == $statusCodeRequest)
- {
- $statusCode = 200;
- $fileData = ob_get_contents();
- $modified = strtotime($this->yellow->page->getHeader("Last-Modified"));
+ $fileName = $this->getStaticFile($path, $location, $statusCode);
if(!$this->yellow->toolbox->createFile($fileName, $fileData, true) ||
!$this->yellow->toolbox->modifyFile($fileName, $modified))
{
@@ -199,13 +170,17 @@ class YellowCommandline
}
}
ob_end_clean();
- ++$this->system;
+ if($statusCode==200 && $analyse) $this->analyseStaticPage($fileData);
+ if($statusCode==404 && $error) $statusCode = 200;
+ if($statusCode==404 && $probe) $statusCode = 0;
+ if($statusCode != 0) ++$this->content;
if($statusCode >= 400)
{
++$this->error;
- echo "ERROR building error file, ".$this->yellow->page->getStatusCode(true)."\n";
+ echo "ERROR building content location '$location', ".$this->yellow->page->getStatusCode(true)."\n";
}
- if(defined("DEBUG") && DEBUG>=1) echo "YellowCommandline::buildStaticError status:$statusCode file:$fileName\n";
+ if(defined("DEBUG") && DEBUG>=3) echo $fileData;
+ if(defined("DEBUG") && DEBUG>=1) echo "YellowCommandline::buildStaticPage status:$statusCode location:$location\n";
return $statusCode;
}
@@ -226,8 +201,8 @@ class YellowCommandline
return $statusCode;
}
- // Analyse static content, detect locations with arguments and pagination
- function analyseStaticContent($text)
+ // Analyse static page, detect locations with arguments
+ function analyseStaticPage($text)
{
$serverName = $this->yellow->config->get("serverName");
$serverBase = $this->yellow->config->get("serverBase");
@@ -243,20 +218,20 @@ class YellowCommandline
if(!$this->yellow->toolbox->isLocationArgs($match)) continue;
if(substru($match, 0, strlenu($serverBase)) != $serverBase) continue;
$location = rawurldecode(substru($match, strlenu($serverBase)));
- if(!$this->yellow->toolbox->isPaginationLocation($location, $pagination))
+ if(!$this->yellow->toolbox->isLocationArgsPagination($location, $pagination))
{
$location = rtrim($location, '/').'/';
- if(is_null($this->locationsArguments[$location]))
+ if(is_null($this->locationsArgs[$location]))
{
- $this->locationsArguments[$location] = $location;
- if(defined("DEBUG") && DEBUG>=2) echo "YellowCommandline::analyseStaticContent type:arguments location:$location\n";
+ $this->locationsArgs[$location] = $location;
+ if(defined("DEBUG") && DEBUG>=2) echo "YellowCommandline::analyseStaticPage detected location:$location\n";
}
} else {
$location = rtrim($location, "0..9");
- if(is_null($this->locationsPagination[$location]))
+ if(is_null($this->locationsArgsPagination[$location]))
{
- $this->locationsPagination[$location] = $location;
- if(defined("DEBUG") && DEBUG>=2) echo "YellowCommandline::analyseStaticContent type:pagination location:$location\n";
+ $this->locationsArgsPagination[$location] = $location;
+ if(defined("DEBUG") && DEBUG>=2) echo "YellowCommandline::analyseStaticPage detected location:$location\n";
}
}
}
@@ -297,9 +272,9 @@ class YellowCommandline
function cleanStaticDirectory($path)
{
$statusCode = 200;
- if($this->isYellowDirectory($path))
+ if(is_dir($path))
{
- if(is_file("$path/yellow.php") || $path=="/" || !$this->yellow->toolbox->deleteDirectory($path, true))
+ if(!$this->checkStaticDirectory($path) || !$this->yellow->toolbox->deleteDirectory($path, true))
{
$statusCode = 500;
echo "ERROR cleaning pages: Can't delete directory '$path'!\n";
@@ -312,18 +287,13 @@ class YellowCommandline
function cleanStaticFile($path, $location)
{
$statusCode = 200;
- $fileName = $this->yellow->toolbox->findStaticFileFromLocation($location, $path,
- $this->yellow->config->get("staticDefaultFile"));
- if($this->isYellowDirectory($path) && is_file($fileName))
+ $fileName = $this->getStaticFile($path, $location, $statusCode);
+ if(is_file($fileName))
{
- $entry = basename($fileName);
- if($entry!="yellow.php" && substru($entry, 0, 1)!=".")
+ if(!$this->checkStaticDirectory($path) || !$this->yellow->toolbox->deleteFile($fileName))
{
- if(!$this->yellow->toolbox->deleteFile($fileName))
- {
- $statusCode = 500;
- echo "ERROR cleaning pages: Can't delete file '$fileName'!\n";
- }
+ $statusCode = 500;
+ echo "ERROR cleaning pages: Can't delete file '$fileName'!\n";
}
}
return $statusCode;
@@ -352,7 +322,20 @@ class YellowCommandline
$serverName = $this->yellow->config->get("serverName");
$serverBase = $this->yellow->config->get("serverBase");
return !empty($serverScheme) && !empty($serverName) &&
- $this->yellow->toolbox->isValidLocation($serverBase) && $serverBase!="/";
+ $this->yellow->lookup->isValidLocation($serverBase) && $serverBase!="/";
+ }
+
+ // Check static directory
+ function checkStaticDirectory($path)
+ {
+ $ok = false;
+ if(!empty($path))
+ {
+ if($path == rtrim($this->yellow->config->get("staticDir"), '/')) $ok = true;
+ if(is_file("$path/".$this->yellow->config->get("commandlineSystemFile"))) $ok = true;
+ if(is_file("$path/yellow.php")) $ok = false;
+ }
+ return $ok;
}
// Return static locations from file system
@@ -409,6 +392,29 @@ class YellowCommandline
return $files;
}
+ // Return static file
+ function getStaticFile($path, $location, $statusCode)
+ {
+ if($statusCode < 400)
+ {
+ $fileName = $path.$location;
+ if(!$this->yellow->lookup->isFileLocation($location)) $fileName .= $this->yellow->config->get("staticDefaultFile");
+ } else if($statusCode == 404) {
+ $fileName = $path."/".$this->yellow->config->get("staticErrorFile");
+ }
+ return $fileName;
+ }
+
+ // Return static redirect
+ function getStaticRedirect($location)
+ {
+ $output = "\n
\n";
+ $output .= "\n";
+ $output .= "\n";
+ $output .= "\n";
+ return $output;
+ }
+
// Return command help
function getCommandHelp()
{
@@ -436,12 +442,6 @@ class YellowCommandline
usort($data, strnatcasecmp);
return $data;
}
-
- // Check if directory contains Yellow files
- function isYellowDirectory($path)
- {
- return is_file("$path/yellow.php") || is_file("$path/".$this->yellow->config->get("commandlineSystemFile"));
- }
}
$yellow->plugins->register("commandline", "YellowCommandline", YellowCommandline::Version);
diff --git a/system/core/core-webinterface.css b/system/core/core-webinterface.css
index 0a2b3f8..8f19472 100644
--- a/system/core/core-webinterface.css
+++ b/system/core/core-webinterface.css
@@ -1,4 +1,4 @@
-/* Yellow web interface 0.5.1 */
+/* Yellow web interface 0.5.3 */
.yellow-bar { position:relative; overflow:hidden; line-height:2em; margin-bottom:10px; }
.yellow-bar-left { display:block; float:left; }
diff --git a/system/core/core-webinterface.js b/system/core/core-webinterface.js
index d86af9d..ab9ece3 100644
--- a/system/core/core-webinterface.js
+++ b/system/core/core-webinterface.js
@@ -4,7 +4,7 @@
// Yellow main API
var yellow =
{
- version: "0.5.1",
+ version: "0.5.3",
action: function(text) { yellow.webinterface.action(text); },
onClick: function(e) { yellow.webinterface.hidePanesOnClick(yellow.toolbox.getEventElement(e)); },
onKeydown: function(e) { yellow.webinterface.hidePanesOnKeydown(yellow.toolbox.getEventKeycode(e)); },
diff --git a/system/core/core-webinterface.php b/system/core/core-webinterface.php
index 88fbcab..1cc67c0 100755
--- a/system/core/core-webinterface.php
+++ b/system/core/core-webinterface.php
@@ -5,7 +5,7 @@
// Web interface core plugin
class YellowWebinterface
{
- const Version = "0.5.1";
+ const Version = "0.5.3";
var $yellow; //access to API
var $active; //web interface is active? (boolean)
var $userLoginFailed; //web interface login failed? (boolean)
@@ -15,7 +15,7 @@ class YellowWebinterface
var $rawDataSource; //raw data of page for comparison
var $rawDataEdit; //raw data of page for editing
- // Handle plugin initialisation
+ // Handle initialisation
function onLoad($yellow)
{
$this->yellow = $yellow;
@@ -27,7 +27,8 @@ class YellowWebinterface
$this->yellow->config->setDefault("webinterfaceUserHashAlgorithm", "bcrypt");
$this->yellow->config->setDefault("webinterfaceUserHashCost", "10");
$this->yellow->config->setDefault("webinterfaceUserFile", "user.ini");
- $this->yellow->config->setDefault("webinterfaceFilePrefix", "published");
+ $this->yellow->config->setDefault("webinterfaceNewFile", "page-new-(.*).txt");
+ $this->yellow->config->setDefault("webinterfaceMetaFilePrefix", "published");
$this->users->load($this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile"));
}
@@ -44,17 +45,17 @@ class YellowWebinterface
if(rtrim($location, '/') == rtrim($activeLocation, '/'))
{
$statusCode = 301;
- $locationHeader = $this->yellow->toolbox->getLocationHeader(
+ $location = $this->yellow->lookup->normaliseUrl(
$this->yellow->config->get("webinterfaceServerScheme"),
$this->yellow->config->get("webinterfaceServerName"), $base, $activeLocation);
- $this->yellow->sendStatus($statusCode, $locationHeader, false);
+ $this->yellow->sendStatus($statusCode, $location);
}
}
return $statusCode;
}
// Handle page meta data parsing
- function onParseMeta($page, $text)
+ function onParseMeta($page)
{
if($this->isActive() && $this->isUser())
{
@@ -71,41 +72,35 @@ class YellowWebinterface
}
}
- // Handle page extra header
- function onHeaderExtra($page)
+ // Handle page extra HTML data
+ function onExtra()
{
- $header = "";
+ $output = "";
if($this->isActive())
{
$location = $this->yellow->config->getHtml("serverBase").$this->yellow->config->getHtml("pluginLocation");
- $header .= "\n";
- $header .= "\n";
- $header .= "\n";
+ $output .= "\n";
+ $output .= "yellow.text = ".json_encode($this->yellow->text->getData("webinterface", $language)).";\n";
+ if(defined("DEBUG")) $output .= "yellow.debug = ".json_encode(DEBUG).";\n";
+ $output .= "// ]]>\n";
+ $output .= "\n";
}
- return $header;
- }
-
- // Handle command help
- function onCommandHelp()
- {
- return "user EMAIL PASSWORD [NAME LANGUAGE HOME]\n";
+ return $output;
}
// Handle command
@@ -120,6 +115,12 @@ class YellowWebinterface
return $statusCode;
}
+ // Handle command help
+ function onCommandHelp()
+ {
+ return "user EMAIL PASSWORD [NAME LANGUAGE HOME]\n";
+ }
+
// Create or update user account
function userCommand($args)
{
@@ -180,11 +181,12 @@ class YellowWebinterface
{
$statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
} else {
- if($this->yellow->toolbox->isFileLocation($location) && $this->yellow->isContentDirectory("$location/"))
+ if($this->yellow->isRequestContentDirectory($location))
{
$statusCode = 301;
- $locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, "$location/");
- $this->yellow->sendStatus($statusCode, $locationHeader, false);
+ $location = $this->yellow->lookup->isFileLocation($location) ? "$location/" : "/".$this->yellow->getRequestLanguage()."/";
+ $location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
+ $this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = $this->userPermission ? 424 : 404;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
@@ -207,8 +209,8 @@ class YellowWebinterface
if($this->yellow->toolbox->createFile($page->fileName, $page->rawData))
{
$statusCode = 303;
- $locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, $page->location);
- $this->yellow->sendStatus($statusCode, $locationHeader, false);
+ $location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $page->location);
+ $this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = 500;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
@@ -239,8 +241,8 @@ class YellowWebinterface
$this->yellow->toolbox->createFile($page->fileName, $page->rawData))
{
$statusCode = 303;
- $locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, $page->location);
- $this->yellow->sendStatus($statusCode, $locationHeader, false);
+ $location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $page->location);
+ $this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = 500;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
@@ -265,8 +267,8 @@ class YellowWebinterface
if(!is_file($fileName) || $this->yellow->toolbox->deleteFile($fileName))
{
$statusCode = 303;
- $locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, $location);
- $this->yellow->sendStatus($statusCode, $locationHeader, false);
+ $location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
+ $this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = 500;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
@@ -284,12 +286,12 @@ class YellowWebinterface
if(substru($location, 0, strlenu($home)) == $home)
{
$statusCode = 303;
- $locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, $location);
- $this->yellow->sendStatus($statusCode, $locationHeader, false);
+ $location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
+ $this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = 302;
- $locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, $home);
- $this->yellow->sendStatus($statusCode, $locationHeader, false);
+ $location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $home);
+ $this->yellow->sendStatus($statusCode, $location);
}
return $statusCode;
}
@@ -300,11 +302,11 @@ class YellowWebinterface
$statusCode = 302;
$this->users->destroyCookie("login");
$this->users->email = "";
- $locationHeader = $this->yellow->toolbox->getLocationHeader(
+ $location = $this->yellow->lookup->normaliseUrl(
$this->yellow->config->get("serverScheme"),
$this->yellow->config->get("serverName"),
$this->yellow->config->get("serverBase"), $location);
- $this->yellow->sendStatus($statusCode, $locationHeader, false);
+ $this->yellow->sendStatus($statusCode, $location);
return $statusCode;
}
@@ -390,14 +392,11 @@ class YellowWebinterface
{
$page = new YellowPage($this->yellow);
$page->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName);
- $page->parseData($rawData, false);
- $page->fileName = $this->yellow->toolbox->findFileFromTitle(
- $page->get($this->yellow->config->get("webinterfaceFilePrefix")), $page->get("title"), $fileName,
- $this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
- $page->location = $this->yellow->toolbox->findLocationFromFile(
- $page->fileName, $this->yellow->config->get("contentDir"),
- $this->yellow->config->get("contentRootDir"), $this->yellow->config->get("contentHomeDir"),
+ $page->parseData($rawData, false, 0);
+ $page->fileName = $this->yellow->lookup->findFileFromTitle(
+ $page->get($this->yellow->config->get("webinterfaceMetaFilePrefix")), $page->get("title"), $fileName,
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
+ $page->location = $this->yellow->lookup->findLocationFromFile($page->fileName);
if($this->yellow->pages->find($page->location))
{
preg_match("/^(.*?)(\d*)$/", $page->get("title"), $matches);
@@ -407,13 +406,10 @@ class YellowWebinterface
for(; $titleNumber<=999; ++$titleNumber)
{
$page->rawData = $this->updateDataTitle($rawData, $titleText.$titleNumber);
- $page->fileName = $this->yellow->toolbox->findFileFromTitle(
- $page->get($this->yellow->config->get("webinterfaceFilePrefix")), $titleText.$titleNumber, $fileName,
- $this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
- $page->location = $this->yellow->toolbox->findLocationFromFile(
- $page->fileName, $this->yellow->config->get("contentDir"),
- $this->yellow->config->get("contentRootDir"), $this->yellow->config->get("contentHomeDir"),
+ $page->fileName = $this->yellow->lookup->findFileFromTitle(
+ $page->get($this->yellow->config->get("webinterfaceMetaFilePrefix")), $titleText.$titleNumber, $fileName,
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
+ $page->location = $this->yellow->lookup->findLocationFromFile($page->fileName);
if(!$this->yellow->pages->find($page->location)) { $ok = true; break; }
}
if(!$ok) $page->error(500, "Page '".$page->get("title")."' can not be created!");
@@ -427,23 +423,20 @@ class YellowWebinterface
{
$page = new YellowPage($this->yellow);
$page->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName);
- $page->parseData($this->merge->merge($rawDataSource, $rawDataEdit, $rawDataFile), false);
+ $page->parseData($this->merge->merge($rawDataSource, $rawDataEdit, $rawDataFile), false, 0);
if(empty($page->rawData)) $page->error(500, "Page has been modified by someone else!");
- if($this->yellow->toolbox->isFileLocation($location) && !$page->isError())
+ if($this->yellow->lookup->isFileLocation($location) && !$page->isError())
{
$pageSource = new YellowPage($this->yellow);
$pageSource->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName);
- $pageSource->parseData($rawDataSource, false);
- $prefix = $this->yellow->config->get("webinterfaceFilePrefix");
+ $pageSource->parseData($rawDataSource, false, 0);
+ $prefix = $this->yellow->config->get("webinterfaceMetaFilePrefix");
if($pageSource->get($prefix)!=$page->get($prefix) || $pageSource->get("title")!=$page->get("title"))
{
- $page->fileName = $this->yellow->toolbox->findFileFromTitle(
+ $page->fileName = $this->yellow->lookup->findFileFromTitle(
$page->get($prefix), $page->get("title"), $fileName,
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
- $page->location = $this->yellow->toolbox->findLocationFromFile(
- $page->fileName, $this->yellow->config->get("contentDir"),
- $this->yellow->config->get("contentRootDir"), $this->yellow->config->get("contentHomeDir"),
- $this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
+ $page->location = $this->yellow->lookup->findLocationFromFile($page->fileName);
if($pageSource->location!=$page->location && $this->yellow->pages->find($page->location))
{
$page->error(500, "Page '".$page->get("title")."' already exists!");
@@ -457,12 +450,9 @@ class YellowWebinterface
// Return content data for new page
function getDataNew($title = "")
{
- $fileName = $this->yellow->toolbox->findFileFromLocation(
- $this->yellow->page->location, $this->yellow->config->get("contentDir"),
- $this->yellow->config->get("contentRootDir"), $this->yellow->config->get("contentHomeDir"),
- $this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
- $fileName = $this->yellow->toolbox->findFileNew($fileName,
- $this->yellow->config->get("configDir"), $this->yellow->config->get("newPageFile"),
+ $fileName = $this->yellow->lookup->findFileFromLocation($this->yellow->page->location);
+ $fileName = $this->yellow->lookup->findFileNew($fileName,
+ $this->yellow->config->get("configDir"), $this->yellow->config->get("webinterfaceNewFile"),
$this->yellow->config->get("contentDefaultFile"));
$fileData = $this->yellow->toolbox->getFileData($fileName);
$fileData = preg_replace("/@datetime/i", date("Y-m-d H:i:s"), $fileData);
diff --git a/system/core/core.php b/system/core/core.php
index 066859b..f358fd5 100755
--- a/system/core/core.php
+++ b/system/core/core.php
@@ -5,27 +5,30 @@
// Yellow main class
class Yellow
{
- const Version = "0.5.2";
+ const Version = "0.5.3";
var $page; //current page
var $pages; //pages from file system
+ var $files; //files from file system
+ var $plugins; //plugins
var $config; //configuration
var $text; //text strings
- var $plugins; //plugins
+ var $lookup; //location and file lookup
var $toolbox; //toolbox with helpers
function __construct()
{
$this->page = new YellowPage($this);
$this->pages = new YellowPages($this);
+ $this->files = new YellowFiles($this);
+ $this->plugins = new YellowPlugins($this);
$this->config = new YellowConfig($this);
$this->text = new YellowText($this);
+ $this->lookup = new YellowLookup($this);
$this->toolbox = new YellowToolbox();
- $this->plugins = new YellowPlugins();
$this->config->setDefault("sitename", "Yellow");
$this->config->setDefault("author", "Yellow");
$this->config->setDefault("language", "en");
$this->config->setDefault("theme", "default");
- $this->config->setDefault("template", "default");
$this->config->setDefault("timeZone", $this->toolbox->getTimeZone());
$this->config->setDefault("serverScheme", $this->toolbox->getServerScheme());
$this->config->setDefault("serverName", $this->toolbox->getServerName());
@@ -35,16 +38,16 @@ class Yellow
$this->config->setDefault("themeLocation", "/media/themes/");
$this->config->setDefault("systemDir", "system/");
$this->config->setDefault("configDir", "system/config/");
- $this->config->setDefault("staticDir", "cache/");
- $this->config->setDefault("staticDefaultFile", "index.html");
- $this->config->setDefault("staticErrorFile", "error404.html");
$this->config->setDefault("coreDir", "system/core/");
$this->config->setDefault("pluginDir", "system/plugins/");
- $this->config->setDefault("snippetDir", "system/snippets/");
- $this->config->setDefault("templateDir", "system/templates/");
$this->config->setDefault("themeDir", "system/themes/");
+ $this->config->setDefault("snippetDir", "system/themes/snippets/");
+ $this->config->setDefault("templateDir", "system/themes/templates/");
$this->config->setDefault("mediaDir", "media/");
$this->config->setDefault("imageDir", "media/images/");
+ $this->config->setDefault("staticDir", "cache/");
+ $this->config->setDefault("staticDefaultFile", "index.html");
+ $this->config->setDefault("staticErrorFile", "error.html");
$this->config->setDefault("contentDir", "content/");
$this->config->setDefault("contentRootDir", "default/");
$this->config->setDefault("contentHomeDir", "home/");
@@ -53,24 +56,24 @@ class Yellow
$this->config->setDefault("contentExtension", ".txt");
$this->config->setDefault("configExtension", ".ini");
$this->config->setDefault("configFile", "config.ini");
- $this->config->setDefault("errorPageFile", "error(.*).txt");
- $this->config->setDefault("newPageFile", "new(.*).txt");
- $this->config->setDefault("textStringFile", "text(.*).ini");
+ $this->config->setDefault("textFile", "language-(.*).ini");
+ $this->config->setDefault("errorFile", "page-error-(.*).txt");
$this->config->setDefault("robotsTextFile", "robots.txt");
- $this->config->setDefault("parser", "markdownextra");
+ $this->config->setDefault("template", "default");
+ $this->config->setDefault("parser", "markdown");
$this->config->setDefault("parserSafeMode", "0");
$this->config->setDefault("multiLanguageMode", "0");
$this->config->load($this->config->get("configDir").$this->config->get("configFile"));
- $this->text->load($this->config->get("configDir").$this->config->get("textStringFile"));
+ $this->text->load($this->config->get("configDir").$this->config->get("textFile"));
$this->updateConfig();
}
// Handle request
- function request($statusCodeRequest = 0)
+ function request()
{
- $this->toolbox->timerStart($time);
ob_start();
$statusCode = 0;
+ $this->toolbox->timerStart($time);
list($serverScheme, $serverName, $base, $location, $fileName) = $this->getRequestInformation();
$this->page->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName);
foreach($this->plugins->plugins as $key=>$value)
@@ -87,10 +90,9 @@ class Yellow
$this->pages->requestHandler = "core";
$statusCode = $this->processRequest($serverScheme, $serverName, $base, $location, $fileName, true);
}
- if($statusCodeRequest >= 400) $this->page->error($statusCodeRequest, "Request error");
if($this->page->isError()) $statusCode = $this->processRequestError();
- ob_end_flush();
$this->toolbox->timerStop($time);
+ ob_end_flush();
if(defined("DEBUG") && DEBUG>=1) echo "Yellow::request status:$statusCode location:$location
\n";
if(defined("DEBUG") && DEBUG>=1) echo "Yellow::request time:$time ms
\n";
return $statusCode;
@@ -99,37 +101,33 @@ class Yellow
// Process request
function processRequest($serverScheme, $serverName, $base, $location, $fileName, $cacheable)
{
+ $statusCode = 0;
if(is_readable($fileName))
{
- if($cacheable) $fileName = $this->getStaticFile($location, $fileName);
if($this->toolbox->isRequestCleanUrl($location))
{
$statusCode = 303;
$locationArgs = $this->toolbox->getLocationArgsCleanUrl($this->config->get("contentPagination"));
- $locationHeader = $this->toolbox->getLocationHeader($serverScheme, $serverName, $base, $location.$locationArgs);
- $this->sendStatus($statusCode, $locationHeader, false);
- } else if($this->isStaticFile($fileName)) {
- $statusCode = 200;
- $statusCode = $this->sendFile($statusCode, $fileName, $cacheable);
- } else {
- $statusCode = 200;
- $fileName = $this->readPage($serverScheme, $serverName, $base, $location, $fileName, $cacheable, $statusCode);
- $statusCode = $this->sendPage();
+ $location = $this->lookup->normaliseUrl($serverScheme, $serverName, $base, $location.$locationArgs);
+ $this->sendStatus($statusCode, $location);
}
} else {
- if($cacheable) $fileName = $this->getStaticFile("", "");
- if(($this->toolbox->isFileLocation($location) && $this->isContentDirectory("$location/")) ||
- ($location=="/" && $this->config->get("multiLanguageMode")))
+ if($this->isRequestContentDirectory($location))
{
$statusCode = 301;
- $location = $this->toolbox->isFileLocation($location) ? "$location/" : "/".$this->getRequestLanguage()."/";
- $locationHeader = $this->toolbox->getLocationHeader($serverScheme, $serverName, $base, $location);
- $this->sendStatus($statusCode, $locationHeader, false);
- } else if($this->isStaticFile($fileName)) {
- $statusCode = 404;
+ $location = $this->lookup->isFileLocation($location) ? "$location/" : "/".$this->getRequestLanguage()."/";
+ $location = $this->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
+ $this->sendStatus($statusCode, $location);
+ }
+ }
+ if($statusCode == 0)
+ {
+ $statusCode = is_readable($fileName) ? 200 : 404;
+ $fileName = $this->getStaticFileFromCache($location, $fileName, $cacheable, $statusCode);
+ if($this->isStaticFile($fileName))
+ {
$statusCode = $this->sendFile($statusCode, $fileName, $cacheable);
} else {
- $statusCode = 404;
$fileName = $this->readPage($serverScheme, $serverName, $base, $location, $fileName, $cacheable, $statusCode);
$statusCode = $this->sendPage();
}
@@ -137,7 +135,7 @@ class Yellow
if(defined("DEBUG") && DEBUG>=1)
{
$handler = $this->getRequestHandler();
- echo "Yellow::processRequest handler:$handler file:$fileName
\n";
+ echo "Yellow::processRequest file:$fileName handler:$handler
\n";
}
return $statusCode;
}
@@ -153,17 +151,17 @@ class Yellow
if(defined("DEBUG") && DEBUG>=1)
{
$handler = $this->getRequestHandler();
- echo "Yellow::processRequestError handler:$handler file:$fileName
\n";
+ echo "Yellow::processRequestError file:$fileName handler:$handler
\n";
}
return $statusCode;
}
- // Read page from file
+ // Read page
function readPage($serverScheme, $serverName, $base, $location, $fileName, $cacheable, $statusCode, $pageError = "")
{
if($statusCode >= 400)
{
- $fileName = $this->config->get("configDir").$this->config->get("errorPageFile");
+ $fileName = $this->config->get("configDir").$this->config->get("errorFile");
$fileName = strreplaceu("(.*)", $statusCode, $fileName);
$cacheable = false;
}
@@ -178,29 +176,25 @@ class Yellow
// Send page response
function sendPage()
{
- $this->page->parseResponse();
+ $this->page->parsePage();
$statusCode = $this->page->statusCode;
$lastModifiedFormatted = $this->page->getHeader("Last-Modified");
- if($statusCode==200 && $this->page->isCacheable() && $this->toolbox->isFileNotModified($lastModifiedFormatted))
+ if($statusCode==200 && $this->page->isCacheable() && $this->toolbox->isRequestNotModified($lastModifiedFormatted))
{
$statusCode = 304;
- $this->page->clean($statusCode);
- }
- if($this->page->isExisting("pageClean")) ob_clean();
- if(PHP_SAPI != "cli")
- {
+ @header($this->toolbox->getHttpStatusFormatted($statusCode));
+ } else {
@header($this->toolbox->getHttpStatusFormatted($statusCode));
foreach($this->page->headerData as $key=>$value) @header("$key: $value");
- } else {
- if($statusCode>=301 && $statusCode<=303) $this->sendStaticRedirect();
+ if(!is_null($this->page->outputData)) echo $this->page->outputData;
}
if(defined("DEBUG") && DEBUG>=1)
{
foreach($this->page->headerData as $key=>$value) echo "Yellow::sendPage $key: $value
\n";
- $fileNameTemplate = $this->config->get("templateDir").$this->page->get("template").".php";
$fileNameTheme = $this->config->get("themeDir").$this->page->get("theme").".css";
+ $templateName = $this->page->get("template");
$parserName = $this->page->get("parser");
- echo "Yellow::sendPage template:$fileNameTemplate theme:$fileNameTheme parser:$parserName
\n";
+ echo "Yellow::sendPage theme:$fileNameTheme template:$templateName parser:$parserName
\n";
}
return $statusCode;
}
@@ -209,7 +203,7 @@ class Yellow
function sendFile($statusCode, $fileName, $cacheable)
{
$lastModifiedFormatted = $this->toolbox->getHttpDateFormatted(filemtime($fileName));
- if($statusCode==200 && $cacheable && $this->toolbox->isFileNotModified($lastModifiedFormatted))
+ if($statusCode==200 && $cacheable && $this->toolbox->isRequestNotModified($lastModifiedFormatted))
{
$statusCode = 304;
@header($this->toolbox->getHttpStatusFormatted($statusCode));
@@ -224,29 +218,16 @@ class Yellow
}
// Send status response
- function sendStatus($statusCode, $responseHeader, $cacheable)
+ function sendStatus($statusCode, $location = "")
{
- if(PHP_SAPI != "cli")
+ 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)
{
- @header($this->toolbox->getHttpStatusFormatted($statusCode));
- if(!$cacheable) @header("Cache-Control: no-cache, must-revalidate");
- if(!empty($responseHeader)) @header($responseHeader);
- } else {
- if(!empty($responseHeader)) $this->page->header($responseHeader);
- if($statusCode>=301 && $statusCode<=303) $this->sendStaticRedirect();
+ foreach($this->page->headerData as $key=>$value) echo "Yellow::sendStatus $key: $value
\n";
}
}
-
- // Send static redirect response
- function sendStaticRedirect()
- {
- $lastModifiedFormatted = $this->toolbox->getHttpDateFormatted(time());
- if(!$this->page->isHeader("Last-Modified")) $this->page->setHeader("Last-Modified", $lastModifiedFormatted);
- echo "\n\n";
- echo "\n";
- echo "page->getHeader("Location"))."\" />\n";
- echo "\n";
- }
// Return request information
function getRequestInformation($serverScheme = "", $serverName = "", $base = "")
@@ -271,20 +252,14 @@ class Yellow
$fileName = $this->config->get("configDir").$this->config->get("robotsTextFile");
}
}
- if(empty($fileName))
- {
- $fileName = $this->toolbox->findFileFromLocation($location, $this->config->get("contentDir"),
- $this->config->get("contentRootDir"), $this->config->get("contentHomeDir"),
- $this->config->get("contentDefaultFile"), $this->config->get("contentExtension"));
- }
+ if(empty($fileName)) $fileName = $this->lookup->findFileFromLocation($location);
return array($serverScheme, $serverName, $base, $location, $fileName);
}
// Return request language
function getRequestLanguage()
{
- $languages = $this->toolbox->findRootLanguages($this->config->get("contentDir"), $this->config->get("contentRootDir"));
- return $this->toolbox->detectBrowserLanguage($languages, $this->config->get("language"));
+ return $this->toolbox->detectBrowserLanguage($this->pages->getLanguages(), $this->config->get("language"));
}
// Return request handler
@@ -293,16 +268,17 @@ class Yellow
return $this->pages->requestHandler;
}
- // Return static file
- function getStaticFile($location, $fileName)
+ // Return static file from cache if available
+ function getStaticFileFromCache($location, $fileName, $cacheable, $statusCode)
{
- if(PHP_SAPI != "cli")
+ if(PHP_SAPI != "cli" && $cacheable)
{
- if(!empty($location))
+ if($statusCode == 200)
{
- $fileNameStatic = $this->toolbox->findStaticFileFromLocation($location,
- $this->config->get("staticDir"), $this->config->get("staticDefaultFile"));
- } else {
+ $location .= $this->toolbox->getLocationArgs();
+ $fileNameStatic = rtrim($this->config->get("staticDir"), '/').$location;
+ if(!$this->lookup->isFileLocation($location)) $fileNameStatic .= $this->config->get("staticDefaultFile");
+ } else if($statusCode == 404) {
$fileNameStatic = $this->config->get("staticDir").$this->config->get("staticErrorFile");
}
if(is_readable($fileNameStatic)) $fileName = $fileNameStatic;
@@ -316,26 +292,30 @@ class Yellow
$staticDirLength = strlenu($this->config->get("staticDir"));
$systemDirLength = strlenu($this->config->get("systemDir"));
return substru($fileName, 0, $staticDirLength) == $this->config->get("staticDir") ||
- substru($fileName, 0, $systemDirLength) == $this->config->get("systemDir");
+ substru($fileName, 0, $systemDirLength) == $this->config->get("systemDir");
}
- // Check if content directory
- function isContentDirectory($location)
+ // Check if request can be redirected into content directory
+ function isRequestContentDirectory($location)
{
- $path = $this->toolbox->findFileFromLocation($location, $this->config->get("contentDir"),
- $this->config->get("contentRootDir"), $this->config->get("contentHomeDir"), "", "");
- return is_dir($path);
+ $ok = false;
+ if($this->lookup->isFileLocation($location))
+ {
+ $path = $this->lookup->findFileFromLocation("$location/", true);
+ $ok = is_dir($path);
+ } else if($location=="/") {
+ $ok = $this->config->get("multiLanguageMode");
+ }
+ return $ok;
}
// Update configuration
function updateConfig()
{
- date_default_timezone_set($this->config->get("timeZone"));
- list($pathRoot, $pathHome) = $this->toolbox->findRootConfig($this->config->get("contentDir"),
- $this->config->get("contentRootDir"), $this->config->get("contentHomeDir"),
- $this->config->get("multiLanguageMode"));
+ list($pathRoot, $pathHome) = $this->lookup->getContentInformation();
$this->config->set("contentRootDir", $pathRoot);
$this->config->set("contentHomeDir", $pathHome);
+ date_default_timezone_set($this->config->get("timeZone"));
}
// Execute command
@@ -356,7 +336,7 @@ class Yellow
// Execute template
function template($name)
{
- $fileNameTemplate = $this->config->get("templateDir")."$name.php";
+ $fileNameTemplate = $this->config->get("templateDir")."$name.html";
if(is_file($fileNameTemplate))
{
$this->page->setLastModified(filemtime($fileNameTemplate));
@@ -364,6 +344,7 @@ class Yellow
require($fileNameTemplate);
} else {
$this->page->error(500, "Template '$name' does not exist!");
+ echo "Template error
\n";
}
}
@@ -379,6 +360,7 @@ class Yellow
require($fileNameSnippet);
} else {
$this->page->error(500, "Snippet '$name' does not exist!");
+ echo "Snippet error
\n";
}
}
@@ -403,11 +385,14 @@ class YellowPage
var $metaDataOffsetBytes; //meta data offset
var $metaData; //meta data
var $headerData; //response header
- var $parserData; //content data of page
+ var $outputData; //response output
+ var $pages; //page collection
var $parser; //content parser
+ var $parserData; //content data of page
var $parserSafeMode; //page is parsed in safe mode? (boolean)
- var $active; //page is active location? (boolean)
+ var $available; //page is available? (boolean)
var $visible; //page is visible location? (boolean)
+ var $active; //page is active location? (boolean)
var $cacheable; //page is cacheable? (boolean)
var $statusCode; //status code
@@ -416,6 +401,7 @@ class YellowPage
$this->yellow = $yellow;
$this->metaData = array();
$this->headerData = array();
+ $this->pages = new YellowPageCollection($yellow);
}
// Set request information
@@ -429,17 +415,16 @@ class YellowPage
}
// Parse page data
- function parseData($rawData, $cacheable, $statusCode = 0, $pageError = "")
+ function parseData($rawData, $cacheable, $statusCode, $pageError = "")
{
$this->lastModified = 0;
$this->rawData = $rawData;
- $this->parserData = "";
$this->parser = NULL;
+ $this->parserData = "";
$this->parserSafeMode = $this->yellow->config->get("parserSafeMode");
- $this->active = $this->yellow->toolbox->isActiveLocation($this->location, $this->yellow->page->location,
- $this->yellow->pages->getHomeLocation($this->yellow->page->location));
- $this->visible = $this->yellow->toolbox->isVisibleLocation($this->location, $this->fileName,
- $this->yellow->config->get("contentDir"));
+ $this->available = true;
+ $this->visible = $this->yellow->lookup->isVisibleLocation($this->location, $this->fileName);
+ $this->active = $this->yellow->lookup->isActiveLocation($this->location, $this->yellow->page->location);
$this->cacheable = $cacheable;
$this->statusCode = $statusCode;
$this->parseMeta($pageError);
@@ -465,48 +450,59 @@ class YellowPage
function parseMeta($pageError = "")
{
$this->metaData = array();
- $this->set("title", $this->yellow->toolbox->createTextTitle($this->location));
- $this->set("sitename", $this->yellow->config->get("sitename"));
- $this->set("author", $this->yellow->config->get("author"));
- $this->set("language", $this->yellow->toolbox->findLanguageFromFile($this->fileName,
- $this->yellow->config->get("contentDir"), $this->yellow->config->get("contentRootDir"),
- $this->yellow->config->get("language")));
- $this->set("theme", $this->yellow->toolbox->findNameFromFile($this->fileName,
- $this->yellow->config->get("themeDir"), $this->yellow->config->get("theme"), ".css"));
- $this->set("template", $this->yellow->toolbox->findNameFromFile($this->fileName,
- $this->yellow->config->get("templateDir"), $this->yellow->config->get("template"), ".php"));
- $this->set("modified", date("Y-m-d H:i:s", $this->yellow->toolbox->findModifiedFromFile($this->fileName)));
- $this->set("parser", $this->yellow->config->get("parser"));
-
- if(preg_match("/^(\xEF\xBB\xBF)?\-\-\-[\r\n]+(.+?)[\r\n]+\-\-\-[\r\n]+/s", $this->rawData, $parsed))
+ if(!is_null($this->rawData))
{
- $this->metaDataOffsetBytes = strlenb($parsed[0]);
- foreach(preg_split("/[\r\n]+/", $parsed[2]) as $line)
+ $this->set("title", $this->yellow->toolbox->createTextTitle($this->location));
+ $this->set("sitename", $this->yellow->config->get("sitename"));
+ $this->set("author", $this->yellow->config->get("author"));
+ $this->set("language", $this->yellow->lookup->findLanguageFromFile($this->fileName,
+ $this->yellow->config->get("language")));
+ $this->set("theme", $this->yellow->lookup->findNameFromFile($this->fileName,
+ $this->yellow->config->get("themeDir"), $this->yellow->config->get("theme"), ".css"));
+ $this->set("template", $this->yellow->lookup->findNameFromFile($this->fileName,
+ $this->yellow->config->get("templateDir"), $this->yellow->config->get("template"), ".html"));
+ $this->set("modified", date("Y-m-d H:i:s", $this->yellow->toolbox->getFileModified($this->fileName)));
+ $this->set("parser", $this->yellow->config->get("parser"));
+
+ if(preg_match("/^(\xEF\xBB\xBF)?\-\-\-[\r\n]+(.+?)[\r\n]+\-\-\-[\r\n]+/s", $this->rawData, $parts))
{
- preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
- if(!empty($matches[1]) && !strempty($matches[2])) $this->set(lcfirst($matches[1]), $matches[2]);
+ $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(lcfirst($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]);
}
- } else if(preg_match("/^(\xEF\xBB\xBF)?([^\r\n]+)[\r\n]+=+[\r\n]+/", $this->rawData, $parsed)) {
- $this->metaDataOffsetBytes = strlenb($parsed[0]);
- $this->set("title", $parsed[2]);
+
+ $titleHeader = ($this->location == $this->yellow->pages->getHomeLocation($this->location)) ?
+ $this->get("sitename") : $this->get("title")." - ".$this->get("sitename");
+ if($this->get("titleContent") == "-") $this->set("titleContent", "");
+ if(!$this->isExisting("titleContent")) $this->set("titleContent", $this->get("title"));
+ if(!$this->isExisting("titleHeader")) $this->set("titleHeader", $titleHeader);
+ if(!$this->isExisting("titleNavigation")) $this->set("titleNavigation", $this->get("title"));
+ $this->set("pageRead", $this->yellow->lookup->normaliseUrl(
+ $this->yellow->config->get("serverScheme"),
+ $this->yellow->config->get("serverName"),
+ $this->yellow->config->get("serverBase"), $this->location));
+ $this->set("pageEdit", $this->yellow->lookup->normaliseUrl(
+ $this->yellow->config->get("webinterfaceServerScheme"),
+ $this->yellow->config->get("webinterfaceServerName"),
+ $this->yellow->config->get("serverBase"),
+ rtrim($this->yellow->config->get("webinterfaceLocation"), '/').$this->location));
+ $this->set("pageFile", $this->yellow->lookup->normaliseFile($this->fileName));
+ if($this->get("status") == "hidden") $this->available = false;
+ } else {
+ $this->set("type", $this->yellow->toolbox->getFileExtension($this->fileName));
+ $this->set("modified", date("Y-m-d H:i:s", $this->yellow->toolbox->getFileModified($this->fileName)));
+ $this->set("pageFile", $this->yellow->lookup->normaliseFile($this->fileName, true));
}
-
- $titleHeader = ($this->location == $this->yellow->pages->getHomeLocation($this->location)) ?
- $this->get("sitename") : $this->get("title")." - ".$this->get("sitename");
- if($this->get("titleContent") == "-") $this->set("titleContent", "");
- if(!$this->isExisting("titleContent")) $this->set("titleContent", $this->get("title"));
- if(!$this->isExisting("titleHeader")) $this->set("titleHeader", $titleHeader);
- if(!$this->isExisting("titleNavigation")) $this->set("titleNavigation", $this->get("title"));
- $this->set("pageRead", $this->yellow->toolbox->getUrl(
- $this->yellow->config->get("serverScheme"), $this->yellow->config->get("serverName"),
- $this->yellow->config->get("serverBase"), $this->location));
- $this->set("pageEdit", $this->yellow->toolbox->getUrl(
- $this->yellow->config->get("webinterfaceServerScheme"), $this->yellow->config->get("webinterfaceServerName"),
- $this->yellow->config->get("serverBase"), rtrim($this->yellow->config->get("webinterfaceLocation"), '/').$this->location));
if(!empty($pageError)) $this->set("pageError", $pageError);
foreach($this->yellow->plugins->plugins as $key=>$value)
{
- if(method_exists($value["obj"], "onParseMeta")) $value["obj"]->onParseMeta($this, $this->rawData);
+ if(method_exists($value["obj"], "onParseMeta")) $value["obj"]->onParseMeta($this);
}
}
@@ -518,52 +514,69 @@ class YellowPage
if($this->yellow->plugins->isExisting($this->get("parser")))
{
$plugin = $this->yellow->plugins->plugins[$this->get("parser")];
- if(method_exists($plugin["obj"], "onParseContentText"))
+ if(method_exists($plugin["obj"], "onParseContentRaw"))
{
$this->parser = $plugin["obj"];
- $this->parserData = $this->parser->onParseContentText($this, $this->getContent(true));
+ $this->parserData = $this->parser->onParseContentRaw($this, $this->getContent(true));
foreach($this->yellow->plugins->plugins as $key=>$value)
{
- if(method_exists($value["obj"], "onParseContent"))
+ if(method_exists($value["obj"], "onParseContentText"))
{
- $output = $value["obj"]->onParseContent($this, $this->parserData);
+ $output = $value["obj"]->onParseContentText($this, $this->parserData);
if(!is_null($output)) { $this->parserData = $output; }
}
}
- 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));
- }
}
+ } else {
+ $this->parserData = $this->getContent(true);
+ $this->parserData = preg_replace("/@pageError/i", $this->get("pageError"), $this->parserData);
}
- if(defined("DEBUG") && DEBUG>=2) echo "YellowPage::parseContent location:".$this->location."
\n";
+ if(!$this->isExisting("description"))
+ {
+ $this->set("description", $this->yellow->toolbox->createTextDescription($this->parserData, 150));
+ }
+ if(!$this->isExisting("keywords"))
+ {
+ $this->set("keywords", $this->yellow->toolbox->createTextKeywords($this->get("title"), 10));
+ }
+ if(defined("DEBUG") && DEBUG>=3) echo "YellowPage::parseContent location:".$this->location."
\n";
}
}
- // Parse page custom type
- function parseType($name, $text, $typeShortcut)
+ // Parse page content block
+ function parseContentBlock($name, $text, $typeShortcut)
{
$output = NULL;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
- if(method_exists($value["obj"], "onParseType"))
+ if(method_exists($value["obj"], "onParseContentBlock"))
{
- $output = $value["obj"]->onParseType($this, $name, $text, $typeShortcut);
+ $output = $value["obj"]->onParseContentBlock($this, $name, $text, $typeShortcut);
if(!is_null($output)) break;
}
}
- if(defined("DEBUG") && DEBUG>=3 && !empty($name)) echo "YellowPage::parseType name:$name shortcut:$typeShortcut
\n";
+ if(defined("DEBUG") && DEBUG>=3 && !empty($name)) echo "YellowPage::parseContentBlock name:$name shortcut:$typeShortcut
\n";
return $output;
}
- // Parse page response
- function parseResponse()
+ // Parse page
+ function parsePage()
{
- $this->yellow->template($this->get("template"));
+ $this->outputData = NULL;
+ if(!$this->isError())
+ {
+ foreach($this->yellow->plugins->plugins as $key=>$value)
+ {
+ if(method_exists($value["obj"], "onParsePage")) $value["obj"]->onParsePage();
+ }
+ }
+ if(is_null($this->outputData))
+ {
+ ob_start();
+ $this->yellow->template($this->get("template"));
+ $this->outputData = ob_get_contents();
+ ob_end_clean();
+ }
if(!$this->isCacheable()) $this->setHeader("Cache-Control", "no-cache, must-revalidate");
if(!$this->isHeader("Content-Type")) $this->setHeader("Content-Type", "text/html; charset=utf-8");
if(!$this->isHeader("Content-Modified")) $this->setHeader("Content-Modified", $this->getModified(true));
@@ -580,30 +593,17 @@ class YellowPage
{
$this->error(500, "Parser '".$this->get("parser")."' does not exist!");
}
- if($this->statusCode==200 &&
- !$this->yellow->toolbox->isValidContentType($this->getHeader("Content-Type"), $this->getLocation()))
+ if($this->yellow->getRequestHandler()=="core" && $this->isExisting("redirect") && $this->statusCode==200)
{
- $this->error(500, "Type '".$this->getHeader("Content-Type")."' does not match file name!");
+ $location = $this->yellow->lookup->normaliseLocation($this->get("redirect"), $this->base, $this->location);
+ $location = $this->yellow->lookup->normaliseUrl($this->serverScheme, $this->serverName, "", $location);
+ $this->clean(301, $location);
}
- if($this->statusCode==200 && $this->yellow->getRequestHandler()=="core" && $this->isExisting("redirect"))
+ if($this->yellow->getRequestHandler()=="core" && !$this->isAvailable() && $this->statusCode==200)
{
- $location = $this->yellow->toolbox->normaliseLocation($this->get("redirect"), $this->base, $this->location);
- $locationHeader = $this->yellow->toolbox->getLocationHeader($this->serverScheme, $this->serverName, "", $location);
- $this->clean(301, $locationHeader);
- $this->setHeader("Cache-Control", "no-cache, must-revalidate");
+ $this->error(404);
}
- }
-
- // 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] : "";
+ if($this->isExisting("pageClean")) $this->page->outputData = NULL;
}
// Set page meta data
@@ -624,10 +624,10 @@ class YellowPage
return htmlspecialchars($this->get($key));
}
- // Return page meta data as human readable date
+ // Return page meta data as language specific date
function getDate($key, $dateFormat = "")
{
- if($this->yellow->text->isExisting($dateFormat))
+ if(!empty($dateFormat))
{
$format = $this->yellow->text->get($dateFormat);
} else {
@@ -650,17 +650,6 @@ class YellowPage
return $text;
}
- // Return page extra header, HTML encoded
- function getHeaderExtra()
- {
- $header = "";
- foreach($this->yellow->plugins->plugins as $key=>$value)
- {
- if(method_exists($value["obj"], "onHeaderExtra")) $header .= $value["obj"]->onHeaderExtra($this);
- }
- return $header;
- }
-
// Return parent page relative to current page, NULL if none
function getParent()
{
@@ -683,13 +672,31 @@ class YellowPage
function getSiblings($showInvisible = false)
{
$parentLocation = $this->yellow->pages->getParentLocation($this->location);
- return $this->yellow->pages->findChildren($parentLocation, $showInvisible);
+ return $this->yellow->pages->getChildren($parentLocation, $showInvisible);
}
// Return page collection with child pages relative to current page
function getChildren($showInvisible = false)
{
- return $this->yellow->pages->findChildren($this->location, $showInvisible);
+ return $this->yellow->pages->getChildren($this->location, $showInvisible);
+ }
+
+ // Return page collection with media files for current page
+ function getFiles($showInvisible = false)
+ {
+ return $this->yellow->files->index($showInvisible, true)->filter("pageFile", $this->get("pageFile"));
+ }
+
+ // Set page collection with additional pages for current page
+ function setPages($pages)
+ {
+ $this->pages = $pages;
+ }
+
+ // Return page collection with additional pages for current page
+ function getPages()
+ {
+ return $this->pages;
}
// Return absolute page location
@@ -701,7 +708,36 @@ class YellowPage
// Return page URL with server scheme and server name
function getUrl()
{
- return $this->yellow->toolbox->getUrl($this->serverScheme, $this->serverName, $this->base, $this->location);
+ return $this->yellow->lookup->normaliseUrl($this->serverScheme, $this->serverName, $this->base, $this->location);
+ }
+
+ // Return page extra HTML data
+ function getExtra()
+ {
+ $output = "";
+ foreach($this->yellow->plugins->plugins as $key=>$value)
+ {
+ if(method_exists($value["obj"], "onExtra")) $output .= $value["obj"]->onExtra();
+ }
+ return $output;
+ }
+
+ // 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] : "";
}
// Return page content modification date, Unix time or HTTP format
@@ -748,23 +784,50 @@ class YellowPage
}
// Respond with status code, no page content
- function clean($statusCode, $responseHeader = "")
+ function clean($statusCode, $location = "")
{
if(!$this->isExisting("pageClean") && $statusCode>0)
{
$this->statusCode = $statusCode;
$this->lastModified = 0;
$this->headerData = array();
- if(!empty($responseHeader)) $this->header($responseHeader);
+ if(!empty($location))
+ {
+ $this->setHeader("Location", $location);
+ $this->setHeader("Cache-Control", "no-cache, must-revalidate");
+ }
$this->set("pageClean", (string)$statusCode);
}
}
- // Add page response header, HTTP format
- function header($responseHeader)
+ // Check if page is available
+ function isAvailable()
{
- $tokens = explode(':', $responseHeader, 2);
- $this->setHeader(trim($tokens[0]), trim($tokens[1]));
+ return $this->available;
+ }
+
+ // Check if page is visible
+ function isVisible()
+ {
+ return $this->visible;
+ }
+
+ // Check if page is within current request
+ function isActive()
+ {
+ return $this->active;
+ }
+
+ // Check if page is cacheable
+ function isCacheable()
+ {
+ return $this->cacheable;
+ }
+
+ // Check if page with error
+ function isError()
+ {
+ return $this->isExisting("pageError");
}
// Check if response header exists
@@ -772,36 +835,12 @@ class YellowPage
{
return !is_null($this->headerData[$key]);
}
-
+
// Check if page meta data exists
function isExisting($key)
{
return !is_null($this->metaData[$key]);
}
-
- // Check if page with error
- function isError()
- {
- return $this->isExisting("pageError");
- }
-
- // Check if page is within current HTTP request
- function isActive()
- {
- return $this->active;
- }
-
- // Check if page is visible in navigation
- function isVisible()
- {
- return $this->visible;
- }
-
- // Check if page is cacheable
- function isCacheable()
- {
- return $this->cacheable;
- }
}
// Yellow page collection as array
@@ -809,7 +848,7 @@ class YellowPageCollection extends ArrayObject
{
var $yellow; //access to API
var $filterValue; //current page filter value
- var $paginationPage; //current page number in pagination
+ var $paginationNumber; //current page number in pagination
var $paginationCount; //highest page number in pagination
function __construct($yellow)
@@ -861,6 +900,18 @@ class YellowPageCollection extends ArrayObject
return $this;
}
+ // Filter page collection by file
+ function match($regex = "/.*/")
+ {
+ $array = array();
+ foreach($this->getArrayCopy() as $page)
+ {
+ if(preg_match($regex, basename($page->fileName))) array_push($array, $page);
+ }
+ $this->exchangeArray($array);
+ return $this;
+ }
+
// Merge page collection
function merge($input)
{
@@ -910,23 +961,24 @@ class YellowPageCollection extends ArrayObject
// Paginate page collection
function pagination($limit, $reverse = true)
{
- $array = $this->getArrayCopy();
- if($reverse) $array = array_reverse($array);
- $this->paginationPage = 1;
+ $this->paginationNumber = 1;
$this->paginationCount = ceil($this->count() / $limit);
- if($limit < $this->count())
+ $pagination = $this->yellow->config->get("contentPagination");
+ if(isset($_REQUEST[$pagination])) $this->paginationNumber = intval($_REQUEST[$pagination]);
+ if($this->paginationNumber > $this->paginationCount) $this->paginationNumber = 0;
+ if($this->paginationNumber >= 1)
{
- $pagination = $this->yellow->config->get("contentPagination");
- if(isset($_REQUEST[$pagination])) $this->paginationPage = max(1, $_REQUEST[$pagination]);
+ $array = $this->getArrayCopy();
+ if($reverse) $array = array_reverse($array);
+ $this->exchangeArray(array_slice($array, ($this->paginationNumber - 1) * $limit, $limit));
}
- $this->exchangeArray(array_slice($array, ($this->paginationPage - 1) * $limit, $limit));
return $this;
}
// Return current page number in pagination
- function getPaginationPage()
+ function getPaginationNumber()
{
- return $this->paginationPage;
+ return $this->paginationNumber;
}
// Return highest page number in pagination
@@ -936,7 +988,7 @@ class YellowPageCollection extends ArrayObject
}
// Return absolute location for a page in pagination
- function getLocationPage($pageNumber)
+ function getPaginationLocation($pageNumber)
{
if($pageNumber>=1 && $pageNumber<=$this->paginationCount)
{
@@ -949,19 +1001,19 @@ class YellowPageCollection extends ArrayObject
}
// Return absolute location for previous page in pagination
- function getLocationPrevious()
+ function getPaginationPrevious()
{
- $pageNumber = $this->paginationPage;
+ $pageNumber = $this->paginationNumber;
$pageNumber = ($pageNumber>1 && $pageNumber<=$this->paginationCount) ? $pageNumber-1 : 0;
- return $this->getLocationPage($pageNumber);
+ return $this->getPaginationLocation($pageNumber);
}
// Return absolute location for next page in pagination
- function getLocationNext()
+ function getPaginationNext()
{
- $pageNumber = $this->paginationPage;
+ $pageNumber = $this->paginationNumber;
$pageNumber = ($pageNumber>=1 && $pageNumber<$this->paginationCount) ? $pageNumber+1 : 0;
- return $this->getLocationPage($pageNumber);
+ return $this->getPaginationLocation($pageNumber);
}
// Return current page filter
@@ -978,26 +1030,14 @@ class YellowPageCollection extends ArrayObject
return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($modified) : $modified;
}
- // Return first page in page collection
- function first()
- {
- return $this->offsetGet(0);
- }
-
- // Return last page in page collection
- function last()
- {
- return $this->offsetGet($this->count()-1);
- }
-
- // Check if there is an active pagination
+ // Check if there is a pagination
function isPagination()
{
return $this->paginationCount > 1;
}
}
-// Yellow pages from file system
+// Yellow pages
class YellowPages
{
var $yellow; //access to API
@@ -1011,130 +1051,29 @@ class YellowPages
$this->pages = array();
}
- // Return page collection with all pages from file system
- function index($showInvisible = false, $showMulti = false, $levelMax = 0)
- {
- $rootLocation = $showMulti ? "" : $this->getRootLocation($this->yellow->page->location);
- return $this->findChildrenRecursive($rootLocation, $showInvisible, $levelMax);
- }
-
- // Return page collection with top-level navigation
- function top($showInvisible = false)
- {
- $rootLocation = $this->getRootLocation($this->yellow->page->location);
- return $this->findChildren($rootLocation, $showInvisible);
- }
-
- // Return page collection with path ancestry
- function path($location, $absoluteLocation = false)
- {
- $pages = new YellowPageCollection($this->yellow);
- if($page = $this->find($location, $absoluteLocation))
- {
- $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);
- }
- 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));
- $postfix = substru($location, strlenu($this->getRootLocation($location)) - 4);
- $this->scanChildren("");
- foreach($this->pages[""] as $page)
- {
- if($content = $this->find(substru($page->location, 4).$postfix))
- {
- if($content->isVisible() || $showInvisible) $pages->append($content);
- }
- }
- return $pages;
- }
-
- // Return empty page collection
- function create()
- {
- return new YellowPageCollection($this->yellow);
- }
-
- // Return one page from file system, NULL if not found
- function find($location, $absoluteLocation = false)
- {
- if(!$this->yellow->toolbox->isRootLocation($location))
- {
- if($absoluteLocation) $location = substru($location, strlenu($this->yellow->page->base));
- $parentLocation = $this->getParentLocation($location);
- $this->scanChildren($parentLocation);
- foreach($this->pages[$parentLocation] as $page) if($page->location == $location) { $found = true; break; }
- }
- return $found ? $page : NULL;
- }
-
- // Find child pages
- function findChildren($location, $showInvisible = false)
- {
- $pages = new YellowPageCollection($this->yellow);
- $this->scanChildren($location);
- foreach($this->pages[$location] as $page)
- {
- if($page->isVisible() || $showInvisible)
- {
- if(!$this->yellow->toolbox->isRootLocation($page->location)) $pages->append($page);
- }
- }
- return $pages;
- }
-
- // Find child pages recursively
- function findChildrenRecursive($location, $showInvisible = false, $levelMax = 0)
- {
- --$levelMax;
- $pages = new YellowPageCollection($this->yellow);
- $this->scanChildren($location);
- foreach($this->pages[$location] as $page)
- {
- if($page->isVisible() || $showInvisible)
- {
- if(!$this->yellow->toolbox->isRootLocation($page->location)) $pages->append($page);
- if(!$this->yellow->toolbox->isFileLocation($page->location) && $levelMax!=0)
- {
- $pages->merge($this->findChildrenRecursive($page->location, $showInvisible, $levelMax));
- }
- }
- }
- return $pages;
- }
-
- // Scan child pages on demand
- function scanChildren($location)
+ // Scan file system on demand
+ function scanLocation($location)
{
if(is_null($this->pages[$location]))
{
- if(defined("DEBUG") && DEBUG>=2) echo "YellowPages::scanChildren location:$location
\n";
+ if(defined("DEBUG") && DEBUG>=2) echo "YellowPages::scanLocation location:$location
\n";
$this->pages[$location] = array();
$serverScheme = $this->yellow->page->serverScheme;
$serverName = $this->yellow->page->serverName;
$base = $this->yellow->page->base;
if(empty($location))
{
- $rootLocations = $this->yellow->toolbox->findRootLocations($this->yellow->config->get("contentDir"),
- $this->yellow->config->get("contentRootDir"));
+ $rootLocations = $this->yellow->lookup->findRootLocations();
foreach($rootLocations as $rootLocation)
{
+ list($rootLocation, $fileName) = explode(' ', $rootLocation, 2);
$page = new YellowPage($this->yellow);
- $page->setRequestInformation($serverScheme, $serverName, $base, $rootLocation, "");
- $page->parseData("", false);
+ $page->setRequestInformation($serverScheme, $serverName, $base, $rootLocation, $fileName);
+ $page->parseData("", false, 0);
array_push($this->pages[$location], $page);
}
} else {
- $fileNames = $this->yellow->toolbox->findChildrenFromLocation($location, $this->yellow->config->get("contentDir"),
- $this->yellow->config->get("contentRootDir"), $this->yellow->config->get("contentHomeDir"),
- $this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
+ $fileNames = $this->yellow->lookup->findChildrenFromLocation($location);
foreach($fileNames as $fileName)
{
$fileHandle = @fopen($fileName, "r");
@@ -1149,15 +1088,128 @@ class YellowPages
}
$page = new YellowPage($this->yellow);
$page->setRequestInformation($serverScheme, $serverName, $base,
- $this->yellow->toolbox->findLocationFromFile($fileName, $this->yellow->config->get("contentDir"),
- $this->yellow->config->get("contentRootDir"), $this->yellow->config->get("contentHomeDir"),
- $this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension")),
- $fileName);
+ $this->yellow->lookup->findLocationFromFile($fileName), $fileName);
$page->parseData($fileData, false, $statusCode);
array_push($this->pages[$location], $page);
}
}
}
+ return $this->pages[$location];
+ }
+
+ // Return page from file system, NULL if not found
+ function find($location, $absoluteLocation = false)
+ {
+ if($absoluteLocation) $location = substru($location, strlenu($this->yellow->page->base));
+ foreach($this->scanLocation($this->getParentLocation($location)) as $page)
+ {
+ if($page->location == $location)
+ {
+ if(!$this->yellow->lookup->isRootLocation($page->location)) { $found = true; break; }
+ }
+ }
+ return $found ? $page : NULL;
+ }
+
+ // Return page collection with all pages
+ function index($showInvisible = false, $showMultiLanguage = false, $levelMax = 0)
+ {
+ $rootLocation = $showMultiLanguage ? "" : $this->getRootLocation($this->yellow->page->location);
+ return $this->getChildrenRecursive($rootLocation, $showInvisible, $levelMax);
+ }
+
+ // Return page collection with top-level navigation
+ function top($showInvisible = false)
+ {
+ $rootLocation = $this->getRootLocation($this->yellow->page->location);
+ return $this->getChildren($rootLocation, $showInvisible);
+ }
+
+ // Return page collection with path ancestry
+ function path($location, $absoluteLocation = false)
+ {
+ $pages = new YellowPageCollection($this->yellow);
+ if($absoluteLocation) $location = substru($location, strlenu($this->yellow->page->base));
+ if($page = $this->find($location))
+ {
+ $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);
+ }
+ 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));
+ $locationEnd = substru($location, strlenu($this->getRootLocation($location)) - 4);
+ foreach($this->scanLocation("") as $page)
+ {
+ if($content = $this->find(substru($page->location, 4).$locationEnd))
+ {
+ if($content->isAvailable() && ($content->isVisible() || $showInvisible))
+ {
+ if(!$this->yellow->lookup->isRootLocation($content->location)) $pages->append($content);
+ }
+ }
+ }
+ return $pages;
+ }
+
+ // Return page collection that's empty
+ function clean()
+ {
+ return new YellowPageCollection($this->yellow);
+ }
+
+ // Return available languages
+ function getLanguages($showInvisible = false)
+ {
+ $languages = array();
+ foreach($this->scanLocation("") as $page)
+ {
+ if($page->isAvailable() && ($page->isVisible() || $showInvisible))
+ {
+ array_push($languages, $page->get("language"));
+ }
+ }
+ return $languages;
+ }
+
+ // Return child pages
+ function getChildren($location, $showInvisible = false)
+ {
+ $pages = new YellowPageCollection($this->yellow);
+ foreach($this->scanLocation($location) as $page)
+ {
+ if($page->isAvailable() && ($page->isVisible() || $showInvisible))
+ {
+ if(!$this->yellow->lookup->isRootLocation($page->location)) $pages->append($page);
+ }
+ }
+ return $pages;
+ }
+
+ // Return child pages recursively
+ function getChildrenRecursive($location, $showInvisible = false, $levelMax = 0)
+ {
+ --$levelMax;
+ $pages = new YellowPageCollection($this->yellow);
+ foreach($this->scanLocation($location) as $page)
+ {
+ if($page->isAvailable() && ($page->isVisible() || $showInvisible))
+ {
+ if(!$this->yellow->lookup->isRootLocation($page->location)) $pages->append($page);
+ if(!$this->yellow->lookup->isFileLocation($page->location) && $levelMax!=0)
+ {
+ $pages->merge($this->getChildrenRecursive($page->location, $showInvisible, $levelMax));
+ }
+ }
+ }
+ return $pages;
}
// Return root location
@@ -1166,8 +1218,7 @@ class YellowPages
$rootLocation = "root/";
if($this->yellow->config->get("multiLanguageMode"))
{
- $this->scanChildren("");
- foreach($this->pages[""] as $page)
+ foreach($this->scanLocation("") as $page)
{
$token = substru($page->location, 4);
if($token!="/" && substru($location, 0, strlenu($token))==$token) { $rootLocation = "root$token"; break; }
@@ -1185,24 +1236,225 @@ class YellowPages
// Return parent location
function getParentLocation($location)
{
- $prefix = rtrim(substru($this->getRootLocation($location), 4), '/');
- if(preg_match("#^($prefix.*\/).+?$#", $location, $matches))
+ $token = rtrim(substru($this->getRootLocation($location), 4), '/');
+ if(preg_match("#^($token.*\/).+?$#", $location, $matches))
{
- if($matches[1]!="$prefix/" || $this->yellow->toolbox->isFileLocation($location)) $parentLocation = $matches[1];
+ if($matches[1]!="$token/" || $this->yellow->lookup->isFileLocation($location)) $parentLocation = $matches[1];
}
- if(empty($parentLocation)) $parentLocation = "root$prefix/";
+ if(empty($parentLocation)) $parentLocation = "root$token/";
return $parentLocation;
}
// Return top-level location
function getParentTopLocation($location)
{
- $prefix = rtrim(substru($this->getRootLocation($location), 4), '/');
- if(preg_match("#^($prefix.+?\/)#", $location, $matches)) $parentTopLocation = $matches[1];
- if(empty($parentTopLocation)) $parentTopLocation = "$prefix/";
+ $token = rtrim(substru($this->getRootLocation($location), 4), '/');
+ if(preg_match("#^($token.+?\/)#", $location, $matches)) $parentTopLocation = $matches[1];
+ if(empty($parentTopLocation)) $parentTopLocation = "$token/";
return $parentTopLocation;
}
}
+
+// Yellow files
+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
\n";
+ $this->files[$location] = array();
+ $serverScheme = $this->yellow->page->serverScheme;
+ $serverName = $this->yellow->page->serverName;
+ $base = $this->yellow->page->base;
+ 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);
+ $file->setRequestInformation($serverScheme, $serverName, $base, "/".$fileName, $fileName);
+ $file->parseData(NULL, false, 0);
+ array_push($this->files[$location], $file);
+ }
+ }
+ return $this->files[$location];
+ }
+
+ // Return page with media file information, NULL if not found
+ function find($location, $absoluteLocation = false)
+ {
+ if($absoluteLocation) $location = substru($location, strlenu($this->yellow->page->base));
+ foreach($this->scanLocation($this->getParentLocation($location)) as $file)
+ {
+ if($file->location == $location) { $found = true; break; }
+ }
+ return $found ? $file : NULL;
+ }
+
+ // Return page collection with all media files
+ function index($showInvisible = false, $showMultiPass = false, $levelMax = 0)
+ {
+ 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))
+ {
+ $files->append($file);
+ }
+ }
+ return $files;
+ }
+
+ // Return child files recursively
+ 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))
+ {
+ $files->append($file);
+ 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)
+ {
+ return "/".$this->yellow->config->get("mediaDir");
+ }
+
+ // Return parent location
+ function getParentLocation($location)
+ {
+ $token = rtrim("/".$this->yellow->config->get("mediaDir"), '/');
+ if(preg_match("#^($token.*\/).+?$#", $location, $matches))
+ {
+ if($matches[1]!="$token/" || $this->yellow->lookup->isFileLocation($location)) $parentLocation = $matches[1];
+ }
+ if(empty($parentLocation)) $parentLocation = "";
+ return $parentLocation;
+ }
+
+ // Return top-level location
+ function getParentTopLocation($location)
+ {
+ $token = rtrim("/".$this->yellow->config->get("mediaDir"), '/');
+ if(preg_match("#^($token.+?\/)#", $location, $matches)) $parentTopLocation = $matches[1];
+ if(empty($parentTopLocation)) $parentTopLocation = "$token/";
+ return $parentTopLocation;
+ }
+}
+
+// Yellow plugins
+class YellowPlugins
+{
+ var $yellow; //access to API
+ var $plugins; //registered plugins
+ var $modified; //plugin modification date
+
+ function __construct($yellow)
+ {
+ $this->yellow = $yellow;
+ $this->plugins = array();
+ $this->modified = 0;
+ }
+
+ // Load plugins
+ function load()
+ {
+ $path = $this->yellow->config->get("coreDir");
+ foreach($this->yellow->toolbox->getDirectoryEntries($path, "/^core-.*\.php$/", true, false) as $entry)
+ {
+ $this->modified = max($this->modified, filemtime($entry));
+ global $yellow;
+ require_once($entry);
+ }
+ $path = $this->yellow->config->get("pluginDir");
+ foreach($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.php$/", true, false) as $entry)
+ {
+ $this->modified = max($this->modified, filemtime($entry));
+ global $yellow;
+ require_once($entry);
+ }
+ foreach($this->plugins as $key=>$value)
+ {
+ $this->plugins[$key]["obj"] = new $value["class"];
+ if(defined("DEBUG") && DEBUG>=3) echo "YellowPlugins::load class:$value[class] $value[version]
\n";
+ if(method_exists($this->plugins[$key]["obj"], "onLoad")) $this->plugins[$key]["obj"]->onLoad($yellow);
+ }
+ }
+
+ // Register plugin
+ function register($name, $class, $version)
+ {
+ if(!$this->isExisting($name))
+ {
+ $this->plugins[$name] = array();
+ $this->plugins[$name]["class"] = $class;
+ $this->plugins[$name]["version"] = $version;
+ }
+ }
+
+ // Return plugin
+ function get($name)
+ {
+ return $this->plugins[$name]["obj"];
+ }
+
+ // Return plugins modification date, Unix time or HTTP format
+ 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]);
+ }
+}
// Yellow configuration
class YellowConfig
@@ -1455,66 +1707,393 @@ class YellowText
return !is_null($this->text[$language]) && !is_null($this->text[$language][$key]);
}
}
-
-// Yellow plugins
-class YellowPlugins
-{
- var $plugins; //registered plugins
- var $modified; //plugin modification date
- function __construct()
+// Yellow location and file lookup
+class YellowLookup
+{
+ var $yellow; //access to API
+
+ function __construct($yellow)
{
- $this->plugins = array();
- $this->modified = 0;
+ $this->yellow = $yellow;
}
- // Load plugins
- function load()
+ // Return root locations
+ function findRootLocations($includePath = true)
{
- global $yellow;
- $path = $yellow->config->get("coreDir");
- foreach($yellow->toolbox->getDirectoryEntries($path, "/^core-.*\.php$/", true, false) as $entry) require_once($entry);
- $path = $yellow->config->get("pluginDir");
- foreach($yellow->toolbox->getDirectoryEntries($path, "/^.*\.php$/", true, false) as $entry)
+ $locations = array();
+ $pathBase = $this->yellow->config->get("contentDir");
+ $pathRoot = $this->yellow->config->get("contentRootDir");
+ if(!empty($pathRoot))
{
- $this->modified = max($this->modified, filemtime($entry));
- require_once($entry);
+ foreach($this->yellow->toolbox->getDirectoryEntries($pathBase, "/.*/", true, true, false) as $entry)
+ {
+ $token = $this->normaliseName($entry)."/";
+ if($token == $pathRoot) $token = "";
+ array_push($locations, $includePath ? "root/$token $pathBase$entry/" : "root/$token");
+ if(defined("DEBUG") && DEBUG>=2) echo "YellowLookup::findRootLocations root/$token
\n";
+ }
+ } else {
+ array_push($locations, $includePath ? "root/ $pathBase" : "root/");
}
- foreach($this->plugins as $key=>$value)
+ return $locations;
+ }
+
+ // Return location from file path
+ function findLocationFromFile($fileName)
+ {
+ $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");
+ if(substru($fileName, 0, strlenu($pathBase)) == $pathBase)
{
- $this->plugins[$key]["obj"] = new $value["class"];
- if(defined("DEBUG") && DEBUG>=3) echo "YellowPlugins::load class:$value[class] $value[version]
\n";
- if(method_exists($this->plugins[$key]["obj"], "onLoad")) $this->plugins[$key]["obj"]->onLoad($yellow);
+ $fileName = substru($fileName, strlenu($pathBase));
+ $tokens = explode('/', $fileName);
+ if(!empty($pathRoot))
+ {
+ $token = $this->normaliseName($tokens[0]).'/';
+ if($token!=$pathRoot) $location .= $token;
+ array_shift($tokens);
+ }
+ for($i=0; $inormaliseName($tokens[$i]).'/';
+ if($i || $token!=$pathHome) $location .= $token;
+ }
+ $token = $this->normaliseName($tokens[$i]);
+ $fileFolder = $this->normaliseName($tokens[$i-1]).$fileExtension;
+ if($token!=$fileDefault && $token!=$fileFolder) $location .= $this->normaliseName($tokens[$i], true, true);
+ $extension = ($pos = strrposu($fileName, '.')) ? substru($fileName, $pos) : "";
+ if($extension != $fileExtension) $invalid = true;
+ } else {
+ $invalid = true;
}
- }
-
- // Register plugin
- function register($name, $class, $version)
- {
- if(!$this->isExisting($name))
+ if(defined("DEBUG") && DEBUG>=2)
{
- $this->plugins[$name] = array();
- $this->plugins[$name]["class"] = $class;
- $this->plugins[$name]["version"] = $version;
+ $debug = ($invalid ? "INVALID" : $location)." <- $pathBase$fileName";
+ echo "YellowLookup::findLocationFromFile $debug
\n";
}
+ return $invalid ? "" : $location;
}
- // Return plugin object
- function get($name)
+ // Return file path from location
+ function findFileFromLocation($location, $directory = false)
{
- return $this->plugins[$name]["obj"];
+ $path = $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");
+ $tokens = explode('/', $location);
+ if($this->isRootLocation($location))
+ {
+ if(!empty($pathRoot))
+ {
+ $token = (count($tokens) > 2) ? $tokens[1] : rtrim($pathRoot, '/');
+ $path .= $this->findFileDirectory($path, $token, true, true, $found, $invalid);
+ }
+ } else {
+ if(!empty($pathRoot))
+ {
+ if(count($tokens) > 2)
+ {
+ if($this->normaliseName($tokens[1]) == $this->normaliseName($pathRoot)) $invalid = true;
+ $path .= $this->findFileDirectory($path, $tokens[1], false, true, $found, $invalid);
+ if($found) array_shift($tokens);
+ }
+ if(!$found) $path .= $this->findFileDirectory($path, rtrim($pathRoot, '/'), true, true, $found, $invalid);
+
+ }
+ if(count($tokens) > 2)
+ {
+ if($this->normaliseName($tokens[1]) == $this->normaliseName($pathHome)) $invalid = true;
+ for($i=1; $ifindFileDirectory($path, $tokens[$i], true, true, $found, $invalid);
+ }
+ } else {
+ $i = 1;
+ $tokens[0] = rtrim($pathHome, '/');
+ $path .= $this->findFileDirectory($path, $tokens[0], true, true, $found, $invalid);
+ }
+ if(!$directory)
+ {
+ $fileFolder = $tokens[$i-1].$fileExtension;
+ if(!empty($tokens[$i]))
+ {
+ $token = $tokens[$i].$fileExtension;
+ if($token==$fileDefault || $token==$fileFolder) $invalid = true;
+ $path .= $this->findFileDirectory($path, $token, true, false, $found, $invalid);
+ } else {
+ $path .= $this->findFileDefault($path, $fileDefault, $fileFolder);
+ }
+ if(defined("DEBUG") && DEBUG>=2)
+ {
+ $debug = "$location -> ".($invalid ? "INVALID" : $path);
+ echo "YellowLookup::findFileFromLocation $debug
\n";
+ }
+ }
+ }
+ return $invalid ? "" : $path;
}
- // Return plugins modification date, Unix time or HTTP format
- function getModified($httpFormat = false)
+ // Return file or directory that matches token
+ function findFileDirectory($path, $token, $tokenFailback, $directory, &$found, &$invalid)
{
- return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($this->modified) : $this->modified;
+ if($this->normaliseName($token) != $token) $invalid = true;
+ if(!$invalid)
+ {
+ $regex = "/^[\d\-\_\.]*".strreplaceu('-', '.', $token)."$/";
+ foreach($this->yellow->toolbox->getDirectoryEntries($path, $regex, false, $directory, false) as $entry)
+ {
+ if($this->normaliseName($entry) == $token) { $token = $entry; $found = true; break; }
+ }
+ }
+ if($directory) $token .= '/';
+ return ($tokenFailback || $found) ? $token : "";
}
- // Check if plugin exists
- function isExisting($name)
+ // Return default file in directory
+ function findFileDefault($path, $fileDefault, $fileFolder)
{
- return !is_null($this->plugins[$name]);
+ $token = $fileDefault;
+ if(!is_file($path."/".$fileDefault))
+ {
+ $regex = "/^[\d\-\_\.]*($fileDefault|$fileFolder)$/";
+ foreach($this->yellow->toolbox->getDirectoryEntries($path, $regex, true, false, false) as $entry)
+ {
+ if($this->normaliseName($entry) == $fileDefault) { $token = $entry; break; }
+ if($this->normaliseName($entry) == $fileFolder) { $token = $entry; break; }
+ }
+ }
+ return $token;
+ }
+
+ // Return children from location
+ function findChildrenFromLocation($location)
+ {
+ $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)
+ {
+ $fileFolder = $this->normaliseName($entry).$fileExtension;
+ $token = $this->findFileDefault($path.$entry, $fileDefault, $fileFolder);
+ array_push($fileNames, $path.$entry."/".$token);
+ }
+ if(!$this->isRootLocation($location))
+ {
+ $fileFolder = $this->normaliseName(basename($path)).$fileExtension;
+ $regex = "/^.*\\".$fileExtension."$/";
+ foreach($this->yellow->toolbox->getDirectoryEntries($path, $regex, true, false, false) as $entry)
+ {
+ if($this->normaliseName($entry) == $fileDefault) continue;
+ if($this->normaliseName($entry) == $fileFolder) continue;
+ if($this->normaliseName($entry, true, true) == "") continue;
+ array_push($fileNames, $path.$entry);
+ }
+ }
+ }
+ return $fileNames;
+ }
+
+ // Return language from file path
+ function findLanguageFromFile($fileName, $languageDefault)
+ {
+ $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->normaliseName($matches[1]);
+ if(strlenu($name) == 2) $language = $name;
+ }
+ return $language;
+ }
+
+ // Return theme/template name from file path
+ function findNameFromFile($fileName, $pathBase, $nameDefault, $fileExtension)
+ {
+ $name = "";
+ if(preg_match("/^.*\/(.+?)$/", dirname($fileName), $matches)) $name = $this->normaliseName($matches[1]);
+ if(!is_file("$pathBase$name$fileExtension")) $name = $this->normaliseName($nameDefault);
+ return $name;
+ }
+
+ // Return file path for new page
+ function findFileNew($fileName, $pathBase, $fileNew, $fileDefault)
+ {
+ if(preg_match("/^.*\/(.+?)$/", dirname($fileName), $matches)) $name = $this->normaliseName($matches[1]);
+ $fileName = strreplaceu("(.*)", $name, $pathBase.$fileNew);
+ if(!is_file($fileName))
+ {
+ $name = $this->normaliseName($fileDefault, true, true);
+ $fileName = strreplaceu("(.*)", $name, $pathBase.$fileNew);
+ }
+ return $fileName;
+ }
+
+ // Return file path from title
+ function findFileFromTitle($titlePrefix, $titleText, $fileName, $fileDefault, $fileExtension)
+ {
+ preg_match("/^([\d\-\_\.]*)(.*)$/", $titlePrefix, $matches);
+ if(preg_match("/\d$/", $matches[1])) $matches[1] .= '-';
+ $titleText = $this->normaliseName($titleText, false, false, true);
+ preg_match("/^([\d\-\_\.]*)(.*)$/", $matches[1].$titleText, $matches);
+ $fileNamePrefix = $matches[1];
+ $fileNameText = empty($matches[2]) ? $fileDefault : $matches[2].$fileExtension;
+ return dirname($fileName)."/".$fileNamePrefix.$fileNameText;
+ }
+
+ // Normalise file/directory/other name
+ function normaliseName($text, $removePrefix = true, $removeExtension = false, $filterStrict = false)
+ {
+ if($removeExtension) $text = ($pos = strrposu($text, '.')) ? substru($text, 0, $pos) : $text;
+ if($removePrefix) if(preg_match("/^[\d\-\_\.]+(.*)$/", $text, $matches)) $text = $matches[1];
+ if($filterStrict) $text = strreplaceu('.', '-', strtoloweru($text));
+ return preg_replace("/[^\pL\d\-\_\.]/u", "-", rtrim($text, '/'));
+ }
+
+ // Normalise content/media file name
+ function normaliseFile($fileName, $convertExtension = false)
+ {
+ $fileName = basename($fileName);
+ if($convertExtension)
+ {
+ $fileName = ($pos = strposu($fileName, '.')) ? substru($fileName, 0, $pos) : $fileName;
+ $fileName .= $this->yellow->config->get("contentExtension");
+ }
+ return $fileName;
+ }
+
+ // Normalise location, make absolute location
+ function normaliseLocation($location, $pageBase, $pageLocation, $staticLocation = "", $filterStrict = true)
+ {
+ if(!preg_match("/^\w+:/", trim(html_entity_decode($location, ENT_QUOTES, "UTF-8"))))
+ {
+ if(empty($staticLocation) || !preg_match("#^$staticLocation#", $location))
+ {
+ if(preg_match("/^\#/", $location))
+ {
+ $location = $pageBase.$pageLocation.$location;
+ } else if(!preg_match("/^\//", $location)) {
+ $location = $this->getDirectoryLocation($pageBase.$pageLocation).$location;
+ } else if(!preg_match("#^$pageBase#", $location)) {
+ $location = $pageBase.$location;
+ }
+ }
+ } else {
+ if($filterStrict && !preg_match("/^(http|https|ftp|mailto):/", $location)) $location = "error-xss-filter";
+ }
+ return $location;
+ }
+
+ // Normalise URL, make absolute URL
+ function normaliseUrl($serverScheme, $serverName, $base, $location)
+ {
+ if(!preg_match("/^\w+:/", $location))
+ {
+ $url = "$serverScheme://$serverName$base$location";
+ } else {
+ $url = $location;
+ }
+ return $url;
+ }
+
+ // Return content information
+ function getContentInformation()
+ {
+ $path = $pathBase = $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->normaliseName($entry) == $root) { $token = $entry; break; }
+ }
+ $pathRoot = $this->normaliseName($token)."/";
+ $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->normaliseName($entry) == $home) { $token = $entry; break; }
+ }
+ $pathHome = $this->normaliseName($token)."/";
+ }
+ return array($pathRoot, $pathHome);
+ }
+
+ // Return directory location
+ function getDirectoryLocation($location)
+ {
+ return ($pos = strrposu($location, '/')) ? substru($location, 0, $pos+1) : "/";
+ }
+
+ // Check if location is specifying root
+ function isRootLocation($location)
+ {
+ return $location[0] != "/";
+ }
+
+ // Check if location is specifying file or directory
+ function isFileLocation($location)
+ {
+ return substru($location, -1, 1) != "/";
+ }
+
+ // Check if location is visible
+ function isVisibleLocation($location, $fileName)
+ {
+ $visible = true;
+ $pathBase = $this->yellow->config->get("contentDir");
+ if(substru($fileName, 0, strlenu($pathBase)) == $pathBase)
+ {
+ $fileName = substru($fileName, strlenu($pathBase));
+ $tokens = explode('/', $fileName);
+ for($i=0; $iyellow->pages->getHomeLocation($currentLocation))
+ {
+ $active = substru($currentLocation, 0, strlenu($location))==$location;
+ } else {
+ $active = $this->getDirectoryLocation($currentLocation)==$location;
+ }
+ return $active;
+ }
+
+ // Check if location is valid
+ function isValidLocation($location)
+ {
+ $string = "";
+ $tokens = explode('/', $location);
+ for($i=1; $inormaliseName($tokens[$i]);
+ return $location == $string;
}
}
@@ -1578,7 +2157,8 @@ class YellowToolbox
}
if(preg_match("/^(.*?\/)([^\/]+:.*)$/", $location, $matches))
{
- $location = $matches[1];
+ $_SERVER["LOCATION"] = $location = $matches[1];
+ $_SERVER["LOCATION_ARGS"] = $matches[2];
foreach(explode('/', $matches[2]) as $token)
{
preg_match("/^(.*?):(.*)$/", $token, $matches);
@@ -1597,25 +2177,21 @@ class YellowToolbox
// Return location arguments from current HTTP request
function getLocationArgs()
{
- if(preg_match("/^(.*?\/)([^\/]+:.*)$/", $this->getLocation(), $matches)) $locationArgs = $matches[2];
- return $locationArgs;
+ return $_SERVER["LOCATION_ARGS"];
}
// Return location arguments from current HTTP request, modify an argument
function getLocationArgsNew($arg, $pagination)
{
preg_match("/^(.*?):(.*)$/", $arg, $args);
- if(preg_match("/^(.*?\/)([^\/]+:.*)$/", $this->getLocation(), $matches))
+ foreach(explode('/', $_SERVER["LOCATION_ARGS"]) as $token)
{
- foreach(explode('/', $matches[2]) as $token)
+ preg_match("/^(.*?):(.*)$/", $token, $matches);
+ if($matches[1] == $args[1]) { $matches[2] = $args[2]; $found = true; }
+ if(!empty($matches[1]) && !strempty($matches[2]))
{
- preg_match("/^(.*?):(.*)$/", $token, $matches);
- if($matches[1] == $args[1]) { $matches[2] = $args[2]; $found = true; }
- if(!empty($matches[1]) && !strempty($matches[2]))
- {
- if(!empty($locationArgs)) $locationArgs .= '/';
- $locationArgs .= "$matches[1]:$matches[2]";
- }
+ if(!empty($locationArgs)) $locationArgs .= '/';
+ $locationArgs .= "$matches[1]:$matches[2]";
}
}
if(!$found && !empty($args[1]) && !strempty($args[2]))
@@ -1625,7 +2201,7 @@ class YellowToolbox
}
if(!empty($locationArgs))
{
- if(!$this->isPaginationLocation($locationArgs, $pagination)) $locationArgs .= '/';
+ if(!$this->isLocationArgsPagination($locationArgs, $pagination)) $locationArgs .= '/';
$locationArgs = $this->normaliseArgs($locationArgs, false, false);
}
return $locationArgs;
@@ -1646,419 +2222,34 @@ class YellowToolbox
}
if(!empty($locationArgs))
{
- if(!$this->isPaginationLocation($locationArgs, $pagination)) $locationArgs .= '/';
+ if(!$this->isLocationArgsPagination($locationArgs, $pagination)) $locationArgs .= '/';
$locationArgs = $this->normaliseArgs($locationArgs, false, false);
}
return $locationArgs;
}
- // Return location header with URL
- function getLocationHeader($serverScheme, $serverName, $base, $location)
- {
- return "Location: ".$this->getUrl($serverScheme, $serverName, $base, $location);
- }
-
// Check if location contains location arguments
function isLocationArgs($location)
{
return preg_match("/[^\/]+:.*$/", $location);
}
- // Check if location contains pagination
- function isPaginationLocation($location, $pagination)
+ // Check if location contains pagination arguments
+ function isLocationArgsPagination($location, $pagination)
{
- return preg_match("/^(.*\/)?$pagination:\d*$/", $location);
+ return preg_match("/^(.*\/)?$pagination:.*$/", $location);
}
- // Check if location is specifying root
- function isRootLocation($location)
- {
- return $location[0] != "/";
- }
-
- // Check if location is specifying file or directory
- function isFileLocation($location)
- {
- return substru($location, -1, 1) != "/";
- }
-
- // Check if file is unmodified since last HTTP request
- function isFileNotModified($lastModifiedFormatted)
- {
- return isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && $_SERVER["HTTP_IF_MODIFIED_SINCE"]==$lastModifiedFormatted;
- }
-
// Check if clean URL is requested
function isRequestCleanUrl($location)
{
- return (isset($_GET["clean-url"]) || isset($_POST["clean-url"])) && !$this->isFileLocation($location);
- }
-
- // Check if content type is valid for location
- function isValidContentType($contentType, $location)
- {
- $ok = false;
- $extension = ($pos = strrposu($location, '.')) ? substru($location, $pos) : "";
- $tokens = explode(';', $contentType);
- if($tokens[0] == "text/html")
- {
- if($this->isFileLocation($location))
- {
- if(empty($extension) || preg_match("/^\.(html|md)$/", $extension)) $ok = true;
- } else {
- $ok = true;
- }
- } else {
- if($this->isFileLocation($location))
- {
- if(!empty($extension) && preg_match("/^.*$extension$/", $tokens[0])) $ok = true;
- }
- }
- return $ok;
- }
-
- // Check if location is valid
- function isValidLocation($location)
- {
- $string = "";
- $tokens = explode('/', $location);
- for($i=1; $inormaliseName($tokens[$i]);
- return $location == $string;
- }
-
- // Check if location is within current HTTP request
- function isActiveLocation($location, $currentLocation, $homeLocation)
- {
- if($location != $homeLocation)
- {
- $active = substru($currentLocation, 0, strlenu($location))==$location;
- } else {
- $active = $this->getDirectoryLocation($currentLocation)==$location;
- }
- return $active;
- }
-
- // Check if location is visible in navigation
- function isVisibleLocation($location, $fileName, $pathBase)
- {
- $visible = true;
- if(substru($fileName, 0, strlenu($pathBase)) == $pathBase)
- {
- $fileName = substru($fileName, strlenu($pathBase));
- $tokens = explode('/', $fileName);
- for($i=0; $igetDirectoryEntries($path, "/.*/", true, true, false) as $entry)
- {
- if(empty($firstRoot)) { $firstRoot = $token = $entry; }
- if($this->normaliseName($entry) == $root) { $token = $entry; break; }
- }
- $pathRoot = $this->normaliseName($token)."/";
- $path .= "$firstRoot/";
- }
- if(!empty($pathHome))
- {
- $token = $home = rtrim($pathHome, '/');
- foreach($this->getDirectoryEntries($path, "/.*/", true, true, false) as $entry)
- {
- if(empty($firstHome)) { $firstHome = $token = $entry; }
- if($this->normaliseName($entry) == $home) { $token = $entry; break; }
- }
- $pathHome = $this->normaliseName($token)."/";
- }
- return array($pathRoot, $pathHome);
- }
-
- // Return root languages
- function findRootLanguages($pathBase, $pathRoot, $includeInvisible = false)
- {
- $languages = array();
- if(!empty($pathRoot))
- {
- foreach($this->getDirectoryEntries($pathBase, "/.*/", true, true, false) as $entry)
- {
- if($includeInvisible || preg_match("/^[\d\-\_\.]+(.*)$/", $entry))
- {
- $token = $this->normaliseName($entry);
- if(strlenu($token) == 2) array_push($languages, $token);
- }
- }
- }
- return $languages;
- }
-
- // Return root locations
- function findRootLocations($pathBase, $pathRoot)
- {
- $locations = array("root/");
- if(!empty($pathRoot))
- {
- $root = rtrim($pathRoot, '/');
- foreach($this->getDirectoryEntries($pathBase, "/.*/", true, true, false) as $entry)
- {
- $token = $this->normaliseName($entry);
- if($token != $root) array_push($locations, "root/$token/");
- }
- }
- return $locations;
- }
-
- // Return location from file path
- function findLocationFromFile($fileName, $pathBase, $pathRoot, $pathHome, $fileDefault, $fileExtension)
- {
- $location = "/";
- if(substru($fileName, 0, strlenu($pathBase)) == $pathBase)
- {
- $fileName = substru($fileName, strlenu($pathBase));
- $tokens = explode('/', $fileName);
- if(!empty($pathRoot))
- {
- $token = $this->normaliseName($tokens[0]).'/';
- if($token!=$pathRoot) $location .= $token;
- array_shift($tokens);
- }
- for($i=0; $inormaliseName($tokens[$i]).'/';
- if($i || $token!=$pathHome) $location .= $token;
- }
- $token = $this->normaliseName($tokens[$i]);
- $fileFolder = $this->normaliseName($tokens[$i-1]).$fileExtension;
- if($token!=$fileDefault && $token!=$fileFolder) $location .= $this->normaliseName($tokens[$i], true, true);
- $extension = ($pos = strrposu($fileName, '.')) ? substru($fileName, $pos) : "";
- if($extension != $fileExtension) $invalid = true;
- } else {
- $invalid = true;
- }
- if(defined("DEBUG") && DEBUG>=2)
- {
- $debug = ($invalid ? "INVALID" : $location)." <- $pathBase$fileName";
- echo "YellowToolbox::findLocationFromFile $debug
\n";
- }
- return $invalid ? "" : $location;
- }
-
- // Return file path from location
- function findFileFromLocation($location, $pathBase, $pathRoot, $pathHome, $fileDefault, $fileExtension)
- {
- $path = $pathBase;
- $tokens = explode('/', $location);
- if($this->isRootLocation($location))
- {
- if(!empty($pathRoot))
- {
- $token = (count($tokens) > 2) ? $tokens[1] : rtrim($pathRoot, '/');
- $path .= $this->findFileDirectory($path, $token, true, true, $found, $invalid);
- }
- } else {
- if(!empty($pathRoot))
- {
- if(count($tokens) > 2)
- {
- if($this->normaliseName($tokens[1]) == $this->normaliseName($pathRoot)) $invalid = true;
- $path .= $this->findFileDirectory($path, $tokens[1], false, true, $found, $invalid);
- if($found) array_shift($tokens);
- }
- if(!$found) $path .= $this->findFileDirectory($path, rtrim($pathRoot, '/'), true, true, $found, $invalid);
-
- }
- if(count($tokens) > 2)
- {
- if($this->normaliseName($tokens[1]) == $this->normaliseName($pathHome)) $invalid = true;
- for($i=1; $ifindFileDirectory($path, $tokens[$i], true, true, $found, $invalid);
- }
- } else {
- $i = 1;
- $tokens[0] = rtrim($pathHome, '/');
- $path .= $this->findFileDirectory($path, $tokens[0], true, true, $found, $invalid);
- }
- if(!empty($fileDefault) && !empty($fileExtension))
- {
- $fileFolder = $tokens[$i-1].$fileExtension;
- if(!empty($tokens[$i]))
- {
- $token = $tokens[$i].$fileExtension;
- if($token==$fileDefault || $token==$fileFolder) $invalid = true;
- $path .= $this->findFileDirectory($path, $token, true, false, $found, $invalid);
- } else {
- $path .= $this->findFileDefault($path, $fileDefault, $fileFolder);
- }
- if(defined("DEBUG") && DEBUG>=2)
- {
- $debug = "$location -> ".($invalid ? "INVALID" : $path);
- echo "YellowToolbox::findFileFromLocation $debug
\n";
- }
- }
- }
- return $invalid ? "" : $path;
- }
-
- // Return static file path from location
- function findStaticFileFromLocation($location, $path, $fileDefault)
- {
- $path = rtrim($path, '/').$location;
- if(!$this->isFileLocation($location)) $path .= $fileDefault;
- return $path;
+ return (isset($_GET["clean-url"]) || isset($_POST["clean-url"])) && substru($location, -1, 1)=="/";
}
- // Return file or directory that matches token
- function findFileDirectory($path, $token, $tokenFailback, $directory, &$found, &$invalid)
+ // Check if unmodified since last HTTP request
+ function isRequestNotModified($lastModifiedFormatted)
{
- if($this->normaliseName($token) != $token) $invalid = true;
- if(!$invalid)
- {
- $regex = "/^[\d\-\_\.]*".strreplaceu('-', '.', $token)."$/";
- foreach($this->getDirectoryEntries($path, $regex, false, $directory, false) as $entry)
- {
- if($this->normaliseName($entry) == $token) { $token = $entry; $found = true; break; }
- }
- }
- if($directory) $token .= '/';
- return ($tokenFailback || $found) ? $token : "";
- }
-
- // Return default file in directory
- function findFileDefault($path, $fileDefault, $fileFolder)
- {
- $token = $fileDefault;
- if(!is_file($path."/".$fileDefault))
- {
- $regex = "/^[\d\-\_\.]*($fileDefault|$fileFolder)$/";
- foreach($this->getDirectoryEntries($path, $regex, true, false, false) as $entry)
- {
- if($this->normaliseName($entry) == $fileDefault) { $token = $entry; break; }
- if($this->normaliseName($entry) == $fileFolder) { $token = $entry; break; }
- }
- }
- return $token;
- }
-
- // Return children from location
- function findChildrenFromLocation($location, $pathBase, $pathRoot, $pathHome, $fileDefault, $fileExtension)
- {
- $fileNames = array();
- if(!$this->isFileLocation($location))
- {
- $path = $this->findFileFromLocation($location, $pathBase, $pathRoot, $pathHome, "", "");
- foreach($this->getDirectoryEntries($path, "/.*/", true, true, false) as $entry)
- {
- $fileFolder = $this->normaliseName($entry).$fileExtension;
- $token = $this->findFileDefault($path.$entry, $fileDefault, $fileFolder);
- array_push($fileNames, $path.$entry."/".$token);
- }
- if(!$this->isRootLocation($location))
- {
- $fileFolder = $this->normaliseName(basename($path)).$fileExtension;
- $regex = "/^.*\\".$fileExtension."$/";
- foreach($this->getDirectoryEntries($path, $regex, true, false, false) as $entry)
- {
- if($this->normaliseName($entry) == $fileDefault) continue;
- if($this->normaliseName($entry) == $fileFolder) continue;
- if($this->normaliseName($entry, true, true) == "") continue;
- array_push($fileNames, $path.$entry);
- }
- }
- }
- return $fileNames;
- }
-
- // Return modification date from file path, Unix time
- function findModifiedFromFile($fileName)
- {
- $modified = is_readable($fileName) ? filemtime($fileName) : 0;
- if($modified == 0)
- {
- $path = dirname($fileName);
- $modified = is_readable($path) ? filemtime($path) : 0;
- }
- return $modified;
- }
-
- // Return theme/template name from file path
- function findNameFromFile($fileName, $pathBase, $nameDefault, $fileExtension)
- {
- $name = "";
- if(preg_match("/^.*\/(.+?)$/", dirname($fileName), $matches)) $name = $this->normaliseName($matches[1]);
- if(!is_file("$pathBase$name$fileExtension")) $name = $this->normaliseName($nameDefault);
- return $name;
- }
-
- // Return language from file path
- function findLanguageFromFile($fileName, $pathBase, $pathRoot, $languageDefault)
- {
- $language = $languageDefault;
- if(!empty($pathRoot))
- {
- $fileName = substru($fileName, strlenu($pathBase));
- if(preg_match("/^(.+?)\//", $fileName, $matches)) $name = $this->normaliseName($matches[1]);
- if(strlenu($name) == 2) $language = $name;
- }
- return $language;
- }
-
- // Return file path for new page
- function findFileNew($fileName, $pathBase, $fileNew, $fileDefault)
- {
- if(preg_match("/^.*\/(.+?)$/", dirname($fileName), $matches)) $name = $this->normaliseName($matches[1]);
- $fileName = strreplaceu("(.*)", $name, $pathBase.$fileNew);
- if(!is_file($fileName))
- {
- $name = $this->normaliseName($fileDefault, true, true);
- $fileName = strreplaceu("(.*)", $name, $pathBase.$fileNew);
- }
- return $fileName;
- }
-
- // Return file path from title
- function findFileFromTitle($titlePrefix, $titleText, $fileName, $fileDefault, $fileExtension)
- {
- preg_match("/^([\d\-\_\.]*)(.*)$/", $titlePrefix, $matches);
- if(preg_match("/\d$/", $matches[1])) $matches[1] .= '-';
- $titleText = $this->normaliseName($titleText, false, false, true);
- preg_match("/^([\d\-\_\.]*)(.*)$/", $matches[1].$titleText, $matches);
- $fileNamePrefix = $matches[1];
- $fileNameText = empty($matches[2]) ? $fileDefault : $matches[2].$fileExtension;
- return dirname($fileName)."/".$fileNamePrefix.$fileNameText;
- }
-
- // Normalise location, make absolute location
- function normaliseLocation($location, $pageBase, $pageLocation, $staticLocation = "", $filterStrict = true)
- {
- if(!preg_match("/^\w+:/", trim(html_entity_decode($location, ENT_QUOTES, "UTF-8"))))
- {
- if(empty($staticLocation) || !preg_match("#^$staticLocation#", $location))
- {
- if(preg_match("/^\#/", $location))
- {
- $location = $pageBase.$pageLocation.$location;
- } else if(!preg_match("/^\//", $location)) {
- $location = $this->getDirectoryLocation($pageBase.$pageLocation).$location;
- } else if(!preg_match("#^$pageBase#", $location)) {
- $location = $pageBase.$location;
- }
- }
- } else {
- if($filterStrict && !preg_match("/^(http|https|ftp|mailto):/", $location)) $location = "error-xss-filter";
- }
- return $location;
+ return isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && $_SERVER["HTTP_IF_MODIFIED_SINCE"]==$lastModifiedFormatted;
}
// Normalise location arguments
@@ -2069,15 +2260,6 @@ class YellowToolbox
return strreplaceu(array('%3A','%2F'), array(':','/'), rawurlencode($text));
}
- // Normalise file/directory/other name
- function normaliseName($text, $removePrefix = true, $removeExtension = false, $filterStrict = false)
- {
- if($removeExtension) $text = ($pos = strrposu($text, '.')) ? substru($text, 0, $pos) : $text;
- if($removePrefix) if(preg_match("/^[\d\-\_\.]+(.*)$/", $text, $matches)) $text = $matches[1];
- if($filterStrict) $text = strreplaceu('.', '-', strtoloweru($text));
- return preg_replace("/[^\pL\d\-\_\.]/u", "-", rtrim($text, '/'));
- }
-
// Normalise text into UTF-8 NFC
function normaliseUnicode($text)
{
@@ -2136,31 +2318,14 @@ class YellowToolbox
"jpg" => "image/jpeg",
"png" => "image/png",
"txt" => "text/plain",
- "woff" => "application/font-woff");
+ "woff" => "application/font-woff",
+ "xml" => "text/xml; charset=utf-8");
$contentType = "text/html; charset=utf-8";
- $extension = ($pos = strrposu($fileName, '.')) ? substru($fileName, $pos+1) : "";
+ $extension = $this->getFileExtension($fileName);
if(array_key_exists(strtoloweru($extension), $mimeTypes)) $contentType = $mimeTypes[$extension];
return $contentType;
}
- // Return URL
- function getUrl($serverScheme, $serverName, $base, $location)
- {
- if(!preg_match("/^\w+:/", $location))
- {
- $url = "$serverScheme://$serverName$base$location";
- } else {
- $url = $location;
- }
- return $url;
- }
-
- // Return directory location
- function getDirectoryLocation($location)
- {
- return ($pos = strrposu($location, '/')) ? substru($location, 0, $pos+1) : "/";
- }
-
// Return files and directories
function getDirectoryEntries($path, $regex = "/.*/", $sort = true, $directories = true, $includePath = true)
{
@@ -2230,6 +2395,24 @@ class YellowToolbox
return is_readable($fileName) ? file_get_contents($fileName) : "";
}
+ // Return file extension
+ function getFileExtension($fileName)
+ {
+ return strtoloweru(($pos = strrposu($fileName, '.')) ? substru($fileName, $pos+1) : "");
+ }
+
+ // Return file modification date, Unix time
+ function getFileModified($fileName)
+ {
+ $modified = is_readable($fileName) ? filemtime($fileName) : 0;
+ if($modified == 0)
+ {
+ $path = dirname($fileName);
+ $modified = is_readable($path) ? filemtime($path) : 0;
+ }
+ return $modified;
+ }
+
// Create file
function createFile($fileName, $fileData, $mkdir = false)
{
@@ -2282,7 +2465,17 @@ class YellowToolbox
{
return @unlink($fileName);
}
-
+
+ // Return lines from text string
+ function getTextLines($text)
+ {
+ $lines = array();
+ $split = preg_split("/(\R)/", $text, -1, PREG_SPLIT_DELIM_CAPTURE);
+ for($i=0; $iyellow = $yellow;
}
// Handle page content parsing of raw format
- function onParseContentText($page, $text)
+ function onParseContentRaw($page, $text)
{
- $markdown = new YellowMarkdownExtraParser($this->yellow, $page);
+ $markdown = new YellowMarkdownParser($this->yellow, $page);
return $markdown->transform($text);
}
}
-// Markdown extra parser
-class YellowMarkdownExtraParser extends MarkdownExtraParser
+// Markdown parser
+class YellowMarkdownParser extends MarkdownExtraParser
{
var $yellow; //access to API
var $page; //access to page
@@ -38,7 +38,7 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser
$this->no_entities = $page->parserSafeMode;
$this->url_filter_func = function($url) use ($yellow, $page)
{
- return $yellow->toolbox->normaliseLocation($url, $page->base, $page->location,
+ return $yellow->lookup->normaliseLocation($url, $page->base, $page->location,
$yellow->config->get("serverBase").$yellow->config->get("imageLocation"),
$page->parserSafeMode && $page->statusCode==200);
};
@@ -57,7 +57,7 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser
// Return unique id attribute
function getIdAttribute($text)
{
- $text = $this->yellow->toolbox->normaliseName($text, true, false, true);
+ $text = $this->yellow->lookup->normaliseName($text, true, false, true);
$text = trim(preg_replace("/-+/", "-", $text), "-");
if(is_null($this->idAttributes[$text]))
{
@@ -83,9 +83,9 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser
function _doAutoLinks_shortcut_callback($matches)
{
$text = preg_replace("/\s+/s", " ", $matches[2]);
- $output = $this->page->parseType($matches[1], $text, true);
+ $output = $this->page->parseContentBlock($matches[1], $text, true);
if(is_null($output)) $output = htmlspecialchars($matches[0], ENT_NOQUOTES);
- return $this->hashBlock($output);
+ return substr($output, 0, 4)=="hashBlock($output) : $this->hashPart($output);
}
// Handle comments
@@ -101,7 +101,7 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser
function _doFencedCodeBlocks_callback($matches)
{
$text = $matches[4];
- $output = $this->page->parseType($matches[2], $text, false);
+ $output = $this->page->parseContentBlock($matches[2], $text, false);
if(is_null($output))
{
$attr = $this->doExtraAttributes("pre", $dummy =& $matches[3]);
@@ -3325,5 +3325,5 @@ class MarkdownExtraParser extends MarkdownParser {
}
-$yellow->plugins->register("markdownextra", "YellowMarkdownExtra", YellowMarkdownExtra::Version);
+$yellow->plugins->register("markdown", "YellowMarkdown", YellowMarkdown::Version);
?>
\ No newline at end of file
diff --git a/system/snippets/pagination.php b/system/snippets/pagination.php
deleted file mode 100755
index c062989..0000000
--- a/system/snippets/pagination.php
+++ /dev/null
@@ -1,11 +0,0 @@
-getSnippetArgs() ?>
-isPagination()): ?>
-
-
diff --git a/system/themes/default.css b/system/themes/default.css
deleted file mode 100644
index 98816ea..0000000
--- a/system/themes/default.css
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Default theme 0.5.2 */
-/* Designer: Datenstrom Sweden */
-
-html, body, div, form, pre, span, tr, th, td { margin:0; padding:0; border:0; vertical-align:baseline; }
-body {
- margin:1em;
- background-color:#fff; color:#717171;
- font-family:"Helvetica Neue",Helvetica,sans-serif;
- font-size:1.0em;
- font-weight:200;
- line-height:1.5;
-}
-h1, h2, h3, h4, h5, h6 { color:#07d; font-weight:normal; }
-hr { height:1px; background:#ddd; border:0; }
-strong { font-weight:bold; }
-code { font-size:1.1em; }
-a { color:#07d; }
-a:hover { color:#07d; text-decoration:underline; }
-a, img { border:none; text-decoration:none; }
-.sitename h1 { margin-top:0.5em; margin-bottom:0em; font-size:2.2em; font-weight:500; }
-.sitename h1 a { color:#111; text-decoration:none; }
-.navigation { margin-bottom:1em; line-height:2em; }
-.navigation a { color:#111; padding:0 0.3em; display:inline-block; }
-.navigation a:hover { color:#07d; }
-.navigation ul { margin:0 -0.3em; padding:0; list-style:none; }
-.navigation li { display:inline; }
-.content h1 a:hover { text-decoration:none; }
-.content img { max-width:100%; height:auto; }
-.content form { margin:1em 0; }
-.content table { border-spacing:0; border-collapse:collapse; }
-.content th { text-align:left; padding:0.3em; border-bottom:1px solid #ddd;}
-.content td { text-align:left; padding:0.3em; border-top:1px solid #ddd;}
-.content .flexible { position:relative; padding-bottom:56.25%; padding-top:30px; }
-.content .flexible iframe { position:absolute; top:0; left:0; width:100%; height:100%; }
-.content .toc { margin:0; padding:0; list-style:none; }
-.pagination { margin:1em 0; }
-.footer { margin-top:1em; }
-.footer a { color:#717171; }
-.footer a:hover { color:#07d; text-decoration:underline; }
-.left { float:left; margin:0 1em 0 0; }
-.center { display:block; margin:0 auto; }
-.right { float:right; margin:0 0 0 1em; }
-
-/* Responsive and print */
-
-.page { margin:0 auto; max-width:62em; }
-
-@media screen and (min-width:62em) {
- body { width:60em; margin:1em auto; }
-}
-@media screen and (max-width:30em) {
- body { margin:0.5em; font-size:0.9em; }
- .sitename h1, h1, h2 { font-size:1.3em; }
- .sitename h1, .sitename, .navigation, .footer, .page { margin:0; padding:0; border:0; }
-}
-@media print {
- body, h1, h2, h3, h4, h5, h6 { background-color:white; color:black; }
- .page { border:none !important; }
-}
\ No newline at end of file
diff --git a/system/themes/flatsite.css b/system/themes/flatsite.css
new file mode 100644
index 0000000..3d7a95b
--- /dev/null
+++ b/system/themes/flatsite.css
@@ -0,0 +1,101 @@
+/* Flatsite theme 0.1.7 */
+/* Designer: Mark Mayberg */
+
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:300,400,700);
+html, body, div, form, pre, span, tr, th, td { margin:0; padding:0; border:0; vertical-align:baseline; }
+body {
+ margin:1em;
+ background-color:#fff; color:#717171;
+ font-family:'Open Sans',sans-serif;
+ font-size:1.0em;
+ font-weight:300;
+ line-height:1.5;
+}
+h1, h2, h3, h4, h5, h6 { color:#07d; font-weight:normal; }
+h1 { font-size:2.0em; }
+hr { height:1px; background:#ddd; border:0; }
+strong { font-weight:bold; }
+code { font-size:1.1em; }
+a { color:#07d; }
+a:hover { color:#07d; text-decoration:underline; }
+a, img { border:none; text-decoration:none; }
+.sitename { display:block; float:left; }
+.sitename h1 { margin:0; }
+.sitename h1 a { color:#111; text-decoration:none; }
+.navigation { display:block; float:right; }
+.navigation { margin-top:0.9em; margin-bottom:0.9em; line-height:2em; }
+.navigation a { padding:0 0.3em; display:inline-block; }
+.navigation ul { margin:0 -0.3em; padding:0; list-style:none; }
+.navigation li { display:inline; }
+.content { clear:both; }
+.content h1 a:hover { text-decoration:none; }
+.content img { max-width:100%; height:auto; }
+.content form { margin:1em 0; }
+.content table { border-spacing:0; border-collapse:collapse; }
+.content th { text-align:left; padding:0.3em; border-bottom:1px solid #ddd;}
+.content td { text-align:left; padding:0.3em; border-top:1px solid #ddd;}
+.content .flexible { position:relative; padding-bottom:56.25%; padding-top:30px; }
+.content .flexible iframe { position:absolute; top:0; left:0; width:100%; height:100%; }
+.content .toc { margin:0; padding:0; list-style:none; }
+.content code { border:1px solid #ddd; border-radius:3px; padding:0 0.5em; }
+.content pre>code { border:none; padding:0; }
+.content pre { border:1px solid #ddd; border-radius:3px; padding:1em; overflow:hidden; }
+.content .imagelist { margin:0; padding:0; list-style:none; }
+.content .themes { margin:0; padding:0; list-style:none; width:100%; }
+.content .themes li { padding-bottom:1em; text-align:center; white-space:nowrap; display:inline-block; width:24%; }
+.pagination { margin:1em 0; }
+.footer { margin-top:2em; }
+.footer a { color:#07d; }
+.footer a:hover { color:#07d; text-decoration:underline; }
+.left { float:left; margin:0 1em 0 0; }
+.center { display:block; margin:0 auto; }
+.right { float:right; margin:0 0 0 1em; }
+
+/* Forms and buttons */
+
+.form-control {
+ margin:0; padding:2px 4px;
+ display:inline-block;
+ background-color:#fff; color:#555;
+ background-image:linear-gradient(to bottom, #fff, #fff);
+ border:1px solid #bbb;
+ border-radius:4px;
+ font-size:0.9em; font-family:inherit; font-weight:normal; line-height:1;
+}
+.btn {
+ margin:0; padding:4px 22px;
+ display:inline-block; min-width:8em;
+ background-color:#eaeaea; color:#333333;
+ background-image:linear-gradient(to bottom, #f8f8f8, #e1e1e1);
+ border:1px solid #bbb;
+ border-color:#c1c1c1 #c1c1c1 #aaaaaa;
+ border-radius:4px;
+ outline-offset:-2px;
+ font-size:0.9em; font-family:inherit; font-weight:normal; line-height:1;
+ text-align:center; text-decoration:none;
+}
+.btn:hover, .btn:focus, .btn:active {
+ color:#333333;
+ background-image:none;
+ text-decoration:none;
+}
+.btn:active { box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.1); }
+
+/* Responsive and print */
+
+.page { margin:0 auto; max-width:1000px; }
+
+@media screen and (min-width:62em) {
+ body { width:60em; margin:1em auto; }
+ .page{ margin:0; max-width:none; }
+}
+@media screen and (max-width:30em) {
+ body { margin:0.5em; font-size:0.9em; }
+ .sitename h1, h1, h2 { font-size:1.2em; }
+ .sitename h1, .header, .navigation, .footer, .page { margin:0; padding:0; }
+ .sitename, .navigation { float:none; }
+}
+@media print {
+ body, h1, h2, h3, h4, h5, h6 { background-color:white; color:black; }
+ .page { border:none !important; }
+}
\ No newline at end of file
diff --git a/system/snippets/content.php b/system/themes/snippets/content.php
similarity index 100%
rename from system/snippets/content.php
rename to system/themes/snippets/content.php
diff --git a/system/snippets/footer.php b/system/themes/snippets/footer.php
similarity index 100%
rename from system/snippets/footer.php
rename to system/themes/snippets/footer.php
diff --git a/system/snippets/header.php b/system/themes/snippets/header.php
similarity index 95%
rename from system/snippets/header.php
rename to system/themes/snippets/header.php
index 1e67137..01dc1f5 100755
--- a/system/snippets/header.php
+++ b/system/themes/snippets/header.php
@@ -11,7 +11,7 @@
page->getHtml("titleHeader") ?>
config->get("imageLocation")."icon.png" ?>" />
config->get("themeLocation").$yellow->page->get("theme").".css" ?>" />
-page->getHeaderExtra() ?>
+page->getExtra() ?>
diff --git a/system/snippets/navigation.php b/system/themes/snippets/navigation.php
similarity index 100%
rename from system/snippets/navigation.php
rename to system/themes/snippets/navigation.php
diff --git a/system/themes/snippets/pagination.php b/system/themes/snippets/pagination.php
new file mode 100755
index 0000000..3a7cf4c
--- /dev/null
+++ b/system/themes/snippets/pagination.php
@@ -0,0 +1,11 @@
+getSnippetArgs() ?>
+isPagination()): ?>
+
+
diff --git a/system/snippets/sitename.php b/system/themes/snippets/sitename.php
similarity index 100%
rename from system/snippets/sitename.php
rename to system/themes/snippets/sitename.php
diff --git a/system/templates/default.php b/system/themes/templates/default.html
similarity index 69%
rename from system/templates/default.php
rename to system/themes/templates/default.html
index 2a4cadf..a576c2c 100755
--- a/system/templates/default.php
+++ b/system/themes/templates/default.html
@@ -1,4 +1,3 @@
-
snippet("header") ?>
snippet("sitename") ?>
snippet("navigation") ?>