2013-04-14 22:41:04 +00:00
|
|
|
<?php
|
2019-02-23 14:04:34 +00:00
|
|
|
// Edit extension, https://github.com/datenstrom/yellow-extensions/tree/master/features/edit
|
2020-01-03 09:15:15 +00:00
|
|
|
// Copyright (c) 2013-2020 Datenstrom, https://datenstrom.se
|
2013-04-14 22:41:04 +00:00
|
|
|
// This file may be used and distributed under the terms of the public license.
|
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
class YellowEdit {
|
2020-01-30 20:01:14 +00:00
|
|
|
const VERSION = "0.8.20";
|
2019-02-23 14:04:34 +00:00
|
|
|
const TYPE = "feature";
|
2018-08-10 22:23:50 +00:00
|
|
|
public $yellow; //access to API
|
|
|
|
public $response; //web response
|
|
|
|
public $users; //user accounts
|
|
|
|
public $merge; //text merge
|
2013-04-14 22:41:04 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Handle initialisation
|
|
|
|
public function onLoad($yellow) {
|
|
|
|
$this->yellow = $yellow;
|
2019-03-21 10:58:12 +00:00
|
|
|
$this->response = new YellowEditResponse($yellow);
|
|
|
|
$this->users = new YellowEditUsers($yellow);
|
|
|
|
$this->merge = new YellowEditMerge($yellow);
|
2019-02-23 14:04:34 +00:00
|
|
|
$this->yellow->system->setDefault("editLocation", "/edit/");
|
|
|
|
$this->yellow->system->setDefault("editUploadNewLocation", "/media/@group/@filename");
|
2020-01-03 20:12:36 +00:00
|
|
|
$this->yellow->system->setDefault("editUploadExtensions", ".gif, .jpg, .pdf, .png, .svg, .zip");
|
2019-04-03 14:44:12 +00:00
|
|
|
$this->yellow->system->setDefault("editKeyboardShortcuts", "ctrl+b bold, ctrl+i italic, ctrl+k strikethrough, ctrl+e code, ctrl+s save, ctrl+alt+p preview");
|
2019-02-23 14:04:34 +00:00
|
|
|
$this->yellow->system->setDefault("editToolbarButtons", "auto");
|
|
|
|
$this->yellow->system->setDefault("editEndOfLine", "auto");
|
2019-04-11 19:43:30 +00:00
|
|
|
$this->yellow->system->setDefault("editNewFile", "page-new-(.*).md");
|
2019-02-23 14:04:34 +00:00
|
|
|
$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", "/");
|
2019-12-17 10:46:09 +00:00
|
|
|
$this->yellow->system->setDefault("editUserAccess", "create, edit, delete, upload");
|
2019-06-01 13:21:51 +00:00
|
|
|
$this->yellow->system->setDefault("editLoginRestriction", "0");
|
2020-01-03 09:15:15 +00:00
|
|
|
$this->yellow->system->setDefault("editLoginSessionTimeout", "2592000");
|
2019-02-23 14:04:34 +00:00
|
|
|
$this->yellow->system->setDefault("editBruteForceProtection", "25");
|
2019-12-15 16:22:07 +00:00
|
|
|
$this->users->load($this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile"));
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Handle request
|
|
|
|
public function onRequest($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$statusCode = 0;
|
|
|
|
if ($this->checkRequest($location)) {
|
2019-12-15 16:22:07 +00:00
|
|
|
$scheme = $this->yellow->system->get("coreServerScheme");
|
|
|
|
$address = $this->yellow->system->get("coreServerAddress");
|
|
|
|
$base = rtrim($this->yellow->system->get("coreServerBase").$this->yellow->system->get("editLocation"), "/");
|
2018-08-10 22:23:50 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
2018-11-09 08:36:49 +00:00
|
|
|
// Handle page content of shortcut
|
|
|
|
public function onParseContentShortcut($page, $name, $text, $type) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$output = null;
|
2018-11-09 08:36:49 +00:00
|
|
|
if ($name=="edit" && $type=="inline") {
|
2018-08-10 22:23:50 +00:00
|
|
|
$editText = "$name $text";
|
|
|
|
if (substru($text, 0, 2)=="- ") $editText = trim(substru($text, 2));
|
|
|
|
$output = "<a href=\"".$page->get("pageEdit")."\">".htmlspecialchars($editText)."</a>";
|
|
|
|
}
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
2018-08-23 20:12:14 +00:00
|
|
|
// Handle page extra data
|
|
|
|
public function onParsePageExtra($page, $name) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$output = null;
|
|
|
|
if ($name=="header" && $this->response->isActive()) {
|
2019-06-01 13:21:51 +00:00
|
|
|
$this->response->processPageData($page);
|
2019-12-15 16:22:07 +00:00
|
|
|
$extensionLocation = $this->yellow->system->get("coreServerBase").$this->yellow->system->get("coreExtensionLocation");
|
2019-02-23 14:04:34 +00:00
|
|
|
$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";
|
2018-08-10 22:23:50 +00:00
|
|
|
$output .= "<script type=\"text/javascript\">\n";
|
|
|
|
$output .= "// <![CDATA[\n";
|
2019-01-28 13:58:26 +00:00
|
|
|
$output .= "yellow.page = ".json_encode($this->response->getPageData($page)).";\n";
|
2019-02-23 14:04:34 +00:00
|
|
|
$output .= "yellow.system = ".json_encode($this->response->getSystemData()).";\n";
|
2018-08-10 22:23:50 +00:00
|
|
|
$output .= "yellow.text = ".json_encode($this->response->getTextData()).";\n";
|
|
|
|
$output .= "// ]]>\n";
|
|
|
|
$output .= "</script>\n";
|
|
|
|
}
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle command
|
|
|
|
public function onCommand($args) {
|
|
|
|
list($command) = $args;
|
|
|
|
switch ($command) {
|
2018-09-06 11:23:56 +00:00
|
|
|
case "user": $statusCode = $this->processCommandUser($args); break;
|
2018-08-10 22:23:50 +00:00
|
|
|
default: $statusCode = 0;
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle command help
|
|
|
|
public function onCommandHelp() {
|
|
|
|
return "user [option email password name]\n";
|
|
|
|
}
|
2016-06-02 15:31:42 +00:00
|
|
|
|
2019-03-16 07:59:37 +00:00
|
|
|
// Handle update
|
|
|
|
public function onUpdate($action) {
|
2019-09-12 12:56:05 +00:00
|
|
|
if ($action=="update") { //TODO: remove later, converts old format
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2019-03-16 07:59:37 +00:00
|
|
|
$fileData = $this->yellow->toolbox->readFile($fileNameUser);
|
|
|
|
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
|
|
|
|
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
|
2019-12-17 10:46:09 +00:00
|
|
|
if (lcfirst($matches[1])=="group") {
|
|
|
|
$fileDataNew .= "Access: create, edit, delete, upload".($matches[2]=="administrator" ? ", system, update" : "")."\n";
|
|
|
|
} elseif (!empty($matches[1]) && !empty($matches[2]) && $matches[1][0]!="#" && preg_match("/@/", $matches[1])) {
|
2020-01-03 09:15:15 +00:00
|
|
|
list($hash, $name, $language, $status, $pending, $stamp, $timestamp, $failed, $group, $home) = explode(",", $matches[2]);
|
2019-12-17 10:46:09 +00:00
|
|
|
$access = "create, edit, delete, upload".($group=="administrator" ? ", system, update" : "");
|
2020-01-03 09:15:15 +00:00
|
|
|
$modified = date("Y-m-d H:i:s", $timestamp);
|
2020-01-15 18:30:45 +00:00
|
|
|
$fileDataNew .= "Email: $matches[1]\nName: $name\nLanguage: $language\nHome: $home\nAccess: $access\nHash: $hash\nStamp: $stamp\nPending: $pending\nFailed: $failed\nModified: $modified\nStatus: $status\n\n";
|
2019-03-16 07:59:37 +00:00
|
|
|
} else {
|
|
|
|
$fileDataNew .= $line;
|
|
|
|
}
|
|
|
|
}
|
2019-09-12 12:56:05 +00:00
|
|
|
$fileDataNew = rtrim($fileDataNew)."\n";
|
|
|
|
if ($fileData!=$fileDataNew && !$this->yellow->toolbox->createFile($fileNameUser, $fileDataNew)) {
|
|
|
|
$this->yellow->log("error", "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($action=="update") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2019-09-12 12:56:05 +00:00
|
|
|
$fileData = $this->yellow->toolbox->readFile($fileNameUser);
|
|
|
|
$fileDataNew = "";
|
|
|
|
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
|
|
|
|
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
|
|
|
|
if (lcfirst($matches[1])=="email" && !strempty($matches[2])) {
|
|
|
|
$status = $this->users->getUser($matches[2], "status");
|
|
|
|
$cleanup = !empty($status) && $status!="active" && $status!="inactive";
|
|
|
|
}
|
|
|
|
if (!$cleanup) $fileDataNew .= $line;
|
|
|
|
}
|
|
|
|
$fileDataNew = rtrim($fileDataNew)."\n";
|
2019-06-04 20:39:27 +00:00
|
|
|
if ($fileData!=$fileDataNew && !$this->yellow->toolbox->createFile($fileNameUser, $fileDataNew)) {
|
|
|
|
$this->yellow->log("error", "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
2019-03-16 07:59:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-06 11:23:56 +00:00
|
|
|
// Process command to update user account
|
|
|
|
public function processCommandUser($args) {
|
2018-08-10 22:23:50 +00:00
|
|
|
list($command, $option) = $args;
|
|
|
|
switch ($option) {
|
|
|
|
case "": $statusCode = $this->userShow($args); break;
|
|
|
|
case "add": $statusCode = $this->userAdd($args); break;
|
|
|
|
case "change": $statusCode = $this->userChange($args); break;
|
|
|
|
case "remove": $statusCode = $this->userRemove($args); break;
|
|
|
|
default: $statusCode = 400; echo "Yellow $command: Invalid arguments\n";
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show user accounts
|
|
|
|
public function userShow($args) {
|
|
|
|
list($command) = $args;
|
|
|
|
foreach ($this->users->getData() as $line) {
|
|
|
|
echo "$line\n";
|
|
|
|
}
|
|
|
|
if (!$this->users->getNumber()) echo "Yellow $command: No user accounts\n";
|
|
|
|
return 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add user account
|
|
|
|
public function userAdd($args) {
|
|
|
|
$status = "ok";
|
|
|
|
list($command, $option, $email, $password, $name) = $args;
|
|
|
|
if (empty($email) || empty($password)) $status = $this->response->status = "incomplete";
|
2019-03-27 12:19:30 +00:00
|
|
|
if (empty($name)) $name = $this->yellow->system->get("sitename");
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($status=="ok") $status = $this->getUserAccount($email, $password, "add");
|
|
|
|
if ($status=="ok" && $this->users->isTaken($email)) $status = "taken";
|
|
|
|
switch ($status) {
|
2019-02-23 14:04:34 +00:00
|
|
|
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;
|
2019-06-04 20:39:27 +00:00
|
|
|
case "short": echo "ERROR updating settings: Please enter a longer password!\n"; break;
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
if ($status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2019-09-12 12:56:05 +00:00
|
|
|
$settings = array(
|
|
|
|
"name" => $name,
|
|
|
|
"language" => $this->yellow->system->get("language"),
|
|
|
|
"home" => $this->yellow->system->get("editUserHome"),
|
2019-12-17 10:46:09 +00:00
|
|
|
"access" => $this->yellow->system->get("editUserAccess"),
|
2019-09-12 12:56:05 +00:00
|
|
|
"hash" => $this->users->createHash($password),
|
|
|
|
"stamp" => $this->users->createStamp(),
|
2020-01-15 18:30:45 +00:00
|
|
|
"pending" => "none",
|
2019-09-12 12:56:05 +00:00
|
|
|
"failed" => "0",
|
2020-01-15 18:30:45 +00:00
|
|
|
"modified" => date("Y-m-d H:i:s", time()),
|
|
|
|
"status" => "active");
|
2019-09-12 12:56:05 +00:00
|
|
|
$status = $this->users->save($fileNameUser, $email, $settings) ? "ok" : "error";
|
2019-02-23 14:04:34 +00:00
|
|
|
if ($status=="error") echo "ERROR updating settings: Can't write file '$fileNameUser'!\n";
|
2019-03-27 12:19:30 +00:00
|
|
|
$this->yellow->log($status=="ok" ? "info" : "error", "Add user '".strtok($name, " ")."'");
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
if ($status=="ok") {
|
2019-02-23 14:04:34 +00:00
|
|
|
$algorithm = $this->yellow->system->get("editUserHashAlgorithm");
|
2019-09-12 12:56:05 +00:00
|
|
|
$status = substru($this->users->getUser($email, "hash"), 0, 10)!="error-hash" ? "ok" : "error";
|
2019-02-23 14:04:34 +00:00
|
|
|
if ($status=="error") echo "ERROR updating settings: Hash algorithm '$algorithm' not supported!\n";
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
$statusCode = $status=="ok" ? 200 : 500;
|
|
|
|
echo "Yellow $command: User account ".($statusCode!=200 ? "not " : "")."added\n";
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change user account
|
|
|
|
public function userChange($args) {
|
|
|
|
$status = "ok";
|
|
|
|
list($command, $option, $email, $password, $name) = $args;
|
|
|
|
if (empty($email)) $status = $this->response->status = "invalid";
|
|
|
|
if ($status=="ok") $status = $this->getUserAccount($email, $password, "change");
|
|
|
|
if ($status=="ok" && !$this->users->isExisting($email)) $status = "unknown";
|
|
|
|
switch ($status) {
|
2019-02-23 14:04:34 +00:00
|
|
|
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;
|
2019-06-04 20:39:27 +00:00
|
|
|
case "short": echo "ERROR updating settings: Please enter a longer password!\n"; break;
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
if ($status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2019-09-12 12:56:05 +00:00
|
|
|
$settings = array(
|
|
|
|
"name" => empty($name) ? $this->users->getUser($email, "name") : $name,
|
|
|
|
"hash" => empty($password) ? $this->users->getUser($email, "hash") : $this->users->createHash($password),
|
|
|
|
"failed" => "0",
|
2020-01-03 09:15:15 +00:00
|
|
|
"modified" => date("Y-m-d H:i:s", time()));
|
2019-09-12 12:56:05 +00:00
|
|
|
$status = $this->users->save($fileNameUser, $email, $settings) ? "ok" : "error";
|
2019-02-23 14:04:34 +00:00
|
|
|
if ($status=="error") echo "ERROR updating settings: Can't write file '$fileNameUser'!\n";
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
$statusCode = $status=="ok" ? 200 : 500;
|
|
|
|
echo "Yellow $command: User account ".($statusCode!=200 ? "not " : "")."changed\n";
|
|
|
|
return $statusCode;
|
|
|
|
}
|
2018-06-14 08:32:07 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Remove user account
|
|
|
|
public function userRemove($args) {
|
|
|
|
$status = "ok";
|
|
|
|
list($command, $option, $email) = $args;
|
2019-09-12 12:56:05 +00:00
|
|
|
$name = $this->users->getUser($email, "name");
|
2018-08-10 22:23:50 +00:00
|
|
|
if (empty($email)) $status = $this->response->status = "invalid";
|
2019-03-27 12:19:30 +00:00
|
|
|
if (empty($name)) $name = $this->yellow->system->get("sitename");
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($status=="ok") $status = $this->getUserAccount($email, "", "remove");
|
|
|
|
if ($status=="ok" && !$this->users->isExisting($email)) $status = "unknown";
|
|
|
|
switch ($status) {
|
2019-02-23 14:04:34 +00:00
|
|
|
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;
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
if ($status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2018-08-10 22:23:50 +00:00
|
|
|
$status = $this->users->remove($fileNameUser, $email) ? "ok" : "error";
|
2019-02-23 14:04:34 +00:00
|
|
|
if ($status=="error") echo "ERROR updating settings: Can't write file '$fileNameUser'!\n";
|
2019-03-27 12:19:30 +00:00
|
|
|
$this->yellow->log($status=="ok" ? "info" : "error", "Remove user '".strtok($name, " ")."'");
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
$statusCode = $status=="ok" ? 200 : 500;
|
|
|
|
echo "Yellow $command: User account ".($statusCode!=200 ? "not " : "")."removed\n";
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request
|
|
|
|
public function processRequest($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$statusCode = 0;
|
|
|
|
if ($this->checkUserAuth($scheme, $address, $base, $location, $fileName)) {
|
|
|
|
switch ($_REQUEST["action"]) {
|
|
|
|
case "": $statusCode = $this->processRequestShow($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "login": $statusCode = $this->processRequestLogin($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "logout": $statusCode = $this->processRequestLogout($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "quit": $statusCode = $this->processRequestQuit($scheme, $address, $base, $location, $fileName); break;
|
2019-04-03 14:44:12 +00:00
|
|
|
case "account": $statusCode = $this->processRequestAccount($scheme, $address, $base, $location, $fileName); break;
|
2019-06-09 09:38:12 +00:00
|
|
|
case "system": $statusCode = $this->processRequestSystem($scheme, $address, $base, $location, $fileName); break;
|
2019-04-03 14:44:12 +00:00
|
|
|
case "update": $statusCode = $this->processRequestUpdate($scheme, $address, $base, $location, $fileName); break;
|
2018-08-10 22:23:50 +00:00
|
|
|
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 "preview": $statusCode = $this->processRequestPreview($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "upload": $statusCode = $this->processRequestUpload($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
}
|
|
|
|
} elseif ($this->checkUserUnauth($scheme, $address, $base, $location, $fileName)) {
|
|
|
|
$this->yellow->lookup->requestHandler = "core";
|
|
|
|
switch ($_REQUEST["action"]) {
|
|
|
|
case "": $statusCode = $this->processRequestShow($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "signup": $statusCode = $this->processRequestSignup($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "forgot": $statusCode = $this->processRequestForgot($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "confirm": $statusCode = $this->processRequestConfirm($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "approve": $statusCode = $this->processRequestApprove($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "recover": $statusCode = $this->processRequestRecover($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "reactivate": $statusCode = $this->processRequestReactivate($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "verify": $statusCode = $this->processRequestVerify($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "change": $statusCode = $this->processRequestChange($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
case "remove": $statusCode = $this->processRequestRemove($scheme, $address, $base, $location, $fileName); break;
|
|
|
|
}
|
|
|
|
}
|
2019-01-28 13:58:26 +00:00
|
|
|
if ($statusCode==0) $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
2018-08-10 22:23:50 +00:00
|
|
|
$this->checkUserFailed($scheme, $address, $base, $location, $fileName);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to show file
|
|
|
|
public function processRequestShow($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$statusCode = 0;
|
|
|
|
if (is_readable($fileName)) {
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
} else {
|
|
|
|
if ($this->yellow->lookup->isRedirectLocation($location)) {
|
|
|
|
$location = $this->yellow->lookup->isFileLocation($location) ? "$location/" : "/".$this->yellow->getRequestLanguage()."/";
|
|
|
|
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
|
|
|
|
$statusCode = $this->yellow->sendStatus(301, $location);
|
|
|
|
} else {
|
2019-12-17 10:46:09 +00:00
|
|
|
$this->yellow->page->error($this->response->isUserAccess("edit", $location) ? 434 : 404);
|
2018-08-10 22:23:50 +00:00
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
2014-07-25 10:46:58 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Process request for user login
|
|
|
|
public function processRequestLogin($scheme, $address, $base, $location, $fileName) {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2020-01-03 09:15:15 +00:00
|
|
|
$settings = array("failed" => "0", "modified" => date("Y-m-d H:i:s", time()));
|
2019-09-12 12:56:05 +00:00
|
|
|
if ($this->users->save($fileNameUser, $this->response->userEmail, $settings)) {
|
|
|
|
$home = $this->users->getUser($this->response->userEmail, "home");
|
2018-08-10 22:23:50 +00:00
|
|
|
if (substru($location, 0, strlenu($home))==$home) {
|
|
|
|
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
|
|
|
|
$statusCode = $this->yellow->sendStatus(303, $location);
|
|
|
|
} else {
|
|
|
|
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $home);
|
|
|
|
$statusCode = $this->yellow->sendStatus(302, $location);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request for user logout
|
|
|
|
public function processRequestLogout($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->userEmail = "";
|
|
|
|
$this->response->destroyCookies($scheme, $address, $base);
|
|
|
|
$location = $this->yellow->lookup->normaliseUrl(
|
2019-12-15 16:22:07 +00:00
|
|
|
$this->yellow->system->get("coreServerScheme"),
|
|
|
|
$this->yellow->system->get("coreServerAddress"),
|
|
|
|
$this->yellow->system->get("coreServerBase"),
|
2018-08-10 22:23:50 +00:00
|
|
|
$location);
|
|
|
|
$statusCode = $this->yellow->sendStatus(302, $location);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
2016-04-12 13:58:56 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Process request for user signup
|
|
|
|
public function processRequestSignup($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "signup";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$name = trim(preg_replace("/[^\pL\d\-\. ]/u", "-", $_REQUEST["name"]));
|
|
|
|
$email = trim($_REQUEST["email"]);
|
|
|
|
$password = trim($_REQUEST["password"]);
|
|
|
|
$consent = trim($_REQUEST["consent"]);
|
|
|
|
if (empty($name) || empty($email) || empty($password) || empty($consent)) $this->response->status = "incomplete";
|
|
|
|
if ($this->response->status=="ok") $this->response->status = $this->getUserAccount($email, $password, $this->response->action);
|
2019-03-16 07:59:37 +00:00
|
|
|
if ($this->response->status=="ok" && $this->response->isLoginRestriction()) $this->response->status = "next";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($this->response->status=="ok" && $this->users->isTaken($email)) $this->response->status = "next";
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2019-09-12 12:56:05 +00:00
|
|
|
$settings = array(
|
|
|
|
"name" => $name,
|
|
|
|
"language" => $this->yellow->lookup->findLanguageFromFile($fileName, $this->yellow->system->get("language")),
|
|
|
|
"home" => $this->yellow->system->get("editUserHome"),
|
2019-12-17 10:46:09 +00:00
|
|
|
"access" => $this->yellow->system->get("editUserAccess"),
|
2019-09-12 12:56:05 +00:00
|
|
|
"hash" => $this->users->createHash($password),
|
|
|
|
"stamp" => $this->users->createStamp(),
|
2020-01-15 18:30:45 +00:00
|
|
|
"pending" => "none",
|
2019-09-12 12:56:05 +00:00
|
|
|
"failed" => "0",
|
2020-01-15 18:30:45 +00:00
|
|
|
"modified" => date("Y-m-d H:i:s", time()),
|
|
|
|
"status" => "unconfirmed");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $email, $settings) ? "ok" : "error";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
2019-02-23 14:04:34 +00:00
|
|
|
$algorithm = $this->yellow->system->get("editUserHashAlgorithm");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = substru($this->users->getUser($email, "hash"), 0, 10)!="error-hash" ? "ok" : "error";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Hash algorithm '$algorithm' not supported!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "confirm") ? "next" : "error";
|
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!");
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to confirm user signup
|
|
|
|
public function processRequestConfirm($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "confirm";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$email = $_REQUEST["email"];
|
|
|
|
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2020-01-15 18:30:45 +00:00
|
|
|
$settings = array("failed" => "0", "modified" => date("Y-m-d H:i:s", time()), "status" => "unapproved");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $email, $settings) ? "ok" : "error";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "approve") ? "done" : "error";
|
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!");
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to approve user signup
|
|
|
|
public function processRequestApprove($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "approve";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$email = $_REQUEST["email"];
|
|
|
|
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2020-01-15 18:30:45 +00:00
|
|
|
$settings = array("failed" => "0", "modified" => date("Y-m-d H:i:s", time()), "status" => "active");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $email, $settings) ? "ok" : "error";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->yellow->log($this->response->status=="ok" ? "info" : "error", "Add user '".strtok($this->users->getUser($email, "name"), " ")."'");
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "welcome") ? "done" : "error";
|
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!");
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
2017-07-05 10:25:25 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Process request for forgotten password
|
|
|
|
public function processRequestForgot($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "forgot";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$email = trim($_REQUEST["email"]);
|
|
|
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $this->response->status = "invalid";
|
|
|
|
if ($this->response->status=="ok" && !$this->users->isExisting($email)) $this->response->status = "next";
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "recover") ? "next" : "error";
|
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!");
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to recover password
|
|
|
|
public function processRequestRecover($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "recover";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$email = trim($_REQUEST["email"]);
|
|
|
|
$password = trim($_REQUEST["password"]);
|
|
|
|
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
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") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2020-01-03 09:15:15 +00:00
|
|
|
$settings = array("hash" => $this->users->createHash($password), "failed" => "0", "modified" => date("Y-m-d H:i:s", time()));
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $email, $settings) ? "ok" : "error";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$this->response->destroyCookies($scheme, $address, $base);
|
|
|
|
$this->response->status = "done";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to reactivate account
|
|
|
|
public function processRequestReactivate($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "reactivate";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$email = $_REQUEST["email"];
|
|
|
|
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2020-01-15 18:30:45 +00:00
|
|
|
$settings = array("failed" => "0", "modified" => date("Y-m-d H:i:s", time()), "status" => "active");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $email, $settings) ? "done" : "error";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to verify email
|
|
|
|
public function processRequestVerify($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "verify";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$email = $emailSource = $_REQUEST["email"];
|
|
|
|
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
|
|
|
|
if ($this->response->status=="ok") {
|
2019-09-12 12:56:05 +00:00
|
|
|
$emailSource = $this->users->getUser($email, "pending");
|
|
|
|
if ($this->users->getUser($emailSource, "status")!="active") $this->response->status = "done";
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2020-01-15 18:30:45 +00:00
|
|
|
$settings = array("failed" => "0", "modified" => date("Y-m-d H:i:s", time()), "status" => "unchanged");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $email, $settings) ? "ok" : "error";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$this->response->status = $this->response->sendMail($scheme, $address, $base, $emailSource, "change") ? "done" : "error";
|
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!");
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to change email or password
|
|
|
|
public function processRequestChange($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "change";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$email = $emailSource = trim($_REQUEST["email"]);
|
|
|
|
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
|
|
|
|
if ($this->response->status=="ok") {
|
2019-09-12 12:56:05 +00:00
|
|
|
list($email, $hash) = explode(":", $this->users->getUser($email, "pending"), 2);
|
2018-08-10 22:23:50 +00:00
|
|
|
if (!$this->users->isExisting($email) || empty($hash)) $this->response->status = "done";
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2019-09-12 12:56:05 +00:00
|
|
|
$settings = array(
|
|
|
|
"hash" => $hash,
|
2020-01-15 18:30:45 +00:00
|
|
|
"pending" => "none",
|
2019-09-12 12:56:05 +00:00
|
|
|
"failed" => "0",
|
2020-01-15 18:30:45 +00:00
|
|
|
"modified" => date("Y-m-d H:i:s", time()),
|
|
|
|
"status" => "active");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $email, $settings) ? "ok" : "error";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok" && $email!=$emailSource) {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2018-08-10 22:23:50 +00:00
|
|
|
$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'!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$this->response->destroyCookies($scheme, $address, $base);
|
|
|
|
$this->response->status = "done";
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
2019-04-03 14:44:12 +00:00
|
|
|
// Process request to quit account
|
|
|
|
public function processRequestQuit($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "quit";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$name = trim($_REQUEST["name"]);
|
|
|
|
$email = $this->response->userEmail;
|
|
|
|
if (empty($name)) $this->response->status = "none";
|
2019-09-12 12:56:05 +00:00
|
|
|
if ($this->response->status=="ok" && $name!=$this->users->getUser($email, "name")) $this->response->status = "mismatch";
|
2019-04-03 14:44:12 +00:00
|
|
|
if ($this->response->status=="ok") $this->response->status = $this->getUserAccount($email, "", $this->response->action);
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "remove") ? "next" : "error";
|
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!");
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to remove account
|
|
|
|
public function processRequestRemove($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "remove";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$email = $_REQUEST["email"];
|
|
|
|
$this->response->status = $this->getUserStatus($email, $_REQUEST["action"]);
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2020-01-15 18:30:45 +00:00
|
|
|
$settings = array("failed" => "0", "modified" => date("Y-m-d H:i:s", time()), "status" => "removed");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $email, $settings) ? "ok" : "error";
|
2019-04-03 14:44:12 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->yellow->log($this->response->status=="ok" ? "info" : "error", "Remove user '".strtok($this->users->getUser($email, "name"), " ")."'");
|
2019-04-03 14:44:12 +00:00
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$this->response->status = $this->response->sendMail($scheme, $address, $base, $email, "goodbye") ? "ok" : "error";
|
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2019-04-03 14:44:12 +00:00
|
|
|
$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'!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$this->response->destroyCookies($scheme, $address, $base);
|
|
|
|
$this->response->status = "done";
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to change account settings
|
|
|
|
public function processRequestAccount($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$this->response->action = "account";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$email = trim($_REQUEST["email"]);
|
|
|
|
$emailSource = $this->response->userEmail;
|
|
|
|
$password = trim($_REQUEST["password"]);
|
|
|
|
$name = trim(preg_replace("/[^\pL\d\-\. ]/u", "-", $_REQUEST["name"]));
|
|
|
|
$language = trim($_REQUEST["language"]);
|
|
|
|
if ($email!=$emailSource || !empty($password)) {
|
|
|
|
if (empty($email)) $this->response->status = "invalid";
|
|
|
|
if ($this->response->status=="ok") $this->response->status = $this->getUserAccount($email, $password, $this->response->action);
|
|
|
|
if ($this->response->status=="ok" && $email!=$emailSource && $this->users->isTaken($email)) $this->response->status = "taken";
|
|
|
|
if ($this->response->status=="ok" && $email!=$emailSource) {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2019-09-12 12:56:05 +00:00
|
|
|
$settings = array(
|
|
|
|
"name" => $name,
|
|
|
|
"language" => $language,
|
|
|
|
"home" => $this->users->getUser($emailSource, "home"),
|
2019-12-17 10:46:09 +00:00
|
|
|
"access" => $this->users->getUser($emailSource, "access"),
|
2019-09-12 12:56:05 +00:00
|
|
|
"hash" => $this->users->createHash("none"),
|
|
|
|
"stamp" => $this->users->createStamp(),
|
2020-01-15 18:30:45 +00:00
|
|
|
"pending" => $emailSource,
|
2019-09-12 12:56:05 +00:00
|
|
|
"failed" => "0",
|
2020-01-15 18:30:45 +00:00
|
|
|
"modified" => date("Y-m-d H:i:s", time()),
|
|
|
|
"status" => "unverified");
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $email, $settings) ? "ok" : "error";
|
2019-04-03 14:44:12 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2019-09-12 12:56:05 +00:00
|
|
|
$settings = array(
|
|
|
|
"name" => $name,
|
|
|
|
"language" => $language,
|
|
|
|
"pending" => $email.":".(empty($password) ? $this->users->getUser($emailSource, "hash") : $this->users->createHash($password)),
|
|
|
|
"failed" => "0",
|
2020-01-03 09:15:15 +00:00
|
|
|
"modified" => date("Y-m-d H:i:s", time()));
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $emailSource, $settings) ? "ok" : "error";
|
2019-04-03 14:44:12 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
|
|
|
$action = $email!=$emailSource ? "verify" : "change";
|
|
|
|
$this->response->status = $this->response->sendMail($scheme, $address, $base, $email, $action) ? "next" : "error";
|
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't send email on this server!");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2020-01-03 09:15:15 +00:00
|
|
|
$settings = array("name" => $name, "language" => $language, "failed" => "0", "modified" => date("Y-m-d H:i:s", time()));
|
2019-09-12 12:56:05 +00:00
|
|
|
$this->response->status = $this->users->save($fileNameUser, $email, $settings) ? "done" : "error";
|
2019-04-03 14:44:12 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($this->response->status=="done") {
|
|
|
|
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
|
|
|
|
$statusCode = $this->yellow->sendStatus(303, $location);
|
|
|
|
} else {
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
2019-06-09 09:38:12 +00:00
|
|
|
|
|
|
|
// Process request to change system settings
|
|
|
|
public function processRequestSystem($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$statusCode = 0;
|
2019-12-17 10:46:09 +00:00
|
|
|
if ($this->response->isUserAccess("system")) {
|
2019-06-09 09:38:12 +00:00
|
|
|
$this->response->action = "system";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$sitename = trim($_REQUEST["sitename"]);
|
|
|
|
$author = trim($_REQUEST["author"]);
|
|
|
|
$email = trim($_REQUEST["email"]);
|
|
|
|
if ($email!=$this->yellow->system->get("email")) {
|
|
|
|
if(empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) $this->response->status = "invalid";
|
|
|
|
}
|
|
|
|
if ($this->response->status=="ok") {
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileName = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("coreSystemFile");
|
2019-06-09 09:38:12 +00:00
|
|
|
$settings = array("sitename" => $sitename, "author" => $author, "email" => $email);
|
2019-12-17 10:46:09 +00:00
|
|
|
$file = $this->response->getFileSystem($scheme, $address, $base, $location, $fileName, $settings);
|
|
|
|
$this->response->status = (!$file->isError() && $this->yellow->system->save($fileName, $settings)) ? "done" : "error";
|
2019-06-09 09:38:12 +00:00
|
|
|
if ($this->response->status=="error") $this->yellow->page->error(500, "Can't write file '$fileName'!");
|
|
|
|
}
|
|
|
|
if ($this->response->status=="done") {
|
|
|
|
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
|
|
|
|
$statusCode = $this->yellow->sendStatus(303, $location);
|
|
|
|
} else {
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
2019-06-01 13:21:51 +00:00
|
|
|
|
|
|
|
// Process request to update website
|
|
|
|
public function processRequestUpdate($scheme, $address, $base, $location, $fileName) {
|
2019-06-09 09:38:12 +00:00
|
|
|
$statusCode = 0;
|
2019-12-17 10:46:09 +00:00
|
|
|
if ($this->response->isUserAccess("update")) {
|
2019-06-09 09:38:12 +00:00
|
|
|
$this->response->action = "update";
|
|
|
|
$this->response->status = "ok";
|
|
|
|
$extension = trim($_REQUEST["extension"]);
|
|
|
|
$option = trim($_REQUEST["option"]);
|
|
|
|
if ($option=="check") {
|
|
|
|
list($statusCode, $updates, $rawData) = $this->response->getUpdateInformation();
|
|
|
|
$this->response->status = $updates ? "updates" : "ok";
|
|
|
|
$this->response->rawDataOutput = $rawData;
|
|
|
|
if ($statusCode!=200) {
|
|
|
|
$this->response->status = "error";
|
|
|
|
$this->response->rawDataOutput = "";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$this->response->status = $this->yellow->command("update", $extension, $option)==200 ? "done" : "error";
|
|
|
|
}
|
|
|
|
if ($this->response->status=="done") {
|
|
|
|
$location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
|
|
|
|
$statusCode = $this->yellow->sendStatus(303, $location);
|
|
|
|
} else {
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to create page
|
|
|
|
public function processRequestCreate($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$statusCode = 0;
|
2019-12-17 10:46:09 +00:00
|
|
|
if ($this->response->isUserAccess("create", $location) && !empty($_REQUEST["rawdataedit"])) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$this->response->rawDataSource = $_REQUEST["rawdatasource"];
|
|
|
|
$this->response->rawDataEdit = $_REQUEST["rawdatasource"];
|
|
|
|
$this->response->rawDataEndOfLine = $_REQUEST["rawdataendofline"];
|
|
|
|
$rawData = $_REQUEST["rawdataedit"];
|
2018-11-09 08:36:49 +00:00
|
|
|
$page = $this->response->getPageNew($scheme, $address, $base, $location, $fileName,
|
|
|
|
$rawData, $this->response->getEndOfLine());
|
2018-08-10 22:23:50 +00:00
|
|
|
if (!$page->isError()) {
|
|
|
|
if ($this->yellow->toolbox->createFile($page->fileName, $page->rawData, true)) {
|
|
|
|
$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"));
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to edit page
|
|
|
|
public function processRequestEdit($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$statusCode = 0;
|
2019-12-17 10:46:09 +00:00
|
|
|
if ($this->response->isUserAccess("edit", $location) && !empty($_REQUEST["rawdataedit"])) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$this->response->rawDataSource = $_REQUEST["rawdatasource"];
|
|
|
|
$this->response->rawDataEdit = $_REQUEST["rawdataedit"];
|
|
|
|
$this->response->rawDataEndOfLine = $_REQUEST["rawdataendofline"];
|
|
|
|
$rawDataFile = $this->yellow->toolbox->readFile($fileName);
|
|
|
|
$page = $this->response->getPageEdit($scheme, $address, $base, $location, $fileName,
|
|
|
|
$this->response->rawDataSource, $this->response->rawDataEdit, $rawDataFile, $this->response->rawDataEndOfLine);
|
|
|
|
if (!$page->isError()) {
|
2018-11-09 08:36:49 +00:00
|
|
|
if ($this->yellow->lookup->isFileLocation($location)) {
|
|
|
|
if ($this->yellow->toolbox->renameFile($fileName, $page->fileName, true) &&
|
2018-08-10 22:23:50 +00:00
|
|
|
$this->yellow->toolbox->createFile($page->fileName, $page->rawData)) {
|
2018-11-09 08:36:49 +00:00
|
|
|
$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);
|
|
|
|
}
|
2018-08-10 22:23:50 +00:00
|
|
|
} else {
|
2018-11-09 08:36:49 +00:00
|
|
|
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);
|
|
|
|
}
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$this->yellow->page->error(500, $page->get("pageError"));
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
2014-07-25 10:46:58 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Process request to delete page
|
|
|
|
public function processRequestDelete($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$statusCode = 0;
|
2019-12-17 10:46:09 +00:00
|
|
|
if ($this->response->isUserAccess("delete", $location) && is_file($fileName)) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$this->response->rawDataSource = $_REQUEST["rawdatasource"];
|
|
|
|
$this->response->rawDataEdit = $_REQUEST["rawdatasource"];
|
|
|
|
$this->response->rawDataEndOfLine = $_REQUEST["rawdataendofline"];
|
|
|
|
$rawDataFile = $this->yellow->toolbox->readFile($fileName);
|
|
|
|
$page = $this->response->getPageDelete($scheme, $address, $base, $location, $fileName,
|
|
|
|
$rawDataFile, $this->response->rawDataEndOfLine);
|
|
|
|
if (!$page->isError()) {
|
|
|
|
if ($this->yellow->lookup->isFileLocation($location)) {
|
2019-12-15 16:22:07 +00:00
|
|
|
if ($this->yellow->toolbox->deleteFile($fileName, $this->yellow->system->get("coreTrashDir"))) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$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 {
|
2019-12-15 16:22:07 +00:00
|
|
|
if ($this->yellow->toolbox->deleteDirectory(dirname($fileName), $this->yellow->system->get("coreTrashDir"))) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$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"));
|
|
|
|
$statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
2018-04-15 12:45:50 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Process request to show preview
|
|
|
|
public function processRequestPreview($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$page = $this->response->getPagePreview($scheme, $address, $base, $location, $fileName,
|
|
|
|
$_REQUEST["rawdataedit"], $_REQUEST["rawdataendofline"]);
|
|
|
|
$statusCode = $this->yellow->sendData(200, $page->outputData, "", false);
|
|
|
|
if (defined("DEBUG") && DEBUG>=1) {
|
|
|
|
$parser = $page->get("parser");
|
|
|
|
echo "YellowEdit::processRequestPreview parser:$parser<br/>\n";
|
|
|
|
}
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process request to upload file
|
|
|
|
public function processRequestUpload($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$data = array();
|
|
|
|
$fileNameTemp = $_FILES["file"]["tmp_name"];
|
|
|
|
$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) : "");
|
2019-02-23 14:04:34 +00:00
|
|
|
$extensions = preg_split("/\s*,\s*/", $this->yellow->system->get("editUploadExtensions"));
|
2019-12-17 10:46:09 +00:00
|
|
|
if ($this->response->isUserAccess("upload", $location) && is_uploaded_file($fileNameTemp) &&
|
|
|
|
filesize($fileNameTemp)<=$fileSizeMax && in_array($extension, $extensions)) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$file = $this->response->getFileUpload($scheme, $address, $base, $location, $fileNameTemp, $fileNameShort);
|
|
|
|
if (!$file->isError() && $this->yellow->toolbox->copyFile($fileNameTemp, $file->fileName, true)) {
|
|
|
|
$data["location"] = $file->getLocation();
|
|
|
|
} else {
|
|
|
|
$data["error"] = "Can't write file '$file->fileName'!";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$data["error"] = "Can't write file '$fileNameShort'!";
|
|
|
|
}
|
|
|
|
$statusCode = $this->yellow->sendData(is_null($data["error"]) ? 200 : 500, json_encode($data), "a.json", false);
|
|
|
|
return $statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check request
|
|
|
|
public function checkRequest($location) {
|
2019-02-23 14:04:34 +00:00
|
|
|
$locationLength = strlenu($this->yellow->system->get("editLocation"));
|
|
|
|
$this->response->active = substru($location, 0, $locationLength)==$this->yellow->system->get("editLocation");
|
2018-08-10 22:23:50 +00:00
|
|
|
return $this->response->isActive();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check user authentication
|
|
|
|
public function checkUserAuth($scheme, $address, $base, $location, $fileName) {
|
|
|
|
if ($this->isRequestSameSite("POST", $scheme, $address) || $_REQUEST["action"]=="") {
|
|
|
|
if ($_REQUEST["action"]=="login") {
|
|
|
|
$email = $_REQUEST["email"];
|
|
|
|
$password = $_REQUEST["password"];
|
|
|
|
if ($this->users->checkAuthLogin($email, $password)) {
|
|
|
|
$this->response->createCookies($scheme, $address, $base, $email);
|
|
|
|
$this->response->userEmail = $email;
|
|
|
|
$this->response->language = $this->getUserLanguage($email);
|
|
|
|
} else {
|
|
|
|
$this->response->userFailedError = "login";
|
|
|
|
$this->response->userFailedEmail = $email;
|
|
|
|
$this->response->userFailedExpire = PHP_INT_MAX;
|
|
|
|
}
|
|
|
|
} elseif (isset($_COOKIE["authtoken"]) && isset($_COOKIE["csrftoken"])) {
|
|
|
|
if ($this->users->checkAuthToken($_COOKIE["authtoken"], $_COOKIE["csrftoken"], $_POST["csrftoken"], $_REQUEST["action"]=="")) {
|
|
|
|
$this->response->userEmail = $email = $this->users->getAuthEmail($_COOKIE["authtoken"]);
|
|
|
|
$this->response->language = $this->getUserLanguage($email);
|
|
|
|
} else {
|
|
|
|
$this->response->userFailedError = "auth";
|
|
|
|
$this->response->userFailedEmail = $this->users->getAuthEmail($_COOKIE["authtoken"]);
|
|
|
|
$this->response->userFailedExpire = $this->users->getAuthExpire($_COOKIE["authtoken"]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $this->response->isUser();
|
|
|
|
}
|
2018-05-21 21:13:32 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Check user without authentication
|
|
|
|
public function checkUserUnauth($scheme, $address, $base, $location, $fileName) {
|
|
|
|
$ok = false;
|
|
|
|
if ($_REQUEST["action"]=="" || $_REQUEST["action"]=="signup" || $_REQUEST["action"]=="forgot") {
|
|
|
|
$ok = true;
|
|
|
|
} elseif (isset($_REQUEST["actiontoken"])) {
|
|
|
|
if ($this->users->checkActionToken($_REQUEST["actiontoken"], $_REQUEST["email"], $_REQUEST["action"], $_REQUEST["expire"])) {
|
|
|
|
$ok = true;
|
2019-04-03 14:44:12 +00:00
|
|
|
$this->response->language = $this->getActionLanguage($_REQUEST["language"]);
|
2018-08-10 22:23:50 +00:00
|
|
|
} else {
|
|
|
|
$this->response->userFailedError = "action";
|
|
|
|
$this->response->userFailedEmail = $_REQUEST["email"];
|
|
|
|
$this->response->userFailedExpire = $_REQUEST["expire"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $ok;
|
|
|
|
}
|
2018-05-21 21:13:32 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Check user failed
|
|
|
|
public function checkUserFailed($scheme, $address, $base, $location, $fileName) {
|
|
|
|
if (!empty($this->response->userFailedError)) {
|
|
|
|
if ($this->response->userFailedExpire>time() && $this->users->isExisting($this->response->userFailedEmail)) {
|
|
|
|
$email = $this->response->userFailedEmail;
|
2019-09-12 12:56:05 +00:00
|
|
|
$failed = $this->users->getUser($email, "failed")+1;
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileNameUser = $this->yellow->system->get("coreSettingDir").$this->yellow->system->get("editUserFile");
|
2019-09-12 12:56:05 +00:00
|
|
|
$status = $this->users->save($fileNameUser, $email, array("failed" => $failed)) ? "ok" : "error";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
2019-09-12 12:56:05 +00:00
|
|
|
if ($failed==$this->yellow->system->get("editBruteForceProtection")) {
|
|
|
|
$statusBeforeProtection = $this->users->getUser($email, "status");
|
2018-08-10 22:23:50 +00:00
|
|
|
$statusAfterProtection = ($statusBeforeProtection=="active" || $statusBeforeProtection=="inactive") ? "inactive" : "failed";
|
|
|
|
if ($status=="ok") {
|
2019-09-12 12:56:05 +00:00
|
|
|
$status = $this->users->save($fileNameUser, $email, array("status" => $statusAfterProtection)) ? "ok" : "error";
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
|
|
|
|
}
|
|
|
|
if ($status=="ok" && $statusBeforeProtection=="active") {
|
|
|
|
$status = $this->response->sendMail($scheme, $address, $base, $email, "reactivate") ? "done" : "error";
|
|
|
|
if ($status=="error") $this->yellow->page->error(500, "Can't send email on this server!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($this->response->userFailedError=="login" || $this->response->userFailedError=="auth") {
|
|
|
|
$this->response->destroyCookies($scheme, $address, $base);
|
|
|
|
$this->response->status = "error";
|
|
|
|
$this->yellow->page->error(430);
|
|
|
|
} else {
|
|
|
|
$this->response->status = "error";
|
|
|
|
$this->yellow->page->error(500, "Link has expired!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return user status changes
|
|
|
|
public function getUserStatus($email, $action) {
|
|
|
|
switch ($action) {
|
|
|
|
case "confirm": $statusExpected = "unconfirmed"; break;
|
|
|
|
case "approve": $statusExpected = "unapproved"; break;
|
|
|
|
case "recover": $statusExpected = "active"; break;
|
|
|
|
case "reactivate": $statusExpected = "inactive"; break;
|
|
|
|
case "verify": $statusExpected = "unverified"; break;
|
|
|
|
case "change": $statusExpected = "active"; break;
|
|
|
|
case "remove": $statusExpected = "active"; break;
|
|
|
|
}
|
2019-09-12 12:56:05 +00:00
|
|
|
return $this->users->getUser($email, "status")==$statusExpected ? "ok" : "done";
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
2018-05-21 21:13:32 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Return user account changes
|
|
|
|
public function getUserAccount($email, $password, $action) {
|
|
|
|
$status = null;
|
2019-02-23 14:04:34 +00:00
|
|
|
foreach ($this->yellow->extensions->extensions as $key=>$value) {
|
2018-08-10 22:23:50 +00:00
|
|
|
if (method_exists($value["obj"], "onEditUserAccount")) {
|
|
|
|
$status = $value["obj"]->onEditUserAccount($email, $password, $action, $this->users);
|
|
|
|
if (!is_null($status)) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (is_null($status)) {
|
|
|
|
$status = "ok";
|
2019-06-04 20:39:27 +00:00
|
|
|
if (!empty($password) && strlenu($password)<$this->yellow->system->get("editUserPasswordMinLength")) $status = "short";
|
|
|
|
if (!empty($password) && $password==$email) $status = "weak";
|
2018-08-10 22:23:50 +00:00
|
|
|
if (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) $status = "invalid";
|
|
|
|
}
|
|
|
|
return $status;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return user language
|
|
|
|
public function getUserLanguage($email) {
|
2019-09-12 12:56:05 +00:00
|
|
|
$language = $this->users->getUser($email, "language");
|
2019-02-23 14:04:34 +00:00
|
|
|
if (!$this->yellow->text->isLanguage($language)) $language = $this->yellow->system->get("language");
|
2018-08-10 22:23:50 +00:00
|
|
|
return $language;
|
|
|
|
}
|
2019-04-03 14:44:12 +00:00
|
|
|
|
|
|
|
// Return action language
|
|
|
|
public function getActionLanguage($language) {
|
|
|
|
if (!$this->yellow->text->isLanguage($language)) $language = $this->yellow->system->get("language");
|
|
|
|
return $language;
|
|
|
|
}
|
2018-08-10 22:23:50 +00:00
|
|
|
|
|
|
|
// Check if request came from same site
|
|
|
|
public function isRequestSameSite($method, $scheme, $address) {
|
|
|
|
if (preg_match("#^(\w+)://([^/]+)(.*)$#", $_SERVER["HTTP_REFERER"], $matches)) $origin = "$matches[1]://$matches[2]";
|
|
|
|
if (isset($_SERVER["HTTP_ORIGIN"])) $origin = $_SERVER["HTTP_ORIGIN"];
|
|
|
|
return $_SERVER["REQUEST_METHOD"]==$method && $origin=="$scheme://$address";
|
|
|
|
}
|
2016-08-13 15:48:18 +00:00
|
|
|
}
|
2018-08-10 22:23:50 +00:00
|
|
|
|
2019-03-21 10:58:12 +00:00
|
|
|
class YellowEditResponse {
|
2018-08-10 22:23:50 +00:00
|
|
|
public $yellow; //access to API
|
2019-02-23 14:04:34 +00:00
|
|
|
public $extension; //access to extension
|
2018-08-10 22:23:50 +00:00
|
|
|
public $active; //location is active? (boolean)
|
|
|
|
public $userEmail; //user email
|
|
|
|
public $userFailedError; //error of failed authentication
|
|
|
|
public $userFailedEmail; //email of failed authentication
|
|
|
|
public $userFailedExpire; //expiration time of failed authentication
|
|
|
|
public $rawDataSource; //raw data of page for comparison
|
|
|
|
public $rawDataEdit; //raw data of page for editing
|
|
|
|
public $rawDataOutput; //raw data of dynamic output
|
2019-06-01 13:21:51 +00:00
|
|
|
public $rawDataReadonly; //raw data is read only? (boolean)
|
2018-08-10 22:23:50 +00:00
|
|
|
public $rawDataEndOfLine; //end of line format for raw data
|
|
|
|
public $language; //response language
|
|
|
|
public $action; //response action
|
|
|
|
public $status; //response status
|
|
|
|
|
|
|
|
public function __construct($yellow) {
|
|
|
|
$this->yellow = $yellow;
|
2019-02-23 14:04:34 +00:00
|
|
|
$this->extension = $yellow->extensions->get("edit");
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
|
2019-06-01 13:21:51 +00:00
|
|
|
// Process page data
|
|
|
|
public function processPageData($page) {
|
|
|
|
if ($this->isUser()) {
|
|
|
|
if (empty($this->rawDataSource)) $this->rawDataSource = $page->rawData;
|
|
|
|
if (empty($this->rawDataEdit)) $this->rawDataEdit = $page->rawData;
|
|
|
|
if (empty($this->rawDataEndOfLine)) $this->rawDataEndOfLine = $this->getEndOfLine($page->rawData);
|
|
|
|
if ($page->statusCode==434) $this->rawDataEdit = $this->getRawDataNew($page, true);
|
|
|
|
if ($this->yellow->toolbox->isLocationArgs()) {
|
|
|
|
$this->rawDataEdit = $this->getRawDataGenerated($page);
|
|
|
|
$this->rawDataReadonly = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (empty($this->language)) $this->language = $page->get("language");
|
|
|
|
if (empty($this->action)) $this->action = $this->isUser() ? "none" : "login";
|
|
|
|
if (empty($this->status)) $this->status = "none";
|
|
|
|
if ($this->status=="error") $this->action = "error";
|
|
|
|
}
|
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Return new page
|
|
|
|
public function getPageNew($scheme, $address, $base, $location, $fileName, $rawData, $endOfLine) {
|
|
|
|
$page = new YellowPage($this->yellow);
|
|
|
|
$page->setRequestInformation($scheme, $address, $base, $location, $fileName);
|
|
|
|
$page->parseData($this->normaliseLines($rawData, $endOfLine), false, 0);
|
|
|
|
$this->editContentFile($page, "create");
|
2019-02-23 14:04:34 +00:00
|
|
|
if ($this->yellow->content->find($page->location)) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$page->location = $this->getPageNewLocation($page->rawData, $page->location, $page->get("pageNewLocation"));
|
2018-11-09 08:36:49 +00:00
|
|
|
$page->fileName = $this->getPageNewFile($page->location, $page->fileName, $page->get("published"));
|
2019-02-23 14:04:34 +00:00
|
|
|
while ($this->yellow->content->find($page->location) || empty($page->fileName)) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$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"));
|
2018-11-09 08:36:49 +00:00
|
|
|
$page->fileName = $this->getPageNewFile($page->location, $page->fileName, $page->get("published"));
|
2018-08-10 22:23:50 +00:00
|
|
|
if (++$pageCounter>999) break;
|
|
|
|
}
|
2019-02-23 14:04:34 +00:00
|
|
|
if ($this->yellow->content->find($page->location) || empty($page->fileName)) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$page->error(500, "Page '".$page->get("title")."' is not possible!");
|
|
|
|
}
|
|
|
|
} else {
|
2018-11-09 08:36:49 +00:00
|
|
|
$page->fileName = $this->getPageNewFile($page->location);
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
2019-12-17 10:46:09 +00:00
|
|
|
if (!$this->isUserAccess("create", $page->location)) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$page->error(500, "Page '".$page->get("title")."' is restricted!");
|
|
|
|
}
|
|
|
|
return $page;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return modified page
|
|
|
|
public function getPageEdit($scheme, $address, $base, $location, $fileName, $rawDataSource, $rawDataEdit, $rawDataFile, $endOfLine) {
|
|
|
|
$page = new YellowPage($this->yellow);
|
|
|
|
$page->setRequestInformation($scheme, $address, $base, $location, $fileName);
|
2019-02-23 14:04:34 +00:00
|
|
|
$rawData = $this->extension->merge->merge(
|
2018-08-10 22:23:50 +00:00
|
|
|
$this->normaliseLines($rawDataSource, $endOfLine),
|
|
|
|
$this->normaliseLines($rawDataEdit, $endOfLine),
|
|
|
|
$this->normaliseLines($rawDataFile, $endOfLine));
|
|
|
|
$page->parseData($this->normaliseLines($rawData, $endOfLine), false, 0);
|
2018-11-09 08:36:49 +00:00
|
|
|
$pageSource = new YellowPage($this->yellow);
|
|
|
|
$pageSource->setRequestInformation($scheme, $address, $base, $location, $fileName);
|
|
|
|
$pageSource->parseData($this->normaliseLines($rawDataSource, $endOfLine), false, 0);
|
2018-08-10 22:23:50 +00:00
|
|
|
$this->editContentFile($page, "edit");
|
2019-02-23 14:04:34 +00:00
|
|
|
if ($this->isMetaModified($pageSource, $page) && $page->location!=$this->yellow->content->getHomeLocation($page->location)) {
|
2018-11-09 08:36:49 +00:00
|
|
|
$page->location = $this->getPageNewLocation($page->rawData, $page->location, $page->get("pageNewLocation"), true);
|
|
|
|
$page->fileName = $this->getPageNewFile($page->location, $page->fileName, $page->get("published"));
|
2019-02-23 14:04:34 +00:00
|
|
|
if ($page->location!=$pageSource->location && ($this->yellow->content->find($page->location) || empty($page->fileName))) {
|
2018-11-09 08:36:49 +00:00
|
|
|
$page->error(500, "Page '".$page->get("title")."' is not possible!");
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
}
|
2018-11-09 08:36:49 +00:00
|
|
|
if (empty($page->rawData)) $page->error(500, "Page has been modified by someone else!");
|
2019-12-17 10:46:09 +00:00
|
|
|
if (!$this->isUserAccess("edit", $page->location) ||
|
|
|
|
!$this->isUserAccess("edit", $pageSource->location)) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$page->error(500, "Page '".$page->get("title")."' is restricted!");
|
|
|
|
}
|
|
|
|
return $page;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return deleted page
|
|
|
|
public function getPageDelete($scheme, $address, $base, $location, $fileName, $rawData, $endOfLine) {
|
|
|
|
$page = new YellowPage($this->yellow);
|
|
|
|
$page->setRequestInformation($scheme, $address, $base, $location, $fileName);
|
|
|
|
$page->parseData($this->normaliseLines($rawData, $endOfLine), false, 0);
|
|
|
|
$this->editContentFile($page, "delete");
|
2019-12-17 10:46:09 +00:00
|
|
|
if (!$this->isUserAccess("delete", $page->location)) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$page->error(500, "Page '".$page->get("title")."' is restricted!");
|
|
|
|
}
|
|
|
|
return $page;
|
|
|
|
}
|
2018-04-15 12:45:50 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Return preview page
|
|
|
|
public function getPagePreview($scheme, $address, $base, $location, $fileName, $rawData, $endOfLine) {
|
|
|
|
$page = new YellowPage($this->yellow);
|
|
|
|
$page->setRequestInformation($scheme, $address, $base, $location, $fileName);
|
|
|
|
$page->parseData($this->normaliseLines($rawData, $endOfLine), false, 200);
|
|
|
|
$this->yellow->text->setLanguage($page->get("language"));
|
2019-03-18 21:07:19 +00:00
|
|
|
$class = "page-preview layout-".$page->get("layout");
|
2019-06-09 09:38:12 +00:00
|
|
|
$output = "<div class=\"".htmlspecialchars($class)."\"><div class=\"content\"><div class=\"main\">";
|
2019-02-23 14:04:34 +00:00
|
|
|
if ($this->yellow->system->get("editToolbarButtons")!="none") $output .= "<h1>".$page->getHtml("titleContent")."</h1>\n";
|
2018-08-10 22:23:50 +00:00
|
|
|
$output .= $page->getContent();
|
2019-06-09 09:38:12 +00:00
|
|
|
$output .= "</div></div></div>";
|
2018-08-10 22:23:50 +00:00
|
|
|
$page->setOutput($output);
|
|
|
|
return $page;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return uploaded file
|
|
|
|
public function getFileUpload($scheme, $address, $base, $pageLocation, $fileNameTemp, $fileNameShort) {
|
|
|
|
$file = new YellowPage($this->yellow);
|
|
|
|
$file->setRequestInformation($scheme, $address, $base, "/".$fileNameTemp, $fileNameTemp);
|
|
|
|
$file->parseData(null, false, 0);
|
|
|
|
$file->set("fileNameShort", $fileNameShort);
|
|
|
|
$this->editMediaFile($file, "upload");
|
|
|
|
$file->location = $this->getFileNewLocation($fileNameShort, $pageLocation, $file->get("fileNewLocation"));
|
|
|
|
$file->fileName = substru($file->location, 1);
|
|
|
|
while (is_file($file->fileName)) {
|
|
|
|
$fileNameShort = $this->getFileNext(basename($file->fileName));
|
|
|
|
$file->location = $this->getFileNewLocation($fileNameShort, $pageLocation, $file->get("fileNewLocation"));
|
|
|
|
$file->fileName = substru($file->location, 1);
|
|
|
|
if (++$fileCounter>999) break;
|
|
|
|
}
|
|
|
|
if (is_file($file->fileName)) $file->error(500, "File '".$file->get("fileNameShort")."' is not possible!");
|
|
|
|
return $file;
|
|
|
|
}
|
2018-04-15 12:45:50 +00:00
|
|
|
|
2019-12-17 10:46:09 +00:00
|
|
|
// Return system file
|
|
|
|
public function getFileSystem($scheme, $address, $base, $pageLocation, $fileName, $settings) {
|
|
|
|
$file = new YellowPage($this->yellow);
|
|
|
|
$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");
|
|
|
|
return $file;
|
|
|
|
}
|
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Return page data including status information
|
2019-01-28 13:58:26 +00:00
|
|
|
public function getPageData($page) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$data = array();
|
|
|
|
if ($this->isUser()) {
|
|
|
|
$data["title"] = $this->yellow->toolbox->getMetaData($this->rawDataEdit, "title");
|
|
|
|
$data["rawDataSource"] = $this->rawDataSource;
|
|
|
|
$data["rawDataEdit"] = $this->rawDataEdit;
|
2019-01-28 13:58:26 +00:00
|
|
|
$data["rawDataNew"] = $this->getRawDataNew($page);
|
2018-08-10 22:23:50 +00:00
|
|
|
$data["rawDataOutput"] = strval($this->rawDataOutput);
|
2019-06-01 13:21:51 +00:00
|
|
|
$data["rawDataReadonly"] = intval($this->rawDataReadonly);
|
2018-08-10 22:23:50 +00:00
|
|
|
$data["rawDataEndOfLine"] = $this->rawDataEndOfLine;
|
|
|
|
$data["scheme"] = $this->yellow->page->scheme;
|
|
|
|
$data["address"] = $this->yellow->page->address;
|
|
|
|
$data["base"] = $this->yellow->page->base;
|
|
|
|
$data["location"] = $this->yellow->page->location;
|
2018-09-28 12:07:09 +00:00
|
|
|
$data["safeMode"] = $this->yellow->page->safeMode;
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
if ($this->action!="none") $data = array_merge($data, $this->getRequestData());
|
|
|
|
$data["action"] = $this->action;
|
|
|
|
$data["status"] = $this->status;
|
|
|
|
$data["statusCode"] = $this->yellow->page->statusCode;
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
2019-02-23 14:04:34 +00:00
|
|
|
// Return system data including user information
|
|
|
|
public function getSystemData() {
|
|
|
|
$data = $this->yellow->system->getData("", "Location");
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($this->isUser()) {
|
|
|
|
$data["userEmail"] = $this->userEmail;
|
2019-09-12 12:56:05 +00:00
|
|
|
$data["userName"] = $this->extension->users->getUser($this->userEmail, "name");
|
|
|
|
$data["userLanguage"] = $this->extension->users->getUser($this->userEmail, "language");
|
|
|
|
$data["userStatus"] = $this->extension->users->getUser($this->userEmail, "status");
|
|
|
|
$data["userHome"] = $this->extension->users->getUser($this->userEmail, "home");
|
2019-12-17 10:46:09 +00:00
|
|
|
$data["userAccess"] = $this->extension->users->getUser($this->userEmail, "access");
|
|
|
|
$data["coreServerScheme"] = $this->yellow->system->get("coreServerScheme");
|
|
|
|
$data["coreServerAddress"] = $this->yellow->system->get("coreServerAddress");
|
|
|
|
$data["coreServerBase"] = $this->yellow->system->get("coreServerBase");
|
|
|
|
$data["coreFileSizeMax"] = $this->yellow->toolbox->getNumberBytes(ini_get("upload_max_filesize"));
|
|
|
|
$data["coreVersion"] = "Datenstrom Yellow ".YellowCore::VERSION;
|
|
|
|
$data["coreExtensions"] = array();
|
2019-02-23 14:04:34 +00:00
|
|
|
foreach ($this->yellow->extensions->extensions as $key=>$value) {
|
2019-12-17 10:46:09 +00:00
|
|
|
$data["coreExtensions"][$key] = $value["type"];
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
2019-12-17 10:46:09 +00:00
|
|
|
$data["coreLanguages"] = array();
|
2018-08-10 22:23:50 +00:00
|
|
|
foreach ($this->yellow->text->getLanguages() as $language) {
|
2019-12-17 10:46:09 +00:00
|
|
|
$data["coreLanguages"][$language] = $this->yellow->text->getTextHtml("languageDescription", $language);
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
2019-06-09 09:38:12 +00:00
|
|
|
$data["editSettingsActions"] = $this->getSettingsActions();
|
2019-02-23 14:04:34 +00:00
|
|
|
$data["editUploadExtensions"] = $this->yellow->system->get("editUploadExtensions");
|
|
|
|
$data["editKeyboardShortcuts"] = $this->yellow->system->get("editKeyboardShortcuts");
|
2018-08-10 22:23:50 +00:00
|
|
|
$data["editToolbarButtons"] = $this->getToolbarButtons("edit");
|
|
|
|
$data["emojiawesomeToolbarButtons"] = $this->getToolbarButtons("emojiawesome");
|
|
|
|
$data["fontawesomeToolbarButtons"] = $this->getToolbarButtons("fontawesome");
|
2019-12-17 10:46:09 +00:00
|
|
|
if ($this->isUserAccess("system")) {
|
|
|
|
$data["sitename"] = $this->yellow->system->get("sitename");
|
|
|
|
$data["author"] = $this->yellow->system->get("author");
|
|
|
|
$data["email"] = $this->yellow->system->get("email");
|
|
|
|
}
|
2018-08-10 22:23:50 +00:00
|
|
|
} else {
|
|
|
|
$data["editLoginEmail"] = $this->yellow->page->get("editLoginEmail");
|
|
|
|
$data["editLoginPassword"] = $this->yellow->page->get("editLoginPassword");
|
2019-03-16 07:59:37 +00:00
|
|
|
$data["editLoginRestriction"] = intval($this->isLoginRestriction());
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
if (defined("DEBUG") && DEBUG>=1) $data["debug"] = DEBUG;
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return request strings
|
|
|
|
public function getRequestData() {
|
|
|
|
$data = array();
|
|
|
|
foreach ($_REQUEST as $key=>$value) {
|
|
|
|
if ($key=="password" || $key=="authtoken" || $key=="csrftoken" || $key=="actiontoken" || substru($key, 0, 7)=="rawdata") continue;
|
|
|
|
$data["request".ucfirst($key)] = trim($value);
|
|
|
|
}
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return text strings
|
|
|
|
public function getTextData() {
|
|
|
|
$textLanguage = $this->yellow->text->getData("language", $this->language);
|
|
|
|
$textEdit = $this->yellow->text->getData("edit", $this->language);
|
2020-01-15 18:30:45 +00:00
|
|
|
return array_merge($textLanguage, $textEdit);
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
|
2019-06-09 09:38:12 +00:00
|
|
|
// Return settings actions
|
|
|
|
public function getSettingsActions() {
|
2019-12-17 10:46:09 +00:00
|
|
|
$settingsActions = "account";
|
|
|
|
if ($this->isUserAccess("system")) $settingsActions .= ", system";
|
|
|
|
if ($this->isUserAccess("update")) $settingsActions .= ", update";
|
|
|
|
return $settingsActions=="account" ? "" : $settingsActions;
|
2019-06-09 09:38:12 +00:00
|
|
|
}
|
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Return toolbar buttons
|
|
|
|
public function getToolbarButtons($name) {
|
|
|
|
if ($name=="edit") {
|
2019-02-23 14:04:34 +00:00
|
|
|
$toolbarButtons = $this->yellow->system->get("editToolbarButtons");
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($toolbarButtons=="auto") {
|
|
|
|
$toolbarButtons = "";
|
2019-04-11 19:43:30 +00:00
|
|
|
if ($this->yellow->extensions->isExisting("markdown")) $toolbarButtons = "format, bold, italic, strikethrough, code, separator, list, link, file";
|
2019-02-23 14:04:34 +00:00
|
|
|
if ($this->yellow->extensions->isExisting("emojiawesome")) $toolbarButtons .= ", emojiawesome";
|
|
|
|
if ($this->yellow->extensions->isExisting("fontawesome")) $toolbarButtons .= ", fontawesome";
|
|
|
|
if ($this->yellow->extensions->isExisting("draft")) $toolbarButtons .= ", draft";
|
2020-01-15 18:30:45 +00:00
|
|
|
$toolbarButtons .= ", preview";
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
} else {
|
2019-02-23 14:04:34 +00:00
|
|
|
$toolbarButtons = $this->yellow->system->get("{$name}ToolbarButtons");
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
return $toolbarButtons;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return end of line format
|
|
|
|
public function getEndOfLine($rawData = "") {
|
2019-02-23 14:04:34 +00:00
|
|
|
$endOfLine = $this->yellow->system->get("editEndOfLine");
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($endOfLine=="auto") {
|
|
|
|
$rawData = empty($rawData) ? PHP_EOL : substru($rawData, 0, 4096);
|
|
|
|
$endOfLine = strposu($rawData, "\r")===false ? "lf" : "crlf";
|
|
|
|
}
|
|
|
|
return $endOfLine;
|
|
|
|
}
|
|
|
|
|
2019-06-01 13:21:51 +00:00
|
|
|
// Return update information
|
|
|
|
public function getUpdateInformation() {
|
|
|
|
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);
|
2019-06-09 09:38:12 +00:00
|
|
|
foreach ($dataCurrent as $key=>$value) {
|
|
|
|
if (strnatcasecmp($dataCurrent[$key], $dataLatest[$key])<0) {
|
|
|
|
$rawData .= htmlspecialchars(ucfirst($key)." $dataLatest[$key]")."<br />\n";
|
|
|
|
++$updates;
|
2019-06-01 13:21:51 +00:00
|
|
|
}
|
2019-06-09 09:38:12 +00:00
|
|
|
}
|
|
|
|
if ($updates==0) {
|
2019-06-01 13:21:51 +00:00
|
|
|
foreach ($dataCurrent as $key=>$value) {
|
2019-06-09 09:38:12 +00:00
|
|
|
if (!is_null($dataModified[$key]) && !is_null($dataLatest[$key])) {
|
|
|
|
$output = $this->yellow->text->getTextHtml("editUpdateModified", $this->language)." - <a href=\"#\" data-action=\"submit\" data-args=\"".$this->yellow->toolbox->normaliseArgs("action:update/extension:$key/option:force")."\">".$this->yellow->text->getTextHtml("editUpdateForce", $this->language)."</a><br />\n";
|
|
|
|
$rawData .= preg_replace("/@extension/i", htmlspecialchars(ucfirst($key)." $dataLatest[$key]"), $output);
|
|
|
|
}
|
2019-06-01 13:21:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$statusCode = 200;
|
|
|
|
}
|
|
|
|
return array($statusCode, $updates, $rawData);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return raw data for generated page
|
|
|
|
public function getRawDataGenerated($page) {
|
|
|
|
$title = $page->get("title");
|
|
|
|
$text = $this->yellow->text->getText("editDataGenerated", $page->get("language"));
|
|
|
|
return "---\nTitle: $title\n---\n$text";
|
|
|
|
}
|
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Return raw data for new page
|
2019-01-28 13:58:26 +00:00
|
|
|
public function getRawDataNew($page, $customTitle = false) {
|
2019-02-23 14:04:34 +00:00
|
|
|
foreach ($this->yellow->content->path($page->location)->reverse() as $ancestor) {
|
|
|
|
if ($ancestor->isExisting("layoutNew")) {
|
|
|
|
$name = $this->yellow->lookup->normaliseName($ancestor->get("layoutNew"));
|
2019-12-15 16:22:07 +00:00
|
|
|
$location = $this->yellow->content->getHomeLocation($page->location).$this->yellow->system->get("coreContentSharedDir");
|
2019-02-23 14:04:34 +00:00
|
|
|
$fileName = $this->yellow->lookup->findFileFromLocation($location, true).$this->yellow->system->get("editNewFile");
|
2019-01-28 13:58:26 +00:00
|
|
|
$fileName = strreplaceu("(.*)", $name, $fileName);
|
2018-08-10 22:23:50 +00:00
|
|
|
if (is_file($fileName)) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!is_file($fileName)) {
|
2019-02-23 14:04:34 +00:00
|
|
|
$name = $this->yellow->lookup->normaliseName($this->yellow->system->get("layout"));
|
2019-12-15 16:22:07 +00:00
|
|
|
$location = $this->yellow->content->getHomeLocation($page->location).$this->yellow->system->get("coreContentSharedDir");
|
2019-02-23 14:04:34 +00:00
|
|
|
$fileName = $this->yellow->lookup->findFileFromLocation($location, true).$this->yellow->system->get("editNewFile");
|
2019-01-28 13:58:26 +00:00
|
|
|
$fileName = strreplaceu("(.*)", $name, $fileName);
|
|
|
|
}
|
|
|
|
if (is_file($fileName)) {
|
|
|
|
$rawData = $this->yellow->toolbox->readFile($fileName);
|
|
|
|
$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);
|
2019-09-12 12:56:05 +00:00
|
|
|
$rawData = preg_replace("/@usershort/i", strtok($this->extension->users->getUser($this->userEmail, "name"), " "), $rawData);
|
|
|
|
$rawData = preg_replace("/@username/i", $this->extension->users->getUser($this->userEmail, "name"), $rawData);
|
|
|
|
$rawData = preg_replace("/@userlanguage/i", $this->extension->users->getUser($this->userEmail, "language"), $rawData);
|
2019-01-28 13:58:26 +00:00
|
|
|
} else {
|
|
|
|
$rawData = "---\nTitle: Page\n---\n";
|
|
|
|
}
|
|
|
|
if ($customTitle) {
|
|
|
|
$title = $this->yellow->toolbox->createTextTitle($page->location);
|
|
|
|
$rawData = $this->yellow->toolbox->setMetaData($rawData, "title", $title);
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
return $rawData;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return location for new/modified page
|
2018-11-09 08:36:49 +00:00
|
|
|
public function getPageNewLocation($rawData, $pageLocation, $pageNewLocation, $pageMatchLocation = false) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$location = empty($pageNewLocation) ? "@title" : $pageNewLocation;
|
|
|
|
$location = preg_replace("/@title/i", $this->getPageNewTitle($rawData), $location);
|
|
|
|
$location = preg_replace("/@timestamp/i", $this->getPageNewData($rawData, "published", true, "U"), $location);
|
|
|
|
$location = preg_replace("/@date/i", $this->getPageNewData($rawData, "published", true, "Y-m-d"), $location);
|
|
|
|
$location = preg_replace("/@year/i", $this->getPageNewData($rawData, "published", true, "Y"), $location);
|
|
|
|
$location = preg_replace("/@month/i", $this->getPageNewData($rawData, "published", true, "m"), $location);
|
|
|
|
$location = preg_replace("/@day/i", $this->getPageNewData($rawData, "published", true, "d"), $location);
|
|
|
|
$location = preg_replace("/@tag/i", $this->getPageNewData($rawData, "tag", true), $location);
|
|
|
|
$location = preg_replace("/@author/i", $this->getPageNewData($rawData, "author", true), $location);
|
|
|
|
if (!preg_match("/^\//", $location)) {
|
2018-11-09 08:36:49 +00:00
|
|
|
if ($this->yellow->lookup->isFileLocation($pageLocation) || !$pageMatchLocation) {
|
|
|
|
$location = $this->yellow->lookup->getDirectoryLocation($pageLocation).$location;
|
|
|
|
} else {
|
|
|
|
$location = $this->yellow->lookup->getDirectoryLocation(rtrim($pageLocation, "/")).$location;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($pageMatchLocation) {
|
|
|
|
$location = rtrim($location, "/").($this->yellow->lookup->isFileLocation($pageLocation) ? "" : "/");
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
return $location;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return title for new/modified page
|
|
|
|
public function getPageNewTitle($rawData) {
|
|
|
|
$title = $this->yellow->toolbox->getMetaData($rawData, "title");
|
|
|
|
$titleSlug = $this->yellow->toolbox->getMetaData($rawData, "titleSlug");
|
|
|
|
$value = empty($titleSlug) ? $title : $titleSlug;
|
|
|
|
$value = $this->yellow->lookup->normaliseName($value, true, false, true);
|
|
|
|
return trim(preg_replace("/-+/", "-", $value), "-");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return data for new/modified page
|
|
|
|
public function getPageNewData($rawData, $key, $filterFirst = false, $dateFormat = "") {
|
|
|
|
$value = $this->yellow->toolbox->getMetaData($rawData, $key);
|
|
|
|
if ($filterFirst && preg_match("/^(.*?)\,(.*)$/", $value, $matches)) $value = $matches[1];
|
|
|
|
if (!empty($dateFormat)) $value = date($dateFormat, strtotime($value));
|
|
|
|
if (strempty($value)) $value = "none";
|
|
|
|
$value = $this->yellow->lookup->normaliseName($value, true, false, true);
|
|
|
|
return trim(preg_replace("/-+/", "-", $value), "-");
|
|
|
|
}
|
2018-11-09 08:36:49 +00:00
|
|
|
|
|
|
|
// Return file name for new/modified page
|
|
|
|
public function getPageNewFile($location, $pageFileName = "", $pagePrefix = "") {
|
|
|
|
$fileName = $this->yellow->lookup->findFileFromLocation($location);
|
|
|
|
if (!empty($fileName)) {
|
|
|
|
if (!is_dir(dirname($fileName))) {
|
|
|
|
$path = "";
|
|
|
|
$tokens = explode("/", $fileName);
|
|
|
|
for ($i=0; $i<count($tokens)-1; ++$i) {
|
|
|
|
if (!is_dir($path.$tokens[$i])) {
|
|
|
|
if (!preg_match("/^[\d\-\_\.]+(.*)$/", $tokens[$i])) {
|
|
|
|
$number = 1;
|
|
|
|
foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^[\d\-\_\.]+(.*)$/", true, true, false) as $entry) {
|
|
|
|
if ($number!=1 && $number!=intval($entry)) break;
|
|
|
|
$number = intval($entry)+1;
|
|
|
|
}
|
|
|
|
$tokens[$i] = "$number-".$tokens[$i];
|
|
|
|
}
|
|
|
|
$tokens[$i] = $this->yellow->lookup->normaliseName($tokens[$i], false, false, true);
|
|
|
|
}
|
|
|
|
$path .= $tokens[$i]."/";
|
|
|
|
}
|
|
|
|
$fileName = $path.$tokens[$i];
|
|
|
|
$pageFileName = empty($pageFileName) ? $fileName : $pageFileName;
|
|
|
|
}
|
|
|
|
$prefix = $this->getPageNewPrefix($location, $pageFileName, $pagePrefix);
|
|
|
|
if ($this->yellow->lookup->isFileLocation($location)) {
|
|
|
|
preg_match("#^(.*)\/(.+?)$#", $fileName, $matches);
|
|
|
|
$path = $matches[1];
|
|
|
|
$text = $this->yellow->lookup->normaliseName($matches[2], true, true);
|
|
|
|
if (preg_match("/^[\d\-\_\.]*$/", $text)) $prefix = "";
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileName = $path."/".$prefix.$text.$this->yellow->system->get("coreContentExtension");
|
2018-11-09 08:36:49 +00:00
|
|
|
} else {
|
|
|
|
preg_match("#^(.*)\/(.+?)$#", dirname($fileName), $matches);
|
|
|
|
$path = $matches[1];
|
|
|
|
$text = $this->yellow->lookup->normaliseName($matches[2], true, false);
|
|
|
|
if (preg_match("/^[\d\-\_\.]*$/", $text)) $prefix = "";
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileName = $path."/".$prefix.$text."/".$this->yellow->system->get("coreContentDefaultFile");
|
2018-11-09 08:36:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $fileName;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return prefix for new/modified page
|
|
|
|
public function getPageNewPrefix($location, $pageFileName, $pagePrefix) {
|
|
|
|
if (empty($pagePrefix)) {
|
|
|
|
if ($this->yellow->lookup->isFileLocation($location)) {
|
|
|
|
preg_match("#^(.*)\/(.+?)$#", $pageFileName, $matches);
|
|
|
|
$pagePrefix = $matches[2];
|
|
|
|
} else {
|
|
|
|
preg_match("#^(.*)\/(.+?)$#", dirname($pageFileName), $matches);
|
|
|
|
$pagePrefix = $matches[2];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $this->yellow->lookup->normalisePrefix($pagePrefix, true);
|
|
|
|
}
|
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Return location for new file
|
|
|
|
public function getFileNewLocation($fileNameShort, $pageLocation, $fileNewLocation) {
|
2019-02-23 14:04:34 +00:00
|
|
|
$location = empty($fileNewLocation) ? $this->yellow->system->get("editUploadNewLocation") : $fileNewLocation;
|
2018-08-10 22:23:50 +00:00
|
|
|
$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)) {
|
2019-12-15 16:22:07 +00:00
|
|
|
$location = $this->yellow->system->get("coreMediaLocation").$location;
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
return $location;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return group for new file
|
|
|
|
public function getFileNewGroup($fileNameShort) {
|
2019-12-15 16:22:07 +00:00
|
|
|
$path = $this->yellow->system->get("coreMediaDir");
|
2018-08-10 22:23:50 +00:00
|
|
|
$fileType = $this->yellow->toolbox->getFileType($fileNameShort);
|
2019-12-15 16:22:07 +00:00
|
|
|
$fileName = $this->yellow->system->get(preg_match("/(gif|jpg|png|svg)$/", $fileType) ? "coreImageDir" : "coreDownloadDir").$fileNameShort;
|
2018-08-10 22:23:50 +00:00
|
|
|
preg_match("#^$path(.+?)\/#", $fileName, $matches);
|
|
|
|
return strtoloweru($matches[1]);
|
|
|
|
}
|
2018-04-29 15:48:46 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Return folder for new file
|
|
|
|
public function getFileNewFolder($pageLocation) {
|
2019-02-23 14:04:34 +00:00
|
|
|
$parentTopLocation = $this->yellow->content->getParentTopLocation($pageLocation);
|
|
|
|
if ($parentTopLocation==$this->yellow->content->getHomeLocation($pageLocation)) $parentTopLocation .= "home";
|
2018-08-10 22:23:50 +00:00
|
|
|
return strtoloweru(trim($parentTopLocation, "/"));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return next file name
|
|
|
|
public function getFileNext($fileNameShort) {
|
|
|
|
preg_match("/^(.*?)(\d*)(\..*?)?$/", $fileNameShort, $matches);
|
|
|
|
$fileText = $matches[1];
|
|
|
|
$fileNumber = strempty($matches[2]) ? "-2" : $matches[2]+1;
|
|
|
|
$fileExtension = $matches[3];
|
|
|
|
return $fileText.$fileNumber.$fileExtension;
|
|
|
|
}
|
2018-11-09 08:36:49 +00:00
|
|
|
|
|
|
|
// Return next title
|
|
|
|
public function getTitleNext($rawData) {
|
|
|
|
preg_match("/^(.*?)(\d*)$/", $this->yellow->toolbox->getMetaData($rawData, "title"), $matches);
|
|
|
|
$titleText = $matches[1];
|
|
|
|
$titleNumber = strempty($matches[2]) ? " 2" : $matches[2]+1;
|
|
|
|
return $titleText.$titleNumber;
|
|
|
|
}
|
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Send mail to user
|
|
|
|
public function sendMail($scheme, $address, $base, $email, $action) {
|
2019-04-03 14:44:12 +00:00
|
|
|
if ($action=="approve") {
|
|
|
|
$userName = $this->yellow->system->get("author");
|
|
|
|
$userEmail = $this->yellow->system->get("email");
|
|
|
|
$userLanguage = $this->extension->getUserLanguage($userEmail);
|
|
|
|
} else {
|
2019-09-12 12:56:05 +00:00
|
|
|
$userName = $this->extension->users->getUser($email, "name");
|
2019-04-03 14:44:12 +00:00
|
|
|
$userEmail = $email;
|
|
|
|
$userLanguage = $this->extension->getUserLanguage($email);
|
|
|
|
}
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($action=="welcome" || $action=="goodbye") {
|
|
|
|
$url = "$scheme://$address$base/";
|
|
|
|
} else {
|
|
|
|
$expire = time() + 60*60*24;
|
2019-02-23 14:04:34 +00:00
|
|
|
$actionToken = $this->extension->users->createActionToken($email, $action, $expire);
|
2019-04-03 14:44:12 +00:00
|
|
|
$url = "$scheme://$address$base"."/action:$action/email:$email/expire:$expire/language:$userLanguage/actiontoken:$actionToken/";
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
$prefix = "edit".ucfirst($action);
|
2019-04-03 14:44:12 +00:00
|
|
|
$message = $this->yellow->text->getText("{$prefix}Message", $userLanguage);
|
2020-01-08 23:12:39 +00:00
|
|
|
$message = strreplaceu("\\n", "\r\n", $message);
|
2019-04-03 14:44:12 +00:00
|
|
|
$message = preg_replace("/@useraccount/i", $email, $message);
|
|
|
|
$message = preg_replace("/@usershort/i", strtok($userName, " "), $message);
|
|
|
|
$message = preg_replace("/@username/i", $userName, $message);
|
|
|
|
$message = preg_replace("/@userlanguage/i", $userLanguage, $message);
|
|
|
|
$sitename = $this->yellow->system->get("sitename");
|
2020-01-08 23:12:39 +00:00
|
|
|
$footer = $this->yellow->text->getText("editMailFooter", $userLanguage);
|
|
|
|
$footer = strreplaceu("\\n", "\r\n", $footer);
|
|
|
|
$footer = preg_replace("/@sitename/i", $sitename, $footer);
|
2019-04-03 14:44:12 +00:00
|
|
|
$mailTo = mb_encode_mimeheader("$userName")." <$userEmail>";
|
|
|
|
$mailSubject = mb_encode_mimeheader($this->yellow->text->getText("{$prefix}Subject", $userLanguage));
|
2018-08-10 22:23:50 +00:00
|
|
|
$mailHeaders = mb_encode_mimeheader("From: $sitename")." <noreply>\r\n";
|
|
|
|
$mailHeaders .= mb_encode_mimeheader("X-Request-Url: $scheme://$address$base")."\r\n";
|
|
|
|
$mailHeaders .= "Mime-Version: 1.0\r\n";
|
|
|
|
$mailHeaders .= "Content-Type: text/plain; charset=utf-8\r\n";
|
2020-01-08 23:12:39 +00:00
|
|
|
$mailMessage = "$message\r\n\r\n$url\r\n-- \r\n$footer";
|
2018-08-10 22:23:50 +00:00
|
|
|
return mail($mailTo, $mailSubject, $mailMessage, $mailHeaders);
|
|
|
|
}
|
2020-01-16 10:58:00 +00:00
|
|
|
|
|
|
|
// Create browser cookies
|
|
|
|
public function createCookies($scheme, $address, $base, $email) {
|
|
|
|
$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);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Destroy browser cookies
|
|
|
|
public function destroyCookies($scheme, $address, $base) {
|
|
|
|
setcookie("authtoken", "", 1, "$base/", "", $scheme=="https", true);
|
|
|
|
setcookie("csrftoken", "", 1, "$base/", "", $scheme=="https", false);
|
|
|
|
}
|
2018-08-10 22:23:50 +00:00
|
|
|
|
|
|
|
// Change content file
|
|
|
|
public function editContentFile($page, $action) {
|
|
|
|
if (!$page->isError()) {
|
2019-02-23 14:04:34 +00:00
|
|
|
foreach ($this->yellow->extensions->extensions as $key=>$value) {
|
2018-08-10 22:23:50 +00:00
|
|
|
if (method_exists($value["obj"], "onEditContentFile")) $value["obj"]->onEditContentFile($page, $action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-04-29 15:48:46 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Change media file
|
|
|
|
public function editMediaFile($file, $action) {
|
|
|
|
if (!$file->isError()) {
|
2019-02-23 14:04:34 +00:00
|
|
|
foreach ($this->yellow->extensions->extensions as $key=>$value) {
|
2018-08-10 22:23:50 +00:00
|
|
|
if (method_exists($value["obj"], "onEditMediaFile")) $value["obj"]->onEditMediaFile($file, $action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-17 10:46:09 +00:00
|
|
|
// Change system file
|
|
|
|
public function editSystemFile($file, $action) {
|
|
|
|
if (!$file->isError()) {
|
|
|
|
foreach ($this->yellow->extensions->extensions as $key=>$value) {
|
|
|
|
if (method_exists($value["obj"], "onEditSystemFile")) $value["obj"]->onEditSystemFile($file, $action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-16 10:58:00 +00:00
|
|
|
// Normalise text lines, convert line endings
|
|
|
|
public function normaliseLines($text, $endOfLine = "lf") {
|
|
|
|
if ($endOfLine=="lf") {
|
|
|
|
$text = preg_replace("/\R/u", "\n", $text);
|
|
|
|
} else {
|
|
|
|
$text = preg_replace("/\R/u", "\r\n", $text);
|
|
|
|
}
|
|
|
|
return $text;
|
|
|
|
}
|
|
|
|
|
2018-11-09 08:36:49 +00:00
|
|
|
// Check if meta data has been modified
|
|
|
|
public function isMetaModified($pageSource, $pageOther) {
|
|
|
|
return substrb($pageSource->rawData, 0, $pageSource->metaDataOffsetBytes) !=
|
|
|
|
substrb($pageOther->rawData, 0, $pageOther->metaDataOffsetBytes);
|
|
|
|
}
|
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Check if active
|
|
|
|
public function isActive() {
|
|
|
|
return $this->active;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if user is logged in
|
|
|
|
public function isUser() {
|
|
|
|
return !empty($this->userEmail);
|
|
|
|
}
|
|
|
|
|
2019-12-17 10:46:09 +00:00
|
|
|
// Check if user with access
|
|
|
|
public function isUserAccess($action, $location = "") {
|
|
|
|
$userHome = $this->extension->users->getUser($this->userEmail, "home");
|
|
|
|
$userAccess = preg_split("/\s*,\s*/", $this->extension->users->getUser($this->userEmail, "access"));
|
|
|
|
return in_array($action, $userAccess) && (empty($location) || substru($location, 0, strlenu($userHome))==$userHome);
|
2018-11-09 08:36:49 +00:00
|
|
|
}
|
|
|
|
|
2019-03-16 07:59:37 +00:00
|
|
|
// Check if login with restriction
|
|
|
|
public function isLoginRestriction() {
|
|
|
|
return $this->yellow->system->get("editLoginRestriction");
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
2013-04-14 22:41:04 +00:00
|
|
|
}
|
|
|
|
|
2019-03-21 10:58:12 +00:00
|
|
|
class YellowEditUsers {
|
2018-08-10 22:23:50 +00:00
|
|
|
public $yellow; //access to API
|
|
|
|
public $users; //registered users
|
|
|
|
|
|
|
|
public function __construct($yellow) {
|
|
|
|
$this->yellow = $yellow;
|
|
|
|
$this->users = array();
|
|
|
|
}
|
2013-04-14 22:41:04 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Load users from file
|
|
|
|
public function load($fileName) {
|
2019-03-21 10:58:12 +00:00
|
|
|
if (defined("DEBUG") && DEBUG>=2) echo "YellowEditUsers::load file:$fileName<br/>\n";
|
2018-08-10 22:23:50 +00:00
|
|
|
$fileData = $this->yellow->toolbox->readFile($fileName);
|
|
|
|
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
|
|
|
|
if (preg_match("/^\#/", $line)) continue;
|
|
|
|
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
|
2019-09-12 12:56:05 +00:00
|
|
|
if (lcfirst($matches[1])=="email" && !strempty($matches[2])) {
|
|
|
|
$email = $matches[2];
|
|
|
|
if (defined("DEBUG") && DEBUG>=3) echo "YellowEditUsers::load email:$email<br/>\n";
|
|
|
|
}
|
|
|
|
if (!empty($email) && !empty($matches[1]) && !strempty($matches[2])) {
|
|
|
|
$this->setUser($email, $matches[1], $matches[2]);
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-06-14 08:32:07 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Save user to file
|
2019-09-12 12:56:05 +00:00
|
|
|
public function save($fileName, $email, $settings) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$fileData = $this->yellow->toolbox->readFile($fileName);
|
2019-09-12 12:56:05 +00:00
|
|
|
$fileDataStart = $fileDataMiddle = $fileDataEnd = "";
|
2018-08-10 22:23:50 +00:00
|
|
|
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
|
|
|
|
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
|
2019-09-12 12:56:05 +00:00
|
|
|
if (lcfirst($matches[1])=="email" && !strempty($matches[2])) {
|
|
|
|
$scan = $matches[2]==$email;
|
|
|
|
}
|
|
|
|
if (!$scan && empty($fileDataMiddle)) {
|
|
|
|
$fileDataStart .= $line;
|
|
|
|
} elseif ($scan) {
|
|
|
|
$fileDataMiddle .= $line;
|
2018-08-10 22:23:50 +00:00
|
|
|
} else {
|
2019-09-12 12:56:05 +00:00
|
|
|
$fileDataEnd .= $line;
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-12 12:56:05 +00:00
|
|
|
$settingsNew = new YellowDataCollection();
|
|
|
|
$settingsNew["email"] = $email;
|
|
|
|
foreach ($settings as $key=>$value) {
|
|
|
|
if (!empty($key) && !strempty($value)) {
|
|
|
|
$this->setUser($email, $key, $value);
|
|
|
|
$settingsNew[$key] = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($this->yellow->toolbox->getTextLines($fileDataMiddle) as $line) {
|
|
|
|
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
|
|
|
|
if (!empty($matches[1]) && !is_null($settingsNew[$matches[1]])) {
|
|
|
|
$fileDataSettings .= "$matches[1]: ".$settingsNew[$matches[1]]."\n";
|
|
|
|
unset($settingsNew[$matches[1]]);
|
|
|
|
} else {
|
|
|
|
$fileDataSettings .= $line;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($settingsNew as $key=>$value) {
|
|
|
|
$fileDataSettings .= ucfirst($key).": $value\n";
|
|
|
|
}
|
|
|
|
if(!empty($fileDataSettings)) {
|
|
|
|
$fileDataSettings = preg_replace("/\n+/", "\n", $fileDataSettings);
|
|
|
|
if (!empty($fileDataStart) && substr($fileDataStart, -2)!="\n\n") $fileDataSettings = "\n".$fileDataSettings;
|
|
|
|
if (!empty($fileDataEnd)) $fileDataSettings .= "\n";
|
|
|
|
}
|
|
|
|
$fileDataNew = $fileDataStart.$fileDataSettings.$fileDataEnd;
|
2018-08-10 22:23:50 +00:00
|
|
|
return $this->yellow->toolbox->createFile($fileName, $fileDataNew);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove user from file
|
|
|
|
public function remove($fileName, $email) {
|
|
|
|
$fileData = $this->yellow->toolbox->readFile($fileName);
|
2019-09-12 12:56:05 +00:00
|
|
|
$fileDataStart = $fileDataMiddle = $fileDataEnd = "";
|
2018-08-10 22:23:50 +00:00
|
|
|
foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
|
|
|
|
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
|
2019-09-12 12:56:05 +00:00
|
|
|
if (lcfirst($matches[1])=="email" && !strempty($matches[2])) {
|
|
|
|
$scan = $matches[2]==$email;
|
|
|
|
}
|
|
|
|
if (!$scan && empty($fileDataMiddle)) {
|
|
|
|
$fileDataStart .= $line;
|
|
|
|
} elseif ($scan) {
|
|
|
|
$fileDataMiddle .= $line;
|
|
|
|
} else {
|
|
|
|
$fileDataEnd .= $line;
|
|
|
|
}
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
2019-09-12 12:56:05 +00:00
|
|
|
unset($this->users[$email]);
|
|
|
|
$fileDataNew = rtrim($fileDataStart.$fileDataEnd)."\n";
|
2018-08-10 22:23:50 +00:00
|
|
|
return $this->yellow->toolbox->createFile($fileName, $fileDataNew);
|
|
|
|
}
|
|
|
|
|
2019-09-12 12:56:05 +00:00
|
|
|
// Set user setting
|
|
|
|
public function setUser($email, $key, $value) {
|
|
|
|
if (is_null($this->users[$email])) $this->users[$email] = new YellowDataCollection();
|
|
|
|
$this->users[$email][$key] = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return user setting
|
|
|
|
public function getUser($email, $key) {
|
|
|
|
return !is_null($this->users[$email]) && !is_null($this->users[$email][$key]) ? $this->users[$email][$key] : "";
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check user authentication from email and password
|
|
|
|
public function checkAuthLogin($email, $password) {
|
2019-02-23 14:04:34 +00:00
|
|
|
$algorithm = $this->yellow->system->get("editUserHashAlgorithm");
|
2018-08-10 22:23:50 +00:00
|
|
|
return $this->isExisting($email) && $this->users[$email]["status"]=="active" &&
|
|
|
|
$this->yellow->toolbox->verifyHash($password, $algorithm, $this->users[$email]["hash"]);
|
|
|
|
}
|
2013-04-14 22:41:04 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Check user authentication from tokens
|
|
|
|
public function checkAuthToken($authToken, $csrfTokenExpected, $csrfTokenReceived, $ignoreCsrfToken) {
|
|
|
|
$signature = "$5y$".substrb($authToken, 0, 96);
|
|
|
|
$email = $this->getAuthEmail($authToken);
|
|
|
|
$expire = $this->getAuthExpire($authToken);
|
|
|
|
return $expire>time() && $this->isExisting($email) && $this->users[$email]["status"]=="active" &&
|
|
|
|
$this->yellow->toolbox->verifyHash($this->users[$email]["hash"]."auth".$expire, "sha256", $signature) &&
|
|
|
|
($this->yellow->toolbox->verifyToken($csrfTokenExpected, $csrfTokenReceived) || $ignoreCsrfToken);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check action token
|
|
|
|
public function checkActionToken($actionToken, $email, $action, $expire) {
|
|
|
|
$signature = "$5y$".$actionToken;
|
|
|
|
return $expire>time() && $this->isExisting($email) &&
|
|
|
|
$this->yellow->toolbox->verifyHash($this->users[$email]["hash"].$action.$expire, "sha256", $signature);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create authentication token
|
|
|
|
public function createAuthToken($email, $expire) {
|
|
|
|
$signature = $this->yellow->toolbox->createHash($this->users[$email]["hash"]."auth".$expire, "sha256");
|
|
|
|
if (empty($signature)) $signature = "padd"."error-hash-algorithm-sha256";
|
2019-09-12 12:56:05 +00:00
|
|
|
return substrb($signature, 4).$this->getUser($email, "stamp").dechex($expire);
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create action token
|
|
|
|
public function createActionToken($email, $action, $expire) {
|
|
|
|
$signature = $this->yellow->toolbox->createHash($this->users[$email]["hash"].$action.$expire, "sha256");
|
|
|
|
if (empty($signature)) $signature = "padd"."error-hash-algorithm-sha256";
|
|
|
|
return substrb($signature, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create CSRF token
|
|
|
|
public function createCsrfToken() {
|
|
|
|
return $this->yellow->toolbox->createSalt(64);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create password hash
|
|
|
|
public function createHash($password) {
|
2019-02-23 14:04:34 +00:00
|
|
|
$algorithm = $this->yellow->system->get("editUserHashAlgorithm");
|
|
|
|
$cost = $this->yellow->system->get("editUserHashCost");
|
2018-08-10 22:23:50 +00:00
|
|
|
$hash = $this->yellow->toolbox->createHash($password, $algorithm, $cost);
|
|
|
|
if (empty($hash)) $hash = "error-hash-algorithm-$algorithm";
|
|
|
|
return $hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create user stamp
|
|
|
|
public function createStamp() {
|
|
|
|
$stamp = $this->yellow->toolbox->createSalt(20);
|
|
|
|
while ($this->getAuthEmail("none", $stamp)) {
|
|
|
|
$stamp = $this->yellow->toolbox->createSalt(20);
|
|
|
|
}
|
|
|
|
return $stamp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return user email from authentication, timing attack safe email lookup
|
|
|
|
public function getAuthEmail($authToken, $stamp = "") {
|
|
|
|
if (empty($stamp)) $stamp = substrb($authToken, 96, 20);
|
|
|
|
foreach ($this->users as $key=>$value) {
|
|
|
|
if ($this->yellow->toolbox->verifyToken($value["stamp"], $stamp)) $email = $key;
|
|
|
|
}
|
|
|
|
return $email;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return expiration time from authentication
|
|
|
|
public function getAuthExpire($authToken) {
|
|
|
|
return hexdec(substrb($authToken, 96+20));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return number of users
|
|
|
|
public function getNumber() {
|
|
|
|
return count($this->users);
|
|
|
|
}
|
2016-05-15 16:35:10 +00:00
|
|
|
|
2018-08-10 22:23:50 +00:00
|
|
|
// Return user data
|
|
|
|
public function getData() {
|
|
|
|
$data = array();
|
|
|
|
foreach ($this->users as $key=>$value) {
|
|
|
|
$name = $value["name"];
|
|
|
|
if (preg_match("/\s/", $name)) $name = "\"$name\"";
|
2019-12-17 10:46:09 +00:00
|
|
|
$data[$key] = "$value[email] $name $value[status]";
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
uksort($data, "strnatcasecmp");
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if user is taken
|
|
|
|
public function isTaken($email) {
|
|
|
|
$taken = false;
|
|
|
|
if ($this->isExisting($email)) {
|
|
|
|
$status = $this->users[$email]["status"];
|
2020-01-03 09:15:15 +00:00
|
|
|
$reserved = strtotime($this->users[$email]["modified"]) + 60*60*24;
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($status=="active" || $status=="inactive" || $reserved>time()) $taken = true;
|
|
|
|
}
|
|
|
|
return $taken;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if user exists
|
|
|
|
public function isExisting($email) {
|
|
|
|
return !is_null($this->users[$email]);
|
|
|
|
}
|
2013-04-14 22:41:04 +00:00
|
|
|
}
|
2018-08-10 22:23:50 +00:00
|
|
|
|
2019-03-21 10:58:12 +00:00
|
|
|
class YellowEditMerge {
|
2018-08-10 22:23:50 +00:00
|
|
|
public $yellow; //access to API
|
|
|
|
const ADD = "+"; //merge types
|
|
|
|
const MODIFY = "*";
|
|
|
|
const REMOVE = "-";
|
|
|
|
const SAME = " ";
|
|
|
|
|
|
|
|
public function __construct($yellow) {
|
|
|
|
$this->yellow = $yellow;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Merge text, null if not possible
|
|
|
|
public function merge($textSource, $textMine, $textYours, $showDiff = false) {
|
|
|
|
if ($textMine!=$textYours) {
|
|
|
|
$diffMine = $this->buildDiff($textSource, $textMine);
|
|
|
|
$diffYours = $this->buildDiff($textSource, $textYours);
|
|
|
|
$diff = $this->mergeDiff($diffMine, $diffYours);
|
|
|
|
$output = $this->getOutput($diff, $showDiff);
|
|
|
|
} else {
|
|
|
|
$output = $textMine;
|
|
|
|
}
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build differences to common source
|
|
|
|
public function buildDiff($textSource, $textOther) {
|
|
|
|
$diff = array();
|
|
|
|
$lastRemove = -1;
|
|
|
|
$textStart = 0;
|
|
|
|
$textSource = $this->yellow->toolbox->getTextLines($textSource);
|
|
|
|
$textOther = $this->yellow->toolbox->getTextLines($textOther);
|
|
|
|
$sourceEnd = $sourceSize = count($textSource);
|
|
|
|
$otherEnd = $otherSize = count($textOther);
|
|
|
|
while ($textStart<$sourceEnd && $textStart<$otherEnd && $textSource[$textStart]==$textOther[$textStart]) {
|
|
|
|
++$textStart;
|
|
|
|
}
|
|
|
|
while ($textStart<$sourceEnd && $textStart<$otherEnd && $textSource[$sourceEnd-1]==$textOther[$otherEnd-1]) {
|
|
|
|
--$sourceEnd;
|
|
|
|
--$otherEnd;
|
|
|
|
}
|
|
|
|
for ($pos=0; $pos<$textStart; ++$pos) {
|
2019-03-21 10:58:12 +00:00
|
|
|
array_push($diff, array(YellowEditMerge::SAME, $textSource[$pos], false));
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
$lcs = $this->buildDiffLCS($textSource, $textOther, $textStart, $sourceEnd-$textStart, $otherEnd-$textStart);
|
|
|
|
for ($x=0,$y=0,$xEnd=$otherEnd-$textStart,$yEnd=$sourceEnd-$textStart; $x<$xEnd || $y<$yEnd;) {
|
|
|
|
$max = $lcs[$y][$x];
|
|
|
|
if ($y<$yEnd && $lcs[$y+1][$x]==$max) {
|
2019-03-21 10:58:12 +00:00
|
|
|
array_push($diff, array(YellowEditMerge::REMOVE, $textSource[$textStart+$y], false));
|
2018-08-10 22:23:50 +00:00
|
|
|
if ($lastRemove==-1) $lastRemove = count($diff)-1;
|
|
|
|
++$y;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ($x<$xEnd && $lcs[$y][$x+1]==$max) {
|
2019-03-21 10:58:12 +00:00
|
|
|
if ($lastRemove==-1 || $diff[$lastRemove][0]!=YellowEditMerge::REMOVE) {
|
|
|
|
array_push($diff, array(YellowEditMerge::ADD, $textOther[$textStart+$x], false));
|
2018-08-10 22:23:50 +00:00
|
|
|
$lastRemove = -1;
|
|
|
|
} else {
|
2019-03-21 10:58:12 +00:00
|
|
|
$diff[$lastRemove] = array(YellowEditMerge::MODIFY, $textOther[$textStart+$x], false);
|
2018-08-10 22:23:50 +00:00
|
|
|
++$lastRemove;
|
|
|
|
if (count($diff)==$lastRemove) $lastRemove = -1;
|
|
|
|
}
|
|
|
|
++$x;
|
|
|
|
continue;
|
|
|
|
}
|
2019-03-21 10:58:12 +00:00
|
|
|
array_push($diff, array(YellowEditMerge::SAME, $textSource[$textStart+$y], false));
|
2018-08-10 22:23:50 +00:00
|
|
|
$lastRemove = -1;
|
|
|
|
++$x;
|
|
|
|
++$y;
|
|
|
|
}
|
|
|
|
for ($pos=$sourceEnd;$pos<$sourceSize; ++$pos) {
|
2019-03-21 10:58:12 +00:00
|
|
|
array_push($diff, array(YellowEditMerge::SAME, $textSource[$pos], false));
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
return $diff;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build longest common subsequence
|
|
|
|
public function buildDiffLCS($textSource, $textOther, $textStart, $yEnd, $xEnd) {
|
|
|
|
$lcs = array_fill(0, $yEnd+1, array_fill(0, $xEnd+1, 0));
|
|
|
|
for ($y=$yEnd-1; $y>=0; --$y) {
|
|
|
|
for ($x=$xEnd-1; $x>=0; --$x) {
|
|
|
|
if ($textSource[$textStart+$y]==$textOther[$textStart+$x]) {
|
|
|
|
$lcs[$y][$x] = $lcs[$y+1][$x+1]+1;
|
|
|
|
} else {
|
|
|
|
$lcs[$y][$x] = max($lcs[$y][$x+1], $lcs[$y+1][$x]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $lcs;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Merge differences
|
|
|
|
public function mergeDiff($diffMine, $diffYours) {
|
|
|
|
$diff = array();
|
|
|
|
$posMine = $posYours = 0;
|
|
|
|
while ($posMine<count($diffMine) && $posYours<count($diffYours)) {
|
|
|
|
$typeMine = $diffMine[$posMine][0];
|
|
|
|
$typeYours = $diffYours[$posYours][0];
|
2019-03-21 10:58:12 +00:00
|
|
|
if ($typeMine==YellowEditMerge::SAME) {
|
2018-08-10 22:23:50 +00:00
|
|
|
array_push($diff, $diffYours[$posYours]);
|
2019-03-21 10:58:12 +00:00
|
|
|
} elseif ($typeYours==YellowEditMerge::SAME) {
|
2018-08-10 22:23:50 +00:00
|
|
|
array_push($diff, $diffMine[$posMine]);
|
2019-03-21 10:58:12 +00:00
|
|
|
} elseif ($typeMine==YellowEditMerge::ADD && $typeYours==YellowEditMerge::ADD) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$this->mergeConflict($diff, $diffMine[$posMine], $diffYours[$posYours], false);
|
2019-03-21 10:58:12 +00:00
|
|
|
} elseif ($typeMine==YellowEditMerge::MODIFY && $typeYours==YellowEditMerge::MODIFY) {
|
2018-08-10 22:23:50 +00:00
|
|
|
$this->mergeConflict($diff, $diffMine[$posMine], $diffYours[$posYours], false);
|
2019-03-21 10:58:12 +00:00
|
|
|
} elseif ($typeMine==YellowEditMerge::REMOVE && $typeYours==YellowEditMerge::REMOVE) {
|
2018-08-10 22:23:50 +00:00
|
|
|
array_push($diff, $diffMine[$posMine]);
|
2019-03-21 10:58:12 +00:00
|
|
|
} elseif ($typeMine==YellowEditMerge::ADD) {
|
2018-08-10 22:23:50 +00:00
|
|
|
array_push($diff, $diffMine[$posMine]);
|
2019-03-21 10:58:12 +00:00
|
|
|
} elseif ($typeYours==YellowEditMerge::ADD) {
|
2018-08-10 22:23:50 +00:00
|
|
|
array_push($diff, $diffYours[$posYours]);
|
|
|
|
} else {
|
|
|
|
$this->mergeConflict($diff, $diffMine[$posMine], $diffYours[$posYours], true);
|
|
|
|
}
|
2019-03-21 10:58:12 +00:00
|
|
|
if (defined("DEBUG") && DEBUG>=2) echo "YellowEditMerge::mergeDiff $typeMine $typeYours pos:$posMine\t$posYours<br/>\n";
|
|
|
|
if ($typeMine==YellowEditMerge::ADD || $typeYours==YellowEditMerge::ADD) {
|
|
|
|
if ($typeMine==YellowEditMerge::ADD) ++$posMine;
|
|
|
|
if ($typeYours==YellowEditMerge::ADD) ++$posYours;
|
2018-08-10 22:23:50 +00:00
|
|
|
} else {
|
|
|
|
++$posMine;
|
|
|
|
++$posYours;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (;$posMine<count($diffMine); ++$posMine) {
|
|
|
|
array_push($diff, $diffMine[$posMine]);
|
|
|
|
$typeMine = $diffMine[$posMine][0];
|
|
|
|
$typeYours = " ";
|
2019-03-21 10:58:12 +00:00
|
|
|
if (defined("DEBUG") && DEBUG>=2) echo "YellowEditMerge::mergeDiff $typeMine $typeYours pos:$posMine\t$posYours<br/>\n";
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
for (;$posYours<count($diffYours); ++$posYours) {
|
|
|
|
array_push($diff, $diffYours[$posYours]);
|
|
|
|
$typeYours = $diffYours[$posYours][0];
|
|
|
|
$typeMine = " ";
|
2019-03-21 10:58:12 +00:00
|
|
|
if (defined("DEBUG") && DEBUG>=2) echo "YellowEditMerge::mergeDiff $typeMine $typeYours pos:$posMine\t$posYours<br/>\n";
|
2018-08-10 22:23:50 +00:00
|
|
|
}
|
|
|
|
return $diff;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Merge potential conflict
|
|
|
|
public function mergeConflict(&$diff, $diffMine, $diffYours, $conflict) {
|
|
|
|
if (!$conflict && $diffMine[1]==$diffYours[1]) {
|
|
|
|
array_push($diff, $diffMine);
|
|
|
|
} else {
|
|
|
|
array_push($diff, array($diffMine[0], $diffMine[1], true));
|
|
|
|
array_push($diff, array($diffYours[0], $diffYours[1], true));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return merged text, null if not possible
|
|
|
|
public function getOutput($diff, $showDiff = false) {
|
|
|
|
$output = "";
|
|
|
|
if (!$showDiff) {
|
|
|
|
for ($i=0; $i<count($diff); ++$i) {
|
2019-03-21 10:58:12 +00:00
|
|
|
if ($diff[$i][0]!=YellowEditMerge::REMOVE) $output .= $diff[$i][1];
|
2018-08-10 22:23:50 +00:00
|
|
|
$conflict |= $diff[$i][2];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for ($i=0; $i<count($diff); ++$i) {
|
|
|
|
$output .= $diff[$i][2] ? "! " : $diff[$i][0]." ";
|
|
|
|
$output .= $diff[$i][1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return !$conflict ? $output : null;
|
|
|
|
}
|
2014-11-13 13:49:21 +00:00
|
|
|
}
|