Better location handling (UTF-8 is good for you)
This commit is contained in:
parent
1a2d981929
commit
a17580f2d1
7 changed files with 283 additions and 157 deletions
|
@ -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/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
$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";
|
||||
}
|
||||
foreach($fileNames as $fileName)
|
||||
{
|
||||
$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";
|
||||
}
|
||||
$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 "Yellow build: $contentCount content, $mediaCount media";
|
||||
echo ", $errorCount error".($errorCount!=1 ? 's' : '');
|
||||
echo ", status $statusCodeMax\n";
|
||||
echo ", status $statusCode\n";
|
||||
} else {
|
||||
echo "Yellow build: Invalid arguments\n";
|
||||
}
|
||||
return $statusCodeMax;
|
||||
return $statusCode;
|
||||
}
|
||||
|
||||
// Build content file
|
||||
function buildContentFile($path, $location)
|
||||
// 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)
|
||||
{
|
||||
++$errorCount;
|
||||
echo "ERROR building location '".$page->location."', ".$this->yellow->page->getStatusCode(true)."\n";
|
||||
}
|
||||
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)
|
||||
{
|
||||
++$errorCount;
|
||||
echo "ERROR building file '$path/$fileName', ".$this->yellow->toolbox->getHttpStatusFormatted($statusCode)."\n";
|
||||
}
|
||||
if(defined("DEBUG") && DEBUG>=1) echo "Yellow_Commandline::buildStatic status:$statusCode file:$fileName\n";
|
||||
}
|
||||
return array($statusCodeMax, count($pages), count($fileNames), $errorCount);
|
||||
}
|
||||
|
||||
// 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))
|
||||
{
|
||||
$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);
|
||||
}
|
||||
}
|
||||
if(!$ok)
|
||||
{
|
||||
$statusCode = 500;
|
||||
$this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
|
||||
}
|
||||
list($contentType) = explode(';', $this->yellow->page->getHeader("Content-Type"));
|
||||
if($contentType != "text/html")
|
||||
{
|
||||
$statusCode = 500;
|
||||
$this->yellow->page->error($statusCode, "Unsupported type '$contentType'!");
|
||||
}
|
||||
}
|
||||
ob_end_clean();
|
||||
return $statusCode;
|
||||
}
|
||||
|
||||
// Build media file
|
||||
function buildMediaFile($fileNameSource, $fileNameDest)
|
||||
// Create static file
|
||||
function makeStaticFile($fileName, $fileData, $modified)
|
||||
{
|
||||
$statusCode = 200;
|
||||
if(!$this->yellow->toolbox->copyFile($fileNameSource, $fileNameDest, true) ||
|
||||
!$this->yellow->toolbox->modifyFile($fileNameDest, filemtime($fileNameSource)))
|
||||
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)
|
||||
{
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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>"+
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue