Core update (made for people and machines)

This commit is contained in:
markseu 2014-06-14 00:14:09 +02:00
parent 5301ef344a
commit 464e38c819
12 changed files with 142 additions and 113 deletions

View file

@ -6,6 +6,8 @@ RewriteEngine on
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(content|system)/ error404 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^robots.txt$ system/config/robots.txt [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \.(css|js|png)$
RewriteRule ^media/plugins/(core-.+) system/core/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f

View file

@ -1,8 +1,8 @@
Yellow 0.3.1
Yellow 0.3.2
============
Yellow is for people who make websites.
Yellow is for people who make websites.
[![Build Status](https://travis-ci.org/markseu/yellowcms.svg)](https://travis-ci.org/markseu/yellowcms) [![Online demo](https://github.com/markseu/yellowcms-extensions/raw/master/documentation/yellowdemo.png?raw=true)](http://demo.datenstrom.se/)
[![Build Status](https://travis-ci.org/markseu/yellowcms.svg)](https://travis-ci.org/markseu/yellowcms) [![Online demo](https://github.com/markseu/yellowcms-extensions/raw/master/documentation/english/yellowdemo.png?raw=true)](http://demo.datenstrom.se/)
How do I install this?
----------------------
@ -16,9 +16,10 @@ Yellow doesn't come with a lot of stuff. [Download Yellow extensions](https://gi
How do I get started?
---------------------
You already have everything you need. Start by editing your website.
Yellow is a flat-file content management system. [Learn more about it](https://github.com/markseu/yellowcms-extensions/blob/master/documentation/README.md).
Yellow is a flat-file content management system. [Learn more about it](https://github.com/markseu/yellowcms-extensions/blob/master/documentation/english/README.md).
License
-------
* Yellow by Mark Seuffert and David Fehrmann is licensed under [GPLv2](http://opensource.org/licenses/GPL-2.0).
* Yellow by Mark Seuffert and David Fehrmann is licensed under [GPLv2](http://opensource.org/licenses/GPL-2.0).
* Yellow extensions are licensed under [GPLv2](http://opensource.org/licenses/GPL-2.0) unless stated otherwise.
* [PHP Markdown Extra](https://github.com/michelf/php-markdown) by Michel Fortin is licensed under [BSD license](http://opensource.org/licenses/BSD-3-Clause).

View file

@ -4,4 +4,4 @@ Title: Home
Your website works!
You can now [edit this page](@pageedit) or use your text editor.
For more information see [Yellow documentation](https://github.com/markseu/yellowcms-extensions/blob/master/documentation/README.md).
For more information see [Yellow documentation](https://github.com/markseu/yellowcms-extensions/blob/master/documentation/english/README.md).

View file

@ -1,4 +1,4 @@
/* Yellow default style 0.3.1 */
/* Yellow default style 0.3.2 */
html, body, div, form, pre, span, tr, th, td { margin:0; padding:0; border:0; vertical-align:baseline; }
body {
@ -15,7 +15,7 @@ code { font-size:1.1em; }
a, img { border:none; text-decoration:none; }
a { color:#717171; }
a:hover { color:#07d; }
.header h1 { margin-top:1em; margin-bottom:0em; font-size:2.5em; }
.header h1 { margin-top:0.5em; margin-bottom:0em; font-size:2.5em; }
.header a { color:#111; }
.navigation { margin-bottom:1em; border-bottom:1px solid #ddd; line-height:2em; }
.navigation a { color:#111; padding:0 0.3em; display:inline-block; }

View file

@ -30,3 +30,12 @@ contentExtension = .txt
configExtension = .ini
errorPageFile = error(.*).txt
textStringFile = text(.*).ini
webinterfaceLocation = /edit/
webinterfaceServerScheme = https
webinterfaceUserHashAlgorithm = bcrypt
webinterfaceUserHashCost = 10
webinterfaceUserFile = user.ini
webinterfaceNewPage = default
commandlineDefaultFile = index.html
commandlineErrorFile = error404.html
commandlineSystemFile = .htaccess, system/config/robots.txt

4
system/config/robots.txt Normal file
View file

@ -0,0 +1,4 @@
User-agent: *
Disallow: /harming/humans
Disallow: /ignoring/human/orders
Disallow: /risking/own/existence

View file

@ -11,6 +11,8 @@ webinterfaceLoginButton = Login
webinterfaceSaveButton = Save
webinterfaceCancelButton = Cancel
webinterfaceEdit = Edit
webinterfaceUserHelp = Help
webinterfaceUserHelpUrl = https://github.com/markseu/yellowcms-extensions/blob/master/documentation/english/README.md
webinterfaceUserLogout = Logout
paginationPrevious = ← Previous
paginationNext = Next →

View file

@ -5,7 +5,7 @@
// Command line core plugin
class YellowCommandline
{
const Version = "0.3.1";
const Version = "0.3.2";
var $yellow; //access to API
var $content; //number of content pages
var $media; //number of media files
@ -20,9 +20,8 @@ class YellowCommandline
{
$this->yellow = $yellow;
$this->yellow->config->setDefault("commandlineDefaultFile", "index.html");
$this->yellow->config->setDefault("commandlineMediaFile", "(.*).txt");
$this->yellow->config->setDefault("commandlineErrorFile", "error404.html");
$this->yellow->config->setDefault("commandlineServerFile", ".htaccess");
$this->yellow->config->setDefault("commandlineSystemFile", "");
}
// Handle command help
@ -102,10 +101,8 @@ class YellowCommandline
$pages = $this->yellow->pages->index(true);
$fileNamesMedia = $this->yellow->toolbox->getDirectoryEntriesRecursive(
$this->yellow->config->get("mediaDir"), "/.*/", false, false);
$fileNamesMedia = array_merge($fileNamesMedia, $this->yellow->toolbox->getDirectoryEntries(
".", "/".$this->yellow->config->get("commandlineMediaFile")."/", false, false, false));
$fileNamesSystem = array($this->yellow->config->get("commandlineErrorFile"),
$this->yellow->config->get("commandlineServerFile"));
$fileNamesSystem = preg_split("/,\s*/", $this->yellow->config->get(commandlineSystemFile));
array_push($fileNamesSystem, $this->yellow->config->get("commandlineErrorFile"));
} else {
$pages = new YellowPageCollection($this->yellow);
$pages->append(new YellowPage($this->yellow, "", "", "", $location));
@ -138,7 +135,7 @@ class YellowCommandline
}
foreach($fileNamesSystem as $fileName)
{
$statusCodeMax = max($statusCodeMax, $this->buildStaticFile($fileName, "$path/$fileName", false));
$statusCodeMax = max($statusCodeMax, $this->buildStaticFile($fileName, "$path/".basename($fileName), false));
}
$this->yellow->toolbox->timerStop($time);
if(defined("DEBUG") && DEBUG>=1) echo "YellowCommandline::buildStatic time:$time ms\n";

View file

@ -4,7 +4,7 @@
// Yellow main API
var yellow =
{
version: "0.3.1",
version: "0.3.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(); },
@ -70,7 +70,6 @@ yellow.webinterface =
var location = yellow.config.serverBase+yellow.config.pluginLocation;
elementBar.innerHTML =
"<div class=\"yellow-bar-left\">"+
"<a href=\"https://github.com/markseu/yellowcms-extensions/blob/master/documentation/README.md\" target=\"_blank\"><i class=\"yellow-icon\"></i> Yellow</a>"+
"<a href=\"#\" onclick=\"yellow.onShow('yellow-pane-edit'); return false;\">"+this.getText("Edit")+"</a>"+
"</div>"+
"<div class=\"yellow-bar-right\">"+
@ -114,6 +113,7 @@ yellow.webinterface =
} else if(id == "yellow-pane-user") {
elementDiv.innerHTML =
"<p>"+yellow.config.userEmail+"</p>"+
"<p><a href=\""+this.getText("UserHelpUrl")+"\">"+this.getText("UserHelp")+"</a></p>" +
"<p><a href=\"#\" onclick=\"yellow.onLogout(); return false;\">"+this.getText("UserLogout")+"</a></p>";
}

View file

@ -5,7 +5,7 @@
// Web interface core plugin
class YellowWebinterface
{
const Version = "0.3.1";
const Version = "0.3.2";
var $yellow; //access to API
var $users; //web interface users
var $active; //web interface is active? (boolean)
@ -16,14 +16,13 @@ class YellowWebinterface
function onLoad($yellow)
{
$this->yellow = $yellow;
$this->yellow->config->setDefault("webinterfacePage", "default");
$this->yellow->config->setDefault("webinterfaceLocation", "/edit/");
$this->yellow->config->setDefault("webinterfaceUserFile", "user.ini");
$this->yellow->config->setDefault("webinterfaceUserHome", "/");
$this->yellow->config->setDefault("webinterfaceUserHashAlgorithm", "bcrypt");
$this->yellow->config->setDefault("webinterfaceUserHashCost", "10");
$this->yellow->config->setDefault("webinterfaceServerScheme", "https");
$this->yellow->config->setDefault("webinterfaceServerName", $this->yellow->config->get("serverName"));
$this->yellow->config->setDefault("webinterfaceUserHashAlgorithm", "bcrypt");
$this->yellow->config->setDefault("webinterfaceUserHashCost", "10");
$this->yellow->config->setDefault("webinterfaceUserFile", "user.ini");
$this->yellow->config->setDefault("webinterfaceNewPage", "default");
$this->users = new YellowWebinterfaceUsers($yellow);
$this->users->load($this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile"));
}
@ -299,7 +298,7 @@ class YellowWebinterface
$this->yellow->config->get("contentDir"), $this->yellow->config->get("contentHomeDir"),
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
$fileName = $this->yellow->toolbox->findNameFromFile($fileName,
$this->yellow->config->get("configDir"), $this->yellow->config->get("webinterfacePage"),
$this->yellow->config->get("configDir"), $this->yellow->config->get("webinterfaceNewPage"),
$this->yellow->config->get("contentExtension"), true);
$fileHandle = @fopen($fileName, "r");
if($fileHandle)
@ -410,7 +409,7 @@ class YellowWebinterfaceUsers
{
$name = strreplaceu(',', '-', empty($name) ? $this->yellow->config->get("sitename") : $name);
$language = strreplaceu(',', '-', empty($language) ? $this->yellow->config->get("language") : $language);
$home = strreplaceu(',', '-', empty($home) ? $this->yellow->config->get("webinterfaceUserHome") : $home);
$home = strreplaceu(',', '-', empty($home) ? "/" : $home);
$fileDataNew .= "$email,$hash,$name,$language,$home\n";
}
return $this->yellow->toolbox->createFile($fileName, $fileDataNew);

View file

@ -5,7 +5,7 @@
// Yellow main class
class Yellow
{
const Version = "0.3.1";
const Version = "0.3.2";
var $page; //current page
var $pages; //pages from file system
var $config; //configuration
@ -51,6 +51,7 @@ class Yellow
$this->config->setDefault("textStringFile", "text(.*).ini");
$this->config->load($this->config->get("configDir").$this->config->get("configFile"));
$this->text->load($this->config->get("configDir").$this->config->get("textStringFile"));
$this->updateConfig();
}
// Handle request
@ -75,7 +76,7 @@ class Yellow
$this->pages->requestHandler = "core";
$statusCode = $this->processRequest($serverScheme, $serverName, $base, $location, $fileName, true, $statusCode);
}
if($this->isRequestError() || $statusCodeRequest>=400) $statusCode = $this->processRequestError($statusCodeRequest);
if($this->page->isError() || $statusCodeRequest>=400) $statusCode = $this->processRequestError($statusCodeRequest);
ob_end_flush();
$this->toolbox->timerStop($time);
if(defined("DEBUG") && DEBUG>=1) echo "Yellow::request status:$statusCode location:$location<br>\n";
@ -219,6 +220,21 @@ class Yellow
if(!empty($responseHeader)) @header($responseHeader);
}
}
// Update configuration
function updateConfig()
{
if(!$this->isContentDirectory("/"))
{
$path = $this->config->get("contentDir");
foreach($this->toolbox->getDirectoryEntries($path, "/.*/", true, true, false) as $entry)
{
$name = $this->toolbox->normaliseName($entry);
$this->config->set("contentHomeDir", $name."/");
break;
}
}
}
// Return request information
function getRequestInformation($serverScheme = "", $serverName = "", $base = "")
@ -252,13 +268,7 @@ class Yellow
{
return isset($_GET["clean-url"]) || isset($_POST["clean-url"]);
}
// Check if request error happened
function isRequestError()
{
return $this->page->isExisting("pageError");
}
// Check if content directory exists
function isContentDirectory($location)
{
@ -368,6 +378,23 @@ class YellowPage
$this->parseMeta();
}
// Parse page data update
function parseDataUpdate()
{
if($this->statusCode == 0)
{
$fileHandle = @fopen($this->fileName, "r");
if($fileHandle)
{
$this->statusCode = 200;
$this->rawData = fread($fileHandle, filesize($this->fileName));
$this->metaData = array();
fclose($fileHandle);
$this->parseMeta();
}
}
}
// Parse page meta data
function parseMeta()
{
@ -417,24 +444,6 @@ class YellowPage
}
}
// Parse page update if necessary
function parseUpdate()
{
if($this->statusCode == 0)
{
$fileHandle = @fopen($this->fileName, "r");
if($fileHandle)
{
$this->statusCode = 200;
$this->rawData = fread($fileHandle, filesize($this->fileName));
$this->metaData = array();
fclose($fileHandle);
$this->parseMeta();
}
if(defined("DEBUG") && DEBUG>=2) echo "YellowPage::parseUpdate location:".$this->location."<br/>\n";
}
}
// Parse page content
function parseContent()
{
@ -520,7 +529,7 @@ class YellowPage
{
if($rawFormat)
{
$this->parseUpdate();
$this->parseDataUpdate();
$text = substrb($this->rawData, $this->metaDataOffsetBytes);
} else {
$this->parseContent();
@ -640,6 +649,12 @@ class YellowPage
return !is_null($this->metaData[$key]);
}
// Check if page with error
function isError()
{
return $this->isExisting("pageError");
}
// Check if page is within current HTTP request
function isActive()
{
@ -1525,6 +1540,14 @@ class YellowToolbox
return $includeFileName ? "$pathBase$name$fileExtension" : $name;
}
// Normalise location arguments
function normaliseArgs($text, $appendSlash = true, $filterStrict = true)
{
if($appendSlash) $text .= '/';
if($filterStrict) $text = strreplaceu(' ', '-', strtoloweru($text));
return strreplaceu(array('%3A','%2F'), array(':','/'), rawurlencode($text));
}
// Normalise file/directory/attribute name
function normaliseName($text, $removeExtension = false, $filterStrict = false)
{
@ -1534,7 +1557,7 @@ class YellowToolbox
return preg_replace("/[^\pL\d\-\_\.]/u", "-", $text);
}
// Normalise location, make absolute page location
// Normalise location, make absolute location
function normaliseLocation($location, $pageBase, $pageLocation)
{
if(!preg_match("/^\w+:/", $location))
@ -1551,14 +1574,6 @@ class YellowToolbox
return $location;
}
// Normalise location arguments
function normaliseArgs($text, $appendSlash = true, $filterStrict = true)
{
if($appendSlash) $text .= '/';
if($filterStrict) $text = strreplaceu(' ', '-', strtoloweru($text));
return strreplaceu(array('%3A','%2F'), array(':','/'), rawurlencode($text));
}
// Normalise text into UTF-8 NFC
function normaliseUnicode($text)
{
@ -1776,46 +1791,6 @@ class YellowToolbox
return $text;
}
// Detect PNG and JPG image dimensions
function detectImageDimensions($fileName)
{
$width = $height = 0;
$fileHandle = @fopen($fileName, "rb");
if($fileHandle)
{
if(substru($fileName, -3) == "png")
{
$dataSignature = fread($fileHandle, 8);
$dataHeader = fread($fileHandle, 16);
if(!feof($fileHandle) && $dataSignature=="\x89PNG\r\n\x1a\n")
{
$width = (ord($dataHeader[10])<<8) + ord($dataHeader[11]);
$height = (ord($dataHeader[14])<<8) + ord($dataHeader[15]);
}
} else if(substru($fileName, -3) == "jpg") {
$dataBufferSize = min(filesize($fileName), 8192);
$dataBuffer = fread($fileHandle, $dataBufferSize);
$dataSignature = substrb($dataBuffer, 0, 11);
if(!feof($fileHandle) && $dataSignature=="\xff\xd8\xff\xe0\x00\x10JFIF\0")
{
for($pos=20; $pos+8<$dataBufferSize; $pos+=$length)
{
if($dataBuffer[$pos] != "\xff") break;
if($dataBuffer[$pos+1]=="\xc0" || $dataBuffer[$pos+1]=="\xc2")
{
$width = (ord($dataBuffer[$pos+7])<<8) + ord($dataBuffer[$pos+8]);
$height = (ord($dataBuffer[$pos+5])<<8) + ord($dataBuffer[$pos+6]);
break;
}
$length = (ord($dataBuffer[$pos+2])<<8) + ord($dataBuffer[$pos+3]) + 2;
}
}
}
fclose($fileHandle);
}
return array($width, $height);
}
// Create random text for cryptography
function createSalt($length, $bcryptFormat = false)
{
@ -1844,7 +1819,7 @@ class YellowToolbox
return $salt;
}
// Create hash with random salt
// Create hash with random salt, bcrypt or sha256
function createHash($text, $algorithm, $cost = 0)
{
$hash = "";
@ -1884,13 +1859,53 @@ class YellowToolbox
return $ok;
}
// Detect image dimensions, PNG or JPG
function detectImageDimensions($fileName)
{
$width = $height = 0;
$fileHandle = @fopen($fileName, "rb");
if($fileHandle)
{
if(substru($fileName, -3) == "png")
{
$dataSignature = fread($fileHandle, 8);
$dataHeader = fread($fileHandle, 16);
if(!feof($fileHandle) && $dataSignature=="\x89PNG\r\n\x1a\n")
{
$width = (ord($dataHeader[10])<<8) + ord($dataHeader[11]);
$height = (ord($dataHeader[14])<<8) + ord($dataHeader[15]);
}
} else if(substru($fileName, -3) == "jpg") {
$dataBufferSize = min(filesize($fileName), 8192);
$dataBuffer = fread($fileHandle, $dataBufferSize);
$dataSignature = substrb($dataBuffer, 0, 11);
if(!feof($fileHandle) && $dataSignature=="\xff\xd8\xff\xe0\x00\x10JFIF\0")
{
for($pos=20; $pos+8<$dataBufferSize; $pos+=$length)
{
if($dataBuffer[$pos] != "\xff") break;
if($dataBuffer[$pos+1]=="\xc0" || $dataBuffer[$pos+1]=="\xc2")
{
$width = (ord($dataBuffer[$pos+7])<<8) + ord($dataBuffer[$pos+8]);
$height = (ord($dataBuffer[$pos+5])<<8) + ord($dataBuffer[$pos+6]);
break;
}
$length = (ord($dataBuffer[$pos+2])<<8) + ord($dataBuffer[$pos+3]) + 2;
}
}
}
fclose($fileHandle);
}
return array($width, $height);
}
// Start timer
function timerStart(&$time)
{
$time = microtime(true);
}
// Stop timer and calcuate elapsed time (milliseconds)
// Stop timer and calculate elapsed time in milliseconds
function timerStop(&$time)
{
$time = intval((microtime(true)-$time) * 1000);
@ -1941,24 +1956,24 @@ class YellowPlugins
}
}
// Unicode support for PHP 5
// Unicode support for PHP
mb_internal_encoding("UTF-8");
function strempty($string) { return is_null($string) || $string===""; }
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 strlenu() { return call_user_func_array("mb_strlen", func_get_args()); }
function strlenb() { return call_user_func_array("strlen", func_get_args()); }
function strposu() { return call_user_func_array("mb_strpos", func_get_args()); }
function strposb() { return call_user_func_array("strpos", func_get_args()); }
function strrposu() { return call_user_func_array("mb_strrpos", func_get_args()); }
function strrposb() { return call_user_func_array("strrpos", func_get_args()); }
function substru() { return call_user_func_array("mb_substr", func_get_args()); }
function substrb() { return call_user_func_array("substr", func_get_args()); }
// Default timezone for PHP 5
// Default timezone for PHP
date_default_timezone_set(@date_default_timezone_get());
// Error reporting for PHP 5
// Error reporting for PHP
error_reporting(E_ALL ^ E_NOTICE);
?>

View file

@ -1,5 +1,5 @@
<div class="footer">
&copy; 2014 <?php echo $yellow->page->getHtml("sitename") ?>. <a href="https://github.com/markseu/yellowcms">Built with Yellow</a>
&copy; 2014 <?php echo $yellow->page->getHtml("sitename") ?>. <a href="https://github.com/markseu/yellowcms">Built with Yellow</a>.
</div>
</div>
</body>