Better location handling (UTF-8 is good for you)

This commit is contained in:
markseu 2013-07-29 20:49:57 +02:00
parent 1a2d981929
commit a17580f2d1
7 changed files with 283 additions and 157 deletions

View file

@ -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/

View file

@ -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

View file

@ -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;
}
}

View file

@ -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];

View file

@ -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>"+

View file

@ -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"));
}
}

View file

@ -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>