You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
339 lines
14 KiB
PHP
339 lines
14 KiB
PHP
<?php
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/**
|
|
* Make things happen when buttons are pressed and forms submitted.
|
|
*/
|
|
require_once __DIR__ . "/required.php";
|
|
require_once __DIR__ . "/lib/util.php";
|
|
|
|
if ($VARS['action'] !== "signout") {
|
|
dieifnotloggedin();
|
|
}
|
|
|
|
/**
|
|
* Redirects back to the page ID in $_POST/$_GET['source'] with the given message ID.
|
|
* The message will be displayed by the app.
|
|
* @param string $msg message ID (see lang/messages.php)
|
|
* @param string $arg If set, replaces "{arg}" in the message string when displayed to the user.
|
|
*/
|
|
function returnToSender($msg, $arg = "") {
|
|
global $VARS;
|
|
if ($arg == "") {
|
|
header("Location: app.php?page=" . urlencode($VARS['source']) . "&msg=" . $msg);
|
|
} else {
|
|
header("Location: app.php?page=" . urlencode($VARS['source']) . "&msg=$msg&arg=$arg");
|
|
}
|
|
die();
|
|
}
|
|
|
|
// https://andrewcurioso.com/blog/archive/2010/detecting-file-size-overflow-in-php.html
|
|
if ($_SERVER['REQUEST_METHOD'] == 'POST' && empty($_POST) &&
|
|
empty($_FILES) && $_SERVER['CONTENT_LENGTH'] > 0) {
|
|
returnToSender("upload_too_big");
|
|
}
|
|
|
|
switch ($VARS['action']) {
|
|
case "newpage":
|
|
if (is_empty($VARS['siteid']) || !$database->has("sites", ["siteid" => $VARS['siteid']])) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
if (is_empty($VARS['title'])) {
|
|
returnToSender("invalid_parameters", $VARS['siteid']);
|
|
}
|
|
if (!is_empty($VARS['slug'])) {
|
|
$slug = strtolower($VARS['slug']);
|
|
$slug = preg_replace("/[^[:alnum:][:space:]]/u", '', $slug);
|
|
$slug = preg_replace("/[[:space:]]/u", '-', $slug);
|
|
if ($database->has("pages", ["AND" => ["siteid" => $VARS['siteid'], "slug" => $VARS['slug']]])) {
|
|
returnToSender("slug_taken", $VARS['siteid']);
|
|
}
|
|
} else {
|
|
// Auto-generate a slug
|
|
$slug = strtolower($VARS['title']);
|
|
$slug = preg_replace("/[^[:alnum:][:space:]]/u", '', $slug);
|
|
$slug = preg_replace("/[[:space:]]/u", '-', $slug);
|
|
if ($database->has("pages", ["AND" => ["siteid" => $VARS['siteid'], "slug" => $slug]])) {
|
|
$num = 2;
|
|
while ($database->has("pages", ["AND" => ["siteid" => $VARS['siteid'], "slug" => $slug . $num]])) {
|
|
$num++;
|
|
}
|
|
$slug = $slug . $num;
|
|
}
|
|
}
|
|
$template = "default";
|
|
if (!is_empty($VARS['template'])) {
|
|
$template = preg_replace("/[^A-Za-z0-9]/", '', $VARS['template']);
|
|
}
|
|
$theme = $database->get("sites", "theme", ["siteid" => $VARS['siteid']]);
|
|
if (!file_exists(__DIR__ . "/public/themes/$theme/$template.php")) {
|
|
returnToSender("template_missing", $VARS['siteid']);
|
|
}
|
|
$database->insert("pages", ["slug" => $slug, "siteid" => $VARS['siteid'], "title" => $VARS['title'], "template" => $VARS['template']]);
|
|
returnToSender("page_added", $VARS['siteid'] . "|" . $database->id());
|
|
break;
|
|
case "pagesettings":
|
|
if (is_empty($VARS['siteid']) || !$database->has("sites", ["siteid" => $VARS['siteid']])) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
if (is_empty($VARS['pageid']) || !$database->has("pages", ["AND" => ["pageid" => $VARS['pageid'], "siteid" => $VARS['siteid']]])) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
if (is_empty($VARS['title'])) {
|
|
returnToSender("invalid_parameters", $VARS['siteid']);
|
|
}
|
|
if (is_empty($VARS['template'])) {
|
|
returnToSender("invalid_parameters", $VARS['siteid']);
|
|
}
|
|
$nav = null;
|
|
if ($VARS['innavbar'] == 1) {
|
|
if (is_empty($VARS['navbartitle'])) {
|
|
returnToSender("invalid_parameters", $VARS['siteid']);
|
|
}
|
|
$nav = $VARS['navbartitle'];
|
|
}
|
|
$template = preg_replace("/[^A-Za-z0-9]/", '', $VARS['template']);
|
|
$theme = $database->get("sites", "theme", ["siteid" => $VARS['siteid']]);
|
|
if (!file_exists(__DIR__ . "/public/themes/$theme/$template.php")) {
|
|
returnToSender("template_missing", $VARS['siteid']);
|
|
}
|
|
$settings = [
|
|
"title" => $VARS['title'],
|
|
"template" => $VARS['template'],
|
|
'nav' => $nav
|
|
];
|
|
if (is_null($nav)) {
|
|
$settings["navorder"] = null;
|
|
}
|
|
$database->update(
|
|
"pages", $settings, [
|
|
"AND" => [
|
|
"siteid" => $VARS['siteid'],
|
|
"pageid" => $VARS['pageid']
|
|
]
|
|
]);
|
|
if (!is_empty($VARS['navorder']) && preg_match("/^[0-9]+([0-9|]*([0-9])|[0-9])$/", $VARS['navorder'])) {
|
|
$pages = explode("|", preg_replace("/[|]{2,}/", "", $VARS['navorder']));
|
|
for ($i = 0; $i < count($pages); $i++) {
|
|
$database->update("pages", [
|
|
"navorder" => $i + 1
|
|
], [
|
|
"AND" => [
|
|
"siteid" => $VARS['siteid'],
|
|
"pageid" => $pages[$i]
|
|
]
|
|
]);
|
|
}
|
|
}
|
|
returnToSender("settings_saved", $VARS['siteid'] . "|" . $VARS['pageid']);
|
|
break;
|
|
case "sitesettings":
|
|
if (!is_empty($VARS['siteid'])) {
|
|
if (!$database->has("sites", ["siteid" => $VARS['siteid']])) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
}
|
|
if (is_empty($VARS['name'])) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
if (is_empty($VARS['url'])) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
if (is_empty($VARS['theme'])) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
if (is_empty($VARS['color'])) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
$url = formatsiteurl($VARS['url']);
|
|
$theme = preg_replace("/[^A-Za-z0-9]/", '', $VARS['theme']);
|
|
$color = preg_replace("/[^A-Za-z0-9]/", '', $VARS['color']);
|
|
if (!file_exists(__DIR__ . "/public/themes/$theme/theme.json")) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
if ($color != "default" && !file_exists(__DIR__ . "/public/themes/$theme/colors/$color")) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
if (is_empty($VARS['siteid'])) {
|
|
$database->insert('sites', ["sitename" => $VARS['name'], "url" => $url, "theme" => $theme, "color" => $color]);
|
|
$siteid = $database->id();
|
|
$template = (file_exists(__DIR__ . "/public/themes/$theme/home.php") ? "home" : "default");
|
|
$database->insert('pages', ["slug" => "index", "siteid" => $siteid, "title" => "Home", "nav" => "Home", "navorder" => 1, "template" => $template]);
|
|
} else {
|
|
$database->update('sites', ["sitename" => $VARS['name'], "url" => $url, "theme" => $theme, "color" => $color], ["siteid" => $VARS['siteid']]);
|
|
$siteid = $VARS['siteid'];
|
|
}
|
|
|
|
foreach ($VARS['settings'] as $key => $value) {
|
|
if (is_array($value)) {
|
|
$value = json_encode($value);
|
|
}
|
|
if ($database->has('settings', ["AND" => ["siteid" => $siteid, "key" => $key]])) {
|
|
if ($value == "") {
|
|
//echo "deleting $key => $value\n";
|
|
$database->delete('settings', ["AND" => ["siteid" => $siteid, "key" => $key]]);
|
|
} else {
|
|
//echo "updating $key => $value\n";
|
|
$database->update('settings', ["value" => $value], ["AND" => ["siteid" => $siteid, "key" => $key]]);
|
|
}
|
|
} else if ($value != "") {
|
|
$database->insert('settings', ["siteid" => $siteid, "key" => $key, "value" => $value]);
|
|
}
|
|
}
|
|
|
|
returnToSender("settings_saved");
|
|
break;
|
|
case "saveedits":
|
|
header("Content-Type: application/json");
|
|
$slug = $VARS['slug'];
|
|
$site = $VARS['site'];
|
|
$content = $VARS['content'];
|
|
if ($database->has("pages", ["AND" => ["slug" => $slug, "siteid" => $site]])) {
|
|
$pageid = $database->get("pages", "pageid", ["AND" => ["slug" => $slug, "siteid" => $site]]);
|
|
} else {
|
|
die(json_encode(["status" => "ERROR", "msg" => "Invalid page or site"]));
|
|
}
|
|
foreach ($content as $name => $value) {
|
|
if (is_array($value)) {
|
|
$json = json_encode($value);
|
|
if ($database->has("complex_components", ["AND" => ["pageid" => $pageid, "name" => $name]])) {
|
|
$database->update("complex_components", ["content" => $json], ["AND" => ["pageid" => $pageid, "name" => $name]]);
|
|
} else {
|
|
$database->insert("complex_components", ["name" => $name, "content" => $json, "pageid" => $pageid]);
|
|
}
|
|
} else {
|
|
if ($database->has("components", ["AND" => ["pageid" => $pageid, "name" => $name]])) {
|
|
$database->update("components", ["content" => $value], ["AND" => ["pageid" => $pageid, "name" => $name]]);
|
|
} else {
|
|
$database->insert("components", ["name" => $name, "content" => $value, "pageid" => $pageid]);
|
|
}
|
|
}
|
|
}
|
|
exit(json_encode(["status" => "OK"]));
|
|
break;
|
|
case "deletemessage":
|
|
if ($database->count('messages', ["mid" => $VARS['id']]) !== 1) {
|
|
returnToSender("invalid_parameters");
|
|
}
|
|
$database->delete('messages', ["mid" => $VARS['id']]);
|
|
returnToSender("message_deleted");
|
|
break;
|
|
case "fileupload":
|
|
$destpath = FILE_UPLOAD_PATH . $VARS['path'];
|
|
if (strpos(realpath($destpath), FILE_UPLOAD_PATH) !== 0) {
|
|
returnToSender("file_security_error");
|
|
}
|
|
if (!file_exists($destpath) || !is_dir($destpath)) {
|
|
returnToSender("missing_folder");
|
|
}
|
|
if (!is_writable($destpath)) {
|
|
returnToSender("unwritable_folder");
|
|
}
|
|
|
|
$files = [];
|
|
foreach ($_FILES['files'] as $key => $all) {
|
|
foreach ($all as $i => $val) {
|
|
$files[$i][$key] = $val;
|
|
}
|
|
}
|
|
|
|
$errors = [];
|
|
foreach ($files as $f) {
|
|
if ($f['error'] !== UPLOAD_ERR_OK) {
|
|
$err = "could not be uploaded.";
|
|
switch ($f['error']) {
|
|
case UPLOAD_ERR_INI_SIZE:
|
|
case UPLOAD_ERR_FORM_SIZE:
|
|
$err = "is too big.";
|
|
break;
|
|
case UPLOAD_ERR_CANT_WRITE:
|
|
$err = "could not be saved to disk.";
|
|
break;
|
|
case UPLOAD_ERR_NO_FILE:
|
|
$err = "was not actually sent.";
|
|
break;
|
|
case UPLOAD_ERR_PARTIAL:
|
|
$err = "was only partially sent.";
|
|
break;
|
|
default:
|
|
$err = "could not be uploaded.";
|
|
}
|
|
$errors[] = htmlspecialchars($f['name']) . " $err";
|
|
continue;
|
|
}
|
|
|
|
$filename = basename($f['name']);
|
|
$filename = preg_replace("/[^a-z0-9\._\-]/", "_", strtolower($filename));
|
|
$n = 1;
|
|
if (file_exists($destpath . "/" . $filename)) {
|
|
while (file_exists($destpath . '/' . $n . '_' . $filename)) {
|
|
$n++;
|
|
}
|
|
$filename = $n . '_' . $filename;
|
|
}
|
|
|
|
$finalpath = $destpath . "/" . $filename;
|
|
|
|
if (move_uploaded_file($f['tmp_name'], $finalpath)) {
|
|
|
|
} else {
|
|
$errors[] = htmlspecialchars($f['name']) . " could not be uploaded.";
|
|
}
|
|
}
|
|
|
|
if (count($errors) > 0) {
|
|
returnToSender("upload_warning", implode("<br>", $errors) . "&path=" . $VARS['path']);
|
|
}
|
|
|
|
returnToSender("upload_success", "&path=" . $VARS['path']);
|
|
break;
|
|
case "newfolder":
|
|
$foldername = preg_replace("/[^a-z0-9_\-]/", "_", strtolower($VARS['folder']));
|
|
$newfolder = FILE_UPLOAD_PATH . $VARS['path'] . '/' . $foldername;
|
|
|
|
if (mkdir($newfolder, 0755)) {
|
|
returnToSender("folder_created", "&path=" . $VARS['path']);
|
|
}
|
|
returnToSender("folder_not_created", "&path=" . $VARS['path']);
|
|
break;
|
|
case "filedelete":
|
|
$file = FILE_UPLOAD_PATH . $VARS['file'];
|
|
if (strpos(realpath($file), FILE_UPLOAD_PATH) !== 0) {
|
|
returnToSender("file_security_error");
|
|
}
|
|
if (!file_exists($file)) {
|
|
// Either way the file is gone
|
|
returnToSender("file_deleted");
|
|
}
|
|
if (!is_writable($file) || realpath($file) == realpath(FILE_UPLOAD_PATH)) {
|
|
returnToSender("undeletable_file");
|
|
}
|
|
if (is_dir($file)) {
|
|
if (!rmdir($file)) {
|
|
returnToSender("folder_not_empty");
|
|
}
|
|
} else {
|
|
if (!unlink($file)) {
|
|
returnToSender("file_not_deleted");
|
|
}
|
|
}
|
|
returnToSender("file_deleted");
|
|
break;
|
|
case "unsplash_download":
|
|
Crew\Unsplash\HttpClient::init([
|
|
'applicationId' => UNSPLASH_ACCESSKEY,
|
|
'secret' => UNSPLASH_SECRETKEY,
|
|
'utmSource' => UNSPLASH_UTMSOURCE
|
|
]);
|
|
Crew\Unsplash\Photo::find($VARS['imageid'])->download();
|
|
header('Content-Type: application/json');
|
|
exit(json_encode(["status" => "OK"]));
|
|
break;
|
|
case "signout":
|
|
session_destroy();
|
|
header('Location: index.php');
|
|
die("Logged out.");
|
|
} |