mikuli.cz

:)
git clone https://git.sr.ht/~ashymad/mikuli.cz
Log | Files | Refs

commit 4cf437e623ddcb416750dfc6aa3f09f18e5bc72a
parent 0d8c3a17e82933d84629cb084d248e30531061a1
Author: markseu <mark2011@mayberg.se>
Date:   Mon, 27 Jun 2016 15:28:10 +0200

System update (refactoring)

Diffstat:
Msystem/config/config.ini | 1+
Msystem/plugins/commandline.php | 173++++++++++++++++++++++++++-----------------------------------------------------
Msystem/plugins/core.php | 39++++++++++++++++++++++++---------------
Asystem/plugins/update.php | 263+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msystem/plugins/webinterface.css | 2+-
Msystem/plugins/webinterface.js | 6+++---
Msystem/plugins/webinterface.php | 192++++++++++++++++++-------------------------------------------------------------
7 files changed, 391 insertions(+), 285 deletions(-)

diff --git a/system/config/config.ini b/system/config/config.ini @@ -51,6 +51,7 @@ WebinterfaceUserPasswordMinLength: 4 WebinterfaceUserHashAlgorithm: bcrypt WebinterfaceUserHashCost: 10 WebinterfaceUserStatus: active +WebinterfaceUserPending: none WebinterfaceUserHome: / WebinterfaceUserFile: user.ini WebinterfaceNewFile: page-new-(.*).txt diff --git a/system/plugins/commandline.php b/system/plugins/commandline.php @@ -5,7 +5,7 @@ // Command line plugin class YellowCommandline { - const Version = "0.6.11"; + const Version = "0.6.12"; var $yellow; //access to API var $files; //number of files var $errors; //number of errors @@ -16,27 +16,19 @@ class YellowCommandline function onLoad($yellow) { $this->yellow = $yellow; - $this->yellow->config->setDefault("commandlinePluginsUrl", "https://github.com/datenstrom/yellow-plugins"); - $this->yellow->config->setDefault("commandlineThemesUrl", "https://github.com/datenstrom/yellow-themes"); - $this->yellow->config->setDefault("commandlineVersionFile", "version.ini"); } // Handle command function onCommand($args) { - list($name, $command) = $args; + list($command) = $args; switch($command) { case "": $statusCode = $this->helpCommand(); break; - case "version": $statusCode = $this->versionCommand($args); break; case "build": $statusCode = $this->buildCommand($args); break; case "clean": $statusCode = $this->cleanCommand($args); break; - default: $statusCode = $this->pluginCommand($args); - } - if($statusCode == 0) - { - $statusCode = 400; - echo "Yellow $command: Command not found\n"; + case "version": $statusCode = $this->versionCommand($args); break; + default: $statusCode = 0; } return $statusCode; } @@ -44,9 +36,9 @@ class YellowCommandline // Handle command help function onCommandHelp() { - $help .= "version\n"; $help .= "build [DIRECTORY LOCATION]\n"; $help .= "clean [DIRECTORY LOCATION]\n"; + $help .= "version\n"; return $help; } @@ -58,35 +50,11 @@ class YellowCommandline return 200; } - // Show software version and updates - function versionCommand($args) - { - $statusCode = 0; - $serverSoftware = $this->yellow->toolbox->getServerSoftware(); - echo "Yellow ".YellowCore::Version.", PHP ".PHP_VERSION.", $serverSoftware\n"; - list($dummy, $command) = $args; - list($statusCode, $dataCurrent) = $this->getSoftwareVersion(); - list($statusCode, $dataLatest) = $this->getSoftwareVersion(false); - foreach($dataCurrent as $key=>$value) - { - if(strnatcasecmp($dataCurrent[$key], $dataLatest[$key]) >= 0) - { - echo "$key $value\n"; - } else { - echo "$key $value - Update available\n"; - ++$updates; - } - } - if($statusCode != 200) echo "ERROR checking updates: $dataLatest[error]\n"; - if($updates) echo "Yellow $command: $updates update".($updates==1 ? "":"s")." available\n"; - return $statusCode; - } - // Build static files function buildCommand($args) { $statusCode = 0; - list($dummy, $command, $path, $location) = $args; + list($command, $path, $location) = $args; if(empty($location) || $location[0]=='/') { if($this->checkStaticConfig()) @@ -95,13 +63,9 @@ class YellowCommandline } else { $statusCode = 500; $this->files = 0; $this->errors = 1; - if($this->yellow->config->get("installationMode")) - { - echo "ERROR building files: Please open your website in a web browser to detect server settings!\n"; - } else { - $fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile"); - echo "ERROR building files: Please configure ServerScheme, ServerName, ServerBase, ServerTime in file '$fileName'!\n"; - } + $fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile"); + echo "ERROR building files: Please configure ServerScheme, ServerName, ServerBase, ServerTime in file '$fileName'!\n"; + echo "ERROR building files: To see your web server configuration, open your website in a web browser!\n"; } echo "Yellow $command: $this->files file".($this->files!=1 ? 's' : ''); echo ", $this->errors error".($this->errors!=1 ? 's' : ''); @@ -116,7 +80,6 @@ class YellowCommandline // Build static files and additional locations function buildStatic($path, $location) { - $this->yellow->toolbox->timerStart($time); $path = rtrim(empty($path) ? $this->yellow->config->get("staticDir") : $path, '/'); $this->files = $this->errors = $statusCode = 0; $this->locationsArgs = $this->locationsArgsPagination = array(); @@ -156,8 +119,6 @@ class YellowCommandline } else { $statusCode = $this->buildStaticFile($path, $location); } - $this->yellow->toolbox->timerStop($time); - if(defined("DEBUG") && DEBUG>=1) echo "YellowCommandline::buildStatic time:$time ms\n"; return $statusCode; } @@ -261,7 +222,7 @@ class YellowCommandline function cleanCommand($args) { $statusCode = 0; - list($dummy, $command, $path, $location) = $args; + list($command, $path, $location) = $args; if(empty($location) || $location[0]=='/') { $statusCode = $this->cleanStatic($path, $location); @@ -280,7 +241,7 @@ class YellowCommandline $path = rtrim(empty($path) ? $this->yellow->config->get("staticDir") : $path, '/'); if(empty($location)) { - $statusCode = max($statusCode, $this->pluginCommand(array("all", "clean"))); + $statusCode = max($statusCode, $this->commandForward("all", "clean")); $statusCode = max($statusCode, $this->cleanStaticDirectory($path)); } else { $statusCode = $this->cleanStaticFile($path, $location); @@ -319,30 +280,53 @@ class YellowCommandline return $statusCode; } - // Forward plugin command - function pluginCommand($args) + // Forward command to other plugins + function commandForward($args) { $statusCode = 0; foreach($this->yellow->plugins->plugins as $key=>$value) { - if($key == "commandline") continue; - if(method_exists($value["obj"], "onCommand")) + if(method_exists($value["obj"], "onCommand") && $found) { - $statusCode = $value["obj"]->onCommand($args); + $statusCode = $value["obj"]->onCommand(func_get_args()); if($statusCode != 0) break; } + if($key == "commandline") $found = true; + } + return $statusCode; + } + + // Show software version and updates + function versionCommand($args) + { + $statusCode = 0; + $serverSoftware = $this->yellow->toolbox->getServerSoftware(); + echo "Yellow ".YellowCore::Version.", PHP ".PHP_VERSION.", $serverSoftware\n"; + list($command) = $args; + 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"; + ++$updates; + } } + if($statusCode != 200) echo "ERROR checking updates: $dataLatest[error]\n"; + if($updates) echo "Yellow $command: $updates update".($updates==1 ? "":"s")." available\n"; return $statusCode; } // Check static configuration function checkStaticConfig() { - $installationMode = $this->yellow->config->get("installationMode"); $serverScheme = $this->yellow->config->get("serverScheme"); $serverName = $this->yellow->config->get("serverName"); $serverBase = $this->yellow->config->get("serverBase"); - return !$installationMode && !empty($serverScheme) && !empty($serverName) && + return !empty($serverScheme) && !empty($serverName) && $this->yellow->lookup->isValidLocation($serverBase) && $serverBase!="/"; } @@ -434,66 +418,6 @@ class YellowCommandline return $locations; } - // Return software version - function getSoftwareVersion($current = true) - { - $data = array(); - if($current) - { - $statusCode = 200; - foreach($this->yellow->plugins->getData() as $key=>$value) $data[$key] = $value; - foreach($this->yellow->themes->getData() as $key=>$value) $data[$key] = $value; - } else { - list($statusCodePlugins, $dataPlugins) = $this->getSoftwareVersionFromUrl($this->yellow->config->get("commandlinePluginsUrl")); - list($statusCodeThemes, $dataThemes) = $this->getSoftwareVersionFromUrl($this->yellow->config->get("commandlineThemesUrl")); - $statusCode = max($statusCodePlugins, $statusCodeThemes); - $data = array_merge($dataPlugins, $dataThemes); - } - return array($statusCode, $data); - } - - // Return software version from URL - function getSoftwareVersionFromUrl($url) - { - $data = array(); - $urlVersion = $url; - if(preg_match("#^https://github.com/(.+)$#", $url, $matches)) - { - $urlVersion = "https://raw.githubusercontent.com/".$matches[1]."/master/".$this->yellow->config->get("commandlineVersionFile"); - } - if(extension_loaded("curl")) - { - $curlHandle = curl_init(); - curl_setopt($curlHandle, CURLOPT_URL, $urlVersion); - curl_setopt($curlHandle, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; YellowCore/".YellowCore::Version).")"; - curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 30); - $rawData = curl_exec($curlHandle); - $statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE); - curl_close($curlHandle); - if($statusCode == 200) - { - if(defined("DEBUG") && DEBUG>=2) echo "YellowCommandline::getSoftwareVersion location:$urlVersion\n"; - foreach($this->yellow->toolbox->getTextLines($rawData) as $line) - { - preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); - if(!empty($matches[1]) && !empty($matches[2])) - { - list($version, $url) = explode(',', $matches[2]); - $data[$matches[1]] = $version; - if(defined("DEBUG") && DEBUG>=3) echo "YellowCommandline::getSoftwareVersion $matches[1]:$version\n"; - } - } - } - if($statusCode == 0) $statusCode = 444; - $data["error"] = "$url - ".$this->yellow->toolbox->getHttpStatusFormatted($statusCode); - } else { - $statusCode = 500; - $data["error"] = "Plugin 'commandline' requires cURL library!"; - } - return array($statusCode, $data); - } - // Return command help function getCommandHelp() { @@ -512,6 +436,21 @@ class YellowCommandline uksort($data, strnatcasecmp); return $data; } + + // Return software version + 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; + foreach($this->yellow->plugins->getData() as $key=>$value) $data[$key] = $value; + foreach($this->yellow->themes->getData() as $key=>$value) $data[$key] = $value; + } + return array($statusCode, $data); + } } $yellow->plugins->register("commandline", "YellowCommandline", YellowCommandline::Version); diff --git a/system/plugins/core.php b/system/plugins/core.php @@ -89,21 +89,6 @@ class YellowCore $this->themes->load(); } - // Handle command - function command($name, $args = NULL) - { - $statusCode = 0; - if($this->plugins->isExisting($name)) - { - $plugin = $this->plugins->plugins[$name]; - if(method_exists($plugin["obj"], "onCommand")) $statusCode = $plugin["obj"]->onCommand(func_get_args()); - } else { - $statusCode = 500; - $this->page->error($statusCode, "Plugin '$name' does not exist!"); - } - return $statusCode; - } - // Handle request function request() { @@ -262,6 +247,30 @@ class YellowCore } } + // Handle command + function command($args = NULL) + { + $statusCode = 0; + $this->toolbox->timerStart($time); + foreach($this->plugins->plugins as $key=>$value) + { + if(method_exists($value["obj"], "onCommand")) + { + $statusCode = $value["obj"]->onCommand(func_get_args()); + if($statusCode != 0) break; + } + } + $this->toolbox->timerStop($time); + if(defined("DEBUG") && DEBUG>=1) echo "YellowCore::command time:$time ms<br/>\n"; + if($statusCode == 0) + { + $statusCode = 400; + list($name, $command) = func_get_args(); + echo "Yellow $command: Command not found\n"; + } + return $statusCode; + } + // Parse snippet function snippet($name, $args = NULL) { diff --git a/system/plugins/update.php b/system/plugins/update.php @@ -0,0 +1,262 @@ +<?php +// Copyright (c) 2013-2016 Datenstrom, http://datenstrom.se +// This file may be used and distributed under the terms of the public license. + +// Update plugin +class YellowUpdate +{ + const Version = "0.6.1"; + var $yellow; //access to API + + // Handle initialisation + 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("updateVersionFile", "version.ini"); + $this->yellow->config->setDefault("updateFile", "update.ini"); + } + + // Handle request + function onRequest($serverScheme, $serverName, $base, $location, $fileName) + { + $statusCode = 0; + if($this->isInstallation()) + { + $statusCode = $this->processRequestInstallation($serverScheme, $serverName, $base, $location, $fileName); + } else { + $statusCode = $this->processRequestUpdate($serverScheme, $serverName, $base, $location, $fileName); + } + return $statusCode; + } + + // Handle command + function onCommand($args) + { + list($command) = $args; + switch($command) + { + case "update": $statusCode = $this->updateCommand($args); break; + default: $statusCode = 0; + } + return $statusCode; + } + + // Handle command help + function onCommandHelp() + { + return "update [FEATURE]"; + } + + // Update plugins and themes + function updateCommand($args) + { + $statusCode = 0; + list($command, $feature) = $args; + list($statusCode, $dataCurrent) = $this->getSoftwareVersion(); + list($statusCode, $dataLatest) = $this->getSoftwareVersion(true); + foreach($dataCurrent as $key=>$value) + { + if(strnatcasecmp($dataCurrent[$key], $dataLatest[$key]) < 0) + { + if(empty($feature) || preg_match("/$feature/i", $key)) ++$updates; + } + } + if($statusCode != 200) echo "ERROR checking updates: $data[error]\n"; + if($updates) + { + echo "Yellow $command: $updates update".($updates==1 ? "":"s")." available\n"; + } else { + echo "Yellow $command: No updates available\n"; + + } + return $statusCode; + } + + // Process request to update software + function processRequestUpdate($serverScheme, $serverName, $base, $location, $fileName) + { + return 0; + } + + // Process request to install website + function processRequestInstallation($serverScheme, $serverName, $base, $location, $fileName) + { + $statusCode = 0; + if(!$this->yellow->isStaticFile($location, $fileName, false)) + { + $fileName = $this->yellow->lookup->findFileNew($fileName, + $this->yellow->config->get("webinterfaceNewFile"), $this->yellow->config->get("configDir"), "installation"); + $this->yellow->pages->pages["root/"] = array(); + $this->yellow->page = new YellowPage($this->yellow); + $this->yellow->page->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName); + $this->yellow->page->parseData($this->getRawDataInstallation($fileName, $this->yellow->getRequestLanguage()), false, 404); + $this->yellow->page->parserSafeMode = false; + $this->yellow->page->parseContent(); + $name = trim(preg_replace("/[^\pL\d\-\. ]/u", "-", $_REQUEST["name"])); + $email = trim($_REQUEST["email"]); + $password = trim($_REQUEST["password"]); + $language = trim($_REQUEST["language"]); + $status = trim($_REQUEST["status"]); + if($status == "install") + { + $status = "ok"; + $fileNameHome = $this->yellow->lookup->findFileFromLocation("/"); + $fileData = strreplaceu("\r\n", "\n", $this->yellow->toolbox->readFile($fileNameHome)); + if($fileData==$this->getRawDataHome("en") && $language!="en") + { + $status = $this->yellow->toolbox->createFile($fileNameHome, $this->getRawDataHome($language)) ? "ok" : "error"; + if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameHome'!"); + } + } + if($status == "ok") + { + if(!empty($email) && !empty($password) && $this->yellow->plugins->isExisting("webinterface")) + { + $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile"); + $status = $this->yellow->plugins->get("webinterface")->users->update($fileNameUser, $email, $password, $name, $language) ? "ok" : "error"; + if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); + } + } + if($status == "ok") + { + if($this->yellow->config->get("sitename") == "Yellow") $_REQUEST["sitename"] = $name; + $fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile"); + $status = $this->yellow->config->update($fileNameConfig, $this->getConfigData()) ? "done" : "error"; + if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameConfig'!"); + } + if($status == "done") + { + $statusCode = 303; + $location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location); + $this->yellow->sendStatus($statusCode, $location); + } else { + $statusCode = $this->yellow->sendPage(); + } + } + return $statusCode; + } + + // Return raw data for installation page + function getRawDataInstallation($fileName, $language) + { + $rawData = $this->yellow->toolbox->readFile($fileName); + if(empty($rawData)) + { + $this->yellow->text->setLanguage($language); + $rawData = "---\nTitle:".$this->yellow->text->get("webinterfaceInstallationTitle")."\nLanguage:$language\nNavigation:navigation\n---\n"; + $rawData .= "<form class=\"installation-form\" action=\"".$this->yellow->page->getLocation()."\" method=\"post\">\n"; + $rawData .= "<p><label for=\"name\">".$this->yellow->text->get("webinterfaceSignupName")."</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("webinterfaceSignupEmail")."</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("webinterfaceSignupPassword")."</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"; + } + $rawData .= "<input class=\"btn\" type=\"submit\" value=\"".$this->yellow->text->get("webinterfaceOkButton")."\" />\n"; + $rawData .= "<input type=\"hidden\" name=\"status\" value=\"install\" />\n"; + $rawData .= "</form>\n"; + } + return $rawData; + } + + // Return raw data for home page + function getRawDataHome($language) + { + $rawData = "---\nTitle: Home\n---\n".strreplaceu("\\n", "\n", $this->yellow->text->getText("webinterfaceInstallationHomePage", $language)); + return $rawData; + } + + // Return configuration data + function getConfigData() + { + $data = array(); + foreach($_REQUEST as $key=>$value) + { + if(!$this->yellow->config->isExisting($key)) continue; + $data[$key] = trim($value); + } + $data["# serverScheme"] = $this->yellow->toolbox->getServerScheme(); + $data["# serverName"] = $this->yellow->toolbox->getServerName(); + $data["# serverBase"] = $this->yellow->toolbox->getServerBase(); + $data["# serverTime"] = $this->yellow->toolbox->getServerTime(); + $data["installationMode"] = "0"; + return $data; + } + + // Return software version + function getSoftwareVersion($latest = false) + { + $data = array(); + if($latest) + { + list($statusCodePlugins, $dataPlugins) = $this->getSoftwareVersionFromUrl($this->yellow->config->get("updatePluginsUrl")); + list($statusCodeThemes, $dataThemes) = $this->getSoftwareVersionFromUrl($this->yellow->config->get("updateThemesUrl")); + $statusCode = max($statusCodePlugins, $statusCodeThemes); + $data = array_merge($dataPlugins, $dataThemes); + } else { + $statusCode = 200; + foreach($this->yellow->plugins->getData() as $key=>$value) $data[$key] = $value; + foreach($this->yellow->themes->getData() as $key=>$value) $data[$key] = $value; + } + return array($statusCode, $data); + } + + // Return software version from URL + function getSoftwareVersionFromUrl($url) + { + $data = array(); + $urlVersion = $url; + if(preg_match("#^https://github.com/(.+)$#", $url, $matches)) + { + $urlVersion = "https://raw.githubusercontent.com/".$matches[1]."/master/".$this->yellow->config->get("updateVersionFile"); + } + if(extension_loaded("curl")) + { + $curlHandle = curl_init(); + curl_setopt($curlHandle, CURLOPT_URL, $urlVersion); + curl_setopt($curlHandle, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; YellowCore/".YellowCore::Version).")"; + curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 30); + $rawData = curl_exec($curlHandle); + $statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE); + curl_close($curlHandle); + if($statusCode == 200) + { + if(defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::getSoftwareVersion location:$urlVersion\n"; + foreach($this->yellow->toolbox->getTextLines($rawData) as $line) + { + preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); + if(!empty($matches[1]) && !empty($matches[2])) + { + list($version, $url) = explode(',', $matches[2]); + $data[$matches[1]] = $version; + if(defined("DEBUG") && DEBUG>=3) echo "YellowUpdate::getSoftwareVersion $matches[1]:$version\n"; + } + } + } + if($statusCode == 0) $statusCode = 444; + $data["error"] = "$url - ".$this->yellow->toolbox->getHttpStatusFormatted($statusCode); + } else { + $statusCode = 500; + $data["error"] = "Plugin 'update' requires cURL library!"; + } + return array($statusCode, $data); + } + + // Return if installation is necessary + function isInstallation() + { + return PHP_SAPI!="cli" && $this->yellow->config->get("installationMode"); + } +} + +$yellow->plugins->register("update", "YellowUpdate", YellowUpdate::Version); +?> +\ No newline at end of file diff --git a/system/plugins/webinterface.css b/system/plugins/webinterface.css @@ -1,4 +1,4 @@ -/* Yellow web interface 0.6.8 */ +/* Yellow web interface 0.6.9 */ .yellow-bar { position:relative; overflow:hidden; height:2em; margin-bottom:10px; } .yellow-bar-left { display:block; float:left; } diff --git a/system/plugins/webinterface.js b/system/plugins/webinterface.js @@ -4,7 +4,7 @@ // Yellow API var yellow = { - version: "0.6.8", + version: "0.6.9", action: function(action) { yellow.webinterface.action(action, "none"); }, onLoad: function() { yellow.webinterface.loadInterface(); }, onClick: function(e) { yellow.webinterface.hidePanesOnClick(yellow.toolbox.getEventElement(e)); }, @@ -132,7 +132,7 @@ yellow.webinterface = "<form method=\"post\">"+ "<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-close\">x</a>"+ "<h1>"+this.getText("SignupTitle")+"</h1>"+ - "<div id=\"yellow-pane-signup-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "", paneStatus)+"</div>"+ + "<div id=\"yellow-pane-signup-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "webinterface", paneStatus)+"</div>"+ "<div id=\"yellow-pane-signup-fields\">"+ "<input type=\"hidden\" name=\"action\" value=\"signup\" />"+ "<p><label for=\"yellow-pane-signup-name\">"+this.getText("SignupName")+"</label><br /><input class=\"yellow-form-control\" name=\"name\" id=\"yellow-pane-signup-name\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("name"))+"\" /></p>"+ @@ -170,7 +170,7 @@ yellow.webinterface = "<form method=\"post\">"+ "<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-close\">x</a>"+ "<h1 id=\"yellow-pane-settings-title\">"+this.getText("SettingsTitle")+"</h1>"+ - "<div id=\"yellow-pane-settings-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "", paneStatus)+"</div>"+ + "<div id=\"yellow-pane-settings-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "webinterface", paneStatus)+"</div>"+ "<div id=\"yellow-pane-settings-fields\">"+ "<input type=\"hidden\" name=\"action\" value=\"settings\" />"+ "<p><label for=\"yellow-pane-settings-name\">"+this.getText("SignupName")+"</label><br /><input class=\"yellow-form-control\" name=\"name\" id=\"yellow-pane-settings-name\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("name"))+"\" /></p>"+ diff --git a/system/plugins/webinterface.php b/system/plugins/webinterface.php @@ -5,7 +5,7 @@ // Web interface plugin class YellowWebinterface { - const Version = "0.6.8"; + const Version = "0.6.9"; var $yellow; //access to API var $active; //web interface is active? (boolean) var $userEmail; //web interface user @@ -13,7 +13,6 @@ class YellowWebinterface var $userRestrictions; //web interface user can change page? (boolean) var $action; //web interface action var $status; //web interface status - var $installation; //web interface installation var $users; //web interface users var $merge; //web interface merge var $rawDataSource; //raw data of page for comparison @@ -23,7 +22,6 @@ class YellowWebinterface function onLoad($yellow) { $this->yellow = $yellow; - $this->installation = new YellowInstallation($yellow); $this->users = new YellowUsers($yellow); $this->merge = new YellowMerge($yellow); $this->yellow->config->setDefault("webinterfaceServerScheme", $this->yellow->config->get("serverScheme")); @@ -33,6 +31,7 @@ class YellowWebinterface $this->yellow->config->setDefault("webinterfaceUserHashAlgorithm", "bcrypt"); $this->yellow->config->setDefault("webinterfaceUserHashCost", "10"); $this->yellow->config->setDefault("webinterfaceUserStatus", "active"); + $this->yellow->config->setDefault("webinterfaceUserPending", "none"); $this->yellow->config->setDefault("webinterfaceUserHome", "/"); $this->yellow->config->setDefault("webinterfaceUserFile", "user.ini"); $this->yellow->config->setDefault("webinterfaceNewFile", "page-new-(.*).txt"); @@ -44,10 +43,9 @@ class YellowWebinterface function onRequest($serverScheme, $serverName, $base, $location, $fileName) { $statusCode = 0; - if($this->yellow->config->get("installationMode")) + if($this->checkRequest($location)) { - $statusCode = $this->installation->processRequest($serverScheme, $serverName, $base, $location, $fileName); - } else if($this->checkRequest($location)) { + list($serverScheme, $serverName, $base, $location, $fileName) = $this->updateRequestInformation(); $statusCode = $this->processRequest($serverScheme, $serverName, $base, $location, $fileName); } return $statusCode; @@ -107,7 +105,7 @@ class YellowWebinterface // Handle command function onCommand($args) { - list($name, $command) = $args; + list($command) = $args; switch($command) { case "clean": $statusCode = $this->cleanCommand($args); break; @@ -120,14 +118,15 @@ class YellowWebinterface // Handle command help function onCommandHelp() { - return "user [EMAIL PASSWORD NAME LANGUAGE STATUS HOME]\n"; + return "user [EMAIL PASSWORD NAME LANGUAGE STATUS]\n"; } // Clean user accounts function cleanCommand($args) { + $statusCode = 0; $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile"); - $statusCode = $this->users->clean($fileNameUser) ? 200 : 500; + if(!$this->users->clean($fileNameUser)) $statusCode = 500; if($statusCode == 500) echo "ERROR cleaning configuration: Can't write file '$fileNameUser'!\n"; return status; } @@ -136,7 +135,7 @@ class YellowWebinterface function userCommand($args) { $statusCode = 0; - list($dummy, $command, $email, $password, $name, $language, $status, $home) = $args; + list($command, $email, $password, $name, $language, $status) = $args; if(!empty($email) && !empty($password)) { $userExisting = $this->users->isExisting($email); @@ -149,7 +148,7 @@ class YellowWebinterface if($status == "ok") { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile"); - $status = $this->users->update($fileNameUser, $email, $password, $name, $language, $status, $home) ? "ok" : "error"; + $status = $this->users->update($fileNameUser, $email, $password, $name, $language, $status) ? "ok" : "error"; if($status == "error") echo "ERROR updating configuration: Can't write file '$fileNameUser'!\n"; } if($status == "ok") @@ -173,7 +172,6 @@ class YellowWebinterface function processRequest($serverScheme, $serverName, $base, $location, $fileName) { $statusCode = 0; - list($serverScheme, $serverName, $base, $location, $fileName) = $this->updateRequestInformation(); if($this->checkUser($location, $fileName)) { switch($_REQUEST["action"]) @@ -203,7 +201,6 @@ class YellowWebinterface { $statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false); $fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile"); - if($this->action == "off") $this->yellow->page->error(500, "Please configure webmaster email in file '$fileNameConfig'!"); if($this->action == "fail") $this->yellow->page->error(500, "Login failed, [please log in](javascript:yellow.action('login');)!"); } return $statusCode; @@ -563,7 +560,6 @@ class YellowWebinterface $this->action = "fail"; } } - if(!$this->users->getNumber() && !$this->users->isWebmaster()) $this->action = "off"; return $this->isUser(); } @@ -826,7 +822,8 @@ class YellowWebinterface $data = array(); foreach($this->users->users as $key=>$value) { - $data[$key] = "$value[email] - $value[name] $value[language] $value[status] $value[home]"; + $data[$key] = "$value[email] password $value[name] $value[language] $value[status]"; + if($this->getUserRestrictions($value["email"], "/locationcheck/", "/filecheck")) $data[$key] .= " - User restricted"; } usort($data, strnatcasecmp); return $data; @@ -863,127 +860,6 @@ class YellowWebinterface return $this->active; } } - -// Yellow installation -class YellowInstallation -{ - var $yellow; //access to API - - function __construct($yellow) - { - $this->yellow = $yellow; - } - - // Process request to install - function processRequest($serverScheme, $serverName, $base, $location, $fileName) - { - $statusCode = 0; - if(!$this->yellow->isStaticFile($location, $fileName, false)) - { - $fileName = $this->yellow->config->get("configDir")."page-installation.txt"; - $this->yellow->pages->pages["root/"] = array(); - $this->yellow->page = new YellowPage($this->yellow); - $this->yellow->page->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName); - $this->yellow->page->parseData($this->getRawDataWelcome($fileName, $this->yellow->getRequestLanguage()), false, 404); - $this->yellow->page->parserSafeMode = false; - $this->yellow->page->parseContent(); - $name = trim(preg_replace("/[^\pL\d\-\. ]/u", "-", $_REQUEST["name"])); - $email = trim($_REQUEST["email"]); - $password = trim($_REQUEST["password"]); - $language = trim($_REQUEST["language"]); - $status = trim($_REQUEST["status"]); - if($status == "install") - { - $status = "ok"; - $fileNameHome = $this->yellow->lookup->findFileFromLocation("/"); - $fileData = strreplaceu("\r\n", "\n", $this->yellow->toolbox->readFile($fileNameHome)); - if($fileData==$this->getRawDataHome("en") && $language!="en") - { - $status = $this->yellow->toolbox->createFile($fileNameHome, $this->getRawDataHome($language)) ? "ok" : "error"; - if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameHome'!"); - } - } - if($status == "ok") - { - if(!empty($email) && !empty($password)) - { - $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile"); - $status = $this->yellow->plugins->get("webinterface")->users->update($fileNameUser, $email, $password, $name, $language) ? "ok" : "error"; - if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); - } - } - if($status == "ok") - { - if($this->yellow->config->get("sitename") == "Yellow") $_REQUEST["sitename"] = $name; - $fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile"); - $status = $this->yellow->config->update($fileNameConfig, $this->getConfigData()) ? "done" : "error"; - if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameConfig'!"); - } - if($status == "done") - { - $statusCode = 303; - $location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location); - $this->yellow->sendStatus($statusCode, $location); - } else { - $statusCode = $this->yellow->sendPage(); - } - } - return $statusCode; - } - - // Return raw data for welcome page - function getRawDataWelcome($fileName, $language) - { - $rawData = $this->yellow->toolbox->readFile($fileName); - if(empty($rawData)) - { - $this->yellow->text->setLanguage($language); - $rawData = "---\nTitle:".$this->yellow->text->get("webinterfaceInstallationTitle")."\nLanguage:$language\nNavigation:navigation\n---\n"; - $rawData .= "<form class=\"installation-form\" action=\"".$this->yellow->page->getLocation()."\" method=\"post\">\n"; - $rawData .= "<p><label for=\"name\">".$this->yellow->text->get("webinterfaceSignupName")."</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("webinterfaceSignupEmail")."</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("webinterfaceSignupPassword")."</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"; - } - $rawData .= "<input class=\"btn\" type=\"submit\" value=\"".$this->yellow->text->get("webinterfaceOkButton")."\" />\n"; - $rawData .= "<input type=\"hidden\" name=\"status\" value=\"install\" />\n"; - $rawData .= "</form>\n"; - } - return $rawData; - } - - // Return raw data for home page - function getRawDataHome($language) - { - $rawData = "---\nTitle: Home\n---\n".strreplaceu("\\n", "\n", $this->yellow->text->getText("webinterfaceInstallationHomePage", $language)); - return $rawData; - } - - // Return configuration data - function getConfigData() - { - $data = array(); - foreach($_REQUEST as $key=>$value) - { - if(!$this->yellow->config->isExisting($key)) continue; - $data[$key] = trim($value); - } - $data["# serverScheme"] = $this->yellow->toolbox->getServerScheme(); - $data["# serverName"] = $this->yellow->toolbox->getServerName(); - $data["# serverBase"] = $this->yellow->toolbox->getServerBase(); - $data["# serverTime"] = $this->yellow->toolbox->getServerTime(); - $data["installationMode"] = "0"; - return $data; - } -} // Yellow users class YellowUsers @@ -1005,11 +881,12 @@ class YellowUsers foreach($this->yellow->toolbox->getTextLines($fileData) as $line) { if(preg_match("/^\#/", $line)) continue; - preg_match("/^\s*(.*?)\s*:\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?)\s*$/", $line, $matches); - if(!empty($matches[1]) && !empty($matches[2]) && !empty($matches[3]) && !empty($matches[4]) && - !empty($matches[5]) && !empty($matches[6])) + preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); + if(!empty($matches[1]) && !empty($matches[2])) { - $this->set($matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]); + list($hash, $name, $language, $status, $pending, $home) = explode(',', $matches[2]); + $home = empty($home) ? $pending : $home; //TODO: remove later, converts old file format + $this->set($matches[1], $hash, $name, $language, $status, $pending, $home); if(defined("DEBUG") && DEBUG>=3) echo "YellowUsers::load email:$matches[1]<br/>\n"; } } @@ -1021,9 +898,17 @@ class YellowUsers $fileData = $this->yellow->toolbox->readFile($fileName); foreach($this->yellow->toolbox->getTextLines($fileData) as $line) { - preg_match("/^\s*(.*?)\s*:\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?)\s*$/", $line, $matches); - if(empty($matches[5]) || $matches[5]=="active" || $matches[5]=="inactive") + preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); + if(!empty($matches[1]) && !empty($matches[2])) { + list($hash, $name, $language, $status, $pending, $home) = explode(',', $matches[2]); + if($status=="active" || $status=="inactive") + { + $home = empty($home) ? $pending : $home; //TODO: remove later, converts old file format + $pending = $this->yellow->config->get("webinterfaceUserPending"); + $fileDataNew .= "$matches[1]: $hash,$name,$language,$status,$pending,$home\n"; + } + } else { $fileDataNew .= $line; } } @@ -1031,7 +916,7 @@ class YellowUsers } // Update users in file - function update($fileName, $email, $password = "", $name = "", $language = "", $status = "", $home = "") + function update($fileName, $email, $password = "", $name = "", $language = "", $status = "", $pending = "", $home = "") { if(!empty($password)) { @@ -1047,6 +932,7 @@ class YellowUsers $name = strreplaceu(',', '-', empty($name) ? $this->users[$email]["name"] : $name); $language = strreplaceu(',', '-', empty($language) ? $this->users[$email]["language"] : $language); $status = strreplaceu(',', '-', empty($status) ? $this->users[$email]["status"] : $status); + $pending = strreplaceu(',', '-', empty($pending) ? $this->users[$email]["pending"] : $pending); $home = strreplaceu(',', '-', empty($home) ? $this->users[$email]["home"] : $home); } else { $email = strreplaceu(',', '-', empty($email) ? "none" : $email); @@ -1054,27 +940,28 @@ class YellowUsers $name = strreplaceu(',', '-', empty($name) ? $this->yellow->config->get("sitename") : $name); $language = strreplaceu(',', '-', empty($language) ? $this->yellow->config->get("language") : $language); $status = strreplaceu(',', '-', empty($status) ? $this->yellow->config->get("webinterfaceUserStatus") : $status); + $pending = strreplaceu(',', '-', empty($pending) ? $this->yellow->config->get("webinterfaceUserPending") : $pending); $home = strreplaceu(',', '-', empty($home) ? $this->yellow->config->get("webinterfaceUserHome") : $home); } - $this->set($email, $hash, $name, $language, $status, $home); + $this->set($email, $hash, $name, $language, $status, $pending, $home); $fileData = $this->yellow->toolbox->readFile($fileName); foreach($this->yellow->toolbox->getTextLines($fileData) as $line) { - preg_match("/^\s*(.*?)\s*:\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?)\s*$/", $line, $matches); + preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); if(!empty($matches[1]) && $matches[1]==$email) { - $fileDataNew .= "$email: $hash,$name,$language,$status,$home\n"; + $fileDataNew .= "$email: $hash,$name,$language,$status,$pending,$home\n"; $found = true; } else { $fileDataNew .= $line; } } - if(!$found) $fileDataNew .= "$email: $hash,$name,$language,$status,$home\n"; + if(!$found) $fileDataNew .= "$email: $hash,$name,$language,$status,$pending,$home\n"; return $this->yellow->toolbox->createFile($fileName, $fileDataNew); } // Set user data - function set($email, $hash, $name, $language, $status, $home) + function set($email, $hash, $name, $language, $status, $pending, $home) { $this->users[$email] = array(); $this->users[$email]["email"] = $email; @@ -1082,6 +969,7 @@ class YellowUsers $this->users[$email]["name"] = $name; $this->users[$email]["language"] = $language; $this->users[$email]["status"] = $status; + $this->users[$email]["pending"] = $pending; $this->users[$email]["home"] = $home; } @@ -1164,6 +1052,12 @@ class YellowUsers return $this->isExisting($email) ? $this->users[$email]["status"] : ""; } + // Return user pending + function getPending($email = "") + { + return $this->isExisting($email) ? $this->users[$email]["pending"] : ""; + } + // Return user home function getHome($email = "") { @@ -1179,7 +1073,7 @@ class YellowUsers // Check if web master exists function isWebmaster() { - return strposu($this->yellow->config->get("email"), '@') !== false; + return substru($this->yellow->config->get("email"), 0, 7) != "noreply"; } // Check if user exists