mikuli.cz

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

commit 0870155a60aaff42d1a59f70d865c31ee5d010f8
parent 33436c99a052196a0f174f1c64dacf2cdd106eb4
Author: markseu <mark2011@mayberg.se>
Date:   Tue, 24 Nov 2020 23:16:04 +0100

Added support to restore deleted pages

Diffstat:
Msystem/extensions/core.php | 20+++++++++++++++++++-
Msystem/extensions/edit.js | 45+++++++++++++++++++++++----------------------
Msystem/extensions/edit.php | 329+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msystem/extensions/install-languages.zip | 0
Msystem/extensions/update-current.ini | 8++++----
5 files changed, 269 insertions(+), 133 deletions(-)

diff --git a/system/extensions/core.php b/system/extensions/core.php @@ -2,7 +2,7 @@ // Core extension, https://github.com/datenstrom/yellow-extensions/tree/master/source/core class YellowCore { - const VERSION = "0.8.34"; + const VERSION = "0.8.35"; const RELEASE = "0.8.16"; public $page; // current page public $content; // content files @@ -3135,6 +3135,24 @@ class YellowToolbox { return $rawDataNew; } + // Remove meta data in raw data + public function unsetMetaData($rawData, $key) { + if (preg_match("/^(\xEF\xBB\xBF)?\-\-\-[\r\n]+(.+?)\-\-\-[\r\n]+(.*)$/s", $rawData, $parts)) { + $key = lcfirst($key); + $rawDataMiddle = ""; + foreach ($this->getTextLines($parts[2]) as $line) { + if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { + if (lcfirst($matches[1])==$key) continue; + } + $rawDataMiddle .= $line; + } + $rawDataNew = $parts[1]."---\n".$rawDataMiddle."---\n".$parts[3]; + } else { + $rawDataNew = $rawData; + } + return $rawDataNew; + } + // Detect server URL public function detectServerUrl() { $scheme = "http"; diff --git a/system/extensions/edit.js b/system/extensions/edit.js @@ -243,22 +243,22 @@ yellow.edit = { "</div>"+ "</form>"; break; - case "yellow-pane-system": + case "yellow-pane-configure": 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-system-title\">"+this.getText("SystemTitle")+"</h1></div>"+ - "<div class=\"yellow-status\"><p id=\"yellow-pane-system-status\" class=\""+paneStatus+"\">"+this.getText("SystemStatus", "", paneStatus)+"</p></div>"+ + "<div class=\"yellow-title\"><h1 id=\"yellow-pane-configure-title\">"+this.getText("ConfigureTitle")+"</h1></div>"+ + "<div class=\"yellow-status\"><p id=\"yellow-pane-configure-status\" class=\""+paneStatus+"\">"+this.getText("ConfigureStatus", "", paneStatus)+"</p></div>"+ "<div class=\"yellow-settings\">"+ - "<div id=\"yellow-pane-system-settings-actions\" class=\"yellow-settings-left\"><p>"+this.getRawDataSettingsActions(paneAction)+"</p></div>"+ - "<div id=\"yellow-pane-system-settings-separator\" class=\"yellow-settings-left yellow-settings-separator\">&nbsp;</div>"+ - "<div id=\"yellow-pane-system-settings-fields\" class=\"yellow-settings-right yellow-fields\">"+ - "<input type=\"hidden\" name=\"action\" value=\"system\" />"+ + "<div id=\"yellow-pane-configure-settings-actions\" class=\"yellow-settings-left\"><p>"+this.getRawDataSettingsActions(paneAction)+"</p></div>"+ + "<div id=\"yellow-pane-configure-settings-separator\" class=\"yellow-settings-left yellow-settings-separator\">&nbsp;</div>"+ + "<div id=\"yellow-pane-configure-settings-fields\" class=\"yellow-settings-right yellow-fields\">"+ + "<input type=\"hidden\" name=\"action\" value=\"configure\" />"+ "<input type=\"hidden\" name=\"csrftoken\" value=\""+yellow.toolbox.encodeHtml(this.getCookie("csrftoken"))+"\" />"+ - "<p><label for=\"yellow-pane-system-sitename\">"+this.getText("SystemSitename")+"</label><br /><input class=\"yellow-form-control\" name=\"sitename\" id=\"yellow-pane-system-sitename\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("sitename"))+"\" /></p>"+ - "<p><label for=\"yellow-pane-system-author\">"+this.getText("SystemAuthor")+"</label><br /><input class=\"yellow-form-control\" name=\"author\" id=\"yellow-pane-system-author\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("author"))+"\" /></p>"+ - "<p><label for=\"yellow-pane-system-email\">"+this.getText("SystemEmail")+"</label><br /><input class=\"yellow-form-control\" name=\"email\" id=\"yellow-pane-system-email\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("email"))+"\" /></p>"+ - "<p>"+this.getText("SystemInformation")+"</p>"+ + "<p><label for=\"yellow-pane-configure-sitename\">"+this.getText("ConfigureSitename")+"</label><br /><input class=\"yellow-form-control\" name=\"sitename\" id=\"yellow-pane-configure-sitename\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("sitename"))+"\" /></p>"+ + "<p><label for=\"yellow-pane-configure-author\">"+this.getText("ConfigureAuthor")+"</label><br /><input class=\"yellow-form-control\" name=\"author\" id=\"yellow-pane-configure-author\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("author"))+"\" /></p>"+ + "<p><label for=\"yellow-pane-configure-email\">"+this.getText("ConfigureEmail")+"</label><br /><input class=\"yellow-form-control\" name=\"email\" id=\"yellow-pane-configure-email\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("email"))+"\" /></p>"+ + "<p>"+this.getText("ConfigureInformation")+"</p>"+ "<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("ChangeButton")+"\" /></p>"+ "</div>"+ "<div class=\"yellow-settings yellow-settings-banner\"></div>"+ @@ -380,12 +380,12 @@ yellow.edit = { document.getElementById("yellow-pane-account-"+yellow.user.language).checked = true; } break; - case "yellow-pane-system": + case "yellow-pane-configure": if (paneStatus=="none") { - document.getElementById("yellow-pane-system-status").innerHTML = this.getText("SystemStatusNone"); - document.getElementById("yellow-pane-system-sitename").value = yellow.system.sitename; - document.getElementById("yellow-pane-system-author").value = yellow.system.author; - document.getElementById("yellow-pane-system-email").value = yellow.system.email; + document.getElementById("yellow-pane-configure-status").innerHTML = this.getText("ConfigureStatusNone"); + document.getElementById("yellow-pane-configure-sitename").value = yellow.system.sitename; + document.getElementById("yellow-pane-configure-author").value = yellow.system.author; + document.getElementById("yellow-pane-configure-email").value = yellow.system.email; } break; case "yellow-pane-update": @@ -445,7 +445,7 @@ yellow.edit = { var paneHeight = yellow.toolbox.getWindowHeight() - paneTop - Math.min(yellow.toolbox.getOuterHeight(elementBar) + 10, (yellow.toolbox.getWindowWidth()-yellow.toolbox.getOuterWidth(elementBar))/2); switch (paneId) { case "yellow-pane-account": - case "yellow-pane-system": + case "yellow-pane-configure": yellow.toolbox.setOuterLeft(document.getElementById(paneId), paneLeft); yellow.toolbox.setOuterTop(document.getElementById(paneId), paneTop); yellow.toolbox.setOuterWidth(document.getElementById(paneId), paneWidth); @@ -563,7 +563,7 @@ yellow.edit = { case "quit": this.showPane(paneId, action, status); break; case "remove": this.showPane(paneId, action, status); break; case "account": this.showPane(paneId, action, status); break; - case "system": this.showPane(paneId, action, status); break; + case "configure": this.showPane(paneId, action, status); break; case "update": this.showPane(paneId, action, status); break; case "create": this.showPane(paneId, action, status, true); break; case "edit": this.showPane(paneId, action, status, true); break; @@ -573,6 +573,7 @@ yellow.edit = { case "toolbar": this.processToolbar(status, arguments); break; case "settings": this.processSettings(arguments); break; case "submit": this.processSubmit(arguments); break; + case "restore": this.processSubmit("action:"+action); break; case "help": this.processHelp(); break; } } @@ -829,7 +830,7 @@ yellow.edit = { var extension = (file.name.lastIndexOf(".")!=-1 ? file.name.substring(file.name.lastIndexOf("."), file.name.length) : "").toLowerCase(); var extensions = yellow.system.editUploadExtensions.split(/\s*,\s*/); if (file.size<=yellow.system.coreFileSizeMax && extensions.indexOf(extension)!=-1) { - var text = this.getText("UploadProgress")+"\u200b"; + var text = "["+this.getText("UploadProgress")+"]\u200b"; yellow.editor.setMarkdown(elementText, text, "insert"); var thisObject = this; var formData = new FormData(); @@ -855,7 +856,7 @@ yellow.edit = { uploadFileDone: function(elementText, responseText) { var result = JSON.parse(responseText); if (result) { - var textOld = this.getText("UploadProgress")+"\u200b"; + var textOld = "["+this.getText("UploadProgress")+"]\u200b"; var textNew; if (result.location.substring(0, yellow.system.coreImageLocation.length)==yellow.system.coreImageLocation) { textNew = "[image "+result.location.substring(yellow.system.coreImageLocation.length)+"]"; @@ -870,7 +871,7 @@ yellow.edit = { uploadFileError: function(elementText, responseText) { var result = JSON.parse(responseText); if (result) { - var textOld = this.getText("UploadProgress")+"\u200b"; + var textOld = "["+this.getText("UploadProgress")+"]\u200b"; var textNew = "["+result.error+"]"; yellow.editor.replace(elementText, textOld, textNew); } @@ -894,7 +895,7 @@ yellow.edit = { var paneAction = paneId.substring(panePrefix.length); if (paneAction=="edit") { if (document.getElementById("yellow-pane-edit-text").value.length==0) paneAction = "delete"; - if (yellow.page.statusCode==434) paneAction = "create"; + if (yellow.page.statusCode==434 || yellow.page.statusCode==435) paneAction = "create"; } return paneAction; }, diff --git a/system/extensions/edit.php b/system/extensions/edit.php @@ -2,10 +2,11 @@ // Edit extension, https://github.com/datenstrom/yellow-extensions/tree/master/source/edit class YellowEdit { - const VERSION = "0.8.39"; + const VERSION = "0.8.40"; public $yellow; // access to API public $response; // web response public $merge; // text merge + public $editable; // page can be edited? (boolean) // Handle initialisation public function onLoad($yellow) { @@ -23,17 +24,42 @@ class YellowEdit { $this->yellow->system->setDefault("editUserHashAlgorithm", "bcrypt"); $this->yellow->system->setDefault("editUserHashCost", "10"); $this->yellow->system->setDefault("editUserHome", "/"); - $this->yellow->system->setDefault("editUserAccess", "create, edit, delete, upload"); + $this->yellow->system->setDefault("editUserAccess", "create, edit, delete, restore, upload"); $this->yellow->system->setDefault("editLoginRestriction", "0"); $this->yellow->system->setDefault("editLoginSessionTimeout", "2592000"); $this->yellow->system->setDefault("editBruteForceProtection", "25"); $this->yellow->language->setDefault("editMailFooter"); } + // Handle update + public function onUpdate($action) { + if ($action=="clean" || $action=="daily") { + $cleanup = false; + $fileNameUser = $this->yellow->system->get("coreExtensionDirectory").$this->yellow->system->get("coreUserFile"); + $fileData = $this->yellow->toolbox->readFile($fileNameUser); + $fileDataNew = ""; + foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { + if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { + if (lcfirst($matches[1])=="email" && !strempty($matches[2])) { + $status = $this->yellow->user->getUser("status", $matches[2]); + $reserved = strtotime($this->yellow->user->getUser("modified", $matches[2])) + 60*60*24; + $cleanup = $status!="active" && $status!="inactive" && $reserved<=time(); + } + } + if (!$cleanup) $fileDataNew .= $line; + } + $fileDataNew = rtrim($fileDataNew)."\n"; + if ($fileData!=$fileDataNew && !$this->yellow->toolbox->createFile($fileNameUser, $fileDataNew)) { + $this->yellow->log("error", "Can't write file '$fileNameUser'!"); + } + } + } + // Handle request public function onRequest($scheme, $address, $base, $location, $fileName) { $statusCode = 0; - if ($this->checkRequest($location)) { + if ($this->isEditLocation($location)) { + $this->editable = true; $scheme = $this->yellow->system->get("coreServerScheme"); $address = $this->yellow->system->get("coreServerAddress"); $base = rtrim($this->yellow->system->get("coreServerBase").$this->yellow->system->get("editLocation"), "/"); @@ -44,6 +70,20 @@ class YellowEdit { return $statusCode; } + // Handle command + public function onCommand($command, $text) { + switch ($command) { + case "user": $statusCode = $this->processCommandUser($command, $text); break; + default: $statusCode = 0; + } + return $statusCode; + } + + // Handle command help + public function onCommandHelp() { + return "user [option email password name]\n"; + } + // Handle page content of shortcut public function onParseContentShortcut($page, $name, $text, $type) { $output = null; @@ -57,7 +97,7 @@ class YellowEdit { // Handle page layout public function onParsePageLayout($page, $name) { - if ($this->response->isActive()) { + if ($this->editable) { $this->response->processPageData($page); } } @@ -65,7 +105,7 @@ class YellowEdit { // Handle page extra data public function onParsePageExtra($page, $name) { $output = null; - if ($name=="header" && $this->response->isActive()) { + if ($this->editable && $name=="header") { $extensionLocation = $this->yellow->system->get("coreServerBase").$this->yellow->system->get("coreExtensionLocation"); $output = "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"{$extensionLocation}edit.css\" />\n"; $output .= "<script type=\"text/javascript\" src=\"{$extensionLocation}edit.js\"></script>\n"; @@ -81,44 +121,6 @@ class YellowEdit { return $output; } - // Handle command - public function onCommand($command, $text) { - switch ($command) { - case "user": $statusCode = $this->processCommandUser($command, $text); break; - default: $statusCode = 0; - } - return $statusCode; - } - - // Handle command help - public function onCommandHelp() { - return "user [option email password name]\n"; - } - - // Handle update - public function onUpdate($action) { - if ($action=="clean" || $action=="daily") { - $cleanup = false; - $fileNameUser = $this->yellow->system->get("coreExtensionDirectory").$this->yellow->system->get("coreUserFile"); - $fileData = $this->yellow->toolbox->readFile($fileNameUser); - $fileDataNew = ""; - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (lcfirst($matches[1])=="email" && !strempty($matches[2])) { - $status = $this->yellow->user->getUser("status", $matches[2]); - $reserved = strtotime($this->yellow->user->getUser("modified", $matches[2])) + 60*60*24; - $cleanup = $status!="active" && $status!="inactive" && $reserved<=time(); - } - } - if (!$cleanup) $fileDataNew .= $line; - } - $fileDataNew = rtrim($fileDataNew)."\n"; - if ($fileData!=$fileDataNew && !$this->yellow->toolbox->createFile($fileNameUser, $fileDataNew)) { - $this->yellow->log("error", "Can't write file '$fileNameUser'!"); - } - } - } - // Process command to update user account public function processCommandUser($command, $text) { list($option) = $this->yellow->toolbox->getTextArguments($text); @@ -250,11 +252,12 @@ class YellowEdit { case "logout": $statusCode = $this->processRequestLogout($scheme, $address, $base, $location, $fileName); break; case "quit": $statusCode = $this->processRequestQuit($scheme, $address, $base, $location, $fileName); break; case "account": $statusCode = $this->processRequestAccount($scheme, $address, $base, $location, $fileName); break; - case "system": $statusCode = $this->processRequestSystem($scheme, $address, $base, $location, $fileName); break; + case "configure": $statusCode = $this->processRequestConfigure($scheme, $address, $base, $location, $fileName); break; case "update": $statusCode = $this->processRequestUpdate($scheme, $address, $base, $location, $fileName); break; case "create": $statusCode = $this->processRequestCreate($scheme, $address, $base, $location, $fileName); break; case "edit": $statusCode = $this->processRequestEdit($scheme, $address, $base, $location, $fileName); break; case "delete": $statusCode = $this->processRequestDelete($scheme, $address, $base, $location, $fileName); break; + case "restore": $statusCode = $this->processRequestRestore($scheme, $address, $base, $location, $fileName); break; case "preview": $statusCode = $this->processRequestPreview($scheme, $address, $base, $location, $fileName); break; case "upload": $statusCode = $this->processRequestUpload($scheme, $address, $base, $location, $fileName); break; } @@ -289,7 +292,12 @@ class YellowEdit { $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); $statusCode = $this->yellow->sendStatus(301, $location); } else { - $this->yellow->page->error($this->response->isUserAccess("create", $location) ? 434 : 404); + $statusCode = 404; + if ($this->response->isUserAccess("create", $location)) $statusCode = 434; + if ($this->response->isUserAccess("restore", $location) && $this->response->isDeletedLocation($location)) { + $statusCode = 435; + } + $this->yellow->page->error($statusCode); $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } @@ -636,11 +644,11 @@ class YellowEdit { return $statusCode; } - // Process request to change system settings - public function processRequestSystem($scheme, $address, $base, $location, $fileName) { + // Process request to change settings + public function processRequestConfigure($scheme, $address, $base, $location, $fileName) { $statusCode = 0; - if ($this->response->isUserAccess("system")) { - $this->response->action = "system"; + if ($this->response->isUserAccess("configure")) { + $this->response->action = "configure"; $this->response->status = "ok"; $sitename = trim($this->yellow->page->getRequest("sitename")); $author = trim($this->yellow->page->getRequest("author")); @@ -730,23 +738,18 @@ class YellowEdit { $this->response->rawDataSource, $this->response->rawDataEdit, $rawDataFile, $this->response->rawDataEndOfLine); if (!$page->isError()) { if ($this->yellow->lookup->isFileLocation($location)) { - if ($this->yellow->toolbox->renameFile($fileName, $page->fileName, true) && - $this->yellow->toolbox->createFile($page->fileName, $page->rawData)) { - $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $page->location); - $statusCode = $this->yellow->sendStatus(303, $location); - } else { - $this->yellow->page->error(500, "Can't write file '$page->fileName'!"); - $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - } + $ok = $this->yellow->toolbox->renameFile($fileName, $page->fileName, true) && + $this->yellow->toolbox->createFile($page->fileName, $page->rawData); } else { - if ($this->yellow->toolbox->renameDirectory(dirname($fileName), dirname($page->fileName), true) && - $this->yellow->toolbox->createFile($page->fileName, $page->rawData)) { - $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $page->location); - $statusCode = $this->yellow->sendStatus(303, $location); - } else { - $this->yellow->page->error(500, "Can't write file '$page->fileName'!"); - $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - } + $ok = $this->yellow->toolbox->renameDirectory(dirname($fileName), dirname($page->fileName), true) && + $this->yellow->toolbox->createFile($page->fileName, $page->rawData); + } + if ($ok) { + $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $page->location); + $statusCode = $this->yellow->sendStatus(303, $location); + } else { + $this->yellow->page->error(500, "Can't write file '$page->fileName'!"); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } else { $this->yellow->page->error(500, $page->get("pageError")); @@ -767,23 +770,17 @@ class YellowEdit { $page = $this->response->getPageDelete($scheme, $address, $base, $location, $fileName, $rawDataFile, $this->response->rawDataEndOfLine); if (!$page->isError()) { - $this->yellow->toolbox->createFile($fileName, $page->rawData); if ($this->yellow->lookup->isFileLocation($location)) { - if ($this->yellow->toolbox->deleteFile($fileName, $this->yellow->system->get("coreTrashDirectory"))) { - $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); - $statusCode = $this->yellow->sendStatus(303, $location); - } else { - $this->yellow->page->error(500, "Can't delete file '$fileName'!"); - $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - } + $ok = $this->response->deleteFileLocation($location, $fileName); } else { - if ($this->yellow->toolbox->deleteDirectory(dirname($fileName), $this->yellow->system->get("coreTrashDirectory"))) { - $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); - $statusCode = $this->yellow->sendStatus(303, $location); - } else { - $this->yellow->page->error(500, "Can't delete file '$fileName'!"); - $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - } + $ok = $this->response->deleteDirectoryLocation($location, $fileName); + } + if ($ok) { + $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); + $statusCode = $this->yellow->sendStatus(303, $location); + } else { + $this->yellow->page->error(500, "Can't delete file '$fileName'!"); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } else { $this->yellow->page->error(500, $page->get("pageError")); @@ -793,6 +790,32 @@ class YellowEdit { return $statusCode; } + // Process request to restore deleted page + public function processRequestRestore($scheme, $address, $base, $location, $fileName) { + $statusCode = 0; + if ($this->response->isUserAccess("restore", $location) && !is_file($fileName)) { + $page = $this->response->getPageRestore($scheme, $address, $base, $location, $fileName); + if (!$page->isError()) { + if ($this->yellow->lookup->isFileLocation($location)) { + $ok = $this->response->restoreFileLocation($location); + } else { + $ok = $this->response->restoreDirectoryLocation($location); + } + if ($ok) { + $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); + $statusCode = $this->yellow->sendStatus(303, $location); + } else { + $this->yellow->page->error(500, "Can't restore file '$fileName'!"); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); + } + } else { + $this->yellow->page->error(500, $page->get("pageError")); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); + } + } + return $statusCode; + } + // Process request to show preview public function processRequestPreview($scheme, $address, $base, $location, $fileName) { $page = $this->response->getPagePreview($scheme, $address, $base, $location, $fileName, @@ -825,13 +848,6 @@ class YellowEdit { return $statusCode; } - // Check request - public function checkRequest($location) { - $locationLength = strlenu($this->yellow->system->get("editLocation")); - $this->response->active = substru($location, 0, $locationLength)==$this->yellow->system->get("editLocation"); - return $this->response->isActive(); - } - // Check user authentication public function checkUserAuth($scheme, $address, $base, $location, $fileName) { $action = $this->yellow->page->getRequest("action"); @@ -969,14 +985,6 @@ class YellowEdit { return $language; } - // Check if request came from same site - public function isRequestSameSite($method, $scheme, $address) { - $origin = ""; - if (preg_match("#^(\w+)://([^/]+)(.*)$#", $this->yellow->toolbox->getServer("HTTP_REFERER"), $matches)) $origin = "$matches[1]://$matches[2]"; - if ($this->yellow->toolbox->getServer("HTTP_ORIGIN")) $origin = $this->yellow->toolbox->getServer("HTTP_ORIGIN"); - return $this->yellow->toolbox->getServer("REQUEST_METHOD")==$method && $origin=="$scheme://$address"; - } - // Check if user account is taken public function isUserAccountTaken($email) { $taken = false; @@ -987,6 +995,20 @@ class YellowEdit { } return $taken; } + + // Check if request came from same site + public function isRequestSameSite($method, $scheme, $address) { + $origin = ""; + if (preg_match("#^(\w+)://([^/]+)(.*)$#", $this->yellow->toolbox->getServer("HTTP_REFERER"), $matches)) $origin = "$matches[1]://$matches[2]"; + if ($this->yellow->toolbox->getServer("HTTP_ORIGIN")) $origin = $this->yellow->toolbox->getServer("HTTP_ORIGIN"); + return $this->yellow->toolbox->getServer("REQUEST_METHOD")==$method && $origin=="$scheme://$address"; + } + + // Check if edit location + public function isEditLocation($location) { + $locationLength = strlenu($this->yellow->system->get("editLocation")); + return substru($location, 0, $locationLength)==$this->yellow->system->get("editLocation"); + } } class YellowEditResponse { @@ -1001,7 +1023,6 @@ class YellowEditResponse { public $rawDataOutput; // raw data of dynamic output public $rawDataReadonly; // raw data is read only? (boolean) public $rawDataEndOfLine; // end of line format for raw data - public $active; // response is active? (boolean) public $language; // response language public $action; // response action public $status; // response status @@ -1022,7 +1043,7 @@ class YellowEditResponse { $this->rawDataEdit = $this->getRawDataGenerated($page); $this->rawDataReadonly = true; } - if ($page->statusCode==434) { + if ($page->statusCode==434 || $page->statusCode==435) { $this->rawDataEdit = $this->getRawDataNew($page, true); $this->rawDataReadonly = false; } @@ -1097,13 +1118,24 @@ class YellowEditResponse { $page->setRequestInformation($scheme, $address, $base, $location, $fileName); $page->parseData($rawData, false, 0); $this->editContentFile($page, "delete", $this->userEmail); - $page->rawData = $this->yellow->toolbox->setMetaData($page->rawData, "fileNameOriginal", $fileName); if (!$this->isUserAccess("delete", $page->location)) { $page->error(500, "Page '".$page->get("title")."' is restricted!"); } return $page; } + // Return restored page + public function getPageRestore($scheme, $address, $base, $location, $fileName) { + $page = new YellowPage($this->yellow); + $page->setRequestInformation($scheme, $address, $base, $location, $fileName); + $page->parseData("", false, 0); + $this->editContentFile($page, "restore", $this->userEmail); + if (!$this->isUserAccess("restore", $page->location)) { + $page->error(500, "Page '".$page->get("title")."' is restricted!"); + } + return $page; + } + // Return preview page public function getPagePreview($scheme, $address, $base, $location, $fileName, $rawData, $endOfLine) { $rawData = $this->yellow->toolbox->normaliseLines($rawData, $endOfLine); @@ -1153,7 +1185,7 @@ class YellowEditResponse { $file->setRequestInformation($scheme, $address, $base, "/".$fileName, $fileName); $file->parseData(null, false, 0); foreach ($settings as $key=>$value) $file->set($key, $value); - $this->editSystemFile($file, "system", $this->userEmail); + $this->editSystemFile($file, "configure", $this->userEmail); return $file; } @@ -1205,7 +1237,7 @@ class YellowEditResponse { $data["editStatusValues"] = $this->getStatusValues(); $data["emojiawesomeToolbarButtons"] = $this->yellow->system->get("emojiawesomeToolbarButtons"); $data["fontawesomeToolbarButtons"] = $this->yellow->system->get("fontawesomeToolbarButtons"); - if ($this->isUserAccess("system")) { + if ($this->isUserAccess("configure")) { $data["sitename"] = $this->yellow->system->get("sitename"); $data["author"] = $this->yellow->system->get("author"); $data["email"] = $this->yellow->system->get("email"); @@ -1253,7 +1285,7 @@ class YellowEditResponse { // Return settings actions public function getSettingsActions() { $settingsActions = "account"; - if ($this->isUserAccess("system")) $settingsActions .= ", system"; + if ($this->isUserAccess("configure")) $settingsActions .= ", configure"; if ($this->isUserAccess("update")) $settingsActions .= ", update"; return $settingsActions=="account" ? "" : $settingsActions; } @@ -1667,6 +1699,96 @@ class YellowEditResponse { } } + // Delete file + public function deleteFileLocation($location, $fileName) { + $rawData = $this->yellow->toolbox->readFile($fileName); + $rawData = $this->yellow->toolbox->setMetaData($rawData, "pageOriginalLocation", $location); + $rawData = $this->yellow->toolbox->setMetaData($rawData, "pageOriginalFileName", $fileName); + return $this->yellow->toolbox->createFile($fileName, $rawData) && + $this->yellow->toolbox->deleteFile($fileName, $this->yellow->system->get("coreTrashDirectory")); + } + + // Delete directory + public function deleteDirectoryLocation($location, $fileName) { + $rawData = $this->yellow->toolbox->readFile($fileName); + $rawData = $this->yellow->toolbox->setMetaData($rawData, "pageOriginalLocation", $location); + $rawData = $this->yellow->toolbox->setMetaData($rawData, "pageOriginalFileName", $fileName); + return $this->yellow->toolbox->createFile($fileName, $rawData) && + $this->yellow->toolbox->deleteDirectory(dirname($fileName), $this->yellow->system->get("coreTrashDirectory")); + } + + // Restore deleted file from trash + public function restoreFileLocation($location) { + $fileNameDeleted = $fileNameRestored = ""; + $deleted = 0; + $pathTrash = $this->yellow->system->get("coreTrashDirectory"); + $regex = "/^.*\\".$this->yellow->system->get("coreContentExtension")."$/"; + foreach ($this->yellow->toolbox->getDirectoryEntries($pathTrash, $regex, false, false) as $entry) { + $rawDataOriginal = $this->yellow->toolbox->readFile($entry); + $locationOriginal = $this->yellow->toolbox->getMetaData($rawDataOriginal, "pageOriginalLocation"); + $fileNameOriginal = $this->yellow->toolbox->getMetaData($rawDataOriginal, "pageOriginalFileName"); + $deletedOriginal = $this->yellow->toolbox->getFileDeleted($entry); + if ($location==$locationOriginal && $deleted<=$deletedOriginal) { + $fileNameDeleted = $entry; + $fileNameRestored = $fileNameOriginal; + $rawDataRestored = $rawDataOriginal; + $rawDataRestored = $this->yellow->toolbox->unsetMetaData($rawDataRestored, "pageOriginalLocation"); + $rawDataRestored = $this->yellow->toolbox->unsetMetaData($rawDataRestored, "pageOriginalFileName"); + $deleted = $deletedOriginal; + } + } + return !empty($fileNameDeleted) && $this->yellow->lookup->isContentFile($fileNameRestored) && + $this->yellow->toolbox->renameFile($fileNameDeleted, $fileNameRestored, true) && + $this->yellow->toolbox->createFile($fileNameRestored, $rawDataRestored); + } + + // Restore deleted directory from trash + public function restoreDirectoryLocation($location) { + $pathDeleted = $fileNameRestored = ""; + $deleted = 0; + $pathTrash = $this->yellow->system->get("coreTrashDirectory"); + foreach ($this->yellow->toolbox->getDirectoryEntries($pathTrash, "/.*/", false, true) as $entry) { + $fileName = $entry."/".$this->yellow->system->get("coreContentDefaultFile"); + if (!is_file($fileName)) continue; + $rawDataOriginal = $this->yellow->toolbox->readFile($fileName); + $locationOriginal = $this->yellow->toolbox->getMetaData($rawDataOriginal, "pageOriginalLocation"); + $fileNameOriginal = $this->yellow->toolbox->getMetaData($rawDataOriginal, "pageOriginalFileName"); + $deletedOriginal = $this->yellow->toolbox->getFileDeleted($entry); + if ($location==$locationOriginal && $deleted<=$deletedOriginal) { + $pathDeleted = $entry; + $fileNameRestored = $fileNameOriginal; + $rawDataRestored = $rawDataOriginal; + $rawDataRestored = $this->yellow->toolbox->unsetMetaData($rawDataRestored, "pageOriginalLocation"); + $rawDataRestored = $this->yellow->toolbox->unsetMetaData($rawDataRestored, "pageOriginalFileName"); + $deleted = $deletedOriginal; + } + } + return !empty($pathDeleted) && $this->yellow->lookup->isContentFile($fileNameRestored) && + $this->yellow->toolbox->renameDirectory($pathDeleted, dirname($fileNameRestored), true) && + $this->yellow->toolbox->createFile($fileNameRestored, $rawDataRestored); + } + + // Check if location has been deleted + public function isDeletedLocation($location) { + $found = false; + $pathTrash = $this->yellow->system->get("coreTrashDirectory"); + $regex = "/^.*\\".$this->yellow->system->get("coreContentExtension")."$/"; + $fileNames = $this->yellow->toolbox->getDirectoryEntries($pathTrash, $regex, false, false); + foreach ($this->yellow->toolbox->getDirectoryEntries($pathTrash, "/.*/", false, true) as $entry) { + $fileName = $entry."/".$this->yellow->system->get("coreContentDefaultFile"); + if (is_file($fileName)) array_push($fileNames, $fileName); + } + foreach ($fileNames as $fileName) { + $rawDataOriginal = $this->yellow->toolbox->readFile($fileName, 4096); + $locationOriginal = $this->yellow->toolbox->getMetaData($rawDataOriginal, "pageOriginalLocation"); + if ($location==$locationOriginal) { + $found = true; + break; + } + } + return $found; + } + // Check if meta data has been modified public function isMetaModified($pageSource, $pageOther) { return substrb($pageSource->rawData, 0, $pageSource->metaDataOffsetBytes) != @@ -1689,11 +1811,6 @@ class YellowEditResponse { $tokens = preg_split("/\s*,\s*/", $this->yellow->user->getUser("access", $this->userEmail)); return in_array($action, $tokens) && (empty($location) || substru($location, 0, strlenu($userHome))==$userHome); } - - // Check if page within current HTTP request - public function isActive() { - return $this->active; - } } class YellowEditMerge { diff --git a/system/extensions/install-languages.zip b/system/extensions/install-languages.zip Binary files differ. diff --git a/system/extensions/update-current.ini b/system/extensions/update-current.ini @@ -21,21 +21,21 @@ Tag: feature system/extensions/command.php: command.php, create, update Extension: Core -Version: 0.8.34 +Version: 0.8.35 Description: Core functionality of the website. HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/core DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/core.zip -Published: 2020-11-22 19:14:02 +Published: 2020-11-24 17:43:07 Developer: Datenstrom Tag: feature system/extensions/core.php: core.php, create, update Extension: Edit -Version: 0.8.39 +Version: 0.8.40 Description: Edit your website in a web browser. HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/edit DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/edit.zip -Published: 2020-11-13 21:47:13 +Published: 2020-11-24 21:22:52 Developer: Datenstrom Tag: feature system/extensions/edit.php: edit.php, create, update