commit a17580f2d18e4915577c962cc2ab3cd0e43f8cbc
parent 1a2d98192913998ae3ec42d4e1ce7b3f91d06616
Author: markseu <mark2011@mayberg.se>
Date: Mon, 29 Jul 2013 20:49:57 +0200
Better location handling (UTF-8 is good for you)
Diffstat:
7 files changed, 281 insertions(+), 155 deletions(-)
diff --git a/system/config/config.ini b/system/config/config.ini
@@ -8,6 +8,9 @@ template = default
style = default
parser = markdown
+// serverName = your.domain.name
+// serverBase = /yellow
+
styleLocation = /media/styles/
imageLocation = /media/images/
pluginLocation = /media/plugins/
diff --git a/system/core/core.php b/system/core/core.php
@@ -5,7 +5,7 @@
// Yellow main class
class Yellow
{
- const Version = "0.1.8";
+ const Version = "0.1.9";
var $page; //current page data
var $pages; //current page tree from file system
var $toolbox; //toolbox with helpers
@@ -28,7 +28,7 @@ class Yellow
$this->config->setDefault("parser", "markdown");
$this->config->setDefault("yellowVersion", Yellow::Version);
$this->config->setDefault("serverName", $this->toolbox->getServerName());
- $this->config->setDefault("baseLocation", $this->toolbox->getServerBase());
+ $this->config->setDefault("serverBase", $this->toolbox->getServerBase());
$this->config->setDefault("styleLocation", "/media/styles/");
$this->config->setDefault("imageLocation", "/media/images/");
$this->config->setDefault("pluginLocation", "media/plugins/");
@@ -55,10 +55,11 @@ class Yellow
// Handle request
function request()
{
- ob_start();
$this->toolbox->timerStart($time);
- $baseLocation = $this->config->get("baseLocation");
- $location = $this->getRelativeLocation($baseLocation);
+ ob_start();
+ $serverName = $this->config->get("serverName");
+ $serverBase = $this->config->get("serverBase");
+ $location = $this->getRelativeLocation($serverBase);
$fileName = $this->getContentFileName($location);
$statusCode = 0;
$this->page = new Yellow_Page($this, $location);
@@ -66,64 +67,71 @@ class Yellow
{
if(method_exists($value["obj"], "onRequest"))
{
- $statusCode = $value["obj"]->onRequest($baseLocation, $location, $fileName);
+ $statusCode = $value["obj"]->onRequest($serverName, $serverBase, $location, $fileName);
if($statusCode) break;
}
}
- if($statusCode == 0) $statusCode = $this->processRequest($baseLocation, $location, $fileName, true, $statusCode);
- if($this->page->isExisting("pageError"))
+ if($statusCode == 0) $statusCode = $this->processRequest($serverName, $serverBase, $location, $fileName, true, $statusCode);
+ if($this->isRequestError())
{
ob_clean();
$statusCode = $this->processRequestError();
}
- $this->toolbox->timerStop($time);
ob_end_flush();
+ $this->toolbox->timerStop($time);
if(defined("DEBUG") && DEBUG>=1) echo "Yellow::request status:$statusCode location:$location<br>\n";
if(defined("DEBUG") && DEBUG>=1) echo "Yellow::request time:$time ms<br>\n";
return $statusCode;
}
// Process request
- function processRequest($baseLocation, $location, $fileName, $cacheable, $statusCode)
+ function processRequest($serverName, $serverBase, $location, $fileName, $cacheable, $statusCode)
{
if($statusCode == 0)
{
if(is_readable($fileName))
{
$statusCode = 200;
- $fileName = $this->readPage($baseLocation, $location, $fileName, $cacheable, $statusCode);
+ $fileName = $this->readPage($serverBase, $location, $fileName, $cacheable, $statusCode);
+ if($this->page->isExisting("redirect") && $cacheable)
+ {
+ $statusCode = 301;
+ $locationHeader = $this->toolbox->getHttpLocationHeader($serverName, $serverBase, $this->page->get("redirect"));
+ $this->page->statusCode = 0;
+ $this->header($locationHeader);
+ $this->sendStatus($statusCode, $locationHeader);
+ }
} else {
if($this->toolbox->isFileLocation($location) && is_dir($this->getContentDirectory("$location/")))
{
$statusCode = 301;
- $serverName = $this->config->get("serverName");
- $this->sendStatus($statusCode, "Location: http://$serverName$baseLocation$location/");
+ $this->sendStatus($statusCode, $this->toolbox->getHttpLocationHeader($serverName, $serverBase, "$location/"));
} else {
$statusCode = 404;
- $fileName = $this->readPage($baseLocation, $location, $fileName, $cacheable, $statusCode);
+ $fileName = $this->readPage($serverBase, $location, $fileName, $cacheable, $statusCode);
}
}
} else if($statusCode >= 400) {
- $fileName = $this->readPage($baseLocation, $location, $fileName, $cacheable, $statusCode);
+ $fileName = $this->readPage($serverBase, $location, $fileName, $cacheable, $statusCode);
}
if($this->page->statusCode != 0) $statusCode = $this->sendPage();
- if(defined("DEBUG") && DEBUG>=1) echo "Yellow::processRequest base:$baseLocation file:$fileName<br>\n";
+ if(defined("DEBUG") && DEBUG>=1) echo "Yellow::processRequest base:$serverBase file:$fileName<br>\n";
return $statusCode;
}
// Process request with error
function processRequestError()
{
- $baseLocation = $this->pages->baseLocation;
- $fileName = $this->readPage($baseLocation, $this->page->location, $this->page->fileName, $this->page->cacheable,
+ $serverBase = $this->pages->serverBase;
+ $fileName = $this->readPage($serverBase, $this->page->location, $this->page->fileName, $this->page->cacheable,
$this->page->statusCode, $this->page->get("pageError"));
$statusCode = $this->sendPage();
- if(defined("DEBUG") && DEBUG>=1) echo "Yellow::processRequestError base:$baseLocation file:$fileName<br>\n";
+ if(defined("DEBUG") && DEBUG>=1) echo "Yellow::processRequestError base:$serverBase file:$fileName<br>\n";
return $statusCode;
}
// Read page from file
- function readPage($baseLocation, $location, $fileName, $cacheable, $statusCode, $pageError = "")
+ function readPage($serverBase, $location, $fileName, $cacheable, $statusCode, $pageError = "")
{
if($statusCode >= 400)
{
@@ -137,7 +145,7 @@ class Yellow
$fileData = fread($fileHandle, filesize($fileName));
fclose($fileHandle);
}
- $this->pages->baseLocation = $baseLocation;
+ $this->pages->serverBase = $serverBase;
$this->page = new Yellow_Page($this, $location);
$this->page->parseData($fileName, $fileData, $cacheable, $statusCode, $pageError);
$this->page->parseContent();
@@ -183,8 +191,22 @@ class Yellow
// Send status response
function sendStatus($statusCode, $text = "")
{
- @header($this->toolbox->getHttpStatusFormatted($statusCode));
- if(!empty($text)) @header($text);
+ if(PHP_SAPI != "cli")
+ {
+ @header($this->toolbox->getHttpStatusFormatted($statusCode));
+ if(!empty($text)) @header($text);
+ }
+ }
+
+ // Check for request error
+ function isRequestError()
+ {
+ $serverBase = $this->config->get("serverBase");
+ if(!empty($serverBase) && !$this->toolbox->isValidLocation($serverBase))
+ {
+ $this->page->error(500, "Server base '$serverBase' not supported!");
+ }
+ return $this->page->isExisting("pageError");
}
// Execute a template
@@ -231,14 +253,14 @@ class Yellow
return $header;
}
- // Return content location for current HTTP request, without base location
- function getRelativeLocation($baseLocation)
+ // Return content location for current HTTP request, without server base
+ function getRelativeLocation($serverBase)
{
$location = $this->toolbox->getRequestLocation();
$location = $this->toolbox->normaliseLocation($location);
- return substru($location, strlenu($baseLocation));
+ return substru($location, strlenu($serverBase));
}
-
+
// Return content file name from location
function getContentFileName($location)
{
@@ -253,7 +275,7 @@ class Yellow
return $this->toolbox->findFileFromLocation($location,
$this->config->get("contentDir"), $this->config->get("contentHomeDir"), "", "");
}
-
+
// Execute a plugin command
function plugin($name, $args = NULL)
{
@@ -313,8 +335,9 @@ class Yellow_Page
{
$this->fileName = $fileName;
$this->rawData = $rawData;
- $this->active = $this->yellow->toolbox->isActiveLocation($this->yellow->pages->baseLocation, $this->location);
- $this->visible = $this->yellow->toolbox->isVisibleLocation($this->yellow->pages->baseLocation, $this->location,
+ $this->active = $this->yellow->toolbox->isActiveLocation($this->yellow->pages->serverBase, $this->location,
+ $this->yellow->page->location);
+ $this->visible = $this->yellow->toolbox->isVisibleLocation($this->yellow->pages->serverBase, $this->location,
$fileName, $this->yellow->config->get("contentDir"));
$this->cacheable = $cacheable;
$this->statusCode = $statusCode;
@@ -331,7 +354,7 @@ class Yellow_Page
$this->set("template", $this->yellow->config->get("template"));
$this->set("style", $this->yellow->config->get("style"));
$this->set("parser", $this->yellow->config->get("parser"));
- $location = $this->yellow->config->get("baseLocation").rtrim($this->yellow->config->get("webinterfaceLocation"), '/').$this->location;
+ $location = $this->yellow->config->get("serverBase").rtrim($this->yellow->config->get("webinterfaceLocation"), '/').$this->location;
$this->set("pageEdit", $location);
if(preg_match("/^(\-\-\-[\r\n]+)(.+?)([\r\n]+\-\-\-[\r\n]+)/s", $this->rawData, $parsed))
@@ -442,7 +465,7 @@ class Yellow_Page
// Return absolute page location
function getLocation()
{
- return $this->yellow->pages->baseLocation.$this->location;
+ return $this->yellow->pages->serverBase.$this->location;
}
// Return page modification time, Unix time
@@ -599,7 +622,7 @@ class Yellow_PageCollection extends ArrayObject
if($pageNumber>=1 && $pageNumber<=$this->paginationCount)
{
$locationArgs = $this->yellow->toolbox->getRequestLocationArgs($pageNumber>1 ? "page:$pageNumber" : "page:");
- $location = $this->yellow->pages->baseLocation.$this->location.$locationArgs;
+ $location = $this->yellow->pages->serverBase.$this->location.$locationArgs;
}
return $location;
}
@@ -640,7 +663,7 @@ class Yellow_Pages
{
var $yellow; //access to API
var $pages; //scanned pages
- var $baseLocation; //requested base location
+ var $serverBase; //requested server base
var $snippetArgs; //requested snippet arguments
function __construct($yellow)
@@ -664,7 +687,7 @@ class Yellow_Pages
// Find a specific page
function find($location, $absoluteLocation = false)
{
- if($absoluteLocation) $location = substru($location, strlenu($this->baseLocation));
+ if($absoluteLocation) $location = substru($location, strlenu($this->serverBase));
$parentLocation = $this->getParentLocation($location);
$this->scanChildren($parentLocation);
foreach($this->pages[$parentLocation] as $page) if($page->location == $location) return $page;
@@ -718,8 +741,8 @@ class Yellow_Pages
{
array_push($fileNames, $path.$entry."/".$this->yellow->config->get("contentDefaultFile"));
}
- $fileRegex = "/.*\\".$this->yellow->config->get("contentExtension")."/";
- foreach($this->yellow->toolbox->getDirectoryEntries($path, $fileRegex, true, false) as $entry)
+ $regex = "/.*\\".$this->yellow->config->get("contentExtension")."/";
+ foreach($this->yellow->toolbox->getDirectoryEntries($path, $regex, true, false) as $entry)
{
if($entry != $this->yellow->config->get("contentDefaultFile")) array_push($fileNames, $path.$entry);
}
@@ -840,22 +863,31 @@ class Yellow_Toolbox
return $location;
}
+ // Check if file has been unmodified since last HTTP request
+ static function isFileNotModified($lastModified)
+ {
+ return isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && $_SERVER["HTTP_IF_MODIFIED_SINCE"]==$lastModified;
+ }
+
// Check if location is specifying file or directory
static function isFileLocation($location)
{
return substru($location, -1, 1) != "/";
}
- // Check if file has been unmodified since last HTTP request
- static function isFileNotModified($lastModified)
+ // Check if location is valid
+ static function isValidLocation($location)
{
- return isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && $_SERVER["HTTP_IF_MODIFIED_SINCE"]==$lastModified;
+ $string = "/";
+ $tokens = explode('/', $location);
+ for($i=1; $i<count($tokens)-1; ++$i) $string .= self::normaliseName($tokens[$i]).'/';
+ $string .= self::normaliseName($tokens[$i]);
+ return $location == $string;
}
// Check if location is within current HTTP request
- static function isActiveLocation($baseLocation, $location)
+ static function isActiveLocation($serverBase, $location, $currentLocation)
{
- $currentLocation = substru(self::getRequestLocation(), strlenu($baseLocation));
if($location != "/")
{
$active = substru($currentLocation, 0, strlenu($location))==$location;
@@ -866,14 +898,14 @@ class Yellow_Toolbox
}
// Check if location is visible in navigation
- static function isVisibleLocation($baseLocation, $location, $fileName, $pathBase)
+ static function isVisibleLocation($serverBase, $location, $fileName, $pathBase)
{
$visible = true;
if(substru($fileName, 0, strlenu($pathBase)) == $pathBase) $fileName = substru($fileName, strlenu($pathBase));
$tokens = explode('/', $fileName);
for($i=0; $i<count($tokens)-1; ++$i)
{
- if(!preg_match("/^[\d\-\.]+(.*)$/", $tokens[$i]))
+ if(!preg_match("/^[\d\-\_\.]+(.*)$/", $tokens[$i]))
{
$visible = false;
break;
@@ -881,7 +913,7 @@ class Yellow_Toolbox
}
return $visible;
}
-
+
// Find file path from location
static function findFileFromLocation($location, $pathBase, $pathHome, $fileDefault, $fileExtension)
{
@@ -891,24 +923,34 @@ class Yellow_Toolbox
{
for($i=1; $i<count($tokens)-1; ++$i)
{
- if(preg_match("/^[\d\-\.]+/", $tokens[$i])) $duplicate = true;
- $entries = self::getDirectoryEntries($path, "/^[\d\-\.]+".$tokens[$i]."$/");
- $path .= empty($entries) ? "$tokens[$i]/" : "$entries[0]/";
+ $tokenFound = $tokens[$i];
+ if(self::normaliseName($tokens[$i]) != $tokens[$i]) $invalid = true;
+ $regex = "/^[\d\-\_\.]*".strreplaceu('-', '.', $tokens[$i])."$/";
+ foreach(self::getDirectoryEntries($path, $regex) as $entry)
+ {
+ if(self::normaliseName($entry) == $tokens[$i]) { $tokenFound = $entry; break; }
+ }
+ $path .= "$tokenFound/";
}
- if($path == $pathBase.$pathHome) $duplicate = true;
+ if($path == $pathBase.$pathHome) $invalid = true;
} else {
$i = 1;
$path .= $pathHome;
}
if($tokens[$i] != "")
{
- if(preg_match("/^[\d\-\.]+/", $tokens[$i])) $duplicate = true;
- $entries = self::getDirectoryEntries($path, "/^[\d\-\.]+".$tokens[$i].$fileExtension."$/", false, false);
- $path .= empty($entries) ? $tokens[$i].$fileExtension : $entries[0];
+ $tokenFound = $tokens[$i];
+ if(self::normaliseName($tokens[$i]) != $tokens[$i]) $invalid = true;
+ $regex = "/^[\d\-\_\.]*".strreplaceu('-', '.', $tokens[$i]).$fileExtension."$/";
+ foreach(self::getDirectoryEntries($path, $regex, false, false) as $entry)
+ {
+ if(self::normaliseName($entry, true) == $tokens[$i]) { $tokenFound = $entry; break; }
+ }
+ $path .= $tokenFound;
} else {
$path .= $fileDefault;
}
- return $duplicate ? "" : $path;
+ return $invalid ? "" : $path;
}
// Find location from file path
@@ -918,19 +960,20 @@ class Yellow_Toolbox
if(substru($fileName, 0, strlenu($pathBase)) == $pathBase) $fileName = substru($fileName, strlenu($pathBase));
if(substru($fileName, 0, strlenu($pathHome)) == $pathHome) $fileName = substru($fileName, strlenu($pathHome));
$tokens = explode('/', $fileName);
- for($i=0; $i<count($tokens)-1; ++$i)
- {
- if(preg_match("/^[\d\-\.]+(.*)$/", $tokens[$i], $matches)) $tokens[$i] = $matches[1];
- $location .= "$tokens[$i]/";
- }
- if($tokens[$i] != $fileDefault)
- {
- if(preg_match("/^[\d\-\.]+(.*)$/", $tokens[$i], $matches)) $tokens[$i] = $matches[1];
- $location .= substru($tokens[$i], 0, -strlenu($fileExtension));
- }
+ for($i=0; $i<count($tokens)-1; ++$i) $location .= self::normaliseName($tokens[$i]).'/';
+ if($tokens[$i] != $fileDefault) $location .= self::normaliseName($tokens[$i], true);
return $location;
}
+ // Normalise directory/file name and convert unwanted characters
+ static function normaliseName($text, $removeExtension = false)
+ {
+ if(preg_match("/^[\d\-\_\.]+(.*)$/", $text, $matches)) $text = $matches[1];
+ if($removeExtension) $text = ($pos = strrposu($text, '.')) ? substru($text, 0, $pos) : $text;
+ $text = preg_replace("/[^\pL\d\-\_]/u", "-", $text);
+ return $text;
+ }
+
// Return human readable HTTP server status
static function getHttpStatusFormatted($statusCode)
{
@@ -957,6 +1000,18 @@ class Yellow_Toolbox
return gmdate("D, d M Y H:i:s", $timestamp)." GMT";
}
+ // Return HTTP location header
+ function getHttpLocationHeader($serverName, $serverBase, $location)
+ {
+ if(preg_match("/^(http|https):\/\//", $location))
+ {
+ $locationHeader = "Location: $location";
+ } else {
+ $locationHeader = "Location: http://$serverName$serverBase$location";
+ }
+ return $locationHeader;
+ }
+
// Return files and directories
static function getDirectoryEntries($path, $regex = "/.*/", $sort = false, $directories = true)
{
@@ -999,7 +1054,7 @@ class Yellow_Toolbox
return $entries;
}
- // Create new file
+ // Create file
function makeFile($fileName, $fileData, $mkdir = false)
{
$ok = false;
@@ -1263,8 +1318,8 @@ class Yellow_Text
function load($fileName, $toolbox)
{
$path = dirname($fileName);
- $regex = basename($fileName);
- foreach($toolbox->getDirectoryEntries($path, "/$regex/", true, false) as $entry)
+ $regex = "/".basename($fileName)."/";
+ foreach($toolbox->getDirectoryEntries($path, $regex, true, false) as $entry)
{
$fileData = @file("$path/$entry");
if($fileData)
@@ -1407,12 +1462,14 @@ class Yellow_Plugins
mb_internal_encoding("UTF-8");
function strlenu() { return call_user_func_array("mb_strlen", func_get_args()); }
function strposu() { return call_user_func_array("mb_strpos", func_get_args()); }
+function strrposu() { return call_user_func_array("mb_strrpos", func_get_args()); }
function strreplaceu() { return call_user_func_array("str_replace", func_get_args()); }
function strtoloweru() { return call_user_func_array("mb_strtolower", func_get_args()); }
function strtoupperu() { return call_user_func_array("mb_strtoupper", func_get_args()); }
function substru() { return call_user_func_array("mb_substr", func_get_args()); }
function strlenb() { return call_user_func_array("strlen", func_get_args()); }
function strposb() { return call_user_func_array("strpos", func_get_args()); }
+function strrposb() { return call_user_func_array("strrpos", func_get_args()); }
function substrb() { return call_user_func_array("substr", func_get_args()); }
// Error reporting for PHP 5
diff --git a/system/core/core_commandline.php b/system/core/core_commandline.php
@@ -5,7 +5,7 @@
// Command line core plugin
class Yellow_Commandline
{
- const Version = "0.1.1";
+ const Version = "0.1.2";
var $yellow; //access to API
// Initialise plugin
@@ -43,99 +43,162 @@ class Yellow_Commandline
echo "Yellow ".Yellow::Version."\n";
foreach($this->yellow->plugins->plugins as $key=>$value) echo "$value[class] $value[version]\n";
return 0;
- }
+ }
- // Build static website
+ // Build website
function build($args)
- {
- $statusCodeMax = $errorCount = 0;
+ {
+ $statusCode = 0;
list($name, $command, $path, $location) = $args;
if(!empty($path) && $path!="/")
{
- $this->yellow->toolbox->timerStart($time);
- if(empty($location))
+ if($this->yellow->config->isExisting("serverName") && $this->yellow->config->isExisting("serverBase"))
{
- $pages = $this->yellow->pages->index(true);
- $fileNames = $this->yellow->toolbox->getDirectoryEntriesrecursive($this->yellow->config->get("mediaDir"), "/.*/", false, false);
+ $this->yellow->toolbox->timerStart($time);
+ $serverName = $this->yellow->config->get("serverName");
+ $serverBase = $this->yellow->config->get("serverBase");
+ list($statusCode, $contentCount, $mediaCount, $errorCount) = $this->buildStatic($serverName, $serverBase, $location, $path);
+ $this->yellow->toolbox->timerStop($time);
+ if(defined("DEBUG") && DEBUG>=1) echo "Yellow_Commandline::build time:$time ms\n";
} else {
- $pages = new Yellow_PageCollection($this->yellow, $location);
- $pages->append(new Yellow_Page($this->yellow, $location));
- $fileNames = array();
+ list($statusCode, $contentCount, $mediaCount, $errorCount) = array(500, 0, 0, 1);
+ $fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
+ echo "ERROR bulding website: Please configure serverName and serverBase in file '$fileName'!\n";
}
- foreach($pages as $page)
+ echo "Yellow build: $contentCount content, $mediaCount media";
+ echo ", $errorCount error".($errorCount!=1 ? 's' : '');
+ echo ", status $statusCode\n";
+ } else {
+ echo "Yellow build: Invalid arguments\n";
+ }
+ return $statusCode;
+ }
+
+ // Build static files
+ function buildStatic($serverName, $serverBase, $location, $path)
+ {
+ $statusCodeMax = $errorCount = 0;
+ if(empty($location))
+ {
+ $pages = $this->yellow->pages->index(true);
+ $fileNames = $this->yellow->toolbox->getDirectoryEntriesrecursive($this->yellow->config->get("mediaDir"), "/.*/", false, false);
+ } else {
+ $pages = new Yellow_PageCollection($this->yellow, $location);
+ $pages->append(new Yellow_Page($this->yellow, $location));
+ $fileNames = array();
+ }
+ foreach($pages as $page)
+ {
+ $statusCode = $this->buildStaticFile($serverName, $serverBase, $page->location, $path);
+ $statusCodeMax = max($statusCodeMax, $statusCode);
+ if($statusCode >= 400)
{
- $statusCode = $this->buildContentFile($path, $page->location);
- $statusCodeMax = max($statusCodeMax, $statusCode);
- if($statusCode >= 400)
- {
- ++$errorCount;
- echo "ERROR building location '".$page->location."', ".$this->yellow->page->getStatusCode(true)."\n";
- }
- if(defined("DEBUG") && DEBUG>=1) echo "Yellow_Commandline::build status:$statusCode location:".$page->location."\n";
+ ++$errorCount;
+ echo "ERROR building location '".$page->location."', ".$this->yellow->page->getStatusCode(true)."\n";
}
- foreach($fileNames as $fileName)
+ if(defined("DEBUG") && DEBUG>=1) echo "Yellow_Commandline::buildStatic status:$statusCode location:".$page->location."\n";
+ }
+ foreach($fileNames as $fileName)
+ {
+ $statusCode = $this->copyStaticFile($fileName, "$path/$fileName") ? 200 : 500;
+ $statusCodeMax = max($statusCodeMax, $statusCode);
+ if($statusCode >= 400)
{
- $statusCode = $this->buildMediaFile($fileName, "$path/$fileName");
- $statusCodeMax = max($statusCodeMax, $statusCode);
- if($statusCode >= 400)
- {
- ++$errorCount;
- echo "ERROR building file '$path/$fileName', ".$this->yellow->toolbox->getHttpStatusFormatted($statusCode)."\n";
- }
- if(defined("DEBUG") && DEBUG>=1) echo "Yellow_Commandline::build status:$statusCode file:$fileName\n";
+ ++$errorCount;
+ echo "ERROR building file '$path/$fileName', ".$this->yellow->toolbox->getHttpStatusFormatted($statusCode)."\n";
}
- $this->yellow->toolbox->timerStop($time);
- if(defined("DEBUG") && DEBUG>=1) echo "Yellow_Commandline::build time:$time ms\n";
- echo "Yellow build: ".count($pages)." content, ".count($fileNames)." media";
- echo ", $errorCount error".($errorCount!=1 ? 's' : '');
- echo ", status $statusCodeMax\n";
- } else {
- echo "Yellow build: Invalid arguments\n";
+ if(defined("DEBUG") && DEBUG>=1) echo "Yellow_Commandline::buildStatic status:$statusCode file:$fileName\n";
}
- return $statusCodeMax;
+ return array($statusCodeMax, count($pages), count($fileNames), $errorCount);
}
- // Build content file
- function buildContentFile($path, $location)
+ // Build static file
+ function buildStaticFile($serverName, $serverBase, $location, $path)
{
ob_start();
- $_SERVER["REQUEST_URI"] = $this->yellow->config->get("baseLocation").$location;
- $_SERVER["SCRIPT_NAME"] = $this->yellow->config->get("baseLocation")."yellow.php";
- $_SERVER["SERVER_NAME"] = $this->yellow->config->get("serverName");
$_SERVER["SERVER_PROTOCOL"] = "HTTP/1.1";
- $fileName = $path.$location;
- if(!$this->yellow->toolbox->isFileLocation($location)) $fileName .= $this->yellow->config->get("commandBuildDefaultFile");
+ $_SERVER["SERVER_NAME"] = $serverName;
+ $_SERVER["REQUEST_URI"] = $serverBase.$location;
+ $_SERVER["SCRIPT_NAME"] = $serverBase."yellow.php";
$statusCode = $this->yellow->request();
if($statusCode != 404)
{
+ $ok = true;
$modified = strtotime($this->yellow->page->getHeader("Last-Modified"));
- if(!$this->yellow->toolbox->makeFile($fileName, ob_get_contents(), true) ||
- !$this->yellow->toolbox->modifyFile($fileName, $modified))
+ if(preg_match("/^(\w+)\/(\w+)/", $this->yellow->page->getHeader("Content-Type"), $matches))
{
- $statusCode = 500;
- $this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
+ $contentType = "$matches[1]/$matches[2]";
+ $locationExtension = $this->getStaticLocation($location, ".$matches[2]");
+ }
+ if(empty($contentType) || $contentType=="text/html")
+ {
+ $fileName = $this->getStaticFileName($location, $path);
+ $fileData = ob_get_contents();
+ if($statusCode == 301) $fileData = $this->getStaticRedirect($this->yellow->page->getHeader("Location"));
+ $ok = $this->makeStaticFile($fileName, $fileData, $modified);
+ } else {
+ $fileName = $this->getStaticFileName($location, $path);
+ $fileData = $this->getStaticRedirect("http://$serverName$serverBase$locationExtension");
+ $ok = $this->makeStaticFile($fileName, $fileData, $modified);
+ if($ok)
+ {
+ $fileName = $this->getStaticFileName($locationExtension, $path);
+ $fileData = ob_get_contents();
+ $ok = $this->makeStaticFile($fileName, $fileData, $modified);
+ }
}
- list($contentType) = explode(';', $this->yellow->page->getHeader("Content-Type"));
- if($contentType != "text/html")
+ if(!$ok)
{
$statusCode = 500;
- $this->yellow->page->error($statusCode, "Unsupported type '$contentType'!");
+ $this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
}
}
ob_end_clean();
return $statusCode;
}
- // Build media file
- function buildMediaFile($fileNameSource, $fileNameDest)
+ // Create static file
+ function makeStaticFile($fileName, $fileData, $modified)
+ {
+ return $this->yellow->toolbox->makeFile($fileName, $fileData, true) &&
+ $this->yellow->toolbox->modifyFile($fileName, $modified);
+ }
+
+ // Copy static file
+ function copyStaticFile($fileNameSource, $fileNameDest)
+ {
+ return $this->yellow->toolbox->copyFile($fileNameSource, $fileNameDest, true) &&
+ $this->yellow->toolbox->modifyFile($fileNameDest, filemtime($fileNameSource));
+ }
+
+ // Return static file name from location
+ function getStaticFileName($location, $path)
{
- $statusCode = 200;
- if(!$this->yellow->toolbox->copyFile($fileNameSource, $fileNameDest, true) ||
- !$this->yellow->toolbox->modifyFile($fileNameDest, filemtime($fileNameSource)))
+ $fileName = $path.$location;
+ if(!$this->yellow->toolbox->isFileLocation($location))
{
- $statusCode = 500;
+ $fileName .= $this->yellow->config->get("commandBuildDefaultFile");
}
- return $statusCode;
+ return $fileName;
+ }
+
+ // Return static location with file extension
+ function getStaticLocation($location, $extension)
+ {
+ if(!$this->yellow->toolbox->isFileLocation($location)) $location .= "index";
+ return $location.$extension;
+ }
+
+ // Return static redirect data
+ function getStaticRedirect($url)
+ {
+ $data = "<!DOCTYPE html><html>\n";
+ $data .= "<head>\n";
+ $data .= "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n";
+ $data .= "<meta http-equiv=\"refresh\" content=\"0;url=$url\" />\n";
+ $data .= "</head>\n";
+ $data .= "</html>\n";
+ return $data;
}
}
diff --git a/system/core/core_markdown.php b/system/core/core_markdown.php
@@ -5,7 +5,7 @@
// Markdown parser core plugin
class Yellow_Markdown
{
- const Version = "0.1.4";
+ const Version = "0.1.5";
var $markdown; //markdown parser
var $html; //generated HTML
@@ -45,7 +45,7 @@ class Yellow_MarkdownExtraParser extends MarkdownExtra_Parser
function _doImages_inline_callback($matches)
{
$path = $matches[3]=="" ? $matches[4] : $matches[3];
- $src = $this->yellow->config->get("baseLocation").$this->yellow->config->get("imageLocation").$path;
+ $src = $this->yellow->config->get("serverBase").$this->yellow->config->get("imageLocation").$path;
list($width, $height) = $this->yellow->toolbox->detectImageDimensions($this->yellow->config->get("imageDir").$path);
$alt = $matches[2];
$title = $matches[7];
diff --git a/system/core/core_webinterface.js b/system/core/core_webinterface.js
@@ -4,7 +4,7 @@
// Yellow main API
var yellow =
{
- version: "0.1.1",
+ version: "0.1.2",
onClick: function(e) { yellow.webinterface.hidePanesOnClick(yellow.toolbox.getEventElement(e)); },
onKeydown: function(e) { yellow.webinterface.hidePanesOnKeydown(yellow.toolbox.getEventKeycode(e)); },
onResize: function() { yellow.webinterface.resizePanes(); },
@@ -61,7 +61,7 @@ yellow.webinterface =
elementBar.setAttribute("id", id);
if(!simple)
{
- var location = yellow.config.baseLocation+yellow.config.pluginLocation;
+ var location = yellow.config.serverBase+yellow.config.pluginLocation;
elementBar.innerHTML =
"<div class=\"yellow-barleft\">"+
"<a href=\"http://datenstrom.se/yellow/\" target=\"_blank\"><img src=\""+location+"core_webinterface.png\" width=\"16\" height=\"16\"> Yellow</a>"+
diff --git a/system/core/core_webinterface.php b/system/core/core_webinterface.php
@@ -5,7 +5,7 @@
// Web interface core plugin
class Yellow_Webinterface
{
- const Version = "0.1.5";
+ const Version = "0.1.6";
var $yellow; //access to API
var $users; //web interface users
var $activeLocation; //web interface location? (boolean)
@@ -24,23 +24,23 @@ class Yellow_Webinterface
}
// Handle web interface location
- function onRequest($baseLocation, $location, $fileName)
+ function onRequest($serverName, $serverBase, $location, $fileName)
{
$statusCode = 0;
if($this->checkWebinterfaceLocation($location))
{
- $baseLocation .= rtrim($this->yellow->config->get("webinterfaceLocation"), '/');
- $location = $this->yellow->getRelativeLocation($baseLocation);
+ $serverBase .= rtrim($this->yellow->config->get("webinterfaceLocation"), '/');
+ $location = $this->yellow->getRelativeLocation($serverBase);
$fileName = $this->yellow->getContentFileName($location);
- if($this->checkUser()) $statusCode = $this->processRequestAction($baseLocation, $location, $fileName);
- if($statusCode == 0) $statusCode = $this->yellow->processRequest($baseLocation, $location, $fileName,
+ if($this->checkUser()) $statusCode = $this->processRequestAction($serverName, $serverBase, $location, $fileName);
+ if($statusCode == 0) $statusCode = $this->yellow->processRequest($serverName, $serverBase, $location, $fileName,
false, $this->activeUserFail ? 401 : 0);
} else {
if($this->yellow->config->get("webinterfaceLocation") == "$location/")
{
$statusCode = 301;
- $serverName = $this->yellow->config->get("serverName");
- $this->yellow->sendStatus($statusCode, "Location: http://$serverName$baseLocation$location/");
+ $locationHeader = $this->yellow->toolbox->getHttpLocationHeader($serverName, $serverBase, "$location/");
+ $this->yellow->sendStatus($statusCode, $locationHeader);
}
}
return $statusCode;
@@ -51,10 +51,10 @@ class Yellow_Webinterface
{
if($this->isWebinterfaceLocation() && $this->isUser())
{
- $baseLocation = $this->yellow->config->get("baseLocation");
+ $serverBase = $this->yellow->config->get("serverBase");
$webinterfaceLocation = trim($this->yellow->config->get("webinterfaceLocation"), '/');
- $text = preg_replace("#<a(.*?)href=\"$baseLocation/(?!$webinterfaceLocation)(.*?)\"(.*?)>#",
- "<a$1href=\"$baseLocation/$webinterfaceLocation/$2\"$3>", $text);
+ $text = preg_replace("#<a(.*?)href=\"$serverBase/(?!$webinterfaceLocation)(.*?)\"(.*?)>#",
+ "<a$1href=\"$serverBase/$webinterfaceLocation/$2\"$3>", $text);
switch($statusCode)
{
case 200: $this->rawDataOriginal = $this->yellow->page->rawData; break;
@@ -77,7 +77,7 @@ class Yellow_Webinterface
$header = "";
if($this->isWebinterfaceLocation())
{
- $location = $this->yellow->config->getHtml("baseLocation").$this->yellow->config->getHtml("pluginLocation");
+ $location = $this->yellow->config->getHtml("serverBase").$this->yellow->config->getHtml("pluginLocation");
$language = $this->isUser() ? $this->users->getLanguage($this->activeUserEmail) : $this->yellow->page->get("language");
$header .= "<link rel=\"styleSheet\" type=\"text/css\" media=\"all\" href=\"{$location}core_webinterface.css\" />\n";
$header .= "<script type=\"text/javascript\" src=\"{$location}core_webinterface.js\"></script>\n";
@@ -98,44 +98,46 @@ class Yellow_Webinterface
}
// Process request for an action
- function processRequestAction($baseLocation, $location, $fileName)
+ function processRequestAction($serverName, $serverBase, $location, $fileName)
{
$statusCode = 0;
- $serverName = $this->yellow->config->get("serverName");
if($_POST["action"] == "edit")
{
- if(!empty($_POST["rawdata"]))
+ if(!empty($_POST["rawdata"]) && $this->checkUserPermissions($location, $fileName))
{
$this->rawDataOriginal = $_POST["rawdata"];
if($this->yellow->toolbox->makeFile($fileName, $_POST["rawdata"]))
{
$statusCode = 303;
- $this->yellow->sendStatus($statusCode, "Location: http://$serverName$baseLocation$location");
+ $locationHeader = $this->yellow->toolbox->getHttpLocationHeader($serverName, $serverBase, $location);
+ $this->yellow->sendStatus($statusCode, $locationHeader);
} else {
$statusCode = 500;
- $this->yellow->processRequest($baseLocation, $location, $fileName, false, $statusCode);
+ $this->yellow->processRequest($serverName, $serverBase, $location, $fileName, false, $statusCode);
$this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
}
}
} else if($_POST["action"]== "login") {
$statusCode = 303;
- $this->yellow->sendStatus($statusCode, "Location: http://$serverName$baseLocation$location");
+ $locationHeader = $this->yellow->toolbox->getHttpLocationHeader($serverName, $serverBase, $location);
+ $this->yellow->sendStatus($statusCode, $locationHeader);
} else if($_POST["action"]== "logout") {
$this->users->destroyCookie("login");
$this->activeUserEmail = "";
$statusCode = 302;
- $newLocation = $this->yellow->config->getHtml("baseLocation").$location;
- $this->yellow->sendStatus($statusCode, "Location: http://$serverName$newLocation");
+ $locationHeader = $this->yellow->toolbox->getHttpLocationHeader($serverName, $this->yellow->config->get("serverBase"), $location);
+ $this->yellow->sendStatus($statusCode, $locationHeader);
} else {
if(!is_readable($fileName))
{
if($this->yellow->toolbox->isFileLocation($location) && is_dir($this->yellow->getContentDirectory("$location/")))
{
$statusCode = 301;
- $this->yellow->sendStatus($statusCode, "Location: http://$serverName$baseLocation$location/");
+ $locationHeader = $this->yellow->toolbox->getHttpLocationHeader($serverName, $serverBase, "$location/");
+ $this->yellow->sendStatus($statusCode, $locationHeader);
} else {
$statusCode = $this->checkUserPermissions($location, $fileName) ? 424 : 404;
- $this->yellow->processRequest($baseLocation, $location, $fileName, false, $statusCode);
+ $this->yellow->processRequest($serverName, $serverBase, $location, $fileName, false, $statusCode);
}
}
}
@@ -215,7 +217,8 @@ class Yellow_Webinterface
$data = array("userEmail" => $email,
"userName" => $this->users->getName($email),
"userLanguage" => $this->users->getLanguage($email),
- "baseLocation" => $this->yellow->config->get("baseLocation"));
+ "serverName" => $this->yellow->config->get("serverName"),
+ "serverBase" => $this->yellow->config->get("serverBase"));
return array_merge($data, $this->yellow->config->getData("Location"));
}
}
diff --git a/system/snippets/header.php b/system/snippets/header.php
@@ -6,11 +6,11 @@
<meta name="author" content="<?php echo $yellow->page->getHtml("author") ?>" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo $yellow->config->getHtml("sitename")." - ".$yellow->page->getHtml("title") ?></title>
-<link rel="shortcut icon" href="<?php echo $yellow->config->get("baseLocation").$yellow->config->get("imageLocation")."default_icon.png" ?>" />
-<link rel="stylesheet" type="text/css" media="all" href="<?php echo $yellow->config->get("baseLocation").$yellow->config->get("styleLocation").$yellow->page->get("style").".css" ?>" />
+<link rel="shortcut icon" href="<?php echo $yellow->config->get("serverBase").$yellow->config->get("imageLocation")."default_icon.png" ?>" />
+<link rel="stylesheet" type="text/css" media="all" href="<?php echo $yellow->config->get("serverBase").$yellow->config->get("styleLocation").$yellow->page->get("style").".css" ?>" />
<?php echo $yellow->getHeaderExtra() ?>
</head>
<body>
<div class="page">
-<div class="header"><h1><a href="<?php echo $yellow->config->get("baseLocation")."/" ?>"><?php echo $yellow->config->getHtml("sitename") ?></a></h1></div>
+<div class="header"><h1><a href="<?php echo $yellow->config->get("serverBase")."/" ?>"><?php echo $yellow->config->getHtml("sitename") ?></a></h1></div>
<div class="header-banner"></div>