Updated system, new API

This commit is contained in:
markseu 2019-02-23 15:04:34 +01:00
parent a19b77b40c
commit c17da68c1a
42 changed files with 1401 additions and 1302 deletions

View file

@ -1,2 +0,0 @@
# Datenstrom Yellow text

View file

@ -1,16 +1,17 @@
<?php
// Bundle plugin, https://github.com/datenstrom/yellow-plugins/tree/master/bundle
// Bundle extension, https://github.com/datenstrom/yellow-extensions/tree/master/features/bundle
// Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se
// This file may be used and distributed under the terms of the public license.
class YellowBundle {
const VERSION = "0.8.1";
const VERSION = "0.8.2";
const TYPE = "feature";
public $yellow; //access to API
// Handle initialisation
public function onLoad($yellow) {
$this->yellow = $yellow;
$this->yellow->config->setDefault("bundleAndMinify", "1");
$this->yellow->system->setDefault("bundleAndMinify", "1");
}
// Handle page output data
@ -37,7 +38,7 @@ class YellowBundle {
$statusCode = 0;
list($command, $path) = $args;
if ($path=="all") {
$path = $this->yellow->config->get("assetDir");
$path = $this->yellow->system->get("resourceDir");
foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/bundle-.*/", false, false) as $entry) {
if (!$this->yellow->toolbox->deleteFile($entry)) $statusCode = 500;
}
@ -56,7 +57,7 @@ class YellowBundle {
if (preg_match("/\"stylesheet\"/i", $line)) {
if (is_null($dataCss[$matches[2]])) $dataCss[$matches[2]] = $line;
} else {
if (is_null($dataLink[$matches[2]])) $dataLink[$matches[2]] = $line;
array_push($dataLink, $line);
}
} elseif (preg_match("/^<script (.*?)src=\"([^\"]+)\"(.*?)><\/script>$/i", $line, $matches)) {
if (preg_match("/\"defer\"/i", $line)) {
@ -68,7 +69,7 @@ class YellowBundle {
array_push($dataOther, $line);
}
}
if ($this->yellow->config->get("bundleAndMinify")) {
if ($this->yellow->system->get("bundleAndMinify")) {
$dataCss = $this->processBundle($dataCss, "css");
$dataScript = $this->processBundle($dataScript, "js");
}
@ -79,9 +80,9 @@ class YellowBundle {
// Process bundle, create file on demand
public function processBundle($data, $type) {
$fileNames = array();
$scheme = $this->yellow->config->get("serverScheme");
$address = $this->yellow->config->get("serverAddress");
$base = $this->yellow->config->get("serverBase");
$scheme = $this->yellow->system->get("serverScheme");
$address = $this->yellow->system->get("serverAddress");
$base = $this->yellow->system->get("serverBase");
foreach ($data as $key=>$value) {
if (preg_match("/^\w+:/", $key)) continue;
if (preg_match("/data-bundle=\"none\"/i", $value)) continue;
@ -97,8 +98,8 @@ class YellowBundle {
if (!empty($fileNames)) {
$this->yellow->toolbox->timerStart($time);
$id = substru(md5(implode($fileNames).$base), 0, 10);
$fileNameBundle = $this->yellow->config->get("assetDir")."bundle-$id.min.$type";;
$locationBundle = $base.$this->yellow->config->get("assetLocation")."bundle-$id.min.$type";
$fileNameBundle = $this->yellow->system->get("resourceDir")."bundle-$id.min.$type";;
$locationBundle = $base.$this->yellow->system->get("resourceLocation")."bundle-$id.min.$type";
if ($type=="css") {
$data[$locationBundle] = "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"".htmlspecialchars($locationBundle)."\" />\n";
} else {
@ -134,11 +135,11 @@ class YellowBundle {
// Process bundle, convert URLs
public function processBundleConvert($scheme, $address, $base, $fileData, $fileName, $type) {
if ($type=="css") {
$pluginDirLength = strlenu($this->yellow->config->get("pluginDir"));
if (substru($fileName, 0, $pluginDirLength) == $this->yellow->config->get("pluginDir")) {
$base .= $this->yellow->config->get("pluginLocation");
$extensionDirLength = strlenu($this->yellow->system->get("extensionDir"));
if (substru($fileName, 0, $extensionDirLength) == $this->yellow->system->get("extensionDir")) {
$base .= $this->yellow->system->get("extensionLocation");
} else {
$base .= $this->yellow->config->get("assetLocation");
$base .= $this->yellow->system->get("resourceLocation");
}
$thisCompatible = $this;
$callback = function ($matches) use ($thisCompatible, $scheme, $address, $base) {
@ -1903,7 +1904,7 @@ class Converter implements ConverterInterface {
}
// Minify extensions
// Copyright (c) 2013-2018 Datenstrom
// Copyright (c) 2013-2019 Datenstrom
class MinifyCss extends CSS { }

View file

@ -1,10 +1,11 @@
<?php
// Command plugin, https://github.com/datenstrom/yellow-plugins/tree/master/command
// Command extension, https://github.com/datenstrom/yellow-extensions/tree/master/features/command
// Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se
// This file may be used and distributed under the terms of the public license.
class YellowCommand {
const VERSION = "0.8.1";
const VERSION = "0.8.2";
const TYPE = "feature";
public $yellow; //access to API
public $files; //number of files
public $links; //number of links
@ -22,11 +23,11 @@ class YellowCommand {
list($command) = $args;
switch ($command) {
case "": $statusCode = $this->processCommandHelp(); break;
case "about": $statusCode = $this->processCommandAbout($args); break;
case "build": $statusCode = $this->processCommandBuild($args); break;
case "check": $statusCode = $this->processCommandCheck($args); break;
case "clean": $statusCode = $this->processCommandClean($args); break;
case "serve": $statusCode = $this->processCommandServe($args); break;
case "version": $statusCode = $this->processCommandVersion($args); break;
default: $statusCode = 0;
}
return $statusCode;
@ -34,11 +35,11 @@ class YellowCommand {
// Handle command help
public function onCommandHelp() {
$help .= "about\n";
$help .= "build [directory location]\n";
$help .= "check [directory location]\n";
$help .= "clean [directory location]\n";
$help .= "serve [url]\n";
$help .= "version\n";
return $help;
}
@ -52,18 +53,35 @@ class YellowCommand {
return 200;
}
// Process command to show website version and updates
public function processCommandAbout($args) {
$serverVersion = $this->yellow->toolbox->getServerVersion();
echo "Datenstrom Yellow ".YellowCore::VERSION.", PHP ".PHP_VERSION.", $serverVersion\n";
list($statusCode, $dataCurrent) = $this->getExtensionsVersion();
list($statusCode, $dataLatest) = $this->getExtensionsVersion(true);
foreach ($dataCurrent as $key=>$value) {
if (strnatcasecmp($dataCurrent[$key], $dataLatest[$key])>=0) {
echo ucfirst($key)." $value\n";
} else {
echo ucfirst($key)." $value - Update available\n";
}
}
if ($statusCode!=200) echo "ERROR checking updates: ".$this->yellow->page->get("pageError")."\n";
return $statusCode;
}
// Process command to build static website
public function processCommandBuild($args) {
$statusCode = 0;
list($command, $path, $location) = $args;
if (empty($location) || $location[0]=="/") {
if ($this->checkStaticConfig()) {
if ($this->checkStaticSettings()) {
$statusCode = $this->buildStaticFiles($path, $location);
} else {
$statusCode = 500;
$this->files = 0;
$this->errors = 1;
$fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
$fileName = $this->yellow->system->get("settingDir").$this->yellow->system->get("systemFile");
echo "ERROR building files: Please configure StaticUrl in file '$fileName'!\n";
}
echo "Yellow $command: $this->files file".($this->files!=1 ? "s" : "");
@ -77,11 +95,11 @@ class YellowCommand {
// Build static files
public function buildStaticFiles($path, $locationFilter) {
$path = rtrim(empty($path) ? $this->yellow->config->get("staticDir") : $path, "/");
$path = rtrim(empty($path) ? $this->yellow->system->get("staticDir") : $path, "/");
$this->files = $this->errors = 0;
$this->locationsArgs = $this->locationsArgsPagination = array();
$statusCode = empty($locationFilter) ? $this->cleanStaticFiles($path, $locationFilter) : 200;
$staticUrl = $this->yellow->config->get("staticUrl");
$staticUrl = $this->yellow->system->get("staticUrl");
list($scheme, $address, $base) = $this->yellow->lookup->getUrlInformation($staticUrl);
foreach ($this->getContentLocations() as $location) {
if (!preg_match("#^$base$locationFilter#", "$base$location")) continue;
@ -119,12 +137,12 @@ class YellowCommand {
// Build static file
public function buildStaticFile($path, $location, $analyse = false, $probe = false, $error = false) {
$this->yellow->pages = new YellowPages($this->yellow);
$this->yellow->content = new YellowContent($this->yellow);
$this->yellow->page = new YellowPage($this->yellow);
$this->yellow->page->fileName = substru($location, 1);
if (!is_readable($this->yellow->page->fileName)) {
ob_start();
$staticUrl = $this->yellow->config->get("staticUrl");
$staticUrl = $this->yellow->system->get("staticUrl");
list($scheme, $address, $base) = $this->yellow->lookup->getUrlInformation($staticUrl);
$statusCode = $this->requestStaticFile($scheme, $address, $base, $location);
if ($statusCode<400 || $error) {
@ -199,7 +217,7 @@ class YellowCommand {
// Analyse locations with arguments
public function analyseLocations($scheme, $address, $base, $rawData) {
$pagination = $this->yellow->config->get("contentPagination");
$pagination = $this->yellow->system->get("contentPagination");
preg_match_all("/<(.*?)href=\"([^\"]+)\"(.*?)>/i", $rawData, $matches);
foreach ($matches[2] as $match) {
$location = rawurldecode($match);
@ -233,12 +251,12 @@ class YellowCommand {
$statusCode = 0;
list($command, $path, $location) = $args;
if (empty($location) || $location[0]=="/") {
if ($this->checkStaticConfig()) {
if ($this->checkStaticSettings()) {
$statusCode = $this->checkStaticFiles($path, $location);
} else {
$statusCode = 500;
$this->files = $this->links = 0;
$fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
$fileName = $this->yellow->system->get("settingDir").$this->yellow->system->get("systemFile");
echo "ERROR checking files: Please configure StaticUrl in file '$fileName'!\n";
}
echo "Yellow $command: $this->files file".($this->files!=1 ? "s" : "");
@ -252,9 +270,9 @@ class YellowCommand {
// Check static files for broken links
public function checkStaticFiles($path, $locationFilter) {
$path = rtrim(empty($path) ? $this->yellow->config->get("staticDir") : $path, "/");
$path = rtrim(empty($path) ? $this->yellow->system->get("staticDir") : $path, "/");
$this->files = $this->links = 0;
$regex = "/^[^.]+$|".$this->yellow->config->get("staticDefaultFile")."$/";
$regex = "/^[^.]+$|".$this->yellow->system->get("staticDefaultFile")."$/";
$fileNames = $this->yellow->toolbox->getDirectoryEntriesRecursive($path, $regex, false, false);
list($statusCodeFiles, $links) = $this->analyseLinks($path, $locationFilter, $fileNames);
list($statusCodeLinks, $broken, $redirect) = $this->analyseStatus($path, $links);
@ -270,7 +288,7 @@ class YellowCommand {
$statusCode = 200;
$links = array();
if (!empty($fileNames)) {
$staticUrl = $this->yellow->config->get("staticUrl");
$staticUrl = $this->yellow->system->get("staticUrl");
list($scheme, $address, $base) = $this->yellow->lookup->getUrlInformation($staticUrl);
foreach ($fileNames as $fileName) {
if (is_readable($fileName)) {
@ -294,6 +312,7 @@ class YellowCommand {
}
}
++$this->files;
if (defined("DEBUG") && DEBUG>=1) echo "YellowCommand::analyseLinks location:$locationSource<br/>\n";
} else {
$statusCode = 500;
echo "ERROR reading files: Can't read file '$fileName'!\n";
@ -311,7 +330,7 @@ class YellowCommand {
public function analyseStatus($path, $links) {
$statusCode = 200;
$broken = $redirect = $data = array();
$staticUrl = $this->yellow->config->get("staticUrl");
$staticUrl = $this->yellow->system->get("staticUrl");
$staticUrlLength = strlenu(rtrim($staticUrl, "/"));
list($scheme, $address, $base) = $this->yellow->lookup->getUrlInformation($staticUrl);
$staticLocations = $this->getContentLocations(true);
@ -378,7 +397,7 @@ class YellowCommand {
// Clean static files and directories
public function cleanStaticFiles($path, $location) {
$statusCode = 200;
$path = rtrim(empty($path) ? $this->yellow->config->get("staticDir") : $path, "/");
$path = rtrim(empty($path) ? $this->yellow->system->get("staticDir") : $path, "/");
if (empty($location)) {
$statusCode = max($statusCode, $this->broadcastCommand("clean", "all"));
$statusCode = max($statusCode, $this->cleanStaticDirectory($path));
@ -417,10 +436,10 @@ class YellowCommand {
return $statusCode;
}
// Broadcast command to other plugins
// Broadcast command to other extensions
public function broadcastCommand($args) {
$statusCode = 0;
foreach ($this->yellow->plugins->plugins as $key=>$value) {
foreach ($this->yellow->extensions->extensions as $key=>$value) {
if ($key=="command") continue;
if (method_exists($value["obj"], "onCommand")) {
$statusCode = $value["obj"]->onCommand(func_get_args());
@ -448,48 +467,62 @@ class YellowCommand {
return $statusCode;
}
// Process command to show software version and updates
public function processCommandVersion($args) {
$serverVersion = $this->yellow->toolbox->getServerVersion();
echo "Datenstrom Yellow ".YellowCore::VERSION.", PHP ".PHP_VERSION.", $serverVersion\n";
list($statusCode, $dataCurrent) = $this->getSoftwareVersion();
list($statusCode, $dataLatest) = $this->getSoftwareVersion(true);
foreach ($dataCurrent as $key=>$value) {
if (strnatcasecmp($dataCurrent[$key], $dataLatest[$key])>=0) {
echo "$key $value\n";
} else {
echo "$key $value - Update available\n";
}
}
if ($statusCode!=200) echo "ERROR checking updates: ".$this->yellow->page->get("pageError")."\n";
return $statusCode;
}
// Check static configuration
public function checkStaticConfig() {
$staticUrl = $this->yellow->config->get("staticUrl");
return !empty($staticUrl);
// Check static settings
public function checkStaticSettings() {
return !empty($this->yellow->system->get("staticUrl"));
}
// Check static directory
public function checkStaticDirectory($path) {
$ok = false;
if (!empty($path)) {
if ($path==rtrim($this->yellow->config->get("staticDir"), "/")) $ok = true;
if ($path==rtrim($this->yellow->config->get("trashDir"), "/")) $ok = true;
if (is_file("$path/".$this->yellow->config->get("staticDefaultFile"))) $ok = true;
if ($path==rtrim($this->yellow->system->get("staticDir"), "/")) $ok = true;
if ($path==rtrim($this->yellow->system->get("trashDir"), "/")) $ok = true;
if (is_file("$path/".$this->yellow->system->get("staticDefaultFile"))) $ok = true;
if (is_file("$path/yellow.php")) $ok = false;
}
return $ok;
}
// Return command help
public function getCommandHelp() {
$data = array();
foreach ($this->yellow->extensions->extensions as $key=>$value) {
if (method_exists($value["obj"], "onCommandHelp")) {
foreach (preg_split("/[\r\n]+/", $value["obj"]->onCommandHelp()) as $line) {
list($command) = explode(" ", $line);
if (!empty($command) && is_null($data[$command])) $data[$command] = $line;
}
}
}
uksort($data, "strnatcasecmp");
return $data;
}
// Return extensions version
public function getExtensionsVersion($latest = false) {
$data = array();
if ($this->yellow->extensions->isExisting("update")) {
list($statusCode, $data) = $this->yellow->extensions->get("update")->getExtensionsVersion($latest);
} else {
$statusCode = 200;
$data = $this->yellow->extensions->getData();
}
return array($statusCode, $data);
}
// Return human readable status
public function getStatusFormatted($statusCode) {
return $this->yellow->toolbox->getHttpStatusFormatted($statusCode, true);
}
// Return static file
public function getStaticFile($path, $location, $statusCode) {
if ($statusCode<400) {
$fileName = $path.$location;
if (!$this->yellow->lookup->isFileLocation($location)) $fileName .= $this->yellow->config->get("staticDefaultFile");
if (!$this->yellow->lookup->isFileLocation($location)) $fileName .= $this->yellow->system->get("staticDefaultFile");
} elseif ($statusCode==404) {
$fileName = $path."/".$this->yellow->config->get("staticErrorFile");
$fileName = $path."/".$this->yellow->system->get("staticErrorFile");
}
return $fileName;
}
@ -497,8 +530,8 @@ class YellowCommand {
// Return static location
public function getStaticLocation($path, $fileName) {
$location = substru($fileName, strlenu($path));
if (basename($location)==$this->yellow->config->get("staticDefaultFile")) {
$defaultFileLength = strlenu($this->yellow->config->get("staticDefaultFile"));
if (basename($location)==$this->yellow->system->get("staticDefaultFile")) {
$defaultFileLength = strlenu($this->yellow->system->get("staticDefaultFile"));
$location = substru($location, 0, -$defaultFileLength);
}
return $location;
@ -513,30 +546,25 @@ class YellowCommand {
return $output;
}
// Return human readable status
public function getStatusFormatted($statusCode) {
return $this->yellow->toolbox->getHttpStatusFormatted($statusCode, true);
}
// Return content locations
public function getContentLocations($includeAll = false) {
$locations = array();
$staticUrl = $this->yellow->config->get("staticUrl");
$staticUrl = $this->yellow->system->get("staticUrl");
list($scheme, $address, $base) = $this->yellow->lookup->getUrlInformation($staticUrl);
$this->yellow->page->setRequestInformation($scheme, $address, $base, "", "");
foreach ($this->yellow->pages->index(true, true) as $page) {
foreach ($this->yellow->content->index(true, true) as $page) {
if (($page->get("status")!="ignore" && $page->get("status")!="draft") || $includeAll) {
array_push($locations, $page->location);
}
}
if (!$this->yellow->pages->find("/") && $this->yellow->config->get("multiLanguageMode")) array_unshift($locations, "/");
if (!$this->yellow->content->find("/") && $this->yellow->system->get("multiLanguageMode")) array_unshift($locations, "/");
return $locations;
}
// Return media locations
public function getMediaLocations() {
$locations = array();
$fileNames = $this->yellow->toolbox->getDirectoryEntriesRecursive($this->yellow->config->get("mediaDir"), "/.*/", false, false);
$fileNames = $this->yellow->toolbox->getDirectoryEntriesRecursive($this->yellow->system->get("mediaDir"), "/.*/", false, false);
foreach ($fileNames as $fileName) {
array_push($locations, "/".$fileName);
}
@ -547,15 +575,15 @@ class YellowCommand {
public function getSystemLocations() {
$locations = array();
$regex = "/\.(css|gif|ico|js|jpg|png|svg|txt|woff|woff2)$/";
$pluginDirLength = strlenu($this->yellow->config->get("pluginDir"));
$fileNames = $this->yellow->toolbox->getDirectoryEntriesRecursive($this->yellow->config->get("pluginDir"), $regex, false, false);
$extensionDirLength = strlenu($this->yellow->system->get("extensionDir"));
$fileNames = $this->yellow->toolbox->getDirectoryEntriesRecursive($this->yellow->system->get("extensionDir"), $regex, false, false);
foreach ($fileNames as $fileName) {
array_push($locations, $this->yellow->config->get("pluginLocation").substru($fileName, $pluginDirLength));
array_push($locations, $this->yellow->system->get("extensionLocation").substru($fileName, $extensionDirLength));
}
$themeDirLength = strlenu($this->yellow->config->get("themeDir"));
$fileNames = $this->yellow->toolbox->getDirectoryEntriesRecursive($this->yellow->config->get("themeDir"), $regex, false, false);
$resourceDirLength = strlenu($this->yellow->system->get("resourceDir"));
$fileNames = $this->yellow->toolbox->getDirectoryEntriesRecursive($this->yellow->system->get("resourceDir"), $regex, false, false);
foreach ($fileNames as $fileName) {
array_push($locations, $this->yellow->config->get("themeLocation").substru($fileName, $themeDirLength));
array_push($locations, $this->yellow->system->get("resourceLocation").substru($fileName, $resourceDirLength));
}
return $locations;
}
@ -563,11 +591,11 @@ class YellowCommand {
// Return extra locations
public function getExtraLocations() {
$locations = array();
$pathIgnore = "(".$this->yellow->config->get("staticDir")."|".
$this->yellow->config->get("cacheDir")."|".
$this->yellow->config->get("contentDir")."|".
$this->yellow->config->get("mediaDir")."|".
$this->yellow->config->get("systemDir").")";
$pathIgnore = "(".$this->yellow->system->get("staticDir")."|".
$this->yellow->system->get("cacheDir")."|".
$this->yellow->system->get("contentDir")."|".
$this->yellow->system->get("mediaDir")."|".
$this->yellow->system->get("systemDir").")";
$fileNames = $this->yellow->toolbox->getDirectoryEntriesRecursive(".", "/.*/", false, false);
foreach ($fileNames as $fileName) {
$fileName = substru($fileName, 2);
@ -577,33 +605,6 @@ class YellowCommand {
return $locations;
}
// Return command help
public function getCommandHelp() {
$data = array();
foreach ($this->yellow->plugins->plugins as $key=>$value) {
if (method_exists($value["obj"], "onCommandHelp")) {
foreach (preg_split("/[\r\n]+/", $value["obj"]->onCommandHelp()) as $line) {
list($command) = explode(" ", $line);
if (!empty($command) && is_null($data[$command])) $data[$command] = $line;
}
}
}
uksort($data, "strnatcasecmp");
return $data;
}
// Return software version
public function getSoftwareVersion($latest = false) {
$data = array();
if ($this->yellow->plugins->isExisting("update")) {
list($statusCode, $data) = $this->yellow->plugins->get("update")->getSoftwareVersion($latest);
} else {
$statusCode = 200;
$data = array_merge($this->yellow->plugins->getData(), $this->yellow->themes->getData());
}
return array($statusCode, $data);
}
// Return link status
public function getLinkStatus($url, $referer) {
$curlHandle = curl_init();

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/* Edit plugin, https://github.com/datenstrom/yellow-plugins/tree/master/edit */
/* Copyright (c) 2013-2018 Datenstrom, https://datenstrom.se */
/* Edit extension, https://github.com/datenstrom/yellow-extensions/tree/master/features/edit */
/* Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se */
/* This file may be used and distributed under the terms of the public license. */
.yellow-bar {

View file

@ -1,5 +1,5 @@
// Edit plugin, https://github.com/datenstrom/yellow-plugins/tree/master/edit
// Copyright (c) 2013-2018 Datenstrom, https://datenstrom.se
// Edit extension, https://github.com/datenstrom/yellow-extensions/tree/master/features/edit
// Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se
// This file may be used and distributed under the terms of the public license.
var yellow = {
@ -106,7 +106,7 @@ yellow.edit = {
// Create bar
createBar: function(barId) {
if (yellow.config.debug) console.log("yellow.edit.createBar id:"+barId);
if (yellow.system.debug) console.log("yellow.edit.createBar id:"+barId);
var elementBar = document.createElement("div");
elementBar.className = "yellow-bar";
elementBar.setAttribute("id", barId);
@ -117,7 +117,7 @@ yellow.edit = {
}
var elementDiv = document.createElement("div");
elementDiv.setAttribute("id", barId+"-content");
if (yellow.config.userName) {
if (yellow.system.userName) {
elementDiv.innerHTML =
"<div class=\"yellow-bar-left\">"+
"<a href=\"#\" id=\"yellow-pane-edit-link\" data-action=\"edit\">"+this.getText("Edit")+"</a>"+
@ -125,7 +125,7 @@ yellow.edit = {
"<div class=\"yellow-bar-right\">"+
"<a href=\"#\" id=\"yellow-pane-create-link\" data-action=\"create\">"+this.getText("Create")+"</a>"+
"<a href=\"#\" id=\"yellow-pane-delete-link\" data-action=\"delete\">"+this.getText("Delete")+"</a>"+
"<a href=\"#\" id=\"yellow-pane-user-link\" data-action=\"user\">"+yellow.toolbox.encodeHtml(yellow.config.userName)+"</a>"+
"<a href=\"#\" id=\"yellow-pane-user-link\" data-action=\"user\">"+yellow.toolbox.encodeHtml(yellow.system.userName)+"</a>"+
"</div>"+
"<div class=\"yellow-bar-banner\"></div>";
}
@ -136,7 +136,7 @@ yellow.edit = {
// Create pane
createPane: function(paneId, paneAction, paneStatus) {
if (yellow.config.debug) console.log("yellow.edit.createPane id:"+paneId);
if (yellow.system.debug) console.log("yellow.edit.createPane id:"+paneId);
var elementPane = document.createElement("div");
elementPane.className = "yellow-pane";
elementPane.setAttribute("id", paneId);
@ -164,8 +164,8 @@ yellow.edit = {
"<div class=\"yellow-title\"><h1>"+this.getText("LoginTitle")+"</h1></div>"+
"<div class=\"yellow-fields\" id=\"yellow-pane-login-fields\">"+
"<input type=\"hidden\" name=\"action\" value=\"login\" />"+
"<p><label for=\"yellow-pane-login-email\">"+this.getText("LoginEmail")+"</label><br /><input class=\"yellow-form-control\" name=\"email\" id=\"yellow-pane-login-email\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(yellow.config.editLoginEmail)+"\" /></p>"+
"<p><label for=\"yellow-pane-login-password\">"+this.getText("LoginPassword")+"</label><br /><input class=\"yellow-form-control\" type=\"password\" name=\"password\" id=\"yellow-pane-login-password\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(yellow.config.editLoginPassword)+"\" /></p>"+
"<p><label for=\"yellow-pane-login-email\">"+this.getText("LoginEmail")+"</label><br /><input class=\"yellow-form-control\" name=\"email\" id=\"yellow-pane-login-email\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(yellow.system.editLoginEmail)+"\" /></p>"+
"<p><label for=\"yellow-pane-login-password\">"+this.getText("LoginPassword")+"</label><br /><input class=\"yellow-form-control\" type=\"password\" name=\"password\" id=\"yellow-pane-login-password\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(yellow.system.editLoginPassword)+"\" /></p>"+
"<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("LoginButton")+"\" /></p>"+
"</div>"+
"<div class=\"yellow-actions\" id=\"yellow-pane-login-actions\">"+
@ -225,11 +225,11 @@ yellow.edit = {
break;
case "yellow-pane-settings":
var rawDataLanguages = "";
if (yellow.config.serverLanguages && Object.keys(yellow.config.serverLanguages).length>1) {
if (yellow.system.serverLanguages && Object.keys(yellow.system.serverLanguages).length>1) {
rawDataLanguages += "<p>";
for (var language in yellow.config.serverLanguages) {
for (var language in yellow.system.serverLanguages) {
var checked = language==this.getRequest("language") ? " checked=\"checked\"" : "";
rawDataLanguages += "<label for=\"yellow-pane-settings-"+language+"\"><input type=\"radio\" name=\"language\" id=\"yellow-pane-settings-"+language+"\" value=\""+language+"\""+checked+"> "+yellow.toolbox.encodeHtml(yellow.config.serverLanguages[language])+"</label><br />";
rawDataLanguages += "<label for=\"yellow-pane-settings-"+language+"\"><input type=\"radio\" name=\"language\" id=\"yellow-pane-settings-"+language+"\" value=\""+language+"\""+checked+"> "+yellow.toolbox.encodeHtml(yellow.system.serverLanguages[language])+"</label><br />";
}
rawDataLanguages += "</p>";
}
@ -256,7 +256,7 @@ yellow.edit = {
elementDiv.innerHTML =
"<form method=\"post\">"+
"<a href=\"#\" class=\"yellow-close\" data-action=\"close\"><i class=\"yellow-icon yellow-icon-close\"></i></a>"+
"<div class=\"yellow-title\"><h1 id=\"yellow-pane-version-title\">"+yellow.toolbox.encodeHtml(yellow.config.serverVersion)+"</h1></div>"+
"<div class=\"yellow-title\"><h1 id=\"yellow-pane-version-title\">"+yellow.toolbox.encodeHtml(yellow.system.serverVersion)+"</h1></div>"+
"<div class=\"yellow-status\"><p id=\"yellow-pane-version-status\" class=\""+paneStatus+"\">"+this.getText("VersionStatus", "", paneStatus)+"</p></div>"+
"<div class=\"yellow-output\" id=\"yellow-pane-version-output\">"+yellow.page.rawDataOutput+"</div>"+
"<div class=\"yellow-buttons\" id=\"yellow-pane-version-buttons\">"+
@ -283,8 +283,8 @@ yellow.edit = {
break;
case "yellow-pane-edit":
var rawDataButtons = "";
if (yellow.config.editToolbarButtons && yellow.config.editToolbarButtons!="none") {
var tokens = yellow.config.editToolbarButtons.split(",");
if (yellow.system.editToolbarButtons && yellow.system.editToolbarButtons!="none") {
var tokens = yellow.system.editToolbarButtons.split(",");
for (var i=0; i<tokens.length; i++) {
var token = tokens[i].trim();
if (token!="separator") {
@ -293,7 +293,7 @@ yellow.edit = {
rawDataButtons += "<li><a href=\"#\" class=\"yellow-toolbar-btn-separator\"></a></li>";
}
}
if (yellow.config.debug) console.log("yellow.edit.createPane buttons:"+yellow.config.editToolbarButtons);
if (yellow.system.debug) console.log("yellow.edit.createPane buttons:"+yellow.system.editToolbarButtons);
}
elementDiv.innerHTML =
"<form method=\"post\">"+
@ -313,7 +313,7 @@ yellow.edit = {
case "yellow-pane-user":
elementDiv.innerHTML =
"<ul class=\"yellow-dropdown\">"+
"<li><span>"+yellow.toolbox.encodeHtml(yellow.config.userEmail)+"</span></li>"+
"<li><span>"+yellow.toolbox.encodeHtml(yellow.system.userEmail)+"</span></li>"+
"<li><a href=\"#\" data-action=\"settings\">"+this.getText("SettingsTitle")+"</a></li>" +
"<li><a href=\"#\" data-action=\"help\">"+this.getText("UserHelp")+"</a></li>" +
"<li><a href=\"#\" data-action=\"logout\">"+this.getText("UserLogout")+"</a></li>"+
@ -327,11 +327,11 @@ yellow.edit = {
// Update pane
updatePane: function(paneId, paneAction, paneStatus, init) {
if (yellow.config.debug) console.log("yellow.edit.updatePane id:"+paneId);
if (yellow.system.debug) console.log("yellow.edit.updatePane id:"+paneId);
var showFields = paneStatus!="next" && paneStatus!="done";
switch (paneId) {
case "yellow-pane-login":
if (yellow.config.editLoginRestrictions) {
if (yellow.system.editLoginRestrictions) {
yellow.toolbox.setVisible(document.getElementById("yellow-pane-login-signup"), false);
}
break;
@ -352,18 +352,18 @@ yellow.edit = {
yellow.toolbox.setVisible(document.getElementById("yellow-pane-settings-buttons"), !showFields);
if (paneStatus=="none") {
document.getElementById("yellow-pane-settings-status").innerHTML = "<a href=\"#\" data-action=\"version\">"+this.getText("VersionTitle")+"</a>";
document.getElementById("yellow-pane-settings-name").value = yellow.config.userName;
document.getElementById("yellow-pane-settings-email").value = yellow.config.userEmail;
document.getElementById("yellow-pane-settings-"+yellow.config.userLanguage).checked = true;
document.getElementById("yellow-pane-settings-name").value = yellow.system.userName;
document.getElementById("yellow-pane-settings-email").value = yellow.system.userEmail;
document.getElementById("yellow-pane-settings-"+yellow.system.userLanguage).checked = true;
}
break;
case "yellow-pane-version":
if (paneStatus=="none" && this.isPlugin("update")) {
if (paneStatus=="none" && this.isExtension("update")) {
document.getElementById("yellow-pane-version-status").innerHTML = this.getText("VersionStatusCheck");
document.getElementById("yellow-pane-version-output").innerHTML = "";
setTimeout("yellow.action('send');", 500);
}
if (paneStatus=="updates" && this.isPlugin("update")) {
if (paneStatus=="updates" && this.isExtension("update")) {
document.getElementById("yellow-pane-version-status").innerHTML = "<a href=\"#\" data-action=\"update\">"+this.getText("VersionStatusUpdates")+"</a>";
}
break;
@ -385,16 +385,16 @@ yellow.edit = {
var matches = document.getElementById("yellow-pane-edit-text").value.match(/^(\xEF\xBB\xBF)?\-\-\-[\r\n]+/);
var position = document.getElementById("yellow-pane-edit-text").value.indexOf("\n", matches ? matches[0].length : 0);
document.getElementById("yellow-pane-edit-text").setSelectionRange(position, position);
if (yellow.config.editToolbarButtons!="none") {
if (yellow.system.editToolbarButtons!="none") {
yellow.toolbox.setVisible(document.getElementById("yellow-pane-edit-toolbar-title"), false);
this.updateToolbar(0, "yellow-toolbar-checked");
}
if (yellow.config.userRestrictions) {
if (yellow.system.userRestrictions) {
yellow.toolbox.setVisible(document.getElementById("yellow-pane-edit-send"), false);
document.getElementById("yellow-pane-edit-text").readOnly = true;
}
}
if (!yellow.config.userRestrictions) {
if (!yellow.system.userRestrictions) {
var key, className;
switch (this.getAction(paneId, paneAction)) {
case "create": key = "CreateButton"; className = "yellow-toolbar-btn yellow-toolbar-btn-create"; break;
@ -476,7 +476,7 @@ yellow.edit = {
if (!document.getElementById(paneId)) this.createPane(paneId, paneAction, paneStatus);
var element = document.getElementById(paneId);
if (!yellow.toolbox.isVisible(element)) {
if (yellow.config.debug) console.log("yellow.edit.showPane id:"+paneId);
if (yellow.system.debug) console.log("yellow.edit.showPane id:"+paneId);
yellow.toolbox.setVisible(element, true);
if (modal) {
yellow.toolbox.addClass(document.body, "yellow-body-modal-open");
@ -510,7 +510,7 @@ yellow.edit = {
// Send pane
sendPane: function(paneId, paneAction, paneStatus, paneArgs) {
if (yellow.config.debug) console.log("yellow.edit.sendPane id:"+paneId);
if (yellow.system.debug) console.log("yellow.edit.sendPane id:"+paneId);
var args = { "action":paneAction, "csrftoken":this.getCookie("csrftoken") };
if (paneId=="yellow-pane-edit") {
args.action = this.getAction(paneId, paneAction);
@ -539,7 +539,7 @@ yellow.edit = {
processShortcut: function(e) {
var shortcut = yellow.toolbox.getEventShortcut(e);
if (shortcut) {
var tokens = yellow.config.editKeyboardShortcuts.split(",");
var tokens = yellow.system.editKeyboardShortcuts.split(",");
for (var i=0; i<tokens.length; i++) {
var pair = tokens[i].trim().split(" ");
if (shortcut==pair[0] || shortcut.replace("meta+", "ctrl+")==pair[0]) {
@ -553,10 +553,10 @@ yellow.edit = {
// Process toolbar
processToolbar: function(status, args) {
if (yellow.config.debug) console.log("yellow.edit.processToolbar status:"+status);
if (yellow.system.debug) console.log("yellow.edit.processToolbar status:"+status);
var elementText = document.getElementById("yellow-pane-edit-text");
var elementPreview = document.getElementById("yellow-pane-edit-preview");
if (!yellow.config.userRestrictions && this.paneAction!="delete" && !yellow.toolbox.isVisible(elementPreview)) {
if (!yellow.system.userRestrictions && this.paneAction!="delete" && !yellow.toolbox.isVisible(elementPreview)) {
switch (status) {
case "h1": yellow.editor.setMarkdown(elementText, "# ", "insert-multiline-block", true); break;
case "h2": yellow.editor.setMarkdown(elementText, "## ", "insert-multiline-block", true); break;
@ -581,7 +581,7 @@ yellow.edit = {
}
}
if (status=="preview") this.showPreview(elementText, elementPreview);
if (status=="save" && !yellow.config.userRestrictions && this.paneAction!="delete") this.action("send");
if (status=="save" && !yellow.system.userRestrictions && this.paneAction!="delete") this.action("send");
if (status=="help") window.open(this.getText("HelpUrl", "yellow"), "_blank");
if (status=="markdown") window.open(this.getText("MarkdownUrl", "yellow"), "_blank");
if (status=="format" || status=="heading" || status=="list" || status=="emojiawesome" || status=="fontawesome") {
@ -606,7 +606,7 @@ yellow.edit = {
// Create popup
createPopup: function(popupId) {
if (yellow.config.debug) console.log("yellow.edit.createPopup id:"+popupId);
if (yellow.system.debug) console.log("yellow.edit.createPopup id:"+popupId);
var elementPopup = document.createElement("div");
elementPopup.className = "yellow-popup";
elementPopup.setAttribute("id", popupId);
@ -642,8 +642,8 @@ yellow.edit = {
break;
case "yellow-popup-emojiawesome":
var rawDataEmojis = "";
if (yellow.config.emojiawesomeToolbarButtons && yellow.config.emojiawesomeToolbarButtons!="none") {
var tokens = yellow.config.emojiawesomeToolbarButtons.split(" ");
if (yellow.system.emojiawesomeToolbarButtons && yellow.system.emojiawesomeToolbarButtons!="none") {
var tokens = yellow.system.emojiawesomeToolbarButtons.split(" ");
for (var i=0; i<tokens.length; i++) {
var token = tokens[i].replace(/[\:]/g,"");
var className = token.replace("+1", "plus1").replace("-1", "minus1").replace(/_/g, "-");
@ -654,8 +654,8 @@ yellow.edit = {
break;
case "yellow-popup-fontawesome":
var rawDataIcons = "";
if (yellow.config.fontawesomeToolbarButtons && yellow.config.fontawesomeToolbarButtons!="none") {
var tokens = yellow.config.fontawesomeToolbarButtons.split(" ");
if (yellow.system.fontawesomeToolbarButtons && yellow.system.fontawesomeToolbarButtons!="none") {
var tokens = yellow.system.fontawesomeToolbarButtons.split(" ");
for (var i=0; i<tokens.length; i++) {
var token = tokens[i].replace(/[\:]/g,"");
rawDataIcons += "<li><a href=\"#\" id=\"yellow-popup-list-"+yellow.toolbox.encodeHtml(token)+"\" data-action=\"toolbar\" data-status=\"text\" data-args=\":"+yellow.toolbox.encodeHtml(token)+":\"><i class=\"fa "+yellow.toolbox.encodeHtml(token)+"\"></i></a></li>";
@ -675,7 +675,7 @@ yellow.edit = {
this.hidePopup(this.popupId);
if (!document.getElementById(popupId)) this.createPopup(popupId);
var element = document.getElementById(popupId);
if (yellow.config.debug) console.log("yellow.edit.showPopup id:"+popupId);
if (yellow.system.debug) console.log("yellow.edit.showPopup id:"+popupId);
yellow.toolbox.setVisible(element, true);
this.popupId = popupId;
this.updateToolbar(status, "yellow-toolbar-selected");
@ -737,7 +737,7 @@ yellow.edit = {
var element = document.createElement("input");
element.setAttribute("id", "yellow-file-dialog");
element.setAttribute("type", "file");
element.setAttribute("accept", yellow.config.editUploadExtensions);
element.setAttribute("accept", yellow.system.editUploadExtensions);
element.setAttribute("multiple", "multiple");
yellow.toolbox.addEvent(element, "change", yellow.onDrop);
element.click();
@ -746,8 +746,8 @@ yellow.edit = {
// Upload file
uploadFile: function(elementText, file) {
var extension = (file.name.lastIndexOf(".")!=-1 ? file.name.substring(file.name.lastIndexOf("."), file.name.length) : "").toLowerCase();
var extensions = yellow.config.editUploadExtensions.split(/\s*,\s*/);
if (file.size<=yellow.config.serverFileSizeMax && extensions.indexOf(extension)!=-1) {
var extensions = yellow.system.editUploadExtensions.split(/\s*,\s*/);
if (file.size<=yellow.system.serverFileSizeMax && extensions.indexOf(extension)!=-1) {
var text = this.getText("UploadProgress")+"\u200b";
yellow.editor.setMarkdown(elementText, text, "insert");
var thisObject = this;
@ -768,8 +768,8 @@ yellow.edit = {
if (result) {
var textOld = this.getText("UploadProgress")+"\u200b";
var textNew;
if (result.location.substring(0, yellow.config.imageLocation.length)==yellow.config.imageLocation) {
textNew = "[image "+result.location.substring(yellow.config.imageLocation.length)+"]";
if (result.location.substring(0, yellow.system.imageLocation.length)==yellow.system.imageLocation) {
textNew = "[image "+result.location.substring(yellow.system.imageLocation.length)+"]";
} else {
textNew = "[link]("+result.location+")";
}
@ -830,9 +830,9 @@ yellow.edit = {
return yellow.toolbox.getCookie(name);
},
// Check if plugin exists
isPlugin: function(name) {
return name in yellow.config.serverPlugins;
// Check if extension exists
isExtension: function(name) {
return name in yellow.system.serverExtensions;
}
};
@ -899,7 +899,7 @@ yellow.editor = {
element.value = textSelectionBefore + textSelectionNew + textSelectionAfter;
element.setSelectionRange(selectionStartNew, selectionEndNew);
}
if (yellow.config.debug) console.log("yellow.editor.setMarkdown type:"+information.type);
if (yellow.system.debug) console.log("yellow.editor.setMarkdown type:"+information.type);
},
// Return Markdown formatting information
@ -1027,7 +1027,7 @@ yellow.editor = {
element.value = textSelectionBefore + textSelectionNew + textSelectionAfter;
element.setSelectionRange(selectionStartNew, selectionEndNew);
element.scrollTop = 0;
if (yellow.config.debug) console.log("yellow.editor.setMetaData key:"+key);
if (yellow.system.debug) console.log("yellow.editor.setMetaData key:"+key);
}
},

View file

@ -1,10 +1,11 @@
<?php
// Edit plugin, https://github.com/datenstrom/yellow-plugins/tree/master/edit
// Edit extension, https://github.com/datenstrom/yellow-extensions/tree/master/features/edit
// Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se
// This file may be used and distributed under the terms of the public license.
class YellowEdit {
const VERSION = "0.8.1";
const VERSION = "0.8.2";
const TYPE = "feature";
public $yellow; //access to API
public $response; //web response
public $users; //user accounts
@ -16,34 +17,33 @@ class YellowEdit {
$this->response = new YellowResponse($yellow);
$this->users = new YellowUsers($yellow);
$this->merge = new YellowMerge($yellow);
$this->yellow->config->setDefault("editLocation", "/edit/");
$this->yellow->config->setDefault("editUploadNewLocation", "/media/@group/@filename");
$this->yellow->config->setDefault("editUploadExtensions", ".gif, .jpg, .pdf, .png, .svg, .tgz, .zip");
$this->yellow->config->setDefault("editKeyboardShortcuts", "ctrl+b bold, ctrl+i italic, ctrl+e code, ctrl+k link, ctrl+s save, ctrl+shift+p preview");
$this->yellow->config->setDefault("editToolbarButtons", "auto");
$this->yellow->config->setDefault("editEndOfLine", "auto");
$this->yellow->config->setDefault("editUserFile", "user.ini");
$this->yellow->config->setDefault("editUserPasswordMinLength", "8");
$this->yellow->config->setDefault("editUserHashAlgorithm", "bcrypt");
$this->yellow->config->setDefault("editUserHashCost", "10");
$this->yellow->config->setDefault("editUserHome", "/");
$this->yellow->config->setDefault("editLoginRestrictions", "0");
$this->yellow->config->setDefault("editLoginSessionTimeout", "2592000");
$this->yellow->config->setDefault("editBruteForceProtection", "25");
$this->users->load($this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"));
$this->yellow->system->setDefault("editLocation", "/edit/");
$this->yellow->system->setDefault("editUploadNewLocation", "/media/@group/@filename");
$this->yellow->system->setDefault("editUploadExtensions", ".gif, .jpg, .pdf, .png, .svg, .tgz, .zip");
$this->yellow->system->setDefault("editKeyboardShortcuts", "ctrl+b bold, ctrl+i italic, ctrl+e code, ctrl+k link, ctrl+s save, ctrl+shift+p preview");
$this->yellow->system->setDefault("editToolbarButtons", "auto");
$this->yellow->system->setDefault("editEndOfLine", "auto");
$this->yellow->system->setDefault("editUserFile", "user.ini");
$this->yellow->system->setDefault("editUserPasswordMinLength", "8");
$this->yellow->system->setDefault("editUserHashAlgorithm", "bcrypt");
$this->yellow->system->setDefault("editUserHashCost", "10");
$this->yellow->system->setDefault("editUserHome", "/");
$this->yellow->system->setDefault("editNewFile", "page-new-(.*).md");
$this->yellow->system->setDefault("editLoginRestrictions", "0");
$this->yellow->system->setDefault("editLoginSessionTimeout", "2592000");
$this->yellow->system->setDefault("editBruteForceProtection", "25");
$this->users->load($this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile"));
}
// Handle startup
public function onStartup($update) {
if ($update) {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$fileData = $this->yellow->toolbox->readFile($fileNameUser);
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if (!empty($matches[1]) && !empty($matches[2]) && $matches[1][0]!="#") {
list($hash, $name, $language, $status, $stamp, $modified, $errors, $pending, $home) = explode(",", $matches[2]);
if ($errors=="none") { $home=$pending; $pending=$errors; $errors=$modified; $modified=$stamp; $stamp=""; } //TODO: remove later
if (strlenb($stamp)!=20) $stamp=$this->users->createStamp(); //TODO: remove later, converts old file format
if ($status!="active" && $status!="inactive") {
unset($this->users->users[$matches[1]]);
continue;
@ -63,9 +63,9 @@ class YellowEdit {
public function onRequest($scheme, $address, $base, $location, $fileName) {
$statusCode = 0;
if ($this->checkRequest($location)) {
$scheme = $this->yellow->config->get("serverScheme");
$address = $this->yellow->config->get("serverAddress");
$base = rtrim($this->yellow->config->get("serverBase").$this->yellow->config->get("editLocation"), "/");
$scheme = $this->yellow->system->get("serverScheme");
$address = $this->yellow->system->get("serverAddress");
$base = rtrim($this->yellow->system->get("serverBase").$this->yellow->system->get("editLocation"), "/");
list($scheme, $address, $base, $location, $fileName) = $this->yellow->getRequestInformation($scheme, $address, $base);
$this->yellow->page->setRequestInformation($scheme, $address, $base, $location, $fileName);
$statusCode = $this->processRequest($scheme, $address, $base, $location, $fileName);
@ -104,13 +104,13 @@ class YellowEdit {
public function onParsePageExtra($page, $name) {
$output = null;
if ($name=="header" && $this->response->isActive()) {
$pluginLocation = $this->yellow->config->get("serverBase").$this->yellow->config->get("pluginLocation");
$output = "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" data-bundle=\"none\" href=\"{$pluginLocation}edit.css\" />\n";
$output .= "<script type=\"text/javascript\" data-bundle=\"none\" src=\"{$pluginLocation}edit.js\"></script>\n";
$extensionLocation = $this->yellow->system->get("serverBase").$this->yellow->system->get("extensionLocation");
$output = "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" data-bundle=\"none\" href=\"{$extensionLocation}edit.css\" />\n";
$output .= "<script type=\"text/javascript\" data-bundle=\"none\" src=\"{$extensionLocation}edit.js\"></script>\n";
$output .= "<script type=\"text/javascript\">\n";
$output .= "// <![CDATA[\n";
$output .= "yellow.page = ".json_encode($this->response->getPageData($page)).";\n";
$output .= "yellow.config = ".json_encode($this->response->getConfigData()).";\n";
$output .= "yellow.system = ".json_encode($this->response->getSystemData()).";\n";
$output .= "yellow.text = ".json_encode($this->response->getTextData()).";\n";
$output .= "// ]]>\n";
$output .= "</script>\n";
@ -164,20 +164,20 @@ class YellowEdit {
if ($status=="ok") $status = $this->getUserAccount($email, $password, "add");
if ($status=="ok" && $this->users->isTaken($email)) $status = "taken";
switch ($status) {
case "incomplete": echo "ERROR updating configuration: Please enter email and password!\n"; break;
case "invalid": echo "ERROR updating configuration: Please enter a valid email!\n"; break;
case "taken": echo "ERROR updating configuration: Please enter a different email!\n"; break;
case "weak": echo "ERROR updating configuration: Please enter a different password!\n"; break;
case "incomplete": echo "ERROR updating settings: Please enter email and password!\n"; break;
case "invalid": echo "ERROR updating settings: Please enter a valid email!\n"; break;
case "taken": echo "ERROR updating settings: Please enter a different email!\n"; break;
case "weak": echo "ERROR updating settings: Please enter a different password!\n"; break;
}
if ($status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$status = $this->users->save($fileNameUser, $email, $password, $name, "", "active") ? "ok" : "error";
if ($status=="error") echo "ERROR updating configuration: Can't write file '$fileNameUser'!\n";
if ($status=="error") echo "ERROR updating settings: Can't write file '$fileNameUser'!\n";
}
if ($status=="ok") {
$algorithm = $this->yellow->config->get("editUserHashAlgorithm");
$algorithm = $this->yellow->system->get("editUserHashAlgorithm");
$status = substru($this->users->getHash($email), 0, 10)!="error-hash" ? "ok" : "error";
if ($status=="error") echo "ERROR updating configuration: Hash algorithm '$algorithm' not supported!\n";
if ($status=="error") echo "ERROR updating settings: Hash algorithm '$algorithm' not supported!\n";
}
$statusCode = $status=="ok" ? 200 : 500;
echo "Yellow $command: User account ".($statusCode!=200 ? "not " : "")."added\n";
@ -192,14 +192,14 @@ class YellowEdit {
if ($status=="ok") $status = $this->getUserAccount($email, $password, "change");
if ($status=="ok" && !$this->users->isExisting($email)) $status = "unknown";
switch ($status) {
case "invalid": echo "ERROR updating configuration: Please enter a valid email!\n"; break;
case "unknown": echo "ERROR updating configuration: Can't find email '$email'!\n"; break;
case "weak": echo "ERROR updating configuration: Please enter a different password!\n"; break;
case "invalid": echo "ERROR updating settings: Please enter a valid email!\n"; break;
case "unknown": echo "ERROR updating settings: Can't find email '$email'!\n"; break;
case "weak": echo "ERROR updating settings: Please enter a different password!\n"; break;
}
if ($status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$status = $this->users->save($fileNameUser, $email, $password, $name) ? "ok" : "error";
if ($status=="error") echo "ERROR updating configuration: Can't write file '$fileNameUser'!\n";
if ($status=="error") echo "ERROR updating settings: Can't write file '$fileNameUser'!\n";
}
$statusCode = $status=="ok" ? 200 : 500;
echo "Yellow $command: User account ".($statusCode!=200 ? "not " : "")."changed\n";
@ -214,13 +214,13 @@ class YellowEdit {
if ($status=="ok") $status = $this->getUserAccount($email, "", "remove");
if ($status=="ok" && !$this->users->isExisting($email)) $status = "unknown";
switch ($status) {
case "invalid": echo "ERROR updating configuration: Please enter a valid email!\n"; break;
case "unknown": echo "ERROR updating configuration: Can't find email '$email'!\n"; break;
case "invalid": echo "ERROR updating settings: Please enter a valid email!\n"; break;
case "unknown": echo "ERROR updating settings: Can't find email '$email'!\n"; break;
}
if ($status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$status = $this->users->remove($fileNameUser, $email) ? "ok" : "error";
if ($status=="error") echo "ERROR updating configuration: Can't write file '$fileNameUser'!\n";
if ($status=="error") echo "ERROR updating settings: Can't write file '$fileNameUser'!\n";
}
$statusCode = $status=="ok" ? 200 : 500;
echo "Yellow $command: User account ".($statusCode!=200 ? "not " : "")."removed\n";
@ -285,7 +285,7 @@ class YellowEdit {
// Process request for user login
public function processRequestLogin($scheme, $address, $base, $location, $fileName) {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
if ($this->users->save($fileNameUser, $this->response->userEmail)) {
$home = $this->users->getHome($this->response->userEmail);
if (substru($location, 0, strlenu($home))==$home) {
@ -307,9 +307,9 @@ class YellowEdit {
$this->response->userEmail = "";
$this->response->destroyCookies($scheme, $address, $base);
$location = $this->yellow->lookup->normaliseUrl(
$this->yellow->config->get("serverScheme"),
$this->yellow->config->get("serverAddress"),
$this->yellow->config->get("serverBase"),
$this->yellow->system->get("serverScheme"),
$this->yellow->system->get("serverAddress"),
$this->yellow->system->get("serverBase"),
$location);
$statusCode = $this->yellow->sendStatus(302, $location);
return $statusCode;
@ -328,12 +328,12 @@ class YellowEdit {
if ($this->response->status=="ok" && $this->response->isLoginRestrictions()) $this->response->status = "next";
if ($this->response->status=="ok" && $this->users->isTaken($email)) $this->response->status = "next";
if ($this->response->status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $email, $password, $name, "", "unconfirmed") ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
if ($this->response->status=="ok") {
$algorithm = $this->yellow->config->get("editUserHashAlgorithm");
$algorithm = $this->yellow->system->get("editUserHashAlgorithm");
$this->response->status = substru($this->users->getHash($email), 0, 10)!="error-hash" ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Hash algorithm '$algorithm' not supported!");
}
@ -352,7 +352,7 @@ class YellowEdit {
$email = $_REQUEST["email"];
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
if ($this->response->status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "unapproved") ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
@ -371,7 +371,7 @@ class YellowEdit {
$email = $_REQUEST["email"];
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
if ($this->response->status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "active") ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
@ -409,7 +409,7 @@ class YellowEdit {
if (empty($password)) $this->response->status = "password";
if ($this->response->status=="ok") $this->response->status = $this->getUserAccount($email, $password, $this->response->action);
if ($this->response->status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $email, $password) ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
@ -429,7 +429,7 @@ class YellowEdit {
$email = $_REQUEST["email"];
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
if ($this->response->status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "active") ? "done" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
@ -453,13 +453,13 @@ class YellowEdit {
if ($this->response->status=="ok" && $email!=$emailSource) {
$pending = $emailSource;
$home = $this->users->getHome($emailSource);
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $email, "no", $name, $language, "unverified", "", "", "", $pending, $home) ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
if ($this->response->status=="ok") {
$pending = $email.":".(empty($password) ? $this->users->getHash($emailSource) : $this->users->createHash($password));
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $emailSource, "", $name, $language, "", "", "", "", $pending) ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
@ -470,7 +470,7 @@ class YellowEdit {
}
} else {
if ($this->response->status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $email, "", $name, $language) ? "done" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
@ -495,7 +495,7 @@ class YellowEdit {
if ($this->users->getStatus($emailSource)!="active") $this->response->status = "done";
}
if ($this->response->status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "unchanged") ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
@ -520,12 +520,12 @@ class YellowEdit {
if ($this->response->status=="ok") {
$this->users->users[$email]["hash"] = $hash;
$this->users->users[$email]["pending"] = "none";
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "active") ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
if ($this->response->status=="ok" && $email!=$emailSource) {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->remove($fileNameUser, $emailSource) ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
@ -537,28 +537,28 @@ class YellowEdit {
return $statusCode;
}
// Process request to show software version
// Process request to show version
public function processRequestVersion($scheme, $address, $base, $location, $fileName) {
$this->response->action = "version";
$this->response->status = "ok";
if ($this->yellow->plugins->isExisting("update")) {
list($statusCodeCurrent, $dataCurrent) = $this->yellow->plugins->get("update")->getSoftwareVersion();
list($statusCodeLatest, $dataLatest) = $this->yellow->plugins->get("update")->getSoftwareVersion(true);
list($statusCodeModified, $dataModified) = $this->yellow->plugins->get("update")->getSoftwareModified();
if ($this->yellow->extensions->isExisting("update")) {
list($statusCodeCurrent, $dataCurrent) = $this->yellow->extensions->get("update")->getExtensionsVersion();
list($statusCodeLatest, $dataLatest) = $this->yellow->extensions->get("update")->getExtensionsVersion(true);
list($statusCodeModified, $dataModified) = $this->yellow->extensions->get("update")->getExtensionsModified();
$statusCode = max($statusCodeCurrent, $statusCodeLatest, $statusCodeModified);
if ($this->response->isUserWebmaster()) {
foreach ($dataCurrent as $key=>$value) {
if (strnatcasecmp($dataCurrent[$key], $dataLatest[$key])<0) {
++$updates;
$rawData = htmlspecialchars("$key $dataLatest[$key]")."<br />\n";
$rawData = htmlspecialchars(ucfirst($key)." $dataLatest[$key]")."<br />\n";
$this->response->rawDataOutput .= $rawData;
}
}
if ($updates==0) {
foreach ($dataCurrent as $key=>$value) {
if (!is_null($dataModified[$key]) && !is_null($dataLatest[$key])) {
$rawData = $this->yellow->text->getTextHtml("editVersionUpdateModified", $this->response->language)." - <a href=\"#\" data-action=\"update\" data-status=\"update\" data-args=\"".$this->yellow->toolbox->normaliseArgs("feature:$key/option:force")."\">".$this->yellow->text->getTextHtml("editVersionUpdateForce", $this->response->language)."</a><br />\n";
$rawData = preg_replace("/@software/i", htmlspecialchars("$key $dataLatest[$key]"), $rawData);
$rawData = $this->yellow->text->getTextHtml("editVersionUpdateModified", $this->response->language)." - <a href=\"#\" data-action=\"update\" data-status=\"update\" data-args=\"".$this->yellow->toolbox->normaliseArgs("extension:$key/option:force")."\">".$this->yellow->text->getTextHtml("editVersionUpdateForce", $this->response->language)."</a><br />\n";
$rawData = preg_replace("/@extension/i", htmlspecialchars(ucfirst($key)." $dataLatest[$key]"), $rawData);
$this->response->rawDataOutput .= $rawData;
}
}
@ -579,10 +579,10 @@ class YellowEdit {
// Process request to update website
public function processRequestUpdate($scheme, $address, $base, $location, $fileName) {
$statusCode = 0;
if ($this->yellow->plugins->isExisting("update") && $this->response->isUserWebmaster()) {
$feature = trim($_REQUEST["feature"]);
if ($this->yellow->extensions->isExisting("update") && $this->response->isUserWebmaster()) {
$extension = trim($_REQUEST["extension"]);
$option = trim($_REQUEST["option"]);
$statusCode = $this->yellow->command("update", $feature, $option);
$statusCode = $this->yellow->command("update", $extension, $option);
if ($statusCode==200) {
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
$statusCode = $this->yellow->sendStatus(303, $location);
@ -615,7 +615,7 @@ class YellowEdit {
$email = $_REQUEST["email"];
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
if ($this->response->status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->save($fileNameUser, $email, "", "", "", "removed") ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
@ -624,7 +624,7 @@ class YellowEdit {
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!");
}
if ($this->response->status=="ok") {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$this->response->status = $this->users->remove($fileNameUser, $email) ? "ok" : "error";
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
@ -712,7 +712,7 @@ class YellowEdit {
$rawDataFile, $this->response->rawDataEndOfLine);
if (!$page->isError()) {
if ($this->yellow->lookup->isFileLocation($location)) {
if ($this->yellow->toolbox->deleteFile($fileName, $this->yellow->config->get("trashDir"))) {
if ($this->yellow->toolbox->deleteFile($fileName, $this->yellow->system->get("trashDir"))) {
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
$statusCode = $this->yellow->sendStatus(303, $location);
} else {
@ -720,7 +720,7 @@ class YellowEdit {
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
}
} else {
if ($this->yellow->toolbox->deleteDirectory(dirname($fileName), $this->yellow->config->get("trashDir"))) {
if ($this->yellow->toolbox->deleteDirectory(dirname($fileName), $this->yellow->system->get("trashDir"))) {
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
$statusCode = $this->yellow->sendStatus(303, $location);
} else {
@ -755,7 +755,7 @@ class YellowEdit {
$fileNameShort = preg_replace("/[^\pL\d\-\.]/u", "-", basename($_FILES["file"]["name"]));
$fileSizeMax = $this->yellow->toolbox->getNumberBytes(ini_get("upload_max_filesize"));
$extension = strtoloweru(($pos = strrposu($fileNameShort, ".")) ? substru($fileNameShort, $pos) : "");
$extensions = preg_split("/\s*,\s*/", $this->yellow->config->get("editUploadExtensions"));
$extensions = preg_split("/\s*,\s*/", $this->yellow->system->get("editUploadExtensions"));
if (!$this->response->isUserRestrictions() && is_uploaded_file($fileNameTemp) &&
filesize($fileNameTemp)<=$fileSizeMax && in_array($extension, $extensions)) {
$file = $this->response->getFileUpload($scheme, $address, $base, $location, $fileNameTemp, $fileNameShort);
@ -773,8 +773,8 @@ class YellowEdit {
// Check request
public function checkRequest($location) {
$locationLength = strlenu($this->yellow->config->get("editLocation"));
$this->response->active = substru($location, 0, $locationLength)==$this->yellow->config->get("editLocation");
$locationLength = strlenu($this->yellow->system->get("editLocation"));
$this->response->active = substru($location, 0, $locationLength)==$this->yellow->system->get("editLocation");
return $this->response->isActive();
}
@ -834,10 +834,10 @@ class YellowEdit {
$email = $this->response->userFailedEmail;
$modified = $this->users->getModified($email);
$errors = $this->users->getErrors($email)+1;
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$status = $this->users->save($fileNameUser, $email, "", "", "", "", "", $modified, $errors) ? "ok" : "error";
if ($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
if ($errors==$this->yellow->config->get("editBruteForceProtection")) {
if ($errors==$this->yellow->system->get("editBruteForceProtection")) {
$statusBeforeProtection = $this->users->getStatus($email);
$statusAfterProtection = ($statusBeforeProtection=="active" || $statusBeforeProtection=="inactive") ? "inactive" : "failed";
if ($status=="ok") {
@ -878,7 +878,7 @@ class YellowEdit {
// Return user account changes
public function getUserAccount($email, $password, $action) {
$status = null;
foreach ($this->yellow->plugins->plugins as $key=>$value) {
foreach ($this->yellow->extensions->extensions as $key=>$value) {
if (method_exists($value["obj"], "onEditUserAccount")) {
$status = $value["obj"]->onEditUserAccount($email, $password, $action, $this->users);
if (!is_null($status)) break;
@ -886,7 +886,7 @@ class YellowEdit {
}
if (is_null($status)) {
$status = "ok";
if (!empty($password) && strlenu($password)<$this->yellow->config->get("editUserPasswordMinLength")) $status = "weak";
if (!empty($password) && strlenu($password)<$this->yellow->system->get("editUserPasswordMinLength")) $status = "weak";
if (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) $status = "invalid";
}
return $status;
@ -895,7 +895,7 @@ class YellowEdit {
// Return user restrictions
public function getUserRestrictions($email, $location, $fileName) {
$userRestrictions = null;
foreach ($this->yellow->plugins->plugins as $key=>$value) {
foreach ($this->yellow->extensions->extensions as $key=>$value) {
if (method_exists($value["obj"], "onEditUserRestrictions")) {
$userRestrictions = $value["obj"]->onEditUserRestrictions($email, $location, $fileName, $this->users);
if (!is_null($userRestrictions)) break;
@ -911,7 +911,7 @@ class YellowEdit {
// Return user language
public function getUserLanguage($email) {
$language = $this->users->getLanguage($email);
if (!$this->yellow->text->isLanguage($language)) $language = $this->yellow->config->get("language");
if (!$this->yellow->text->isLanguage($language)) $language = $this->yellow->system->get("language");
return $language;
}
@ -925,7 +925,7 @@ class YellowEdit {
class YellowResponse {
public $yellow; //access to API
public $plugin; //access to plugin
public $extension; //access to extension
public $active; //location is active? (boolean)
public $userEmail; //user email
public $userRestrictions; //user can change page? (boolean)
@ -942,7 +942,7 @@ class YellowResponse {
public function __construct($yellow) {
$this->yellow = $yellow;
$this->plugin = $yellow->plugins->get("edit");
$this->extension = $yellow->extensions->get("edit");
}
// Return new page
@ -951,23 +951,23 @@ class YellowResponse {
$page->setRequestInformation($scheme, $address, $base, $location, $fileName);
$page->parseData($this->normaliseLines($rawData, $endOfLine), false, 0);
$this->editContentFile($page, "create");
if ($this->yellow->pages->find($page->location)) {
if ($this->yellow->content->find($page->location)) {
$page->location = $this->getPageNewLocation($page->rawData, $page->location, $page->get("pageNewLocation"));
$page->fileName = $this->getPageNewFile($page->location, $page->fileName, $page->get("published"));
while ($this->yellow->pages->find($page->location) || empty($page->fileName)) {
while ($this->yellow->content->find($page->location) || empty($page->fileName)) {
$rawData = $this->yellow->toolbox->setMetaData($page->rawData, "title", $this->getTitleNext($page->rawData));
$page->rawData = $this->normaliseLines($rawData, $endOfLine);
$page->location = $this->getPageNewLocation($page->rawData, $page->location, $page->get("pageNewLocation"));
$page->fileName = $this->getPageNewFile($page->location, $page->fileName, $page->get("published"));
if (++$pageCounter>999) break;
}
if ($this->yellow->pages->find($page->location) || empty($page->fileName)) {
if ($this->yellow->content->find($page->location) || empty($page->fileName)) {
$page->error(500, "Page '".$page->get("title")."' is not possible!");
}
} else {
$page->fileName = $this->getPageNewFile($page->location);
}
if ($this->plugin->getUserRestrictions($this->userEmail, $page->location, $page->fileName)) {
if ($this->extension->getUserRestrictions($this->userEmail, $page->location, $page->fileName)) {
$page->error(500, "Page '".$page->get("title")."' is restricted!");
}
return $page;
@ -977,7 +977,7 @@ class YellowResponse {
public function getPageEdit($scheme, $address, $base, $location, $fileName, $rawDataSource, $rawDataEdit, $rawDataFile, $endOfLine) {
$page = new YellowPage($this->yellow);
$page->setRequestInformation($scheme, $address, $base, $location, $fileName);
$rawData = $this->plugin->merge->merge(
$rawData = $this->extension->merge->merge(
$this->normaliseLines($rawDataSource, $endOfLine),
$this->normaliseLines($rawDataEdit, $endOfLine),
$this->normaliseLines($rawDataFile, $endOfLine));
@ -986,16 +986,16 @@ class YellowResponse {
$pageSource->setRequestInformation($scheme, $address, $base, $location, $fileName);
$pageSource->parseData($this->normaliseLines($rawDataSource, $endOfLine), false, 0);
$this->editContentFile($page, "edit");
if ($this->isMetaModified($pageSource, $page) && $page->location!=$this->yellow->pages->getHomeLocation($page->location)) {
if ($this->isMetaModified($pageSource, $page) && $page->location!=$this->yellow->content->getHomeLocation($page->location)) {
$page->location = $this->getPageNewLocation($page->rawData, $page->location, $page->get("pageNewLocation"), true);
$page->fileName = $this->getPageNewFile($page->location, $page->fileName, $page->get("published"));
if ($page->location!=$pageSource->location && ($this->yellow->pages->find($page->location) || empty($page->fileName))) {
if ($page->location!=$pageSource->location && ($this->yellow->content->find($page->location) || empty($page->fileName))) {
$page->error(500, "Page '".$page->get("title")."' is not possible!");
}
}
if (empty($page->rawData)) $page->error(500, "Page has been modified by someone else!");
if ($this->plugin->getUserRestrictions($this->userEmail, $page->location, $page->fileName) ||
$this->plugin->getUserRestrictions($this->userEmail, $pageSource->location, $pageSource->fileName)) {
if ($this->extension->getUserRestrictions($this->userEmail, $page->location, $page->fileName) ||
$this->extension->getUserRestrictions($this->userEmail, $pageSource->location, $pageSource->fileName)) {
$page->error(500, "Page '".$page->get("title")."' is restricted!");
}
return $page;
@ -1007,7 +1007,7 @@ class YellowResponse {
$page->setRequestInformation($scheme, $address, $base, $location, $fileName);
$page->parseData($this->normaliseLines($rawData, $endOfLine), false, 0);
$this->editContentFile($page, "delete");
if ($this->plugin->getUserRestrictions($this->userEmail, $page->location, $page->fileName)) {
if ($this->extension->getUserRestrictions($this->userEmail, $page->location, $page->fileName)) {
$page->error(500, "Page '".$page->get("title")."' is restricted!");
}
return $page;
@ -1020,9 +1020,9 @@ class YellowResponse {
$page->parseData($this->normaliseLines($rawData, $endOfLine), false, 200);
$this->yellow->text->setLanguage($page->get("language"));
$page->set("pageClass", "page-preview");
$page->set("pageClass", $page->get("pageClass")." template-".$page->get("template"));
$page->set("pageClass", $page->get("pageClass")." layout-".$page->get("layout"));
$output = "<div class=\"".$page->getHtml("pageClass")."\"><div class=\"content\">";
if ($this->yellow->config->get("editToolbarButtons")!="none") $output .= "<h1>".$page->getHtml("titleContent")."</h1>\n";
if ($this->yellow->system->get("editToolbarButtons")!="none") $output .= "<h1>".$page->getHtml("titleContent")."</h1>\n";
$output .= $page->getContent();
$output .= "</div></div>";
$page->setOutput($output);
@ -1071,32 +1071,32 @@ class YellowResponse {
return $data;
}
// Return configuration data including user information
public function getConfigData() {
$data = $this->yellow->config->getData("", "Location");
// Return system data including user information
public function getSystemData() {
$data = $this->yellow->system->getData("", "Location");
if ($this->isUser()) {
$data["userEmail"] = $this->userEmail;
$data["userName"] = $this->plugin->users->getName($this->userEmail);
$data["userLanguage"] = $this->plugin->users->getLanguage($this->userEmail);
$data["userStatus"] = $this->plugin->users->getStatus($this->userEmail);
$data["userHome"] = $this->plugin->users->getHome($this->userEmail);
$data["userName"] = $this->extension->users->getName($this->userEmail);
$data["userLanguage"] = $this->extension->users->getLanguage($this->userEmail);
$data["userStatus"] = $this->extension->users->getStatus($this->userEmail);
$data["userHome"] = $this->extension->users->getHome($this->userEmail);
$data["userRestrictions"] = intval($this->isUserRestrictions());
$data["userWebmaster"] = intval($this->isUserWebmaster());
$data["serverScheme"] = $this->yellow->config->get("serverScheme");
$data["serverAddress"] = $this->yellow->config->get("serverAddress");
$data["serverBase"] = $this->yellow->config->get("serverBase");
$data["serverScheme"] = $this->yellow->system->get("serverScheme");
$data["serverAddress"] = $this->yellow->system->get("serverAddress");
$data["serverBase"] = $this->yellow->system->get("serverBase");
$data["serverFileSizeMax"] = $this->yellow->toolbox->getNumberBytes(ini_get("upload_max_filesize"));
$data["serverVersion"] = "Datenstrom Yellow ".YellowCore::VERSION;
$data["serverPlugins"] = array();
foreach ($this->yellow->plugins->plugins as $key=>$value) {
$data["serverPlugins"][$key] = $value["plugin"];
$data["serverExtensions"] = array();
foreach ($this->yellow->extensions->extensions as $key=>$value) {
$data["serverExtensions"][$key] = $value["type"];
}
$data["serverLanguages"] = array();
foreach ($this->yellow->text->getLanguages() as $language) {
$data["serverLanguages"][$language] = $this->yellow->text->getTextHtml("languageDescription", $language);
}
$data["editUploadExtensions"] = $this->yellow->config->get("editUploadExtensions");
$data["editKeyboardShortcuts"] = $this->yellow->config->get("editKeyboardShortcuts");
$data["editUploadExtensions"] = $this->yellow->system->get("editUploadExtensions");
$data["editKeyboardShortcuts"] = $this->yellow->system->get("editKeyboardShortcuts");
$data["editToolbarButtons"] = $this->getToolbarButtons("edit");
$data["emojiawesomeToolbarButtons"] = $this->getToolbarButtons("emojiawesome");
$data["fontawesomeToolbarButtons"] = $this->getToolbarButtons("fontawesome");
@ -1130,24 +1130,24 @@ class YellowResponse {
// Return toolbar buttons
public function getToolbarButtons($name) {
if ($name=="edit") {
$toolbarButtons = $this->yellow->config->get("editToolbarButtons");
$toolbarButtons = $this->yellow->system->get("editToolbarButtons");
if ($toolbarButtons=="auto") {
$toolbarButtons = "";
if ($this->yellow->plugins->isExisting("markdown")) $toolbarButtons = "preview, format, bold, italic, code, list, link, file";
if ($this->yellow->plugins->isExisting("emojiawesome")) $toolbarButtons .= ", emojiawesome";
if ($this->yellow->plugins->isExisting("fontawesome")) $toolbarButtons .= ", fontawesome";
if ($this->yellow->plugins->isExisting("draft")) $toolbarButtons .= ", draft";
if ($this->yellow->plugins->isExisting("markdown")) $toolbarButtons .= ", markdown";
if ($this->yellow->extensions->isExisting("markdown")) $toolbarButtons = "preview, format, bold, italic, code, list, link, file";
if ($this->yellow->extensions->isExisting("emojiawesome")) $toolbarButtons .= ", emojiawesome";
if ($this->yellow->extensions->isExisting("fontawesome")) $toolbarButtons .= ", fontawesome";
if ($this->yellow->extensions->isExisting("draft")) $toolbarButtons .= ", draft";
if ($this->yellow->extensions->isExisting("markdown")) $toolbarButtons .= ", markdown";
}
} else {
$toolbarButtons = $this->yellow->config->get("{$name}ToolbarButtons");
$toolbarButtons = $this->yellow->system->get("{$name}ToolbarButtons");
}
return $toolbarButtons;
}
// Return end of line format
public function getEndOfLine($rawData = "") {
$endOfLine = $this->yellow->config->get("editEndOfLine");
$endOfLine = $this->yellow->system->get("editEndOfLine");
if ($endOfLine=="auto") {
$rawData = empty($rawData) ? PHP_EOL : substru($rawData, 0, 4096);
$endOfLine = strposu($rawData, "\r")===false ? "lf" : "crlf";
@ -1157,19 +1157,19 @@ class YellowResponse {
// Return raw data for new page
public function getRawDataNew($page, $customTitle = false) {
foreach ($this->yellow->pages->path($page->location)->reverse() as $ancestor) {
if ($ancestor->isExisting("templateNew")) {
$name = $this->yellow->lookup->normaliseName($ancestor->get("templateNew"));
$location = $this->yellow->pages->getHomeLocation($page->location).$this->yellow->config->get("contentSharedDir");
$fileName = $this->yellow->lookup->findFileFromLocation($location, true).$this->yellow->config->get("newFile");
foreach ($this->yellow->content->path($page->location)->reverse() as $ancestor) {
if ($ancestor->isExisting("layoutNew")) {
$name = $this->yellow->lookup->normaliseName($ancestor->get("layoutNew"));
$location = $this->yellow->content->getHomeLocation($page->location).$this->yellow->system->get("contentSharedDir");
$fileName = $this->yellow->lookup->findFileFromLocation($location, true).$this->yellow->system->get("editNewFile");
$fileName = strreplaceu("(.*)", $name, $fileName);
if (is_file($fileName)) break;
}
}
if (!is_file($fileName)) {
$name = $this->yellow->lookup->normaliseName($this->yellow->config->get("template"));
$location = $this->yellow->pages->getHomeLocation($page->location).$this->yellow->config->get("contentSharedDir");
$fileName = $this->yellow->lookup->findFileFromLocation($location, true).$this->yellow->config->get("newFile");
$name = $this->yellow->lookup->normaliseName($this->yellow->system->get("layout"));
$location = $this->yellow->content->getHomeLocation($page->location).$this->yellow->system->get("contentSharedDir");
$fileName = $this->yellow->lookup->findFileFromLocation($location, true).$this->yellow->system->get("editNewFile");
$fileName = strreplaceu("(.*)", $name, $fileName);
}
if (is_file($fileName)) {
@ -1177,9 +1177,9 @@ class YellowResponse {
$rawData = preg_replace("/@timestamp/i", time(), $rawData);
$rawData = preg_replace("/@datetime/i", date("Y-m-d H:i:s"), $rawData);
$rawData = preg_replace("/@date/i", date("Y-m-d"), $rawData);
$rawData = preg_replace("/@usershort/i", strtok($this->plugin->users->getName($this->userEmail), " "), $rawData);
$rawData = preg_replace("/@username/i", $this->plugin->users->getName($this->userEmail), $rawData);
$rawData = preg_replace("/@userlanguage/i", $this->plugin->users->getLanguage($this->userEmail), $rawData);
$rawData = preg_replace("/@usershort/i", strtok($this->extension->users->getName($this->userEmail), " "), $rawData);
$rawData = preg_replace("/@username/i", $this->extension->users->getName($this->userEmail), $rawData);
$rawData = preg_replace("/@userlanguage/i", $this->extension->users->getLanguage($this->userEmail), $rawData);
} else {
$rawData = "---\nTitle: Page\n---\n";
}
@ -1263,13 +1263,13 @@ class YellowResponse {
$path = $matches[1];
$text = $this->yellow->lookup->normaliseName($matches[2], true, true);
if (preg_match("/^[\d\-\_\.]*$/", $text)) $prefix = "";
$fileName = $path."/".$prefix.$text.$this->yellow->config->get("contentExtension");
$fileName = $path."/".$prefix.$text.$this->yellow->system->get("contentExtension");
} else {
preg_match("#^(.*)\/(.+?)$#", dirname($fileName), $matches);
$path = $matches[1];
$text = $this->yellow->lookup->normaliseName($matches[2], true, false);
if (preg_match("/^[\d\-\_\.]*$/", $text)) $prefix = "";
$fileName = $path."/".$prefix.$text."/".$this->yellow->config->get("contentDefaultFile");
$fileName = $path."/".$prefix.$text."/".$this->yellow->system->get("contentDefaultFile");
}
}
return $fileName;
@ -1291,31 +1291,31 @@ class YellowResponse {
// Return location for new file
public function getFileNewLocation($fileNameShort, $pageLocation, $fileNewLocation) {
$location = empty($fileNewLocation) ? $this->yellow->config->get("editUploadNewLocation") : $fileNewLocation;
$location = empty($fileNewLocation) ? $this->yellow->system->get("editUploadNewLocation") : $fileNewLocation;
$location = preg_replace("/@timestamp/i", time(), $location);
$location = preg_replace("/@type/i", $this->yellow->toolbox->getFileType($fileNameShort), $location);
$location = preg_replace("/@group/i", $this->getFileNewGroup($fileNameShort), $location);
$location = preg_replace("/@folder/i", $this->getFileNewFolder($pageLocation), $location);
$location = preg_replace("/@filename/i", strtoloweru($fileNameShort), $location);
if (!preg_match("/^\//", $location)) {
$location = $this->yellow->config->get("mediaLocation").$location;
$location = $this->yellow->system->get("mediaLocation").$location;
}
return $location;
}
// Return group for new file
public function getFileNewGroup($fileNameShort) {
$path = $this->yellow->config->get("mediaDir");
$path = $this->yellow->system->get("mediaDir");
$fileType = $this->yellow->toolbox->getFileType($fileNameShort);
$fileName = $this->yellow->config->get(preg_match("/(gif|jpg|png|svg)$/", $fileType) ? "imageDir" : "downloadDir").$fileNameShort;
$fileName = $this->yellow->system->get(preg_match("/(gif|jpg|png|svg)$/", $fileType) ? "imageDir" : "downloadDir").$fileNameShort;
preg_match("#^$path(.+?)\/#", $fileName, $matches);
return strtoloweru($matches[1]);
}
// Return folder for new file
public function getFileNewFolder($pageLocation) {
$parentTopLocation = $this->yellow->pages->getParentTopLocation($pageLocation);
if ($parentTopLocation==$this->yellow->pages->getHomeLocation($pageLocation)) $parentTopLocation .= "home";
$parentTopLocation = $this->yellow->content->getParentTopLocation($pageLocation);
if ($parentTopLocation==$this->yellow->content->getHomeLocation($pageLocation)) $parentTopLocation .= "home";
return strtoloweru(trim($parentTopLocation, "/"));
}
@ -1348,9 +1348,9 @@ class YellowResponse {
// Create browser cookies
public function createCookies($scheme, $address, $base, $email) {
$expire = time() + $this->yellow->config->get("editLoginSessionTimeout");
$authToken = $this->plugin->users->createAuthToken($email, $expire);
$csrfToken = $this->plugin->users->createCsrfToken();
$expire = time() + $this->yellow->system->get("editLoginSessionTimeout");
$authToken = $this->extension->users->createAuthToken($email, $expire);
$csrfToken = $this->extension->users->createCsrfToken();
setcookie("authtoken", $authToken, $expire, "$base/", "", $scheme=="https", true);
setcookie("csrftoken", $csrfToken, $expire, "$base/", "", $scheme=="https", false);
}
@ -1367,20 +1367,20 @@ class YellowResponse {
$url = "$scheme://$address$base/";
} else {
$expire = time() + 60*60*24;
$actionToken = $this->plugin->users->createActionToken($email, $action, $expire);
$actionToken = $this->extension->users->createActionToken($email, $action, $expire);
$url = "$scheme://$address$base"."/action:$action/email:$email/expire:$expire/actiontoken:$actionToken/";
}
if ($action=="approve") {
$account = $email;
$name = $this->yellow->config->get("author");
$email = $this->yellow->config->get("email");
$name = $this->yellow->system->get("author");
$email = $this->yellow->system->get("email");
} else {
$account = $email;
$name = $this->plugin->users->getName($email);
$name = $this->extension->users->getName($email);
}
$language = $this->plugin->users->getLanguage($email);
if (!$this->yellow->text->isLanguage($language)) $language = $this->yellow->config->get("language");
$sitename = $this->yellow->config->get("sitename");
$language = $this->extension->users->getLanguage($email);
if (!$this->yellow->text->isLanguage($language)) $language = $this->yellow->system->get("language");
$sitename = $this->yellow->system->get("sitename");
$prefix = "edit".ucfirst($action);
$message = $this->yellow->text->getText("{$prefix}Message", $language);
$message = strreplaceu("\\n", "\n", $message);
@ -1401,7 +1401,7 @@ class YellowResponse {
// Change content file
public function editContentFile($page, $action) {
if (!$page->isError()) {
foreach ($this->yellow->plugins->plugins as $key=>$value) {
foreach ($this->yellow->extensions->extensions as $key=>$value) {
if (method_exists($value["obj"], "onEditContentFile")) $value["obj"]->onEditContentFile($page, $action);
}
}
@ -1410,7 +1410,7 @@ class YellowResponse {
// Change media file
public function editMediaFile($file, $action) {
if (!$file->isError()) {
foreach ($this->yellow->plugins->plugins as $key=>$value) {
foreach ($this->yellow->extensions->extensions as $key=>$value) {
if (method_exists($value["obj"], "onEditMediaFile")) $value["obj"]->onEditMediaFile($file, $action);
}
}
@ -1434,7 +1434,7 @@ class YellowResponse {
// Check if user is webmaster
public function isUserWebmaster() {
return !empty($this->userEmail) && $this->userEmail==$this->yellow->config->get("email");
return !empty($this->userEmail) && $this->userEmail==$this->yellow->system->get("email");
}
// Check if user has restrictions
@ -1444,7 +1444,7 @@ class YellowResponse {
// Check if login has restrictions
public function isLoginRestrictions() {
return $this->yellow->config->get("editLoginRestrictions");
return $this->yellow->system->get("editLoginRestrictions");
}
}
@ -1489,14 +1489,14 @@ class YellowUsers {
} else {
$email = strreplaceu(",", "-", empty($email) ? "none" : $email);
$hash = strreplaceu(",", "-", empty($hash) ? "none" : $hash);
$name = strreplaceu(",", "-", empty($name) ? $this->yellow->config->get("sitename") : $name);
$language = strreplaceu(",", "-", empty($language) ? $this->yellow->config->get("language") : $language);
$name = strreplaceu(",", "-", empty($name) ? $this->yellow->system->get("sitename") : $name);
$language = strreplaceu(",", "-", empty($language) ? $this->yellow->system->get("language") : $language);
$status = strreplaceu(",", "-", empty($status) ? "active" : $status);
$stamp = strreplaceu(",", "-", empty($stamp) ? $this->createStamp() : $stamp);
$modified = strreplaceu(",", "-", empty($modified) ? time() : $modified);
$errors = strreplaceu(",", "-", empty($errors) ? "0" : $errors);
$pending = strreplaceu(",", "-", empty($pending) ? "none" : $pending);
$home = strreplaceu(",", "-", empty($home) ? $this->yellow->config->get("editUserHome") : $home);
$home = strreplaceu(",", "-", empty($home) ? $this->yellow->system->get("editUserHome") : $home);
}
$this->set($email, $hash, $name, $language, $status, $stamp, $modified, $errors, $pending, $home);
$fileData = $this->yellow->toolbox->readFile($fileName);
@ -1541,7 +1541,7 @@ class YellowUsers {
// Check user authentication from email and password
public function checkAuthLogin($email, $password) {
$algorithm = $this->yellow->config->get("editUserHashAlgorithm");
$algorithm = $this->yellow->system->get("editUserHashAlgorithm");
return $this->isExisting($email) && $this->users[$email]["status"]=="active" &&
$this->yellow->toolbox->verifyHash($password, $algorithm, $this->users[$email]["hash"]);
}
@ -1584,8 +1584,8 @@ class YellowUsers {
// Create password hash
public function createHash($password) {
$algorithm = $this->yellow->config->get("editUserHashAlgorithm");
$cost = $this->yellow->config->get("editUserHashCost");
$algorithm = $this->yellow->system->get("editUserHashAlgorithm");
$cost = $this->yellow->system->get("editUserHashCost");
$hash = $this->yellow->toolbox->createHash($password, $algorithm, $cost);
if (empty($hash)) $hash = "error-hash-algorithm-$algorithm";
return $hash;

View file

View file

@ -0,0 +1,9 @@
<?php
// Flatsite extension, https://github.com/datenstrom/yellow-extensions/tree/master/themes/flatsite
// Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se
// This file may be used and distributed under the terms of the public license.
class YellowFlatsite {
const VERSION = "0.8.2";
const TYPE = "theme";
}

View file

@ -1,23 +1,24 @@
<?php
// Image plugin, https://github.com/datenstrom/yellow-plugins/tree/master/image
// Image extension, https://github.com/datenstrom/yellow-extensions/tree/master/features/image
// Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se
// This file may be used and distributed under the terms of the public license.
class YellowImage {
const VERSION = "0.8.1";
const VERSION = "0.8.2";
const TYPE = "feature";
public $yellow; //access to API
public $graphicsLibrary; //graphics library support? (boolean)
// Handle initialisation
public function onLoad($yellow) {
$this->yellow = $yellow;
$this->yellow->config->setDefault("imageAlt", "Image");
$this->yellow->config->setDefault("imageUploadWidthMax", "1280");
$this->yellow->config->setDefault("imageUploadHeightMax", "1280");
$this->yellow->config->setDefault("imageUploadJpgQuality", "80");
$this->yellow->config->setDefault("imageThumbnailLocation", "/media/thumbnails/");
$this->yellow->config->setDefault("imageThumbnailDir", "media/thumbnails/");
$this->yellow->config->setDefault("imageThumbnailJpgQuality", "80");
$this->yellow->system->setDefault("imageAlt", "Image");
$this->yellow->system->setDefault("imageUploadWidthMax", "1280");
$this->yellow->system->setDefault("imageUploadHeightMax", "1280");
$this->yellow->system->setDefault("imageUploadJpgQuality", "80");
$this->yellow->system->setDefault("imageThumbnailLocation", "/media/thumbnails/");
$this->yellow->system->setDefault("imageThumbnailDir", "media/thumbnails/");
$this->yellow->system->setDefault("imageThumbnailJpgQuality", "80");
$this->graphicsLibrary = $this->isGraphicsLibrary();
}
@ -26,17 +27,17 @@ class YellowImage {
$output = null;
if ($name=="image" && $type=="inline") {
if (!$this->graphicsLibrary) {
$this->yellow->page->error(500, "Plugin 'image' requires GD library with gif/jpg/png support!");
$this->yellow->page->error(500, "Image extension requires GD library with gif/jpg/png support!");
return $output;
}
list($name, $alt, $style, $width, $height) = $this->yellow->toolbox->getTextArgs($text);
if (!preg_match("/^\w+:/", $name)) {
if (empty($alt)) $alt = $this->yellow->config->get("imageAlt");
if (empty($alt)) $alt = $this->yellow->system->get("imageAlt");
if (empty($width)) $width = "100%";
if (empty($height)) $height = $width;
list($src, $width, $height) = $this->getImageInformation($this->yellow->config->get("imageDir").$name, $width, $height);
list($src, $width, $height) = $this->getImageInformation($this->yellow->system->get("imageDir").$name, $width, $height);
} else {
if (empty($alt)) $alt = $this->yellow->config->get("imageAlt");
if (empty($alt)) $alt = $this->yellow->system->get("imageAlt");
$src = $this->yellow->lookup->normaliseUrl("", "", "", $name);
$width = $height = 0;
}
@ -55,17 +56,17 @@ class YellowImage {
$fileName = $file->fileName;
$fileType = $this->yellow->toolbox->getFileType($file->get("fileNameShort"));
list($widthInput, $heightInput, $type) = $this->yellow->toolbox->detectImageInformation($fileName, $fileType);
$widthMax = $this->yellow->config->get("imageUploadWidthMax");
$heightMax = $this->yellow->config->get("imageUploadHeightMax");
$widthMax = $this->yellow->system->get("imageUploadWidthMax");
$heightMax = $this->yellow->system->get("imageUploadHeightMax");
if (($widthInput>$widthMax || $heightInput>$heightMax) && ($type=="gif" || $type=="jpg" || $type=="png")) {
list($widthOutput, $heightOutput) = $this->getImageDimensionsFit($widthInput, $heightInput, $widthMax, $heightMax);
$image = $this->loadImage($fileName, $type);
$image = $this->resizeImage($image, $widthInput, $heightInput, $widthOutput, $heightOutput);
if (!$this->saveImage($image, $fileName, $type, $this->yellow->config->get("imageUploadJpgQuality"))) {
if (!$this->saveImage($image, $fileName, $type, $this->yellow->system->get("imageUploadJpgQuality"))) {
$file->error(500, "Can't write file '$fileName'!");
}
}
if ($this->yellow->config->get("safeMode") && $fileType=="svg") {
if ($this->yellow->system->get("safeMode") && $fileType=="svg") {
$output = $this->sanitiseXmlData($this->yellow->toolbox->readFile($fileName));
if (empty($output) || !$this->yellow->toolbox->createFile($fileName, $output)) {
$file->error(500, "Can't write file '$fileName'!");
@ -89,7 +90,7 @@ class YellowImage {
$statusCode = 0;
list($command, $path) = $args;
if ($path=="all") {
$path = $this->yellow->config->get("imageThumbnailDir");
$path = $this->yellow->system->get("imageThumbnailDir");
foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/.*/", false, false) as $entry) {
if (!$this->yellow->toolbox->deleteFile($entry)) $statusCode = 500;
}
@ -100,29 +101,29 @@ class YellowImage {
// Return image info, create thumbnail on demand
public function getImageInformation($fileName, $widthOutput, $heightOutput) {
$fileNameShort = substru($fileName, strlenu($this->yellow->config->get("imageDir")));
$fileNameShort = substru($fileName, strlenu($this->yellow->system->get("imageDir")));
list($widthInput, $heightInput, $type) = $this->yellow->toolbox->detectImageInformation($fileName);
$widthOutput = $this->convertValueAndUnit($widthOutput, $widthInput);
$heightOutput = $this->convertValueAndUnit($heightOutput, $heightInput);
if (($widthInput==$widthOutput && $heightInput==$heightOutput) || $type=="svg") {
$src = $this->yellow->config->get("serverBase").$this->yellow->config->get("imageLocation").$fileNameShort;
$src = $this->yellow->system->get("serverBase").$this->yellow->system->get("imageLocation").$fileNameShort;
$width = $widthOutput;
$height = $heightOutput;
} else {
$fileNameThumb = ltrim(str_replace(array("/", "\\", "."), "-", dirname($fileNameShort)."/".pathinfo($fileName, PATHINFO_FILENAME)), "-");
$fileNameThumb .= "-".$widthOutput."x".$heightOutput;
$fileNameThumb .= ".".pathinfo($fileName, PATHINFO_EXTENSION);
$fileNameOutput = $this->yellow->config->get("imageThumbnailDir").$fileNameThumb;
$fileNameOutput = $this->yellow->system->get("imageThumbnailDir").$fileNameThumb;
if ($this->isFileNotUpdated($fileName, $fileNameOutput)) {
$image = $this->loadImage($fileName, $type);
$image = $this->resizeImage($image, $widthInput, $heightInput, $widthOutput, $heightOutput);
if (is_file($fileNameOutput)) $this->yellow->toolbox->deleteFile($fileNameOutput);
if (!$this->saveImage($image, $fileNameOutput, $type, $this->yellow->config->get("imageThumbnailJpgQuality")) ||
if (!$this->saveImage($image, $fileNameOutput, $type, $this->yellow->system->get("imageThumbnailJpgQuality")) ||
!$this->yellow->toolbox->modifyFile($fileNameOutput, $this->yellow->toolbox->getFileModified($fileName))) {
$this->yellow->page->error(500, "Can't write file '$fileNameOutput'!");
}
}
$src = $this->yellow->config->get("serverBase").$this->yellow->config->get("imageThumbnailLocation").$fileNameThumb;
$src = $this->yellow->system->get("serverBase").$this->yellow->system->get("imageThumbnailLocation").$fileNameThumb;
list($width, $height) = $this->yellow->toolbox->detectImageInformation($fileNameOutput);
}
return array($src, $width, $height);

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,10 +1,11 @@
<?php
// Install plugin, https://github.com/datenstrom/yellow
// Install extension, https://github.com/datenstrom/yellow
// Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se
// This file may be used and distributed under the terms of the public license.
class YellowInstall {
const VERSION = "0.8.1";
const VERSION = "0.8.2";
const TYPE = "feature";
const PRIORITY = "1";
public $yellow; //access to API
@ -30,11 +31,11 @@ class YellowInstall {
return $this->processCommandInstall();
}
// Process command to set up website
// Process command to install website
public function processCommandInstall() {
$statusCode = $this->updateLanguage();
if ($statusCode==200) $statusCode = $this->updateConfig($this->getConfigData());
if ($statusCode==200) $statusCode = $this->removeInstall();
$statusCode = $this->updateLanguages();
if ($statusCode==200) $statusCode = $this->updateSettings($this->getSystemData());
if ($statusCode==200) $statusCode = $this->removeFiles();
if ($statusCode==200) {
$statusCode = 0;
} else {
@ -44,28 +45,28 @@ class YellowInstall {
return $statusCode;
}
// Process request to set up website
// Process request to install website
public function processRequestInstall($scheme, $address, $base, $location, $fileName) {
$statusCode = 0;
$name = trim(preg_replace("/[^\pL\d\-\. ]/u", "-", $_REQUEST["name"]));
$email = trim($_REQUEST["email"]);
$password = trim($_REQUEST["password"]);
$language = trim($_REQUEST["language"]);
$feature = trim($_REQUEST["feature"]);
$extension = trim($_REQUEST["extension"]);
$status = trim($_REQUEST["status"]);
$this->yellow->pages->pages["root/"] = array();
$this->yellow->content->pages["root/"] = array();
$this->yellow->page = new YellowPage($this->yellow);
$statusCode = $this->updateLanguage();
$statusCode = $this->updateLanguages();
$this->yellow->page->setRequestInformation($scheme, $address, $base, $location, $fileName);
$this->yellow->page->parseData($this->getRawDataInstall(), false, $statusCode, $this->yellow->page->get("pageError"));
$this->yellow->page->safeMode = false;
if ($status=="install") $status = $this->updateUser($email, $password, $name, $language)==200 ? "ok" : "error";
if ($status=="ok") $status = $this->updateFeature($feature)==200 ? "ok" : "error";
if ($status=="ok") $status = $this->updateExtension($extension)==200 ? "ok" : "error";
if ($status=="ok") $status = $this->updateContent($language, "Home", "/")==200 ? "ok" : "error";
if ($status=="ok") $status = $this->updateContent($language, "About", "/about/")==200 ? "ok" : "error";
if ($status=="ok") $status = $this->updateContent($language, "Footer", "/shared/footer")==200 ? "ok" : "error";
if ($status=="ok") $status = $this->updateConfig($this->getConfigData()) ? "ok" : "error";
if ($status=="ok") $status = $this->removeInstall() ? "done" : "error";
if ($status=="ok") $status = $this->updateSettings($this->getSystemData()) ? "ok" : "error";
if ($status=="ok") $status = $this->removeFiles() ? "done" : "error";
if ($status=="done") {
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
$statusCode = $this->yellow->sendStatus(303, $location);
@ -75,48 +76,51 @@ class YellowInstall {
return $statusCode;
}
// Update language
public function updateLanguage() {
// Update languages
public function updateLanguages() {
$statusCode = 200;
$path = $this->yellow->config->get("pluginDir")."install-language.zip";
if (is_file($path) && $this->yellow->plugins->isExisting("update")) {
$path = $this->yellow->system->get("extensionDir")."install-languages.zip";
if (is_file($path) && $this->yellow->extensions->isExisting("update")) {
$zip = new ZipArchive();
if ($zip->open($path)===true) {
if (defined("DEBUG") && DEBUG>=2) echo "YellowInstall::updateLanguage file:$path<br/>\n";
$languages = $this->getLanguageData("en, de, fr");
if (defined("DEBUG") && DEBUG>=2) echo "YellowInstall::updateLanguages file:$path<br/>\n";
$languages = $this->detectBrowserLanguages("en, de, fr");
$languagesFound = array();
foreach ($languages as $language) $languagesFound[$language] = "";
if (preg_match("#^(.*\/).*?$#", $zip->getNameIndex(0), $matches)) $pathBase = $matches[1];
$fileData = $zip->getFromName($pathBase.$this->yellow->config->get("updateInformationFile"));
$fileData = $zip->getFromName($pathBase.$this->yellow->system->get("updateInformationFile"));
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if (!empty($matches[1]) && !empty($matches[2]) && strposu($matches[1], "/")) {
list($dummy, $entry) = explode("/", $matches[1], 2);
if (preg_match("/^language-(.*)\.txt$/", $entry, $tokens) && !is_null($languages[$tokens[1]])) {
$languages[$tokens[1]] = $entry;
$language = array_pop(explode(",", $matches[2]));
if (preg_match("/^(.*)\.php$/", basename($entry), $tokens) && in_array($language, $languages)) {
$languagesFound[$language] = $tokens[1];
}
}
}
$languages = array_slice(array_filter($languages, "strlen"), 0, 3);
$languagesFound = array_slice(array_filter($languagesFound, "strlen"), 0, 3);
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if (lcfirst($matches[1])=="plugin" || lcfirst($matches[1])=="theme") $software = $matches[2];
if (lcfirst($matches[1])=="extension") $extension = lcfirst($matches[2]);
if (lcfirst($matches[1])=="published") $modified = strtotime($matches[2]);
if (!empty($matches[1]) && !empty($matches[2]) && strposu($matches[1], "/")) {
list($dummy, $entry) = explode("/", $matches[1], 2);
list($fileName) = explode(",", $matches[2], 2);
$fileData = $zip->getFromName($pathBase.$entry);
if (preg_match("/^language.php$/", $entry)) {
$statusCode = $this->yellow->plugins->get("update")->updateSoftwareFile($fileName, $fileData,
$modified, 0, 0, "create,update", false, $software);
$fileData = $zip->getFromName($pathBase.basename($entry));
if (preg_match("/^(.*).php$/", basename($entry), $tokens) && in_array($tokens[1], $languagesFound)) {
$statusCode = $this->yellow->extensions->get("update")->updateExtensionFile($fileName, $fileData,
$modified, 0, 0, "create,update", false, $extension);
}
if (preg_match("/^language-(.*)\.txt$/", $entry, $tokens) && !is_null($languages[$tokens[1]])) {
$statusCode = $this->yellow->plugins->get("update")->updateSoftwareFile($fileName, $fileData,
$modified, 0, 0, "create,update", false, $software);
if (preg_match("/^(.*)-language\.txt$/", basename($entry), $tokens) && in_array($tokens[1], $languagesFound)) {
$statusCode = $this->yellow->extensions->get("update")->updateExtensionFile($fileName, $fileData,
$modified, 0, 0, "create,update", false, $extension);
}
}
}
$zip->close();
if ($statusCode==200) {
$this->yellow->text->load($this->yellow->config->get("pluginDir").$this->yellow->config->get("languageFile"), "");
$this->yellow->text->load($this->yellow->system->get("extensionDir").$this->yellow->system->get("languageFile"), "");
}
} else {
$statusCode = 500;
@ -129,23 +133,23 @@ class YellowInstall {
// Update user
public function updateUser($email, $password, $name, $language) {
$statusCode = 200;
if (!empty($email) && !empty($password) && $this->yellow->plugins->isExisting("edit")) {
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
$status = $this->yellow->plugins->get("edit")->users->save($fileNameUser, $email, $password, $name, $language) ? "ok" : "error";
if (!empty($email) && !empty($password) && $this->yellow->extensions->isExisting("edit")) {
$fileNameUser = $this->yellow->system->get("settingDir").$this->yellow->system->get("editUserFile");
$status = $this->yellow->extensions->get("edit")->users->save($fileNameUser, $email, $password, $name, $language) ? "ok" : "error";
if ($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
return $statusCode;
}
// Update feature
public function updateFeature($feature) {
// Update extension
public function updateExtension($extension) {
$statusCode = 200;
$path = $this->yellow->config->get("pluginDir");
if (!empty($feature) && $this->yellow->plugins->isExisting("update")) {
$path = $this->yellow->system->get("extensionDir");
if (!empty($extension) && $this->yellow->extensions->isExisting("update")) {
foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry) {
if (preg_match("/^install-(.*?)\./", basename($entry), $matches)) {
if (strtoloweru($matches[1])==strtoloweru($feature)) {
$statusCode = $this->yellow->plugins->get("update")->updateSoftwareArchive($entry);
if (strtoloweru($matches[1])==strtoloweru($extension)) {
$statusCode = $this->yellow->extensions->get("update")->updateExtensionArchive($entry);
break;
}
}
@ -174,22 +178,22 @@ class YellowInstall {
return $statusCode;
}
// Update config
public function updateConfig($config) {
// Update settings
public function updateSettings($settings) {
$statusCode = 200;
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
if (!$this->yellow->config->save($fileNameConfig, $config)) {
$fileName = $this->yellow->system->get("settingDir").$this->yellow->system->get("systemFile");
if (!$this->yellow->system->save($fileName, $settings)) {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't write file '$fileNameConfig'!");
$this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
}
return $statusCode;
}
// Remove install
public function removeInstall() {
// Remove files used by installation
public function removeFiles() {
$statusCode = 200;
if (function_exists("opcache_reset")) opcache_reset();
$path = $this->yellow->config->get("pluginDir");
$path = $this->yellow->system->get("extensionDir");
foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry) {
if (preg_match("/^install-(.*?)\./", basename($entry), $matches)) {
if (!$this->yellow->toolbox->deleteFile($entry)) {
@ -198,19 +202,19 @@ class YellowInstall {
}
}
}
$path = $this->yellow->config->get("pluginDir")."install.php";
$path = $this->yellow->system->get("extensionDir")."install.php";
if ($statusCode==200 && !$this->yellow->toolbox->deleteFile($path)) {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't delete file '$path'!");
}
if ($statusCode==200) unset($this->yellow->plugins->plugins["install"]);
if ($statusCode==200) unset($this->yellow->extensions->extensions["install"]);
return $statusCode;
}
// Check web server rewrite
public function checkServerRewrite($scheme, $address, $base, $location, $fileName) {
$curlHandle = curl_init();
$location = $this->yellow->config->get("assetLocation").$this->yellow->config->get("theme").".css";
$location = $this->yellow->system->get("resourceLocation").$this->yellow->lookup->normaliseName($this->yellow->system->get("theme")).".css";
$url = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
curl_setopt($curlHandle, CURLOPT_URL, $url);
curl_setopt($curlHandle, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; YellowCore/".YellowCore::VERSION).")";
@ -224,30 +228,30 @@ class YellowInstall {
// Check web server read/write access
public function checkServerAccess() {
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
return $this->yellow->config->save($fileNameConfig, array());
$fileName = $this->yellow->system->get("settingDir").$this->yellow->system->get("systemFile");
return $this->yellow->system->save($fileName, array());
}
// Return language data, detect browser languages
public function getLanguageData($languagesDefault) {
$data = array();
// Detect web browser languages
public function detectBrowserLanguages($languagesDefault) {
$languages = array();
if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {
foreach (preg_split("/\s*,\s*/", $_SERVER["HTTP_ACCEPT_LANGUAGE"]) as $string) {
list($language) = explode(";", $string);
if (!empty($language)) $data[$language] = "";
if (!empty($language)) array_push($languages, $language);
}
}
foreach (preg_split("/\s*,\s*/", $languagesDefault) as $language) {
if (!empty($language)) $data[$language] = "";
if (!empty($language)) array_push($languages, $language);
}
return $data;
return array_unique($languages);
}
// Return configuration data, detect server URL
public function getConfigData() {
// Return system data, detect server URL
public function getSystemData() {
$data = array();
foreach ($_REQUEST as $key=>$value) {
if (!$this->yellow->config->isExisting($key)) continue;
if (!$this->yellow->system->isExisting($key)) continue;
$data[$key] = trim($value);
}
$data["timezone"] = $this->yellow->toolbox->getTimezone();
@ -258,46 +262,42 @@ class YellowInstall {
// Return raw data for install page
public function getRawDataInstall() {
$language = $this->yellow->toolbox->detectBrowserLanguage($this->yellow->text->getLanguages(), $this->yellow->config->get("language"));
$fileName = strreplaceu("(.*)", "install", $this->yellow->config->get("configDir").$this->yellow->config->get("newFile"));
$rawData = $this->yellow->toolbox->readFile($fileName);
if (empty($rawData)) {
$this->yellow->text->setLanguage($language);
$rawData = "---\nTitle:".$this->yellow->text->get("installTitle")."\nLanguage:$language\nNavigation:navigation\n---\n";
$rawData .= "<form class=\"install-form\" action=\"".$this->yellow->page->getLocation(true)."\" method=\"post\">\n";
$rawData .= "<p><label for=\"name\">".$this->yellow->text->get("editSignupName")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"name\" id=\"name\" value=\"\"></p>\n";
$rawData .= "<p><label for=\"email\">".$this->yellow->text->get("editSignupEmail")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"email\" id=\"email\" value=\"\"></p>\n";
$rawData .= "<p><label for=\"password\">".$this->yellow->text->get("editSignupPassword")."</label><br /><input class=\"form-control\" type=\"password\" maxlength=\"64\" name=\"password\" id=\"password\" value=\"\"></p>\n";
if (count($this->yellow->text->getLanguages())>1) {
$rawData .= "<p>";
foreach ($this->yellow->text->getLanguages() as $language) {
$checked = $language==$this->yellow->text->language ? " checked=\"checked\"" : "";
$rawData .= "<label for=\"$language\"><input type=\"radio\" name=\"language\" id=\"$language\" value=\"$language\"$checked> ".$this->yellow->text->getTextHtml("languageDescription", $language)."</label><br />";
}
$rawData .= "</p>\n";
$language = $this->yellow->toolbox->detectBrowserLanguage($this->yellow->text->getLanguages(), $this->yellow->system->get("language"));
$this->yellow->text->setLanguage($language);
$rawData = "---\nTitle:".$this->yellow->text->get("installTitle")."\nLanguage:$language\nNavigation:navigation\n---\n";
$rawData .= "<form class=\"install-form\" action=\"".$this->yellow->page->getLocation(true)."\" method=\"post\">\n";
$rawData .= "<p><label for=\"name\">".$this->yellow->text->get("editSignupName")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"name\" id=\"name\" value=\"\"></p>\n";
$rawData .= "<p><label for=\"email\">".$this->yellow->text->get("editSignupEmail")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"email\" id=\"email\" value=\"\"></p>\n";
$rawData .= "<p><label for=\"password\">".$this->yellow->text->get("editSignupPassword")."</label><br /><input class=\"form-control\" type=\"password\" maxlength=\"64\" name=\"password\" id=\"password\" value=\"\"></p>\n";
if (count($this->yellow->text->getLanguages())>1) {
$rawData .= "<p>";
foreach ($this->yellow->text->getLanguages() as $language) {
$checked = $language==$this->yellow->text->language ? " checked=\"checked\"" : "";
$rawData .= "<label for=\"$language\"><input type=\"radio\" name=\"language\" id=\"$language\" value=\"$language\"$checked> ".$this->yellow->text->getTextHtml("languageDescription", $language)."</label><br />";
}
if (count($this->getFeaturesInstall())>1) {
$rawData .= "<p>".$this->yellow->text->get("installFeature")."<p>";
foreach ($this->getFeaturesInstall() as $feature) {
$checked = $feature=="website" ? " checked=\"checked\"" : "";
$rawData .= "<label for=\"$feature\"><input type=\"radio\" name=\"feature\" id=\"$feature\" value=\"$feature\"$checked> ".ucfirst($feature)."</label><br />";
}
$rawData .= "</p>\n";
}
$rawData .= "<input class=\"btn\" type=\"submit\" value=\"".$this->yellow->text->get("editOkButton")."\" />\n";
$rawData .= "<input type=\"hidden\" name=\"status\" value=\"install\" />\n";
$rawData .= "</form>\n";
$rawData .= "</p>\n";
}
if (count($this->getExtensionsInstall())>1) {
$rawData .= "<p>".$this->yellow->text->get("installExtension")."<p>";
foreach ($this->getExtensionsInstall() as $extension) {
$checked = $extension=="website" ? " checked=\"checked\"" : "";
$rawData .= "<label for=\"$extension\"><input type=\"radio\" name=\"extension\" id=\"$extension\" value=\"$extension\"$checked> ".ucfirst($extension)."</label><br />";
}
$rawData .= "</p>\n";
}
$rawData .= "<input class=\"btn\" type=\"submit\" value=\"".$this->yellow->text->get("editOkButton")."\" />\n";
$rawData .= "<input type=\"hidden\" name=\"status\" value=\"install\" />\n";
$rawData .= "</form>\n";
return $rawData;
}
// Return features for install page
public function getFeaturesInstall() {
$features = array("website");
$path = $this->yellow->config->get("pluginDir");
// Return extensions for install page
public function getExtensionsInstall() {
$extensions = array("website");
$path = $this->yellow->system->get("extensionDir");
foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false, false) as $entry) {
if (preg_match("/^install-(.*?)\./", $entry, $matches) && $matches[1]!="language") array_push($features, $matches[1]);
if (preg_match("/^install-(.*?)\./", $entry, $matches) && $matches[1]!="languages") array_push($extensions, $matches[1]);
}
return $features;
return $extensions;
}
}

View file

@ -1,10 +1,11 @@
<?php
// Markdown plugin, https://github.com/datenstrom/yellow-plugins/tree/master/markdown
// Markdown extension, https://github.com/datenstrom/yellow-extensions/tree/master/features/markdown
// Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se
// This file may be used and distributed under the terms of the public license.
class YellowMarkdown {
const VERSION = "0.8.1";
const VERSION = "0.8.2";
const TYPE = "feature";
public $yellow; //access to API
// Handle initialisation
@ -3732,7 +3733,7 @@ class MarkdownExtraParser extends MarkdownParser {
}
}
// Markdown extra parser extensions
// Yellow Markdown extra extension
// Copyright (c) 2013-2019 Datenstrom
class YellowMarkdownExtraParser extends MarkdownExtraParser {
@ -3840,8 +3841,8 @@ class YellowMarkdownExtraParser extends MarkdownExtraParser {
$width = $height = 0;
$src = $matches[3]=="" ? $matches[4] : $matches[3];
if (!preg_match("/^\w+:/", $src)) {
list($width, $height) = $this->yellow->toolbox->detectImageInformation($this->yellow->config->get("imageDir").$src);
$src = $this->yellow->config->get("serverBase").$this->yellow->config->get("imageLocation").$src;
list($width, $height) = $this->yellow->toolbox->detectImageInformation($this->yellow->system->get("imageDir").$src);
$src = $this->yellow->system->get("serverBase").$this->yellow->system->get("imageLocation").$src;
}
$alt = $matches[2];
$title = $matches[7]=="" ? $matches[2] : $matches[7];

View file

@ -1,10 +1,11 @@
<?php
// Update plugin, https://github.com/datenstrom/yellow-plugins/tree/master/update
// Update extension, https://github.com/datenstrom/yellow-extensions/tree/master/features/update
// Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se
// This file may be used and distributed under the terms of the public license.
class YellowUpdate {
const VERSION = "0.8.1";
const VERSION = "0.8.2";
const TYPE = "feature";
const PRIORITY = "2";
public $yellow; //access to API
public $updates; //number of updates
@ -12,81 +13,135 @@ class YellowUpdate {
// Handle initialisation
public function onLoad($yellow) {
$this->yellow = $yellow;
$this->yellow->config->setDefault("updatePluginsUrl", "https://github.com/datenstrom/yellow-plugins");
$this->yellow->config->setDefault("updateThemesUrl", "https://github.com/datenstrom/yellow-themes");
$this->yellow->config->setDefault("updateInformationFile", "update.ini");
$this->yellow->config->setDefault("updateVersionFile", "version.ini");
$this->yellow->config->setDefault("updateResourceFile", "resource.ini");
$this->yellow->system->setDefault("updateExtensionUrl", "https://github.com/datenstrom/yellow-extensions");
$this->yellow->system->setDefault("updateInformationFile", "update.ini");
$this->yellow->system->setDefault("updateVersionFile", "version.ini");
$this->yellow->system->setDefault("updateWaffleFile", "waffle.ini");
}
// Handle startup
public function onStartup($update) {
if ($update) { //TODO: remove later, converts old config
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
if ($this->yellow->config->isExisting("parserSafeMode")) {
$this->yellow->config->save($fileNameConfig, array("safeMode" => $this->yellow->config->get("parserSafeMode")));
}
if ($this->yellow->config->get("staticDir")=="cache/") {
$this->yellow->config->save($fileNameConfig, array("staticDir" => "public/"));
if ($update) { //TODO: remove later, converts old API in layouts
$fileNameError = $this->yellow->system->get("settingDir")."system-error.log";
if ($this->yellow->system->isExisting("templateDir")) {
$path = $this->yellow->system->get("layoutDir");
foreach ($this->yellow->toolbox->getDirectoryEntriesRecursive($path, "/^.*\.html$/", true, false) as $entry) {
$fileData = $fileDataNew = $this->yellow->toolbox->readFile($entry);
$fileDataNew = str_replace("\$yellow->", "\$this->yellow->", $fileDataNew);
$fileDataNew = str_replace("yellow->config->", "yellow->system->", $fileDataNew);
$fileDataNew = str_replace("yellow->pages->", "yellow->content->", $fileDataNew);
$fileDataNew = str_replace("yellow->files->", "yellow->media->", $fileDataNew);
$fileDataNew = str_replace("yellow->plugins->", "yellow->extensions->", $fileDataNew);
$fileDataNew = str_replace("yellow->themes->", "yellow->extensions->", $fileDataNew);
$fileDataNew = str_replace("yellow->snippet(", "yellow->layout(", $fileDataNew);
$fileDataNew = str_replace("yellow->getSnippetArgs(", "yellow->getLayoutArgs(", $fileDataNew);
$fileDataNew = str_replace("\"template\"", "\"layout\"", $fileDataNew);
$fileDataNew = str_replace("\"page template-\"", "\"page layout-\"", $fileDataNew);
if ($fileData!=$fileDataNew && !$this->yellow->toolbox->createFile($entry, $fileDataNew)) {
$fileDataError .= "ERROR writing file '$entry'!\n";
}
}
if (!empty($fileDataError)) $this->yellow->toolbox->createFile($fileNameError, $fileDataError);
}
}
if ($update) { //TODO: remove later, converts old robots file
$fileNameRobots = $this->yellow->config->get("configDir")."robots.txt";
$fileNameError = $this->yellow->config->get("configDir")."system-error.log";
if (is_file($fileNameRobots)) {
if (!$this->yellow->toolbox->renameFile($fileNameRobots, "./robots.txt")) {
$fileDataError .= "ERROR moving file '$fileNameRobots'!\n";
}
if (!empty($fileDataError)) {
$this->yellow->toolbox->createFile($fileNameError, $fileDataError);
if ($update) { //TODO: remove later, converts old website icon
$fileNameError = $this->yellow->system->get("settingDir")."system-error.log";
if ($this->yellow->system->isExisting("siteicon")) {
$theme = $this->yellow->system->get("theme");
$fileName = $this->yellow->system->get("resourceDir")."icon.png";
$fileNameNew = $this->yellow->system->get("resourceDir").$this->yellow->lookup->normaliseName($theme)."-icon.png";
if (is_file($fileName) && !$this->yellow->toolbox->renameFile($fileName, $fileNameNew)) {
$fileDataError .= "ERROR renaming file '$fileName'!\n";
}
if (!empty($fileDataError)) $this->yellow->toolbox->createFile($fileNameError, $fileDataError);
}
}
if ($update) { //TODO: remove later, converts old Markdown extension
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
$fileNameError = $this->yellow->config->get("configDir")."system-error.log";
if ($this->yellow->config->get("contentDefaultFile")=="page.txt") {
$config = array("contentDefaultFile" => "page.md", "contentExtension" => ".md",
"errorFile" => "page-error-(.*).md", "newFile" => "page-new-(.*).md");
$this->yellow->config->save($fileNameConfig, $config);
$path = $this->yellow->config->get("contentDir");
if ($update) { //TODO: remove later, converts old language files
$fileNameError = $this->yellow->system->get("settingDir")."system-error.log";
if ($this->yellow->system->isExisting("languageFile")) {
$path = $this->yellow->system->get("extensionDir");
foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.txt$/", true, false) as $entry) {
preg_match("/^language-(.*)\.txt$/", basename($entry), $matches);
$languageName = $this->getLanguageName($matches[1]);
if (!empty($languageName)) {
$entryNew = $path.$languageName."-language.txt";
if (!$this->yellow->toolbox->renameFile($entry, $entryNew)) {
$fileDataError .= "ERROR renaming file '$entry'!\n";
}
$fileNameNew = $path.$languageName.".php";
$fileDataNew = "<?php\n\nclass Yellow".ucfirst($languageName)." {\nconst VERSION = \"0.8.2\";\nconst TYPE = \"language\";\n}\n";
if (!$this->yellow->toolbox->createFile($fileNameNew, $fileDataNew)) {
$fileDataError .= "ERROR writing file '$fileNameNew'!\n";
}
}
}
$fileName = $this->yellow->system->get("extensionDir")."language.php";
if (is_file($fileName) && !$this->yellow->toolbox->deleteFile($fileName, $this->yellow->system->get("trashDir"))) {
$fileDataError .= "ERROR deleting file '$fileName'!\n";
}
if (!empty($fileDataError)) $this->yellow->toolbox->createFile($fileNameError, $fileDataError);
}
}
if ($update) { //TODO: remove later, converts old Markdown files
$fileNameError = $this->yellow->system->get("settingDir")."system-error.log";
if ($this->yellow->system->get("contentDefaultFile")=="page.txt") {
$settings = array("contentDefaultFile" => "page.md", "contentExtension" => ".md", "editNewFile" => "page-new-(.*).md");
$fileName = $this->yellow->system->get("settingDir").$this->yellow->system->get("systemFile");
if (!$this->yellow->system->save($fileName, $settings)) {
$fileDataError .= "ERROR writing file '$fileName'!\n";
}
$path = $this->yellow->system->get("contentDir");
foreach ($this->yellow->toolbox->getDirectoryEntriesRecursive($path, "/^.*\.txt$/", true, false) as $entry) {
if (!$this->yellow->toolbox->renameFile($entry, str_replace(".txt", ".md", $entry))) {
$fileDataError .= "ERROR renaming file '$entry'!\n";
}
}
$path = $this->yellow->config->get("configDir");
$path = $this->yellow->system->get("settingDir");
foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.txt$/", true, false) as $entry) {
if (!$this->yellow->toolbox->renameFile($entry, str_replace(".txt", ".md", $entry))) {
$fileDataError .= "ERROR renaming file '$entry!'\n";
}
}
if (!empty($fileDataError)) {
$this->yellow->toolbox->createFile($fileNameError, $fileDataError);
if (!empty($fileDataError)) $this->yellow->toolbox->createFile($fileNameError, $fileDataError);
$_GET["clean-url"] = "system-updated";
}
}
if ($update) { //TODO: remove later, converts old template setting
$fileNameError = $this->yellow->system->get("settingDir")."system-error.log";
if ($this->yellow->system->isExisting("template")) {
$path = $this->yellow->system->get("contentDir");
foreach ($this->yellow->toolbox->getDirectoryEntriesRecursive($path, "/^.*\.md$/", true, false) as $entry) {
$fileData = $fileDataNew = $this->yellow->toolbox->readFile($entry);
$fileDataNew = preg_replace("/Template:/i", "Layout:", $fileDataNew);
$fileDataNew = preg_replace("/TemplateNew:/i", "LayoutNew:", $fileDataNew);
if ($fileData!=$fileDataNew && !$this->yellow->toolbox->createFile($entry, $fileDataNew)) {
$fileDataError .= "ERROR writing file '$entry'!\n";
}
}
if (!empty($fileDataError)) $this->yellow->toolbox->createFile($fileNameError, $fileDataError);
$_GET["clean-url"] = "system-updated";
}
}
if ($update) { //TODO: remove later, updates shared pages
$fileNameError = $this->yellow->config->get("configDir")."system-error.log";
$pathConfig = $this->yellow->config->get("configDir");
$pathShared = $this->yellow->config->get("contentDir").$this->yellow->config->get("contentSharedDir");
if (count($this->yellow->toolbox->getDirectoryEntries($pathConfig, "/.*/", false, false))>3) {
$fileNameError = $this->yellow->system->get("settingDir")."system-error.log";
$pathSetting = $this->yellow->system->get("settingDir");
$pathShared = $this->yellow->system->get("contentDir").$this->yellow->system->get("contentSharedDir");
if (count($this->yellow->toolbox->getDirectoryEntries($pathSetting, "/.*/", false, false))>3) {
$regex = "/^page-error-(.*)\.md$/";
foreach ($this->yellow->toolbox->getDirectoryEntries($pathConfig, $regex, true, false) as $entry) {
if (!$this->yellow->toolbox->deleteFile($entry, $this->yellow->config->get("trashDir"))) {
foreach ($this->yellow->toolbox->getDirectoryEntries($pathSetting, $regex, true, false) as $entry) {
if (!$this->yellow->toolbox->deleteFile($entry, $this->yellow->system->get("trashDir"))) {
$fileDataError .= "ERROR deleting file '$entry'!\n";
}
}
$regex = "/^page-new-(.*)\.md$/";
foreach ($this->yellow->toolbox->getDirectoryEntries($pathConfig, $regex, true, false) as $entry) {
if (!$this->yellow->toolbox->renameFile($entry, str_replace($pathConfig, $pathShared, $entry), true)) {
foreach ($this->yellow->toolbox->getDirectoryEntries($pathSetting, $regex, true, false) as $entry) {
if (!$this->yellow->toolbox->renameFile($entry, str_replace($pathSetting, $pathShared, $entry), true)) {
$fileDataError .= "ERROR moving file '$entry'!\n";
}
}
$fileNameHeader = $pathShared."header.md";
if (!is_file($fileNameHeader) && $this->yellow->config->isExisting("tagline")) {
$fileDataHeader = "---\nTitle: Header\nStatus: hidden\n---\n".$this->yellow->config->get("tagline");
if (!is_file($fileNameHeader) && $this->yellow->system->isExisting("tagline")) {
$fileDataHeader = "---\nTitle: Header\nStatus: hidden\n---\n".$this->yellow->system->get("tagline");
if (!$this->yellow->toolbox->createFile($fileNameHeader, $fileDataHeader, true)) {
$fileDataError .= "ERROR writing file '$fileNameHeader'!\n";
}
@ -94,43 +149,42 @@ class YellowUpdate {
$fileNameFooter = $pathShared."footer.md";
if (!is_file($fileNameFooter)) {
$fileDataFooter = "---\nTitle: Footer\nStatus: hidden\n---\n";
$fileDataFooter .= $this->yellow->text->getText("InstallFooterText", $this->yellow->config->get("language"));
$fileDataFooter .= $this->yellow->text->getText("InstallFooterText", $this->yellow->system->get("language"));
if (!$this->yellow->toolbox->createFile($fileNameFooter, $fileDataFooter, true)) {
$fileDataError .= "ERROR writing file '$fileNameFooter'!\n";
}
}
$this->updateSoftwareMultiLanguage("shared-pages");
if (!empty($fileDataError)) {
$this->yellow->toolbox->createFile($fileNameError, $fileDataError);
}
$this->updateContentMultiLanguage("shared-pages");
if (!empty($fileDataError)) $this->yellow->toolbox->createFile($fileNameError, $fileDataError);
}
}
if ($update) {
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
$fileData = $this->yellow->toolbox->readFile($fileNameConfig);
$configDefaults = new YellowDataCollection();
$configDefaults->exchangeArray($this->yellow->config->configDefaults->getArrayCopy());
$fileName = $this->yellow->system->get("settingDir").$this->yellow->system->get("systemFile");
$fileData = $this->yellow->toolbox->readFile($fileName);
$fileDataNew = "";
$settingsDefaults = new YellowDataCollection();
$settingsDefaults->exchangeArray($this->yellow->system->settingsDefaults->getArrayCopy());
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if (!empty($matches[1]) && !is_null($configDefaults[$matches[1]])) unset($configDefaults[$matches[1]]);
if (!empty($matches[1]) && $matches[1][0]!="#" && is_null($this->yellow->config->configDefaults[$matches[1]])) {
if (!empty($matches[1]) && !is_null($settingsDefaults[$matches[1]])) unset($settingsDefaults[$matches[1]]);
if (!empty($matches[1]) && $matches[1][0]!="#" && is_null($this->yellow->system->settingsDefaults[$matches[1]])) {
$fileDataNew .= "# $line";
} else {
$fileDataNew .= $line;
}
}
unset($configDefaults["configFile"]);
foreach ($configDefaults as $key=>$value) {
unset($settingsDefaults["systemFile"]);
foreach ($settingsDefaults as $key=>$value) {
$fileDataNew .= ucfirst($key).": $value\n";
}
if ($fileData!=$fileDataNew) $this->yellow->toolbox->createFile($fileNameConfig, $fileDataNew);
if ($fileData!=$fileDataNew) $this->yellow->toolbox->createFile($fileName, $fileDataNew);
}
}
// Handle request
public function onRequest($scheme, $address, $base, $location, $fileName) {
$statusCode = 0;
if ($this->yellow->lookup->isContentFile($fileName) && $this->isSoftwarePending()) {
if ($this->yellow->lookup->isContentFile($fileName) && $this->isExtensionPending()) {
$statusCode = $this->processRequestPending($scheme, $address, $base, $location, $fileName);
}
return $statusCode;
@ -139,7 +193,7 @@ class YellowUpdate {
// Handle command
public function onCommand($args) {
$statusCode = 0;
if ($this->isSoftwarePending()) $statusCode = $this->processCommandPending();
if ($this->isExtensionPending()) $statusCode = $this->processCommandPending();
if ($statusCode==0) {
list($command) = $args;
switch ($command) {
@ -155,9 +209,9 @@ class YellowUpdate {
// Handle command help
public function onCommandHelp() {
$help .= "install [feature]\n";
$help .= "uninstall [feature]\n";
$help .= "update [feature]\n";
$help .= "install [extension]\n";
$help .= "uninstall [extension]\n";
$help .= "update [extension]\n";
return $help;
}
@ -166,8 +220,8 @@ class YellowUpdate {
$statusCode = 0;
list($command, $path) = $args;
if ($path=="all") {
$path = $this->yellow->config->get("pluginDir");
$regex = "/^.*\\".$this->yellow->config->get("downloadExtension")."$/";
$path = $this->yellow->system->get("extensionDir");
$regex = "/^.*\\".$this->yellow->system->get("downloadExtension")."$/";
foreach ($this->yellow->toolbox->getDirectoryEntries($path, $regex, false, false) as $entry) {
if (!$this->yellow->toolbox->deleteFile($entry)) $statusCode = 500;
}
@ -176,47 +230,47 @@ class YellowUpdate {
return $statusCode;
}
// Process command to install website features
// Process command to install extensions
public function processCommandInstall($args) {
list($command, $features) = $this->getCommandFeatures($args);
if (!empty($features)) {
list($command, $extensions) = $this->getExtensionInformation($args);
if (!empty($extensions)) {
$this->updates = 0;
list($statusCode, $data) = $this->getInstallInformation($features);
if ($statusCode==200) $statusCode = $this->downloadSoftware($data);
if ($statusCode==200) $statusCode = $this->updateSoftware();
list($statusCode, $data) = $this->getInstallInformation($extensions);
if ($statusCode==200) $statusCode = $this->downloadExtensions($data);
if ($statusCode==200) $statusCode = $this->updateExtensions();
if ($statusCode>=400) echo "ERROR installing files: ".$this->yellow->page->get("pageError")."\n";
echo "Yellow $command: Website ".($statusCode!=200 ? "not " : "")."updated";
echo ", $this->updates feature".($this->updates!=1 ? "s" : "")." installed\n";
echo ", $this->updates extension".($this->updates!=1 ? "s" : "")." installed\n";
} else {
$statusCode = $this->showSoftware();
$statusCode = $this->showExtensions();
}
return $statusCode;
}
// Process command to uninstall website features
// Process command to uninstall extensions
public function processCommandUninstall($args) {
list($command, $features) = $this->getCommandFeatures($args);
if (!empty($features)) {
list($command, $extensions) = $this->getExtensionInformation($args);
if (!empty($extensions)) {
$this->updates = 0;
list($statusCode, $data) = $this->getUninstallInformation($features, "YellowCore, YellowUpdate");
if ($statusCode==200) $statusCode = $this->removeSoftware($data);
list($statusCode, $data) = $this->getUninstallInformation($extensions, "core, command, update");
if ($statusCode==200) $statusCode = $this->removeExtensions($data);
if ($statusCode>=400) echo "ERROR uninstalling files: ".$this->yellow->page->get("pageError")."\n";
echo "Yellow $command: Website ".($statusCode!=200 ? "not " : "")."updated";
echo ", $this->updates feature".($this->updates!=1 ? "s" : "")." uninstalled\n";
echo ", $this->updates extension".($this->updates!=1 ? "s" : "")." uninstalled\n";
} else {
$statusCode = $this->showSoftware();
$statusCode = $this->showExtensions();
}
return $statusCode;
}
// Process command to update website
public function processCommandUpdate($args) {
list($command, $features, $force) = $this->getCommandFeatures($args);
list($statusCode, $data) = $this->getUpdateInformation($features, $force);
list($command, $extensions, $force) = $this->getExtensionInformation($args);
list($statusCode, $data) = $this->getUpdateInformation($extensions, $force);
if ($statusCode!=200 || !empty($data)) {
$this->updates = 0;
if ($statusCode==200) $statusCode = $this->downloadSoftware($data);
if ($statusCode==200) $statusCode = $this->updateSoftware($force);
if ($statusCode==200) $statusCode = $this->downloadExtensions($data);
if ($statusCode==200) $statusCode = $this->updateExtensions($force);
if ($statusCode>=400) echo "ERROR updating files: ".$this->yellow->page->get("pageError")."\n";
echo "Yellow $command: Website ".($statusCode!=200 ? "not " : "")."updated";
echo ", $this->updates update".($this->updates!=1 ? "s" : "")." installed\n";
@ -226,34 +280,47 @@ class YellowUpdate {
return $statusCode;
}
// Process command to update website with pending software
// Process command to update website with pending extension
public function processCommandPending() {
$statusCode = $this->updateSoftware();
$statusCode = $this->updateExtensions();
if ($statusCode!=200) echo "ERROR updating files: ".$this->yellow->page->get("pageError")."\n";
echo "Your website has ".($statusCode!=200 ? "not " : "")."been updated: Please run command again\n";
return $statusCode;
}
// Process request to update website with pending software
// Process request to update website with pending extension
public function processRequestPending($scheme, $address, $base, $location, $fileName) {
$statusCode = $this->updateSoftware();
$statusCode = $this->updateExtensions();
if ($statusCode==200) {
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
$statusCode = $this->yellow->sendStatus(303, $location);
}
return $statusCode;
}
// Return extension information
public function getExtensionInformation($args) {
$command = array_shift($args);
$extensions = array_unique(array_filter($args, "strlen"));
foreach ($extensions as $key=>$value) {
if ($value=="force") {
$force = true;
unset($extensions[$key]);
}
}
return array($command, $extensions, $force);
}
// Return install information
public function getInstallInformation($features) {
public function getInstallInformation($extensions) {
$data = array();
list($statusCodeCurrent, $dataCurrent) = $this->getSoftwareVersion();
list($statusCodeLatest, $dataLatest) = $this->getSoftwareVersion(true, true);
list($statusCodeCurrent, $dataCurrent) = $this->getExtensionsVersion();
list($statusCodeLatest, $dataLatest) = $this->getExtensionsVersion(true, true);
$statusCode = max($statusCodeCurrent, $statusCodeLatest);
foreach ($features as $feature) {
foreach ($extensions as $extension) {
$found = false;
foreach ($dataLatest as $key=>$value) {
if (strtoloweru($key)==strtoloweru($feature)) {
if (strtoloweru($key)==strtoloweru($extension)) {
$data[$key] = $dataLatest[$key];
$found = true;
break;
@ -261,34 +328,34 @@ class YellowUpdate {
}
if (!$found) {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't find feature '$feature'!");
$this->yellow->page->error($statusCode, "Can't find extension '$extension'!");
}
}
return array($statusCode, $data);
}
// Return uninstall information
public function getUninstallInformation($features, $featuresProtected) {
public function getUninstallInformation($extensions, $extensionsProtected) {
$data = array();
list($statusCodeCurrent, $dataCurrent) = $this->getSoftwareVersion();
list($statusCodeLatest, $dataLatest) = $this->getSoftwareVersion(true, true);
list($statusCodeFiles, $dataFiles) = $this->getSoftwareFiles();
$statusCode = max($statusCodeCurrent, $statusCodeLatest, $statusCodeFiles);
foreach ($features as $feature) {
list($statusCodeCurrent, $dataCurrent) = $this->getExtensionsVersion();
list($statusCodeLatest, $dataLatest) = $this->getExtensionsVersion(true, true);
list($statusCodeRelevant, $dataRelevant) = $this->getExtensionsRelevant();
$statusCode = max($statusCodeCurrent, $statusCodeLatest, $statusCodeRelevant);
foreach ($extensions as $extension) {
$found = false;
foreach ($dataCurrent as $key=>$value) {
if (strtoloweru($key)==strtoloweru($feature) && !is_null($dataLatest[$key]) && !is_null($dataFiles[$key])) {
$data[$key] = $dataFiles[$key];
if (strtoloweru($key)==strtoloweru($extension) && !is_null($dataLatest[$key]) && !is_null($dataRelevant[$key])) {
$data[$key] = $dataRelevant[$key];
$found = true;
break;
}
}
if (!$found) {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't find feature '$feature'!");
$this->yellow->page->error($statusCode, "Can't find extension '$extension'!");
}
}
$protected = preg_split("/\s*,\s*/", $featuresProtected);
$protected = preg_split("/\s*,\s*/", $extensionsProtected);
foreach ($data as $key=>$value) {
if (in_array($key, $protected)) unset($data[$key]);
}
@ -296,24 +363,24 @@ class YellowUpdate {
}
// Return update information
public function getUpdateInformation($features, $force) {
public function getUpdateInformation($extensions, $force) {
$data = array();
list($statusCodeCurrent, $dataCurrent) = $this->getSoftwareVersion();
list($statusCodeLatest, $dataLatest) = $this->getSoftwareVersion(true, true);
list($statusCodeModified, $dataModified) = $this->getSoftwareModified();
list($statusCodeCurrent, $dataCurrent) = $this->getExtensionsVersion();
list($statusCodeLatest, $dataLatest) = $this->getExtensionsVersion(true, true);
list($statusCodeModified, $dataModified) = $this->getExtensionsModified();
$statusCode = max($statusCodeCurrent, $statusCodeLatest, $statusCodeModified);
if (empty($features)) {
if (empty($extensions)) {
foreach ($dataCurrent as $key=>$value) {
list($version) = explode(",", $dataLatest[$key]);
if (strnatcasecmp($dataCurrent[$key], $version)<0) $data[$key] = $dataLatest[$key];
if (!is_null($dataModified[$key]) && !empty($version) && $force) $data[$key] = $dataLatest[$key];
}
} else {
foreach ($features as $feature) {
foreach ($extensions as $extension) {
$found = false;
foreach ($dataCurrent as $key=>$value) {
list($version) = explode(",", $dataLatest[$key]);
if (strtoloweru($key)==strtoloweru($feature) && !empty($version)) {
if (strtoloweru($key)==strtoloweru($extension) && !empty($version)) {
$data[$key] = $dataLatest[$key];
$dataModified = array_intersect_key($dataModified, $data);
$found = true;
@ -322,7 +389,7 @@ class YellowUpdate {
}
if (!$found) {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't find feature '$feature'!");
$this->yellow->page->error($statusCode, "Can't find extension '$extension'!");
}
}
}
@ -330,35 +397,35 @@ class YellowUpdate {
foreach (array_merge($dataModified, $data) as $key=>$value) {
list($version) = explode(",", $value);
if (is_null($dataModified[$key]) || $force) {
echo "$key $version\n";
echo ucfirst($key)." $version\n";
} else {
echo "$key $version has been modified - Force update\n";
echo ucfirst($key)." $version has been modified - Force update\n";
}
}
}
return array($statusCode, $data);
}
// Show software
public function showSoftware() {
list($statusCode, $dataLatest) = $this->getSoftwareVersion(true, true);
// Show extensions
public function showExtensions() {
list($statusCode, $dataLatest) = $this->getExtensionsVersion(true, true);
foreach ($dataLatest as $key=>$value) {
list($version, $url, $description) = explode(",", $value, 3);
echo "$key: $description\n";
echo ucfirst($key).": $description\n";
}
if ($statusCode!=200) echo "ERROR checking features: ".$this->yellow->page->get("pageError")."\n";
if ($statusCode!=200) echo "ERROR checking extensions: ".$this->yellow->page->get("pageError")."\n";
return $statusCode;
}
// Download software
public function downloadSoftware($data) {
// Download extensions
public function downloadExtensions($data) {
$statusCode = 200;
$path = $this->yellow->config->get("pluginDir");
$fileExtension = $this->yellow->config->get("downloadExtension");
$path = $this->yellow->system->get("extensionDir");
$fileExtension = $this->yellow->system->get("downloadExtension");
foreach ($data as $key=>$value) {
$fileName = $path.$this->yellow->lookup->normaliseName($key, true, false, true).".zip";
list($version, $url) = explode(",", $value);
list($statusCode, $fileData) = $this->getSoftwareFile($url);
list($statusCode, $fileData) = $this->getExtensionFile($url);
if (empty($fileData) || !$this->yellow->toolbox->createFile($fileName.$fileExtension, $fileData)) {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
@ -377,21 +444,13 @@ class YellowUpdate {
return $statusCode;
}
// Update software
public function updateSoftware($force = false) {
// Update extensions
public function updateExtensions($force = false) {
$statusCode = 200;
if (function_exists("opcache_reset")) opcache_reset();
$path = $this->yellow->config->get("pluginDir");
$path = $this->yellow->system->get("extensionDir");
foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry) {
$statusCode = max($statusCode, $this->updateSoftwareArchive($entry, $force));
if (!$this->yellow->toolbox->deleteFile($entry)) {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't delete file '$entry'!");
}
}
$path = $this->yellow->config->get("themeDir");
foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry) {
$statusCode = max($statusCode, $this->updateSoftwareArchive($entry, $force));
$statusCode = max($statusCode, $this->updateExtensionArchive($entry, $force));
if (!$this->yellow->toolbox->deleteFile($entry)) {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't delete file '$entry'!");
@ -400,20 +459,18 @@ class YellowUpdate {
return $statusCode;
}
// Update software from archive
public function updateSoftwareArchive($path, $force = false) {
// Update extension from archive
public function updateExtensionArchive($path, $force = false) {
$statusCode = 200;
$zip = new ZipArchive();
if ($zip->open($path)===true) {
if (defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::updateSoftwareArchive file:$path<br/>\n";
if (defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::updateExtensionArchive file:$path<br/>\n";
if (preg_match("#^(.*\/).*?$#", $zip->getNameIndex(0), $matches)) $pathBase = $matches[1];
$fileData = $zip->getFromName($pathBase.$this->yellow->config->get("updateInformationFile"));
$fileData = $zip->getFromName($pathBase.$this->yellow->system->get("updateInformationFile"));
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if (!empty($matches[1]) && !empty($matches[2])) {
list($dummy, $entry) = explode("/", $matches[1], 2);
list($fileName) = explode(",", $matches[2], 2);
if ($dummy[0]!="Y") $fileName = $matches[1]; //TODO: remove later, converts old file format
if (is_file($fileName)) {
$lastPublished = filemtime($fileName);
break;
@ -422,24 +479,22 @@ class YellowUpdate {
}
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if (lcfirst($matches[1])=="plugin" || lcfirst($matches[1])=="theme") $software = $matches[2];
if (lcfirst($matches[1])=="extension") $extension = lcfirst($matches[2]);
if (lcfirst($matches[1])=="plugin") $extension = lcfirst(substru($matches[2], 6)); //TODO: remove later, for backwards compatibility
if (lcfirst($matches[1])=="theme") $extension = lcfirst(substru($matches[2], 11)); //TODO: remove later, for backwards compatibility
if (lcfirst($matches[1])=="published") $modified = strtotime($matches[2]);
if (!empty($matches[1]) && !empty($matches[2]) && strposu($matches[1], "/")) {
list($dummy, $entry) = explode("/", $matches[1], 2);
list($fileName, $flags) = explode(",", $matches[2], 2);
if ($dummy[0]!="Y") { //TODO: remove later, converts old file format
list($entry, $flags) = explode(",", $matches[2], 2);
$fileName = $matches[1];
}
$fileData = $zip->getFromName($pathBase.$entry);
$fileData = $zip->getFromName($pathBase.basename($entry));
$lastModified = $this->yellow->toolbox->getFileModified($fileName);
$statusCode = $this->updateSoftwareFile($fileName, $fileData, $modified, $lastModified, $lastPublished, $flags, $force, $software);
$statusCode = $this->updateExtensionFile($fileName, $fileData, $modified, $lastModified, $lastPublished, $flags, $force, $extension);
if ($statusCode!=200) break;
}
}
$zip->close();
if ($statusCode==200) $statusCode = $this->updateSoftwareMultiLanguage($software);
if ($statusCode==200) $statusCode = $this->updateSoftwareNotification($software);
if ($statusCode==200) $statusCode = $this->updateContentMultiLanguage($extension);
if ($statusCode==200) $statusCode = $this->updateStartupNotification($extension);
++$this->updates;
} else {
$statusCode = 500;
@ -448,17 +503,17 @@ class YellowUpdate {
return $statusCode;
}
// Update software file
public function updateSoftwareFile($fileName, $fileData, $modified, $lastModified, $lastPublished, $flags, $force, $software) {
// Update extension from file
public function updateExtensionFile($fileName, $fileData, $modified, $lastModified, $lastPublished, $flags, $force, $extension) {
$statusCode = 200;
$fileName = $this->yellow->toolbox->normaliseTokens($fileName);
if ($this->yellow->lookup->isValidFile($fileName) && !empty($software)) {
if ($this->yellow->lookup->isValidFile($fileName) && !empty($extension)) {
$create = $update = $delete = false;
if (preg_match("/create/i", $flags) && !is_file($fileName) && !empty($fileData)) $create = true;
if (preg_match("/update/i", $flags) && is_file($fileName) && !empty($fileData)) $update = true;
if (preg_match("/delete/i", $flags) && is_file($fileName)) $delete = true;
if (preg_match("/careful/i", $flags) && is_file($fileName) && $lastModified!=$lastPublished && !$force) $update = false;
if (preg_match("/optional/i", $flags) && $this->isSoftwareExisting($software)) $create = $update = $delete = false;
if (preg_match("/optional/i", $flags) && $this->yellow->extensions->isExisting($extension)) $create = $update = $delete = false;
if ($create) {
if (!$this->yellow->toolbox->createFile($fileName, $fileData, true) ||
!$this->yellow->toolbox->modifyFile($fileName, $modified)) {
@ -467,7 +522,7 @@ class YellowUpdate {
}
}
if ($update) {
if (!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->config->get("trashDir")) ||
if (!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->system->get("trashDir")) ||
!$this->yellow->toolbox->createFile($fileName, $fileData) ||
!$this->yellow->toolbox->modifyFile($fileName, $modified)) {
$statusCode = 500;
@ -475,7 +530,7 @@ class YellowUpdate {
}
}
if ($delete) {
if (!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->config->get("trashDir"))) {
if (!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->system->get("trashDir"))) {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't delete file '$fileName'!");
}
@ -483,19 +538,19 @@ class YellowUpdate {
if (defined("DEBUG") && DEBUG>=2) {
$debug = "action:".($create ? "create" : "").($update ? "update" : "").($delete ? "delete" : "");
if (!$create && !$update && !$delete) $debug = "action:none";
echo "YellowUpdate::updateSoftwareFile file:$fileName $debug<br/>\n";
echo "YellowUpdate::updateExtensionFile file:$fileName $debug<br/>\n";
}
}
return $statusCode;
}
// Update software for multiple languages
public function updateSoftwareMultiLanguage($software) {
// Update content for multi language mode
public function updateContentMultiLanguage($extension) {
$statusCode = 200;
if ($this->yellow->config->get("multiLanguageMode") && !$this->isSoftwareExisting($software)) {
if ($this->yellow->system->get("multiLanguageMode") && !$this->yellow->extensions->isExisting($extension)) {
$pathsSource = $pathsTarget = array();
$pathBase = $this->yellow->config->get("contentDir");
$fileExtension = $this->yellow->config->get("contentExtension");
$pathBase = $this->yellow->system->get("contentDir");
$fileExtension = $this->yellow->system->get("contentExtension");
$fileRegex = "/^.*\\".$fileExtension."$/";
foreach ($this->yellow->toolbox->getDirectoryEntries($pathBase, "/.*/", true, true) as $entry) {
if (count($this->yellow->toolbox->getDirectoryEntries($entry, $fileRegex, false, false))) {
@ -518,7 +573,7 @@ class YellowUpdate {
$this->yellow->page->error(500, "Can't write file '$fileNameTarget'!");
}
}
if (defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::updateSoftwareNew file:$fileNameTarget<br/>\n";
if (defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::updateContentMultiLanguage file:$fileNameTarget<br/>\n";
}
}
if (!$this->yellow->toolbox->deleteDirectory($pathSource)) {
@ -531,112 +586,115 @@ class YellowUpdate {
return $statusCode;
}
// Update software notification for next startup
public function updateSoftwareNotification($software) {
// Update notification for next startup
public function updateStartupNotification($extension) {
$statusCode = 200;
$startupUpdate = $this->yellow->config->get("startupUpdate");
if ($startupUpdate=="none") $startupUpdate = "YellowUpdate";
if ($software!="YellowUpdate") $startupUpdate .= ",$software";
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
if (!$this->yellow->config->save($fileNameConfig, array("startupUpdate" => $startupUpdate))) {
$startupUpdate = $this->yellow->system->get("startupUpdate");
if ($startupUpdate=="none") $startupUpdate = "update";
if ($extension!="update") $startupUpdate .= ",$extension";
$fileName = $this->yellow->system->get("settingDir").$this->yellow->system->get("systemFile");
if (!$this->yellow->system->save($fileName, array("startupUpdate" => $startupUpdate))) {
$statusCode = 500;
$this->yellow->page->error(500, "Can't write file '$fileNameConfig'!");
$this->yellow->page->error(500, "Can't write file '$fileName'!");
}
return $statusCode;
}
// Remove software
public function removeSoftware($data) {
// Remove extensions
public function removeExtensions($data) {
$statusCode = 200;
if (function_exists("opcache_reset")) opcache_reset();
foreach ($data as $key=>$value) {
foreach (preg_split("/\s*,\s*/", $value) as $fileName) {
$statusCode = max($statusCode, $this->removeSoftwareFile($fileName, $key));
$statusCode = max($statusCode, $this->removeExtensionsFile($fileName, $key));
}
++$this->updates;
}
if ($statusCode==200) $statusCode = $this->updateSoftwareNotification("YellowUpdate");
if ($statusCode==200) $statusCode = $this->updateStartupNotification("update");
return $statusCode;
}
// Remove software file
public function removeSoftwareFile($fileName, $software) {
// Remove extensions file
public function removeExtensionsFile($fileName, $extension) {
$statusCode = 200;
$fileName = $this->yellow->toolbox->normaliseTokens($fileName);
if ($this->yellow->lookup->isValidFile($fileName) && !empty($software)) {
if (!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->config->get("trashDir"))) {
if ($this->yellow->lookup->isValidFile($fileName) && !empty($extension)) {
if (!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->system->get("trashDir"))) {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't delete file '$fileName'!");
}
if (defined("DEBUG") && DEBUG>=2) {
echo "YellowUpdate::removeSoftwareFile file:$fileName action:delete<br/>\n";
echo "YellowUpdate::removeExtensionsFile file:$fileName action:delete<br/>\n";
}
}
return $statusCode;
}
// Return features from commandline arguments
public function getCommandFeatures($args) {
$command = array_shift($args);
$features = array_unique(array_filter($args, "strlen"));
foreach ($features as $key=>$value) {
if ($value=="force") {
$force = true;
unset($features[$key]);
}
}
return array($command, $features, $force);
}
// Return software version
public function getSoftwareVersion($latest = false, $rawFormat = false) {
// Return extensions version
public function getExtensionsVersion($latest = false, $rawFormat = false) {
$data = array();
if ($latest) {
$urlPlugins = $this->yellow->config->get("updatePluginsUrl")."/raw/master/".$this->yellow->config->get("updateVersionFile");
$urlThemes = $this->yellow->config->get("updateThemesUrl")."/raw/master/".$this->yellow->config->get("updateVersionFile");
list($statusCodePlugins, $fileDataPlugins) = $this->getSoftwareFile($urlPlugins);
list($statusCodeThemes, $fileDataThemes) = $this->getSoftwareFile($urlThemes);
$statusCode = max($statusCodePlugins, $statusCodeThemes);
$url = $this->yellow->system->get("updateExtensionUrl")."/raw/master/".$this->yellow->system->get("updateVersionFile");
list($statusCode, $fileData) = $this->getExtensionFile($url);
if ($statusCode==200) {
foreach ($this->yellow->toolbox->getTextLines($fileDataPlugins."\n".$fileDataThemes) as $line) {
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if (!empty($matches[1]) && !empty($matches[2])) {
$extension = lcfirst($matches[1]);
list($version) = explode(",", $matches[2]);
$data[$matches[1]] = $rawFormat ? $matches[2] : $version;
$data[$extension] = $rawFormat ? $matches[2] : $version;
}
}
}
} else {
$statusCode = 200;
$data = array_merge($this->yellow->plugins->getData(), $this->yellow->themes->getData());
$data = $this->yellow->extensions->getData();
}
return array($statusCode, $data);
}
// Return software modification
public function getSoftwareModified() {
// Return extensions relevant files
public function getExtensionsRelevant() {
$data = array();
$dataCurrent = array_merge($this->yellow->plugins->getData(), $this->yellow->themes->getData());
$urlPlugins = $this->yellow->config->get("updatePluginsUrl")."/raw/master/".$this->yellow->config->get("updateResourceFile");
$urlThemes = $this->yellow->config->get("updateThemesUrl")."/raw/master/".$this->yellow->config->get("updateResourceFile");
list($statusCodePlugins, $fileDataPlugins) = $this->getSoftwareFile($urlPlugins);
list($statusCodeThemes, $fileDataThemes) = $this->getSoftwareFile($urlThemes);
$statusCode = max($statusCodePlugins, $statusCodeThemes);
$url = $this->yellow->system->get("updateExtensionUrl")."/raw/master/".$this->yellow->system->get("updateWaffleFile");
list($statusCode, $fileData) = $this->getExtensionFile($url);
if ($statusCode==200) {
foreach ($this->yellow->toolbox->getTextLines($fileDataPlugins."\n".$fileDataThemes) as $line) {
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if (!empty($matches[1]) && !empty($matches[2])) {
list($softwareNew) = explode("/", $matches[1]);
list($extension) = explode("/", lcfirst($matches[1]));
list($fileName) = explode(",", $matches[2], 2);
if (!is_null($data[$extension])) $data[$extension] .= ",";
$data[$extension] .= $fileName;
}
}
}
return array($statusCode, $data);
}
// Return extensions modified files
public function getExtensionsModified() {
$data = array();
$dataCurrent = $this->yellow->extensions->getData();
$url = $this->yellow->system->get("updateExtensionUrl")."/raw/master/".$this->yellow->system->get("updateWaffleFile");
list($statusCode, $fileData) = $this->getExtensionFile($url);
if ($statusCode==200) {
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if (!empty($matches[1]) && !empty($matches[2])) {
list($extensionNew) = explode("/", lcfirst($matches[1]));
list($fileName, $flags) = explode(",", $matches[2], 2);
if ($software!=$softwareNew) {
$software = $softwareNew;
if ($extension!=$extensionNew) {
$extension = $extensionNew;
$lastPublished = $this->yellow->toolbox->getFileModified($fileName);
}
if (!is_null($dataCurrent[$software])) {
if (!is_null($dataCurrent[$extension])) {
$lastModified = $this->yellow->toolbox->getFileModified($fileName);
if (preg_match("/update/i", $flags) && preg_match("/careful/i", $flags) && $lastModified!=$lastPublished) {
$data[$software] = $dataCurrent[$software];
if (defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::getSoftwareModified detected file:$fileName<br/>\n";
$data[$extension] = $dataCurrent[$extension];
if (defined("DEBUG") && DEBUG>=2) {
echo "YellowUpdate::getExtensionsModified detected file:$fileName extension:$extension<br/>\n";
}
}
}
}
@ -645,30 +703,8 @@ class YellowUpdate {
return array($statusCode, $data);
}
// Return software files
public function getSoftwareFiles() {
$data = array();
$urlPlugins = $this->yellow->config->get("updatePluginsUrl")."/raw/master/".$this->yellow->config->get("updateResourceFile");
$urlThemes = $this->yellow->config->get("updateThemesUrl")."/raw/master/".$this->yellow->config->get("updateResourceFile");
list($statusCodePlugins, $fileDataPlugins) = $this->getSoftwareFile($urlPlugins);
list($statusCodeThemes, $fileDataThemes) = $this->getSoftwareFile($urlThemes);
$statusCode = max($statusCodePlugins, $statusCodeThemes);
if ($statusCode==200) {
foreach ($this->yellow->toolbox->getTextLines($fileDataPlugins."\n".$fileDataThemes) as $line) {
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if (!empty($matches[1]) && !empty($matches[2])) {
list($software) = explode("/", $matches[1]);
list($fileName) = explode(",", $matches[2], 2);
if (!is_null($data[$software])) $data[$software] .= ",";
$data[$software] .= $fileName;
}
}
}
return array($statusCode, $data);
}
// Return software file
public function getSoftwareFile($url) {
// Return extension file
public function getExtensionFile($url) {
$urlRequest = $url;
if (preg_match("#^https://github.com/(.+)/raw/(.+)$#", $url, $matches)) $urlRequest = "https://raw.githubusercontent.com/".$matches[1]."/".$matches[2];
$curlHandle = curl_init();
@ -689,22 +725,26 @@ class YellowUpdate {
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't download file '$url'!");
}
if (defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::getSoftwareFile status:$statusCode url:$url<br/>\n";
if (defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::getExtensionFile status:$statusCode url:$url<br/>\n";
return array($statusCode, $fileData);
}
// Check if software pending
public function isSoftwarePending() {
$path = $this->yellow->config->get("pluginDir");
$foundPlugins = count($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", false, false))>0;
$path = $this->yellow->config->get("themeDir");
$foundThemes = count($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", false, false))>0;
return $foundPlugins || $foundThemes;
// Return human readable language name, TODO: remove later, for backwards compatibility
public function getLanguageName($language) {
$languageName = "";
$languageNames = array("bn" => "bengali", "cs" => "czech", "da" => "danish", "de" => "german",
"en" => "english", "es" => "spanish", "fr" => "french", "hu" => "hungarian", "id" => "indonesian",
"it" => "italian", "ja" => "japanese", "ko" => "korean", "nl" => "dutch", "pl" => "polish",
"pt" => "portuguese", "ru" => "russian", "sk" => "slovenian", "sv" => "swedish", "zh-CN" => "chinese");
if (array_key_exists($language, $languageNames)) {
$languageName = $languageNames[$language];
}
return $languageName;
}
// Check if software exists
public function isSoftwareExisting($software) {
$data = array_merge($this->yellow->plugins->getData(), $this->yellow->themes->getData());
return !is_null($data[$software]);
// Check if extension pending
public function isExtensionPending() {
$path = $this->yellow->system->get("extensionDir");
return count($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", false, false))>0;
}
}

View file

@ -0,0 +1,9 @@
<?php $this->yellow->layout("header") ?>
<div class="content">
<?php $this->yellow->layout("sidebar") ?>
<div class="main" role="main">
<h1><?php echo $this->yellow->page->getHtml("titleContent") ?></h1>
<?php echo $this->yellow->page->getContent() ?>
</div>
</div>
<?php $this->yellow->layout("footer") ?>

View file

@ -0,0 +1,8 @@
<?php $this->yellow->layout("header") ?>
<div class="content">
<div class="main" role="main">
<h1><?php echo $this->yellow->page->getHtml("titleContent") ?></h1>
<?php echo $this->yellow->page->getContent() ?>
</div>
</div>
<?php $this->yellow->layout("footer") ?>

View file

@ -0,0 +1,10 @@
<div class="footer" role="contentinfo">
<div class="siteinfo">
<?php if ($this->yellow->page->isPage("footer")) echo $this->yellow->page->getPage("footer")->getContent() ?>
<div class="siteinfo-banner"></div>
</div>
</div>
</div>
<?php echo $this->yellow->page->getExtra("footer") ?>
</body>
</html>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html><html lang="<?php echo $this->yellow->page->getHtml("language") ?>">
<head>
<title><?php echo $this->yellow->page->getHtml("titleHeader") ?></title>
<meta charset="utf-8" />
<meta name="description" content="<?php echo $this->yellow->page->getHtml("description") ?>" />
<meta name="keywords" content="<?php echo $this->yellow->page->getHtml("keywords") ?>" />
<meta name="author" content="<?php echo $this->yellow->page->getHtml("author") ?>" />
<meta name="generator" content="Datenstrom Yellow" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<?php echo $this->yellow->page->getExtra("header") ?>
</head>
<body>
<?php if ($page = $this->yellow->content->shared($this->yellow->page->location, false, $this->yellow->page->get("header"))) $this->yellow->page->setPage("header", $page) ?>
<?php if ($page = $this->yellow->content->shared($this->yellow->page->location, false, $this->yellow->page->get("footer"))) $this->yellow->page->setPage("footer", $page) ?>
<?php if ($page = $this->yellow->content->shared($this->yellow->page->location, false, $this->yellow->page->get("sidebar"))) $this->yellow->page->setPage("sidebar", $page) ?>
<?php if ($this->yellow->page->get("navigation")=="navigation-sidebar") $this->yellow->page->setPage("navigation-sidebar", $this->yellow->page->getParentTop(true)) ?>
<?php $this->yellow->page->set("pageClass", "page layout-".$this->yellow->page->get("layout")) ?>
<?php if (!$this->yellow->page->isError() && ($this->yellow->page->isPage("sidebar") || $this->yellow->page->isPage("navigation-sidebar"))) $this->yellow->page->set("pageClass", $this->yellow->page->get("pageClass")." with-sidebar") ?>
<div class="<?php echo $this->yellow->page->getHtml("pageClass") ?>">
<div class="header" role="banner">
<div class="sitename">
<h1><a href="<?php echo $this->yellow->page->getBase(true)."/" ?>"><i class="sitename-logo"></i><?php echo $this->yellow->page->getHtml("sitename") ?></a></h1>
<?php if ($this->yellow->page->isPage("header")) echo $this->yellow->page->getPage("header")->getContent() ?>
</div>
<div class="sitename-banner"></div>
<?php $this->yellow->layout($this->yellow->page->get("navigation")) ?>
</div>

View file

@ -1,5 +1,5 @@
<?php $pages = $yellow->pages->top() ?>
<?php $yellow->page->setLastModified($pages->getModified()) ?>
<?php $pages = $this->yellow->content->top() ?>
<?php $this->yellow->page->setLastModified($pages->getModified()) ?>
<div class="navigation" role="navigation">
<ul>
<?php foreach ($pages as $page): ?>

View file

@ -1,13 +1,13 @@
<?php list($name, $pages, $level) = $yellow->getSnippetArgs() ?>
<?php if (!$pages) $pages = $yellow->pages->top() ?>
<?php $yellow->page->setLastModified($pages->getModified()) ?>
<?php list($name, $pages, $level) = $this->yellow->getLayoutArgs() ?>
<?php if (!$pages) $pages = $this->yellow->content->top() ?>
<?php $this->yellow->page->setLastModified($pages->getModified()) ?>
<?php if (!$level): ?>
<div class="navigation-tree" role="navigation">
<?php endif ?>
<ul>
<?php foreach ($pages as $page): ?>
<?php $children = $page->getChildren() ?>
<li><a<?php echo $page->isActive() ? " class=\"active\" aria-current=\"page\"" : "" ?> href="<?php echo $page->getLocation(true) ?>"><?php echo $page->getHtml("titleNavigation") ?></a><?php if ($children->count()) { echo "\n"; $yellow->snippet($name, $children, $level+1); } ?></li>
<li><a<?php echo $page->isActive() ? " class=\"active\" aria-current=\"page\"" : "" ?> href="<?php echo $page->getLocation(true) ?>"><?php echo $page->getHtml("titleNavigation") ?></a><?php if ($children->count()) { echo "\n"; $this->yellow->layout($name, $children, $level+1); } ?></li>
<?php endforeach ?>
</ul>
<?php if (!$level): ?>

View file

@ -1,5 +1,5 @@
<?php $pages = $yellow->pages->top() ?>
<?php $yellow->page->setLastModified($pages->getModified()) ?>
<?php $pages = $this->yellow->content->top() ?>
<?php $this->yellow->page->setLastModified($pages->getModified()) ?>
<div class="navigation" role="navigation">
<ul>
<?php foreach ($pages as $page): ?>

View file

@ -1,11 +1,11 @@
<?php list($name, $pages) = $yellow->getSnippetArgs() ?>
<?php list($name, $pages) = $this->yellow->getLayoutArgs() ?>
<?php if ($pages->isPagination()): ?>
<div class="pagination" role="navigation">
<?php if ($pages->getPaginationPrevious()): ?>
<a class="previous" href="<?php echo $pages->getPaginationPrevious() ?>"><?php echo $yellow->text->getHtml("paginationPrevious") ?></a>
<a class="previous" href="<?php echo $pages->getPaginationPrevious() ?>"><?php echo $this->yellow->text->getHtml("paginationPrevious") ?></a>
<?php endif ?>
<?php if ($pages->getPaginationNext()): ?>
<a class="next" href="<?php echo $pages->getPaginationNext() ?>"><?php echo $yellow->text->getHtml("paginationNext") ?></a>
<a class="next" href="<?php echo $pages->getPaginationNext() ?>"><?php echo $this->yellow->text->getHtml("paginationNext") ?></a>
<?php endif ?>
</div>
<?php endif ?>

View file

@ -1,15 +1,15 @@
<?php if ($yellow->page->isPage("sidebar")): ?>
<?php if ($this->yellow->page->isPage("sidebar")): ?>
<div class="sidebar" role="complementary">
<?php $page = $yellow->page->getPage("sidebar") ?>
<?php $page->setPage("main", $yellow->page) ?>
<?php $page = $this->yellow->page->getPage("sidebar") ?>
<?php $page->setPage("main", $this->yellow->page) ?>
<?php echo $page->getContent() ?>
</div>
<?php elseif ($yellow->page->isPage("navigation-sidebar")): ?>
<?php elseif ($this->yellow->page->isPage("navigation-sidebar")): ?>
<div class="sidebar" role="complementary">
<div class="navigation-sidebar">
<?php $page = $yellow->page->getPage("navigation-sidebar") ?>
<?php $page = $this->yellow->page->getPage("navigation-sidebar") ?>
<?php $pages = $page->getChildren(!$page->isVisible()) ?>
<?php $yellow->page->setLastModified($pages->getModified()) ?>
<?php $this->yellow->page->setLastModified($pages->getModified()) ?>
<p><?php echo $page->getHtml("titleNavigation") ?></p>
<ul>
<?php foreach ($pages as $page): ?>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -1,4 +1,4 @@
/* Flatsite theme, https://github.com/datenstrom/yellow-themes/tree/master/flatsite */
/* Flatsite extension, https://github.com/datenstrom/yellow-extensions/tree/master/themes/flatsite */
/* Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se */
/* This file may be used and distributed under the terms of the public license. */
@ -438,19 +438,19 @@ a:hover {
/* Misc */
.template-default .content img.screenshot {
.layout-default .content img.screenshot {
margin: 0 -0.5em;
}
.template-language .content div.language {
.layout-language .content div.language {
font-size: 1.2em;
text-align: left;
width: 9em;
margin: 0 auto;
}
.template-language .content div.language p {
.layout-language .content div.language p {
margin: 1.5em 0em;
}
.template-language .content div.language img {
.layout-language .content div.language img {
vertical-align: middle;
margin-top: -5px;
margin-right: 1.5em;

View file

@ -1,11 +1,10 @@
# Datenstrom Yellow configuration
# Datenstrom Yellow system settings
Sitename: Datenstrom Yellow
Author: Datenstrom
Email: webmaster
Language: en
Timezone: UTC
Theme: flatsite
StaticUrl:
StaticDefaultFile: index.html
@ -15,19 +14,16 @@ CacheDir: cache/
MediaLocation: /media/
DownloadLocation: /media/downloads/
ImageLocation: /media/images/
PluginLocation: /media/plugins/
ThemeLocation: /media/themes/
AssetLocation: /media/themes/assets/
ExtensionLocation: /media/extensions/
ResourceLocation: /media/resources/
MediaDir: media/
DownloadDir: media/downloads/
ImageDir: media/images/
SystemDir: system/
ConfigDir: system/config/
PluginDir: system/plugins/
ThemeDir: system/themes/
AssetDir: system/themes/assets/
SnippetDir: system/themes/snippets/
TemplateDir: system/themes/templates/
ExtensionDir: system/extensions/
LayoutDir: system/layouts/
ResourceDir: system/resources/
SettingDir: system/settings/
TrashDir: system/trash/
ContentDir: content/
ContentRootDir: default/
@ -36,20 +32,17 @@ ContentSharedDir: shared/
ContentPagination: page
ContentDefaultFile: page.md
ContentExtension: .md
ConfigExtension: .ini
DownloadExtension: .download
TextFile: text.ini
NewFile: page-new-(.*).md
LanguageFile: language-(.*).txt
ServerUrl:
StartupUpdate: none
Template: default
Layout: default
Theme: flatsite
Parser: markdown
Navigation: navigation
Header: header
Footer: footer
Sidebar: sidebar
Siteicon: icon
Parser: markdown
StartupUpdate: none
MultiLanguageMode: 0
SafeMode: 0
BundleAndMinify: 1
@ -64,6 +57,7 @@ EditUserPasswordMinLength: 8
EditUserHashAlgorithm: bcrypt
EditUserHashCost: 10
EditUserHome: /
EditNewFile: page-new-(.*).md
EditLoginRestrictions: 0
EditLoginSessionTimeout: 2592000
EditBruteForceProtection: 25
@ -74,9 +68,7 @@ ImageUploadJpgQuality: 80
ImageThumbnailLocation: /media/thumbnails/
ImageThumbnailDir: media/thumbnails/
ImageThumbnailJpgQuality: 80
UpdatePluginsUrl: https://github.com/datenstrom/yellow-plugins
UpdateThemesUrl: https://github.com/datenstrom/yellow-themes
UpdateExtensionUrl: https://github.com/datenstrom/yellow-extensions
UpdateInformationFile: update.ini
UpdateVersionFile: version.ini
UpdateResourceFile: resource.ini
UpdateWaffleFile: waffle.ini

2
system/settings/text.ini Normal file
View file

@ -0,0 +1,2 @@
# Datenstrom Yellow text settings

View file

@ -1,8 +0,0 @@
<?php
// Flatsite theme, https://github.com/datenstrom/yellow-themes/tree/master/flatsite
// Copyright (c) 2013-2019 Datenstrom, https://datenstrom.se
// This file may be used and distributed under the terms of the public license.
class YellowThemeFlatsite {
const VERSION = "0.8.1";
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,11 +0,0 @@
<div class="footer" role="contentinfo">
<div class="siteinfo">
<?php if ($yellow->page->isPage("footer")) echo $yellow->page->getPage("footer")->getContent() ?>
</div>
<div class="siteinfo-banner"></div>
</div>
</div>
</div>
<?php echo $yellow->page->getExtra("footer") ?>
</body>
</html>

View file

@ -1,27 +0,0 @@
<!DOCTYPE html><html lang="<?php echo $yellow->page->getHtml("language") ?>">
<head>
<title><?php echo $yellow->page->getHtml("titleHeader") ?></title>
<meta charset="utf-8" />
<meta name="description" content="<?php echo $yellow->page->getHtml("description") ?>" />
<meta name="keywords" content="<?php echo $yellow->page->getHtml("keywords") ?>" />
<meta name="author" content="<?php echo $yellow->page->getHtml("author") ?>" />
<meta name="generator" content="Datenstrom Yellow" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<?php echo $yellow->page->getExtra("header") ?>
</head>
<body>
<?php if ($page = $yellow->pages->shared($yellow->page->location, false, $yellow->page->get("header"))) $yellow->page->setPage("header", $page) ?>
<?php if ($page = $yellow->pages->shared($yellow->page->location, false, $yellow->page->get("footer"))) $yellow->page->setPage("footer", $page) ?>
<?php if ($page = $yellow->pages->shared($yellow->page->location, false, $yellow->page->get("sidebar"))) $yellow->page->setPage("sidebar", $page) ?>
<?php if ($yellow->page->get("navigation")=="navigation-sidebar") $yellow->page->setPage("navigation-sidebar", $yellow->page->getParentTop(true)) ?>
<?php $yellow->page->set("pageClass", "page template-".$yellow->page->get("template")) ?>
<?php if (!$yellow->page->isError() && ($yellow->page->isPage("sidebar") || $yellow->page->isPage("navigation-sidebar"))) $yellow->page->set("pageClass", $yellow->page->get("pageClass")." with-sidebar") ?>
<div class="<?php echo $yellow->page->getHtml("pageClass") ?>">
<div class="header" role="banner">
<div class="sitename">
<h1><a href="<?php echo $yellow->page->getBase(true)."/" ?>"><i class="sitename-logo"></i><?php echo $yellow->page->getHtml("sitename") ?></a></h1>
<?php if ($yellow->page->isPage("header")) echo $yellow->page->getPage("header")->getContent() ?>
</div>
<div class="sitename-banner"></div>
<?php $yellow->snippet($yellow->page->get("navigation")) ?>
</div>

View file

@ -1,9 +0,0 @@
<?php $yellow->snippet("header") ?>
<div class="content">
<?php $yellow->snippet("sidebar") ?>
<div class="main" role="main">
<h1><?php echo $yellow->page->getHtml("titleContent") ?></h1>
<?php echo $yellow->page->getContent() ?>
</div>
</div>
<?php $yellow->snippet("footer") ?>

View file

@ -1,8 +0,0 @@
<?php $yellow->snippet("header") ?>
<div class="content">
<div class="main" role="main">
<h1><?php echo $yellow->page->getHtml("titleContent") ?></h1>
<?php echo $yellow->page->getContent() ?>
</div>
</div>
<?php $yellow->snippet("footer") ?>