Core update (hot summer remix)

This commit is contained in:
markseu 2014-07-25 12:46:58 +02:00
parent 8a69cbb9d6
commit 5a56168a87
8 changed files with 621 additions and 261 deletions

View file

@ -1,4 +1,4 @@
Yellow 0.3.7
Yellow 0.3.8
============
Yellow is for people who make websites. [Visit website](http://datenstrom.se/yellow).

View file

@ -1,4 +1,4 @@
---
Title: Page does not exist
Title: File not found
---
You can [create this page](javascript:yellow.onShow('yellow-pane-edit');).
You can [create this page](javascript:yellow.action('edit');).

View file

@ -8,9 +8,12 @@ webinterfaceLoginText = Yellow login
webinterfaceLoginEmail = Email:
webinterfaceLoginPassword = Password:
webinterfaceLoginButton = Login
webinterfaceSaveButton = Save
webinterfaceCreateButton = Create
webinterfaceEditButton = Save
webinterfaceDeleteButton = Delete
webinterfaceCancelButton = Cancel
webinterfaceEdit = Edit
webinterfaceNew = +
webinterfaceUserHelp = Help
webinterfaceUserHelpUrl = https://github.com/markseu/yellowcms-extensions/blob/master/documentation/english/README.md
webinterfaceUserLogout = Logout

View file

@ -5,7 +5,7 @@
// Command line core plugin
class YellowCommandline
{
const Version = "0.3.5";
const Version = "0.3.6";
var $yellow; //access to API
var $content; //number of content pages
var $media; //number of media files
@ -21,7 +21,7 @@ class YellowCommandline
$this->yellow = $yellow;
$this->yellow->config->setDefault("commandlineDefaultFile", "index.html");
$this->yellow->config->setDefault("commandlineErrorFile", "error404.html");
$this->yellow->config->setDefault("commandlineSystemFile", "");
$this->yellow->config->setDefault("commandlineSystemFile", ".htaccess");
}
// Handle command help
@ -29,6 +29,7 @@ class YellowCommandline
{
$help .= "version\n";
$help .= "build DIRECTORY [LOCATION]\n";
$help .= "clean DIRECTORY [LOCATION]\n";
return $help;
}
@ -41,7 +42,13 @@ class YellowCommandline
case "": $statusCode = $this->helpCommand(); break;
case "version": $statusCode = $this->versionCommand(); break;
case "build": $statusCode = $this->buildCommand($args); break;
default: $statusCode = $this->pluginCommand($args); break;
case "clean": $statusCode = $this->cleanCommand($args); break;
default: $statusCode = $this->pluginCommand($args);
}
if($statusCode == 0)
{
$statusCode = 400;
echo "Yellow $command: Command not found\n";
}
return $statusCode;
}
@ -94,49 +101,50 @@ class YellowCommandline
$this->yellow->toolbox->timerStart($time);
$pluginDir = $this->yellow->config->get("pluginDir");
$pathPlugin = rtrim($path.$this->yellow->config->get("pluginLocation"), '/');
$this->content = $this->media = $this->system = $this->error = $statusCodeMax = 0;
$this->content = $this->media = $this->system = $this->error = $statusCode = 0;
$this->locationsArguments = $this->locationsPagination = $this->fileNamesPlugin = array();
if(empty($location))
{
$statusCode = $this->cleanStatic($location, $path);
foreach($this->yellow->pages->index(true) as $page)
{
$statusCodeMax = max($statusCodeMax, $this->buildStaticLocation($page->location, $path, true));
$statusCode = max($statusCode, $this->buildStaticLocation($page->location, $path, true));
}
foreach($this->locationsArguments as $location)
{
$statusCodeMax = max($statusCodeMax, $this->buildStaticLocation($location, $path, true));
$statusCode = max($statusCode, $this->buildStaticLocation($location, $path, true));
}
foreach($this->locationsPagination as $location)
{
for($pageNumber=2; $pageNumber<=999; ++$pageNumber)
{
$statusCode = $this->buildStaticLocation($location.$pageNumber, $path, false, true);
$statusCodeMax = max($statusCodeMax, $statusCode);
if($statusCode == 0) break;
$statusCodeLocation = $this->buildStaticLocation($location.$pageNumber, $path, false, true);
$statusCode = max($statusCode, $statusCodeLocation);
if($statusCodeLocation == 0) break;
}
}
$fileNamesMedia = $this->yellow->toolbox->getDirectoryEntriesRecursive(
$this->yellow->config->get("mediaDir"), "/.*/", false, false);
$fileNamesSystem = preg_split("/,\s*/", $this->yellow->config->get(commandlineSystemFile));
$fileNamesSystem = preg_split("/,\s*/", $this->yellow->config->get("commandlineSystemFile"));
array_push($fileNamesSystem, $this->yellow->config->get("commandlineErrorFile"));
foreach($fileNamesMedia as $fileName)
{
$statusCodeMax = max($statusCodeMax, $this->buildStaticFile($fileName, "$path/$fileName"));
$statusCode = max($statusCode, $this->buildStaticFile($fileName, "$path/$fileName"));
}
foreach($this->fileNamesPlugin as $fileName)
{
$statusCodeMax = max($statusCodeMax, $this->buildStaticFile("$pluginDir$fileName", "$pathPlugin/$fileName"));
$statusCode = max($statusCode, $this->buildStaticFile("$pluginDir$fileName", "$pathPlugin/$fileName"));
}
foreach($fileNamesSystem as $fileName)
{
$statusCodeMax = max($statusCodeMax, $this->buildStaticFile($fileName, "$path/".basename($fileName), false));
$statusCode = max($statusCode, $this->buildStaticFile($fileName, "$path/".basename($fileName), false));
}
} else {
$statusCodeMax = $this->buildStaticLocation($location, $path);
$statusCode = $this->buildStaticLocation($location, $path);
}
$this->yellow->toolbox->timerStop($time);
if(defined("DEBUG") && DEBUG>=1) echo "YellowCommandline::buildStatic time:$time ms\n";
return $statusCodeMax;
return $statusCode;
}
// Build static location
@ -282,6 +290,87 @@ class YellowCommandline
}
}
// Clean static pages
function cleanCommand($args)
{
$statusCode = 0;
list($dummy, $command, $path, $location) = $args;
if(!empty($path) && $path!="/" && (empty($location) || $location[0]=='/'))
{
$statusCode = $this->cleanStatic($location, $path);
echo "Yellow $command: Static page".(empty($location) ? "s" : "")." ".($statusCode!=200 ? "not " : "")."cleaned\n";
} else {
$statusCode = 400;
echo "Yellow $command: Invalid arguments\n";
}
return $statusCode;
}
// Clean static directory and files
function cleanStatic($location, $path)
{
$statusCode = 200;
if(empty($location))
{
$statusCode = max($statusCode, $this->pluginCommand(array("all", "clean")));
$statusCode = max($statusCode, $this->cleanStaticDirectory($path));
} else {
$statusCode = $this->cleanStaticFile($location, $path);
}
return $statusCode;
}
// Clean static directory
function cleanStaticDirectory($path)
{
$statusCode = 200;
if($this->isYellowDirectory($path))
{
if(is_file("$path/yellow.php") || !$this->yellow->toolbox->deleteDirectory($path, true))
{
$statusCode = 500;
echo "ERROR cleaning pages: Can't delete directory '$path'!\n";
}
}
return $statusCode;
}
// Clean static file
function cleanStaticFile($location, $path)
{
$statusCode = 200;
$fileName = $this->getStaticFileName($location, $path);
if($this->isYellowDirectory($path) && is_file($fileName))
{
$entry = basename($fileName);
if($entry!="yellow.php" && substru($entry, 0, 1)!=".")
{
if(!$this->yellow->toolbox->deleteFile($fileName))
{
$statusCode = 500;
echo "ERROR cleaning pages: Can't delete file '$fileName'!\n";
}
}
}
return $statusCode;
}
// Forward plugin command
function pluginCommand($args)
{
$statusCode = 0;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
if($key == "commandline") continue;
if(method_exists($value["obj"], "onCommand"))
{
$statusCode = $value["obj"]->onCommand($args);
if($statusCode != 0) break;
}
}
return $statusCode;
}
// Check static configuration
function checkStaticConfig()
{
@ -336,25 +425,11 @@ class YellowCommandline
return $data;
}
// Forward plugin command
function pluginCommand($args)
// Check if directory contains Yellow files
function isYellowDirectory($path)
{
$statusCode = 0;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
if($key == "commandline") continue;
if(method_exists($value["obj"], "onCommand"))
{
$statusCode = $value["obj"]->onCommand($args);
if($statusCode != 0) break;
}
}
if($statusCode == 0)
{
$statusCode = 400;
echo "Yellow command line: Invalid arguments\n";
}
return $statusCode;
$systemFile = preg_split("/,\s*/", $this->yellow->config->get("commandlineSystemFile"))[0];
return is_file("$path/yellow.php") || is_file("$path/$systemFile");
}
}

View file

@ -1,9 +1,10 @@
/* Yellow web interface 0.3.2 */
/* Yellow web interface 0.3.3 */
.yellow-bar { position:relative; overflow:hidden; line-height:2.0em; }
.yellow-bar-left { display:block; float:left; }
.yellow-bar-left a { margin-right:1em; }
.yellow-bar-right { display:block; float:right; }
.yellow-bar-right a { margin-left:1em; }
.yellow-body-modal-open { overflow:hidden; }
.yellow-pane {
@ -45,12 +46,17 @@
border-color:#b13121 #b13121 #802020;
}
.yellow-btn-red:hover, .yellow-btn-red:focus, .yellow-btn-red:active { color:#ffffff; }
.yellow-btn-green {
background-color:#3cc335; color:#ffffff;
background-image:linear-gradient(to bottom, #5fee5b, #36bd2f);
border-color:#31b121 #31b121 #20b020;
}
.yellow-btn-green:hover, .yellow-btn-green:focus, .yellow-btn-green:active { color:#ffffff; }
#yellow-pane-login { }
#yellow-pane-login h1 { margin:0.5em 0.5em; }
#yellow-pane-login p { margin:0.5em; text-align:right; }
#yellow-pane-edit { }
#yellow-pane-edit #yellow-edit-text { margin:0; padding:5px; border:1px solid #bbb; resize:none; font-size:0.9em }
#yellow-pane-edit #yellow-edit-info { margin:0; padding:5px; border:1px solid #bbb; display:none; }
#yellow-pane-edit #yellow-edit-buttons { margin:5px 0; }
#yellow-pane-user { }
#yellow-pane-edit-page { margin:0; padding:5px; border:1px solid #bbb; resize:none; font-size:0.9em; }
#yellow-pane-edit-buttons { margin:5px 0; }
#yellow-pane-user { }

View file

@ -4,92 +4,103 @@
// Yellow main API
var yellow =
{
version: "0.3.2",
version: "0.3.3",
action: function(text) { yellow.webinterface.action(text); },
onClick: function(e) { yellow.webinterface.hidePanesOnClick(yellow.toolbox.getEventElement(e)); },
onKeydown: function(e) { yellow.webinterface.hidePanesOnKeydown(yellow.toolbox.getEventKeycode(e)); },
onResize: function() { yellow.webinterface.resizePanes(); },
onShow: function(id) { yellow.webinterface.showPane(id); },
onHide: function(id) { yellow.webinterface.hidePane(id); },
onLogout: function() { yellow.toolbox.submitForm({"action":"logout"}); },
webinterface:{}, page:{}, toolbox:{}, config:{}, text:{}
onUpdate: function() { yellow.webinterface.updatePane(yellow.webinterface.paneId, yellow.webinterface.paneType); },
webinterface:{}, toolbox:{}, page:{}, config:{}, text:{}
}
// Yellow web interface
yellow.webinterface =
{
created: false, //interface created? (boolean)
intervalId: 0, //interface timer interval ID
loaded: false, //web interface loaded? (boolean)
intervalId: 0, //timer interval ID
paneId: 0, //visible pane ID
paneType: 0, //visible pane type
// Initialise web interface
init: function()
{
this.intervalId = setInterval("yellow.webinterface.create()", 1);
yellow.toolbox.addEvent(window, "resize", yellow.onResize);
this.intervalId = setInterval("yellow.webinterface.load()", 1);
yellow.toolbox.addEvent(document, "click", yellow.onClick);
yellow.toolbox.addEvent(document, "keydown", yellow.onKeydown);
yellow.toolbox.addEvent(window, "resize", yellow.onResize);
},
// Create web interface
create: function()
// Load web interface
load: function()
{
var body = document.getElementsByTagName("body")[0];
if(body && body.firstChild && !this.created)
if(body && body.firstChild && !this.loaded)
{
this.created = true;
if(yellow.debug) console.log("yellow.webinterface.create email:"+yellow.config.userEmail+" "+yellow.config.userName);
this.loaded = true;
if(yellow.debug) console.log("yellow.webinterface.load email:"+yellow.config.userEmail+" "+yellow.config.userName);
if(yellow.config.userEmail)
{
yellow.toolbox.insertBefore(this.createBar("yellow-bar"), body.firstChild);
yellow.toolbox.insertAfter(this.createPane("yellow-pane-edit"), body.firstChild);
yellow.toolbox.insertAfter(this.createPane("yellow-pane-user"), body.firstChild);
yellow.toolbox.setText(document.getElementById("yellow-edit-text"), yellow.page.rawData);
if(yellow.page.permissions)
{
document.getElementById("yellow-edit-cancel").style.display = "none";
} else {
document.getElementById("yellow-edit-save").style.display = "none";
}
this.createBar("yellow-bar", true, body.firstChild);
this.createPane("yellow-pane-edit", true, body.firstChild);
this.createPane("yellow-pane-user", true, body.firstChild);
yellow.toolbox.addEvent(document.getElementById("yellow-pane-edit-page"), "keyup", yellow.onUpdate);
yellow.toolbox.addEvent(document.getElementById("yellow-pane-edit-page"), "change", yellow.onUpdate);
} else {
yellow.toolbox.insertBefore(this.createBar("yellow-bar", true), body.firstChild);
yellow.toolbox.insertAfter(this.createPane("yellow-pane-login", true), body.firstChild);
this.createBar("yellow-bar", false, body.firstChild);
this.createPane("yellow-pane-login", false, body.firstChild);
this.showPane("yellow-pane-login");
}
clearInterval(this.intervalId);
}
},
// Execute action
action: function(text)
{
// edit and new should be like two panes
switch(text)
{
case "edit": this.togglePane("yellow-pane-edit", "edit"); break;
case "new": this.togglePane("yellow-pane-edit", "new"); break;
case "user": this.togglePane("yellow-pane-user"); break;
case "send": this.sendPane(this.paneId, this.paneType); break;
case "logout": yellow.toolbox.submitForm({"action":"logout"}); break;
}
},
// Create bar
createBar: function(id, simple)
createBar: function(id, normal, elementReference)
{
if(yellow.debug) console.log("yellow.webinterface.createBar id:"+id);
var elementBar = document.createElement("div");
elementBar.className = "yellow-bar yellow";
elementBar.setAttribute("id", id);
if(!simple)
if(normal)
{
var location = yellow.config.serverBase+yellow.config.pluginLocation;
elementBar.innerHTML =
"<div class=\"yellow-bar-left\">"+
"<a href=\"#\" onclick=\"yellow.onShow('yellow-pane-edit'); return false;\">"+this.getText("Edit")+"</a>"+
"<a href=\"#\" onclick=\"yellow.action('edit'); return false;\">"+this.getText("Edit")+"</a>"+
"</div>"+
"<div class=\"yellow-bar-right\">"+
"<a href=\"#\" onclick=\"yellow.onShow('yellow-pane-user'); return false;\" id=\"yellow-username\">"+yellow.config.userName+" &#9662;</a>"+
"<a href=\"#\" onclick=\"yellow.action('new'); return false;\">"+this.getText("New")+"</a>"+
"<a href=\"#\" onclick=\"yellow.action('user'); return false;\">"+yellow.config.userName+" &#9662;</a>"+
"</div>";
}
return elementBar;
yellow.toolbox.insertBefore(elementBar, elementReference);
},
// Create pane
createPane: function(id, simple)
createPane: function(paneId, normal, elementReference)
{
if(yellow.debug) console.log("yellow.webinterface.createPane id:"+id);
if(yellow.debug) console.log("yellow.webinterface.createPane id:"+paneId);
var elementPane = document.createElement("div");
elementPane.className = simple ? "yellow-pane" : "yellow-pane yellow-pane-bubble";
elementPane.setAttribute("id", id);
elementPane.className = normal ? "yellow-pane yellow-pane-bubble" : "yellow-pane";
elementPane.setAttribute("id", paneId);
elementPane.style.display = "none";
var elementDiv = document.createElement("div");
elementDiv.setAttribute("id", id+"-content");
if(id == "yellow-pane-login")
elementDiv.setAttribute("id", paneId+"-content");
if(paneId == "yellow-pane-login")
{
elementDiv.innerHTML =
"<h1>"+this.getText("LoginText")+"</h1>"+
@ -99,53 +110,108 @@ yellow.webinterface =
"<p><label for=\"password\">"+this.getText("LoginPassword")+"</label> <input type=\"password\" name=\"password\" id=\"password\" maxlength=\"64\" /></p>"+
"<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("LoginButton")+"\" /></p>"+
"</form>";
} else if(id == "yellow-pane-edit") {
} else if(paneId == "yellow-pane-edit") {
elementDiv.innerHTML =
"<form method=\"post\">"+
"<input type=\"hidden\" name=\"action\" value=\"edit\" />"+
"<textarea id=\"yellow-edit-text\" name=\"rawdata\"></textarea>"+
"<div id=\"yellow-edit-info\" /></div>"+
"<div id=\"yellow-edit-buttons\">"+
"<input id=\"yellow-edit-save\" class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("SaveButton")+"\" />"+
"<input id=\"yellow-edit-cancel\" class=\"yellow-btn\" type=\"button\" onclick=\"yellow.onHide('yellow-pane-edit'); return false;\" value=\""+this.getText("CancelButton")+"\" />"+
"<textarea id=\"yellow-pane-edit-page\" name=\"rawdataedit\"></textarea>"+
"<div id=\"yellow-pane-edit-buttons\">"+
"<input id=\"yellow-pane-edit-send\" class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('send'); return false;\" value=\""+this.getText("EditButton")+"\" />"+
"</div>"+
"</form>";
} else if(id == "yellow-pane-user") {
} else if(paneId == "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>";
"<p><a href=\"#\" onclick=\"yellow.action('logout'); return false;\">"+this.getText("UserLogout")+"</a></p>";
}
elementPane.appendChild(elementDiv);
return elementPane;
yellow.toolbox.insertAfter(elementPane, elementReference);
},
// Update pane
updatePane: function(paneId, paneType, init)
{
if(yellow.debug) console.log("yellow.webinterface.updatePane id:"+paneId);
if(paneId == "yellow-pane-edit")
{
if(init)
{
var string = paneType=="new" ? yellow.page.rawDataNew : yellow.page.rawDataEdit;
document.getElementById("yellow-pane-edit-page").value = string;
}
var key, className;
switch(this.getPaneAction(paneId, paneType))
{
case "create": key = "CreateButton"; className = "yellow-btn yellow-btn-green"; break;
case "edit": key = "EditButton"; className = "yellow-btn"; break;
case "delete": key = "DeleteButton"; className = "yellow-btn yellow-btn-red"; break;
default: key = "CancelButton"; className = "yellow-btn";
}
document.getElementById("yellow-pane-edit-send").value = this.getText(key);
document.getElementById("yellow-pane-edit-send").className = className;
}
},
// Send pane
sendPane: function(paneId, paneType)
{
if(yellow.debug) console.log("yellow.webinterface.sendPane id:"+paneId);
if(paneId == "yellow-pane-edit")
{
var action = this.getPaneAction(paneId, paneType);
if(action)
{
var params = {};
params.action = action;
params.rawdatasource = yellow.page.rawDataSource;
params.rawdataedit = document.getElementById("yellow-pane-edit-page").value;
yellow.toolbox.submitForm(params, true);
} else {
this.hidePane(paneId);
}
}
},
// Show or hide pane
showPane: function(id)
togglePane: function(paneId, paneType)
{
var element = document.getElementById(id);
if(this.paneId!=paneId || this.paneType!=paneType)
{
this.hidePane(this.paneId);
this.showPane(paneId, paneType);
} else {
this.hidePane(paneId);
}
},
// Show pane
showPane: function(paneId, paneType)
{
var element = document.getElementById(paneId);
if(!yellow.toolbox.isVisible(element))
{
this.hidePanes();
if(yellow.debug) console.log("yellow.webinterface.showPane id:"+id);
if(yellow.debug) console.log("yellow.webinterface.showPane id:"+paneId);
element.style.display = "block";
yellow.toolbox.addClass(document.body, "yellow-body-modal-open");
this.resizePanes();
} else {
this.hidePane(id);
this.updatePane(paneId, paneType, true);
this.paneId = paneId;
this.paneType = paneType;
}
},
// Hide pane
hidePane: function(id)
hidePane: function(paneId)
{
var element = document.getElementById(id);
var element = document.getElementById(paneId);
if(yellow.toolbox.isVisible(element))
{
if(yellow.debug) console.log("yellow.webinterface.hidePane id:"+id);
if(yellow.debug) console.log("yellow.webinterface.hidePane id:"+paneId);
element.style.display = "none";
yellow.toolbox.removeClass(document.body, "yellow-body-modal-open");
this.paneId = 0;
this.paneType = 0;
}
},
@ -198,11 +264,11 @@ yellow.webinterface =
yellow.toolbox.setOuterTop(document.getElementById("yellow-pane-edit"), paneTop);
yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-edit"), paneHeight);
yellow.toolbox.setOuterWidth(document.getElementById("yellow-pane-edit"), paneWidth);
yellow.toolbox.setOuterWidth(document.getElementById("yellow-edit-text"), yellow.toolbox.getWidth(document.getElementById("yellow-pane-edit")));
yellow.toolbox.setOuterWidth(document.getElementById("yellow-pane-edit-page"), yellow.toolbox.getWidth(document.getElementById("yellow-pane-edit")));
var height1 = yellow.toolbox.getHeight(document.getElementById("yellow-pane-edit"));
var height2 = yellow.toolbox.getOuterHeight(document.getElementById("yellow-pane-edit-content"));
var height3 = yellow.toolbox.getOuterHeight(document.getElementById("yellow-edit-text"));
yellow.toolbox.setOuterHeight(document.getElementById("yellow-edit-text"), height1 - height2 + height3);
var height3 = yellow.toolbox.getOuterHeight(document.getElementById("yellow-pane-edit-page"));
yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-edit-page"), height1 - height2 + height3);
}
if(yellow.toolbox.isVisible(document.getElementById("yellow-pane-user")))
{
@ -214,6 +280,26 @@ yellow.webinterface =
}
},
// Return pane action
getPaneAction: function(paneId, paneType)
{
var action = "";
if(paneId == "yellow-pane-edit")
{
if(yellow.page.userPermission)
{
var string = document.getElementById("yellow-pane-edit-page").value;
if(yellow.page.statusCode==424 || paneType=="new")
{
action = string ? "create" : "";
} else {
action = string ? "edit" : "delete";
}
}
}
return action;
},
// Return text string
getText: function(key)
{
@ -224,23 +310,16 @@ yellow.webinterface =
// Yellow toolbox with helpers
yellow.toolbox =
{
// Set element text
setText: function(element, text)
// Insert element before reference element
insertBefore: function(element, elementReference)
{
while(element.firstChild !== null) element.removeChild(element.firstChild);
element.appendChild(document.createTextNode(text));
},
// Insert element before element
insertBefore: function(newElement, referenceElement)
{
referenceElement.parentNode.insertBefore(newElement, referenceElement);
elementReference.parentNode.insertBefore(element, elementReference);
},
// Insert element after element
insertAfter: function(newElement, referenceElement)
// Insert element after reference element
insertAfter: function(element, elementReference)
{
referenceElement.parentNode.insertBefore(newElement, referenceElement.nextSibling);
elementReference.parentNode.insertBefore(element, elementReference.nextSibling);
},
// Add element class
@ -420,18 +499,28 @@ yellow.toolbox =
return element && element.style.display != "none";
},
// Encode newline characters
encodeNewline: function(string)
{
return string
.replace(/[\\]/g, "\\\\")
.replace(/[\r]/g, "\\r")
.replace(/[\n]/g, "\\n");
},
// Submit form with post method
submitForm: function(params)
submitForm: function(params, encodeNewline)
{
var elementForm = document.createElement("form");
elementForm.setAttribute("method", "post");
for(var key in params)
{
if(!params.hasOwnProperty(key)) continue;
var value = encodeNewline ? this.encodeNewline(params[key]) : params[key];
var elementInput = document.createElement("input");
elementInput.setAttribute("type", "hidden");
elementInput.setAttribute("name", key);
elementInput.setAttribute("value", params[key]);
elementInput.setAttribute("value", value);
elementForm.appendChild(elementInput);
}
document.body.appendChild(elementForm);

View file

@ -9,8 +9,10 @@ class YellowWebinterface
var $yellow; //access to API
var $users; //web interface users
var $active; //web interface is active? (boolean)
var $loginFailed; //web interface login failed? (boolean)
var $rawDataOriginal; //raw data of page in case of errors
var $userLoginFailed; //web interface login failed? (boolean)
var $userPermission; //web interface can modify page? (boolean)
var $rawDataSource; //raw data of page for comparison
var $rawDataEdit; //raw data of page for editing
// Handle plugin initialisation
function onLoad($yellow)
@ -33,10 +35,8 @@ class YellowWebinterface
$statusCode = 0;
if($this->checkRequest($location))
{
list($serverScheme, $serverName, $base, $location, $fileName) = $this->getRequestInformation();
if($this->checkUser()) $statusCode = $this->processRequestAction($serverScheme, $serverName, $base, $location, $fileName);
if($statusCode == 0) $statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName,
false, $this->loginFailed ? 401 : 0);
list($serverScheme, $serverName, $base, $location, $fileName) = $this->updateRequestInformation();
$statusCode = $this->processRequest($serverScheme, $serverName, $base, $location, $fileName);
} else {
$activeLocation = $this->yellow->config->get("webinterfaceLocation");
if(rtrim($location, '/') == rtrim($activeLocation, '/'))
@ -44,8 +44,7 @@ class YellowWebinterface
$statusCode = 301;
$locationHeader = $this->yellow->toolbox->getLocationHeader(
$this->yellow->config->get("webinterfaceServerScheme"),
$this->yellow->config->get("webinterfaceServerName"),
$base, $activeLocation);
$this->yellow->config->get("webinterfaceServerName"), $base, $activeLocation);
$this->yellow->sendStatus($statusCode, $locationHeader);
}
}
@ -59,7 +58,13 @@ class YellowWebinterface
{
if($page == $this->yellow->page)
{
if(empty($this->rawDataOriginal)) $this->rawDataOriginal = $page->rawData;
if(empty($this->rawDataSource)) $this->rawDataSource = $page->rawData;
if(empty($this->rawDataEdit)) $this->rawDataEdit = $page->rawData;
if($page->statusCode == 424)
{
$title = $this->yellow->toolbox->createTextTitle($page->location);
$this->rawDataEdit = $this->getDataNew($title);
}
}
}
}
@ -70,14 +75,6 @@ class YellowWebinterface
$output = NULL;
if($this->isActive() && $this->isUser())
{
if($page == $this->yellow->page)
{
switch($page->statusCode)
{
case 424: $page->rawData = $this->getPageData(); break;
case 500: $page->rawData = $this->rawDataOriginal; break;
}
}
$serverBase = $this->yellow->config->get("serverBase");
$activePath = trim($this->yellow->config->get("webinterfaceLocation"), '/');
$callback = function($matches) use ($serverBase, $activePath)
@ -103,10 +100,12 @@ class YellowWebinterface
$header .= "// <![CDATA[\n";
if($this->isUser())
{
$permissions = $this->checkPermissions($page->location, $page->fileName);
$header .= "yellow.page.rawData = ".json_encode($page->rawData).";\n";
$header .= "yellow.page.permissions = " .json_encode($permissions).";\n";
$header .= "yellow.config = ".json_encode($this->getConfigData()).";\n";
$header .= "yellow.page.userPermission = " .json_encode($this->userPermission).";\n";
$header .= "yellow.page.rawDataSource = ".json_encode($this->rawDataSource).";\n";
$header .= "yellow.page.rawDataEdit = ".json_encode($this->rawDataEdit).";\n";
$header .= "yellow.page.rawDataNew = ".json_encode($this->getDataNew()).";\n";
$header .= "yellow.page.statusCode = ".json_encode($page->statusCode).";\n";
$header .= "yellow.config = ".json_encode($this->getDataConfig()).";\n";
}
$language = $this->isUser() ? $this->users->getLanguage() : $page->get("language");
$header .= "yellow.text = ".json_encode($this->yellow->text->getData("webinterface", $language)).";\n";
@ -151,7 +150,7 @@ class YellowWebinterface
$statusCode = 500;
echo "ERROR creating hash: Algorithm '$algorithm' not supported!\n";
} else {
$statusCode = $this->users->createUser($fileName, $email, $hash, $name, $language, $home) ? 200 : 500;
$statusCode = $this->users->createUser($fileName, $email, $hash, $name, $language, $home) ? 200 : 500;
if($statusCode != 200) echo "ERROR updating configuration: Can't write file '$fileName'!\n";
}
echo "Yellow $command: User account ".($statusCode!=200 ? "not " : "");
@ -163,70 +162,182 @@ class YellowWebinterface
return $statusCode;
}
// Process request for an action
function processRequestAction($serverScheme, $serverName, $base, $location, $fileName)
// Process request
function processRequest($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
switch($_POST["action"])
if($this->checkUser($location, $fileName))
{
case "edit": if(!empty($_POST["rawdata"]) && $this->checkPermissions($location, $fileName))
{
$this->rawDataOriginal = $_POST["rawdata"];
if($this->yellow->toolbox->createFile($fileName, $_POST["rawdata"]))
{
$statusCode = 303;
$locationHeader = $this->yellow->toolbox->getLocationHeader(
$serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $locationHeader);
} else {
$statusCode = 500;
$this->yellow->processRequest(
$serverScheme, $serverName, $base, $location, $fileName, false, $statusCode);
$this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
}
}
break;
case "login": $home = $this->users->getHome();
if(substru($location, 0, strlenu($home)) == $home)
{
$statusCode = 303;
$locationHeader = $this->yellow->toolbox->getLocationHeader(
$serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $locationHeader);
} else {
$statusCode = 302;
$locationHeader = $this->yellow->toolbox->getLocationHeader(
$serverScheme, $serverName, $base, $home);
$this->yellow->sendStatus($statusCode, $locationHeader);
}
break;
case "logout": $this->users->destroyCookie("login");
$this->users->email = "";
$statusCode = 302;
$locationHeader = $this->yellow->toolbox->getLocationHeader(
$this->yellow->config->get("serverScheme"),
$this->yellow->config->get("serverName"),
$this->yellow->config->get("serverBase"), $location);
$this->yellow->sendStatus($statusCode, $locationHeader);
break;
default: if(!is_readable($fileName))
{
if($this->yellow->toolbox->isFileLocation($location) && $this->yellow->isContentDirectory("$location/"))
{
$statusCode = 301;
$locationHeader = $this->yellow->toolbox->getLocationHeader(
$serverScheme, $serverName, $base, "$location/");
$this->yellow->sendStatus($statusCode, $locationHeader);
} else {
$statusCode = $this->checkPermissions($location, $fileName) ? 424 : 404;
$this->yellow->processRequest(
$serverScheme, $serverName, $base, $location, $fileName, false, $statusCode);
}
}
switch($_POST["action"])
{
case "": $statusCode = $this->processRequestShow($serverScheme, $serverName, $base, $location, $fileName); break;
case "create": $statusCode = $this->processRequestCreate($serverScheme, $serverName, $base, $location, $fileName); break;
case "edit": $statusCode = $this->processRequestEdit($serverScheme, $serverName, $base, $location, $fileName); break;
case "delete": $statusCode = $this->processRequestDelete($serverScheme, $serverName, $base, $location, $fileName); break;
case "login": $statusCode = $this->processRequestLogin($serverScheme, $serverName, $base, $location, $fileName); break;
case "logout": $statusCode = $this->processRequestLogout($serverScheme, $serverName, $base, $location, $fileName); break;
}
}
if($statusCode == 0)
{
$statusCode = $this->userLoginFailed ? 401 : 0;
$statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false, $statusCode);
}
return $statusCode;
}
// Process request to show page
function processRequestShow($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if(is_readable($fileName))
{
$statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false, 0);
} else {
if($this->yellow->toolbox->isFileLocation($location) && $this->yellow->isContentDirectory("$location/"))
{
$statusCode = 301;
$locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, "$location/");
$this->yellow->sendStatus($statusCode, $locationHeader);
} else {
$statusCode = $this->userPermission ? 424 : 404;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false, $statusCode);
}
}
return $statusCode;
}
// Process request to create page
function processRequestCreate($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
$page = $this->getPageNew($serverScheme, $serverName, $base, $location, $fileName, stripcslashes($_POST["rawdataedit"]));
if($this->userPermission && $this->getUserPermission($page->location, $page->fileName) && !empty($page->rawData))
{
$this->rawDataSource = $this->rawDataEdit = stripcslashes($_POST["rawdatasource"]);
if(is_file($page->fileName) || $this->yellow->toolbox->createFile($page->fileName, $page->rawData))
{
$statusCode = 303;
$locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, $page->location);
$this->yellow->sendStatus($statusCode, $locationHeader);
} else {
$statusCode = 500;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false, $statusCode);
$this->yellow->page->error($statusCode, "Can't write file '$page->fileName'!");
}
}
return $statusCode;
}
// Process request to edit page
function processRequestEdit($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if($this->userPermission && !empty($_POST["rawdataedit"]))
{
$this->rawDataSource = stripcslashes($_POST["rawdatasource"]);
$this->rawDataEdit = stripcslashes($_POST["rawdataedit"]);
$fileData = $this->mergeText($location, $this->rawDataSource, $this->rawDataEdit, $fileName);
if(!empty($fileData))
{
if($this->yellow->toolbox->createFile($fileName, $fileData))
{
$statusCode = 303;
$locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $locationHeader);
} else {
$statusCode = 500;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false, $statusCode);
$this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
}
} else {
$statusCode = 500;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false, $statusCode);
$this->yellow->page->error($statusCode, "Page has been modified by someone else!");
}
}
return $statusCode;
}
// Process request to delete page
function processRequestDelete($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if($this->userPermission)
{
$this->rawDataSource = $this->rawDataEdit = stripcslashes($_POST["rawdatasource"]);
if(!is_file($fileName) || $this->yellow->toolbox->deleteFile($fileName))
{
$statusCode = 303;
$locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $locationHeader);
} else {
$statusCode = 500;
$this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false, $statusCode);
$this->yellow->page->error($statusCode, "Can't delete file '$fileName'!");
}
}
return $statusCode;
}
// Process request for user login
function processRequestLogin($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
$home = $this->users->getHome();
if(substru($location, 0, strlenu($home)) == $home)
{
$statusCode = 303;
$locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $locationHeader);
} else {
$statusCode = 302;
$locationHeader = $this->yellow->toolbox->getLocationHeader($serverScheme, $serverName, $base, $home);
$this->yellow->sendStatus($statusCode, $locationHeader);
}
return $statusCode;
}
// Process request for user logout
function processRequestLogout($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 302;
$this->users->destroyCookie("login");
$this->users->email = "";
$locationHeader = $this->yellow->toolbox->getLocationHeader(
$this->yellow->config->get("serverScheme"),
$this->yellow->config->get("serverName"),
$this->yellow->config->get("serverBase"), $location);
$this->yellow->sendStatus($statusCode, $locationHeader);
return $statusCode;
}
// Merge text
function mergeText($location, $textSource, $textLocal, $fileName)
{
$fileHandle = @fopen($fileName, "r");
if($fileHandle)
{
$fileData = fread($fileHandle, filesize($fileName));
fclose($fileHandle);
}
if(!empty($fileData) && $fileData!=$textSource && $fileData!=$textLocal)
{
$output = NULL;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
if(method_exists($value["obj"], "onMergeText"))
{
$output = $value["obj"]->onMergeText($location, $textSource, $textLocal, $fileData);
if(!is_null($output)) break;
}
}
} else {
$output = $textLocal;
}
return $output;
}
// Check web interface request
function checkRequest($location)
{
@ -240,7 +351,7 @@ class YellowWebinterface
}
// Check web interface user
function checkUser()
function checkUser($location, $fileName)
{
if($_POST["action"] == "login")
{
@ -250,50 +361,97 @@ class YellowWebinterface
{
$this->users->createCookie("login", $email);
$this->users->email = $email;
$this->userPermission = $this->getUserPermission($location, $fileName);
} else {
$this->loginFailed = true;
$this->userLoginFailed = true;
}
} else if(isset($_COOKIE["login"])) {
list($email, $session) = $this->users->getCookieInformation($_COOKIE["login"]);
if($this->users->checkCookie($email, $session))
{
$this->users->email = $email;
$this->userPermission = $this->getUserPermission($location, $fileName);
} else {
$this->loginFailed = true;
$this->userLoginFailed = true;
}
}
return $this->isUser();
}
// Check permissions for changing page
function checkPermissions($location, $fileName)
// Return permission to modify page
function getUserPermission($location, $fileName)
{
$permissions = true;
$userPermission = true;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
if(method_exists($value["obj"], "onCheckPermissions"))
if(method_exists($value["obj"], "onUserPermission"))
{
$permissions = $value["obj"]->onCheckPermissions($location, $fileName, $this->users);
if(!$permissions) break;
$userPermission = $value["obj"]->onUserPermission($location, $fileName, $this->users);
if(!$userPermission) break;
}
}
$permissions &= is_dir(dirname($fileName)) && strlenu(basename($fileName))<128;
return $permissions;
$userPermission &= is_dir(dirname($fileName)) && strlenu(basename($fileName))<128;
return $userPermission;
}
// Return request information
function getRequestInformation()
// Update request information
function updateRequestInformation()
{
$serverScheme = $this->yellow->config->get("webinterfaceServerScheme");
$serverName = $this->yellow->config->get("webinterfaceServerName");
$base = rtrim($this->yellow->config->get("serverBase").$this->yellow->config->get("webinterfaceLocation"), '/');
$this->yellow->page->base = $base;
return $this->yellow->getRequestInformation($serverScheme, $serverName, $base);
}
// Return content data for new page
function getPageData()
// Update page data with title
function updateDataTitle($rawData, $title)
{
foreach(preg_split("/([\r\n]+)/", $rawData, -1, PREG_SPLIT_DELIM_CAPTURE) as $line)
{
if(preg_match("/^(\s*Title\s*:\s*)(.*?)(\s*)$/i", $line, $matches)) $line = $matches[1].$title.$matches[3];
$rawDataNew .= $line;
}
return $rawDataNew;
}
// Return new page
function getPageNew($serverScheme, $serverName, $base, $location, $fileName, $rawData)
{
$page = new YellowPage($this->yellow, $serverScheme, $serverName, $base, $location, $fileName);
$page->parseData($rawData, false, 0);
$page->fileName = $this->yellow->toolbox->findFileFromTitle($page->get("title"), $fileName,
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
$page->location = $this->yellow->toolbox->findLocationFromFile($page->fileName,
$this->yellow->config->get("contentDir"), $this->yellow->config->get("contentHomeDir"),
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
if($this->yellow->pages->find($page->location))
{
if(preg_match("/^(.*?)(\d+)$/", $page->get("title"), $matches))
{
$pageTitle = $matches[1];
$pageNumber = max(2, $matches[2]);
} else {
$pageTitle = $page->get("title").' ';
$pageNumber = 2;
}
for(; $pageNumber<=999; ++$pageNumber)
{
$page->rawData = $this->updateDataTitle($rawData, $pageTitle.$pageNumber);
$page->fileName = $this->yellow->toolbox->findFileFromTitle($pageTitle.$pageNumber, $fileName,
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
$page->location = $this->yellow->toolbox->findLocationFromFile($page->fileName,
$this->yellow->config->get("contentDir"), $this->yellow->config->get("contentHomeDir"),
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
if(!$this->yellow->pages->find($page->location)) break;
}
}
return $page;
}
// Return content data for new page
function getDataNew($title = "")
{
$fileData = "";
$fileName = $this->yellow->toolbox->findFileFromLocation($this->yellow->page->location,
$this->yellow->config->get("contentDir"), $this->yellow->config->get("contentHomeDir"),
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension"));
@ -304,13 +462,14 @@ class YellowWebinterface
if($fileHandle)
{
$fileData = fread($fileHandle, filesize($fileName));
if(!empty($title)) $fileData = $this->updateDataTitle($fileData, $title);
fclose($fileHandle);
}
return $fileData;
}
// Return configuration data including information of current user
function getConfigData()
function getDataConfig()
{
$data = array("userEmail" => $this->users->email,
"userName" => $this->users->getName(),
@ -383,7 +542,6 @@ class YellowWebinterfaceUsers
{
$email = strreplaceu(',', '-', $email);
$hash = strreplaceu(',', '-', $hash);
$fileNewUser = true;
$fileData = @file($fileName);
if($fileData)
{
@ -398,14 +556,14 @@ class YellowWebinterfaceUsers
$language = strreplaceu(',', '-', empty($language) ? $matches[4] : $language);
$home = strreplaceu(',', '-', empty($home) ? $matches[5] : $home);
$fileDataNew .= "$email,$hash,$name,$language,$home\n";
$fileNewUser = false;
$found = true;
continue;
}
}
$fileDataNew .= $line;
}
}
if($fileNewUser)
if(!$found)
{
$name = strreplaceu(',', '-', empty($name) ? $this->yellow->config->get("sitename") : $name);
$language = strreplaceu(',', '-', empty($language) ? $this->yellow->config->get("language") : $language);

View file

@ -5,7 +5,7 @@
// Yellow main class
class Yellow
{
const Version = "0.3.7";
const Version = "0.3.8";
var $page; //current page
var $pages; //pages from file system
var $config; //configuration
@ -61,7 +61,7 @@ class Yellow
ob_start();
$statusCode = 0;
list($serverScheme, $serverName, $base, $location, $fileName) = $this->getRequestInformation();
$this->page = new YellowPage($this, $serverScheme, $serverName, $base, $location);
$this->page = new YellowPage($this, $serverScheme, $serverName, $base, $location, $fileName);
foreach($this->plugins->plugins as $key=>$value)
{
if(method_exists($value["obj"], "onRequest"))
@ -149,8 +149,8 @@ class Yellow
$fileData = fread($fileHandle, filesize($fileName));
fclose($fileHandle);
}
$this->page = new YellowPage($this, $serverScheme, $serverName, $base, $location);
$this->page->parseData($fileName, $fileData, $cacheable, $statusCode, $pageError);
$this->page = new YellowPage($this, $serverScheme, $serverName, $base, $location, $fileName);
$this->page->parseData($fileData, $cacheable, $statusCode, $pageError);
$this->page->setHeader("Content-Type", "text/html; charset=UTF-8");
$this->page->setHeader("Last-Modified", $this->page->getModified(true));
if(!$this->page->isCacheable()) $this->page->setHeader("Cache-Control", "no-cache, must-revalidate");
@ -352,25 +352,25 @@ class YellowPage
var $cacheable; //page is cacheable? (boolean)
var $statusCode; //status code
function __construct($yellow, $serverScheme, $serverName, $base, $location)
function __construct($yellow, $serverScheme, $serverName, $base, $location, $fileName)
{
$this->yellow = $yellow;
$this->serverScheme = $serverScheme;
$this->serverName = $serverName;
$this->base = $base;
$this->location = $location;
$this->fileName = $fileName;
$this->metaData = array();
$this->headerData = array();
$this->statusCode = 0;
}
// Parse page data
function parseData($fileName, $rawData, $cacheable, $statusCode, $pageError = "")
function parseData($rawData, $cacheable, $statusCode, $pageError = "")
{
$this->fileName = $fileName;
$this->rawData = $rawData;
$this->active = $this->yellow->toolbox->isActiveLocation($this->location, $this->yellow->page->location);
$this->visible = $this->yellow->toolbox->isVisibleLocation($this->location, $fileName,
$this->visible = $this->yellow->toolbox->isVisibleLocation($this->location, $this->fileName,
$this->yellow->config->get("contentDir"));
$this->cacheable = $cacheable;
$this->statusCode = $statusCode;
@ -553,7 +553,7 @@ class YellowPage
function getParent()
{
$parentLocation = $this->yellow->pages->getParentLocation($this->location);
return $this->yellow->pages->find($parentLocation, false)->first();
return $this->yellow->pages->find($parentLocation);
}
// Return top-level parent page of current page
@ -561,7 +561,7 @@ class YellowPage
{
$parentTopLocation = $this->yellow->pages->getParentTopLocation($this->location);
if($homeFailback && !$this->yellow->isContentDirectory($parentTopLocation)) $parentTopLocation = "/";
return $this->yellow->pages->find($parentTopLocation, false)->first();
return $this->yellow->pages->find($parentTopLocation);
}
// Return pages on the same level as current page
@ -872,10 +872,14 @@ class YellowPages
$this->pages = array();
}
// Return empty page collection
function create()
// Return one page from file system
function find($location, $absoluteLocation = false)
{
return new YellowPageCollection($this->yellow);
if($absoluteLocation) $location = substru($location, strlenu($this->yellow->page->base));
$parentLocation = $this->getParentLocation($location);
$this->scanChildren($parentLocation);
foreach($this->pages[$parentLocation] as $page) if($page->location == $location) { $found = true; break; }
return $found ? $page : NULL;
}
// Return page collection with all pages from file system
@ -894,24 +898,20 @@ class YellowPages
function path($location, $absoluteLocation = false)
{
if($absoluteLocation) $location = substru($location, strlenu($this->yellow->page->base));
$pages = $this->find($location, false);
for($page=$pages->first(); $page; $page=$parent)
$pages = new YellowPageCollection($this->yellow);
if($page = $this->find($location))
{
if($parent = $page->getParent()) $pages->prepend($parent);
else if($page->location!="/" && $home = $this->find("/", false)->first()) $pages->prepend($home);
$pages->prepend($page);
for(; $parent = $page->getParent(); $page=$parent) $pages->prepend($parent);
if($page->location!="/" && $home=$this->find("/")) $pages->prepend($home);
}
return $pages;
}
// Return page collection with one specific page
function find($location, $absoluteLocation = false)
// Return empty page collection
function create()
{
if($absoluteLocation) $location = substru($location, strlenu($this->yellow->page->base));
$parentLocation = $this->getParentLocation($location);
$this->scanChildren($parentLocation);
$pages = new YellowPageCollection($this->yellow);
foreach($this->pages[$parentLocation] as $page) if($page->location == $location) { $pages->append($page); break; }
return $pages;
return new YellowPageCollection($this->yellow);
}
// Find child pages
@ -969,8 +969,9 @@ class YellowPages
$this->yellow->page->serverScheme, $this->yellow->page->serverName, $this->yellow->page->base,
$this->yellow->toolbox->findLocationFromFile($fileName,
$this->yellow->config->get("contentDir"), $this->yellow->config->get("contentHomeDir"),
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension")));
$page->parseData($fileName, $fileData, false, $statusCode);
$this->yellow->config->get("contentDefaultFile"), $this->yellow->config->get("contentExtension")),
$fileName);
$page->parseData($fileData, false, $statusCode);
array_push($this->pages[$location], $page);
}
}
@ -1497,6 +1498,14 @@ class YellowToolbox
return $invalid ? "" : $path;
}
// Return file path from title
function findFileFromTitle($title, $fileName, $fileDefault, $fileExtension)
{
$token = $this->normaliseName($title, false, true);
$path = dirname($fileName)."/".(empty($token) ? $fileDefault : $token.$fileExtension);
return $path;
}
// Return file path of children from location
function findChildrenFromLocation($location, $pathBase, $pathHome, $fileDefault, $fileExtension)
{
@ -1548,15 +1557,6 @@ class YellowToolbox
return strreplaceu(array('%3A','%2F'), array(':','/'), rawurlencode($text));
}
// Normalise file/directory/attribute name
function normaliseName($text, $removeExtension = false, $filterStrict = false)
{
if(preg_match("/^[\d\-\_\.]+(.*)$/", $text, $matches)) $text = $matches[1];
if($removeExtension) $text = ($pos = strrposu($text, '.')) ? substru($text, 0, $pos) : $text;
if($filterStrict) $text = strreplaceu('.', '-', strtoloweru($text));
return preg_replace("/[^\pL\d\-\_\.]/u", "-", $text);
}
// Normalise location, make absolute location
function normaliseLocation($location, $pageBase, $pageLocation)
{
@ -1573,7 +1573,16 @@ class YellowToolbox
}
return $location;
}
// Normalise file/directory/other name
function normaliseName($text, $removeExtension = false, $filterStrict = false)
{
if(preg_match("/^[\d\-\_\.]+(.*)$/", $text, $matches)) $text = $matches[1];
if($removeExtension) $text = ($pos = strrposu($text, '.')) ? substru($text, 0, $pos) : $text;
if($filterStrict) $text = strreplaceu('.', '-', strtoloweru($text));
return preg_replace("/[^\pL\d\-\_\.]/u", "-", $text);
}
// Normalise text into UTF-8 NFC
function normaliseUnicode($text)
{
@ -1599,7 +1608,7 @@ class YellowToolbox
case 400: $text = "$_SERVER[SERVER_PROTOCOL] $statusCode Bad request"; break;
case 401: $text = "$_SERVER[SERVER_PROTOCOL] $statusCode Unauthorised"; break;
case 404: $text = "$_SERVER[SERVER_PROTOCOL] $statusCode Not found"; break;
case 424: $text = "$_SERVER[SERVER_PROTOCOL] $statusCode Does not exist"; break;
case 424: $text = "$_SERVER[SERVER_PROTOCOL] $statusCode Not existing"; break;
case 500: $text = "$_SERVER[SERVER_PROTOCOL] $statusCode Server error"; break;
default: $text = "$_SERVER[SERVER_PROTOCOL] $statusCode Unknown status";
}
@ -1672,6 +1681,26 @@ class YellowToolbox
}
return $entries;
}
// Delete directory
function deleteDirectory($path, $recursive = false)
{
if($recursive)
{
$iterator = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file)
{
if($file->isDir())
{
@rmdir($file->getRealPath());
} else {
@unlink($file->getRealPath());
}
}
}
return @rmdir($path);
}
// Create file
function createFile($fileName, $fileData, $mkdir = false)
@ -1702,19 +1731,19 @@ class YellowToolbox
}
return @copy($fileNameSource, $fileNameDest);
}
// Delete file
function deleteFile($fileName)
{
return @unlink($fileName);
}
// Set file modification time, Unix time
function modifyFile($fileName, $modified)
{
return @touch($fileName, $modified);
}
// Delete file
function deleteFile($fileName)
{
return @unlink($fileName);
}
// Return arguments from text string
function getTextArgs($text, $optional = "-")
{
@ -1801,7 +1830,7 @@ class YellowToolbox
// Create title from text string
function createTextTitle($text)
{
if(preg_match("/^.*\/([\w\-]+)/", $text, $matches)) $text = ucfirst($matches[1]);
if(preg_match("/^.*\/([\w\-]+)/", $text, $matches)) $text = strreplaceu('-', ' ', ucfirst($matches[1]));
return $text;
}