Add basic page editing and saving in control panel

master
Skylar Ittner 6 years ago
parent b377e57b5d
commit aef29f18ab

@ -7,7 +7,6 @@
/**
* Make things happen when buttons are pressed and forms submitted.
*/
require_once __DIR__ . "/required.php";
if ($VARS['action'] !== "signout") {
@ -32,8 +31,24 @@ function returnToSender($msg, $arg = "") {
switch ($VARS['action']) {
case "saveedits":
$page = $VARS['page'];
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 ($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 "signout":
session_destroy();
header('Location: index.php');

Binary file not shown.

@ -28,7 +28,18 @@ define("STRINGS", [
"login server error" => "The login server returned an error: {arg}",
"login server user data error" => "The login server refused to provide account information. Try again or contact technical support.",
"captcha error" => "There was a problem with the CAPTCHA (robot test). Try again.",
"actions" => "Actions",
"home" => "Home",
"more" => "More",
"test" => "Test"
"sites" => "Sites",
"theme" => "Theme",
"name" => "Name",
"site name" => "Site Name",
"url" => "URL",
"editing site" => "Editing {site}",
"theme type" => "Theme type",
"single page" => "Single page",
"multiple page" => "Multiple page",
"templates" => "Templates",
"color styles" => "Color styles"
]);

@ -59,7 +59,11 @@ function get_page_url($echo = true, $slug = null) {
if ($slug == null) {
$slug = get_page_slug(false);
}
$url = get_site_url(false) . "index.php?id=$slug";
$edit = "";
if (isset($_GET['edit'])) {
$edit = "&edit";
}
$url = get_site_url(false) . "index.php?id=$slug$edit";
if ($echo) {
echo $url;
} else {

@ -11,7 +11,30 @@ define("PAGES", [
"navbar" => true,
"icon" => "fas fa-home"
],
"sites" => [
"title" => "sites",
"navbar" => true,
"icon" => "fas fa-sitemap"
],
"sitesettings" => [
"title" => "settings",
"styles" => [
"static/css/themeselector.css"
],
"scripts" => [
"static/js/sitesettings.js"
]
],
"editor" => [
"title" => "editor",
"styles" => [
"static/css/editorparent.css"
],
"scripts" => [
"static/js/editorparent.js"
]
],
"404" => [
"title" => "404 error"
]
]);
]);

@ -0,0 +1,71 @@
<?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/. */
require_once __DIR__ . '/../required.php';
redirectifnotloggedin();
if (!is_empty($VARS['siteid'])) {
if ($database->has('sites', ['siteid' => $VARS['siteid']])) {
$sitedata = $database->get(
'sites', [
'siteid',
'sitename',
'url',
'theme',
'color'
], [
'siteid' => $VARS['siteid']
]);
$pagedata = $database->select(
'pages', [
"pageid",
"slug",
"title",
"template"
], ["siteid" => $VARS['siteid']]
);
$slug = "index";
if (isset($VARS['slug']) && $database->has('pages', ["AND" => ['slug' => $VARS['slug'], 'siteid' => $VARS['siteid']]])) {
$slug = $VARS['slug'];
}
} else {
header('Location: app.php?page=sites');
die();
}
} else {
header('Location: app.php?page=sites');
die();
}
?>
<div class="row mb-2">
<div class="col-12 col-sm-6 col-md-4">
<div class="btn btn-success" id="savebtn">
<i class="fas fa-save"></i> <?php lang("save"); ?>
</div>
</div>
<form method="GET" action="app.php" class="col-12 col-sm-6 col-md-4">
<input type="hidden" name="page" value="editor" />
<input type="hidden" name="siteid" value="<?php echo $VARS['siteid']; ?>" />
<div class="input-group">
<select name="slug" class="form-control">
<?php
foreach ($pagedata as $p) {
$selected = "";
if ($slug == $p['slug']) {
$selected = " selected";
}
echo "<option value=\"" . $p['slug'] . "\"$selected>" . $p['title'] . ' (' . $p['slug'] . ')' . "</option>\n";
}
?>
</select>
<div class="input-group-append">
<button type="submit" class="btn btn-primary"><?php lang("edit"); ?></button>
</div>
</div>
</form>
</div>
<iframe id="editorframe" src="public/index.php?id=<?php echo $slug; ?>&edit"></iframe>

@ -0,0 +1,60 @@
<?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/. */
require_once __DIR__ . '/../required.php';
redirectifnotloggedin();
?>
<div class="btn-group">
<a href="app.php?page=addsite" class="btn btn-success"><i class="fas fa-plus"></i> <?php lang("new site"); ?></a>
</div>
<table id="cattable" class="table table-bordered table-hover table-sm">
<thead>
<tr>
<th data-priority="0"></th>
<th data-priority="1"><?php lang('actions'); ?></th>
<th data-priority="1"><i class="fas fa-font d-none d-md-inline"></i> <?php lang('site name'); ?></th>
<th data-priority="2"><i class="fas fa-globe d-none d-md-inline"></i> <?php lang('url'); ?></th>
<th data-priority="3"><i class="fas fa-paint-brush d-none d-md-inline"></i> <?php lang('theme'); ?></th>
</tr>
</thead>
<tbody>
<?php
$sites = $database->select('sites', [
'siteid',
'sitename',
'url',
'theme',
'color'
]);
foreach ($sites as $site) {
$theme = json_decode(file_get_contents("public/themes/".$site['theme']."/theme.json"), true);
$themename = $theme["name"];
?>
<tr>
<td></td>
<td>
<a class="btn btn-primary btn-sm" href="app.php?page=editor&siteid=<?php echo $site['siteid']; ?>"><i class="fas fa-edit"></i> <?php lang("editor"); ?></a>
<a class="btn btn-secondary btn-sm" href="app.php?page=sitesettings&siteid=<?php echo $site['siteid']; ?>"><i class="fas fa-cog"></i> <?php lang("settings"); ?></a>
<a class="btn btn-info btn-sm" href="<?php echo $site['url']; ?>" target="_BLANK"><i class="fas fa-eye"></i> <?php lang("view"); ?></a>
</td>
<td><?php echo $site['sitename']; ?></td>
<td><?php echo $site['url']; ?></td>
<td><?php echo $themename; ?></td>
</tr>
<?php
}
?>
</tbody>
<tfoot>
<tr>
<th data-priority="0"></th>
<th data-priority="1"><?php lang('actions'); ?></th>
<th data-priority="1"><i class="fas fa-font d-none d-md-inline"></i> <?php lang('site name'); ?></th>
<th data-priority="2"><i class="fas fa-globe d-none d-md-inline"></i> <?php lang('url'); ?></th>
<th data-priority="3"><i class="fas fa-paint-brush d-none d-md-inline"></i> <?php lang('theme'); ?></th>
</tr>
</tfoot>
</table>

@ -0,0 +1,97 @@
<?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/. */
require_once __DIR__ . '/../required.php';
redirectifnotloggedin();
if (!is_empty($VARS['siteid'])) {
if ($database->has('sites', ['siteid' => $VARS['siteid']])) {
$sitedata = $database->select(
'sites', [
'siteid',
'sitename',
'url',
'theme',
'color'
], [
'siteid' => $VARS['siteid']
])[0];
} else {
header('Location: app.php?page=sites');
}
} else {
header('Location: app.php?page=sites');
}
?>
<form role="form" action="action.php" method="POST">
<div class="card border-light-blue">
<h3 class="card-header text-light-blue">
<i class="fas fa-edit"></i> <?php lang2("editing site", ['site' => "<span id=\"name_title\">" . htmlspecialchars($sitedata['sitename']) . "</span>"]); ?>
</h3>
<div class="card-body">
<div class="form-group">
<label for="name"><i class="fas fa-font"></i> <?php lang("name"); ?></label>
<input type="text" class="form-control" id="name" name="name" placeholder="Foo Bar" required="required" value="<?php echo htmlspecialchars($sitedata['sitename']); ?>" />
</div>
<div class="form-group">
<label for="url"><i class="fas fa-globe"></i> <?php lang("url"); ?></label>
<input type="text" class="form-control" id="url" name="url" placeholder="https://example.com" required="required" value="<?php echo htmlspecialchars($sitedata['url']); ?>" />
</div>
<div class="row">
<div class="col-12">
<div class="form-group">
<label for="style"><i class="fas fa-paint-brush"></i> <?php lang('theme'); ?></label>
<div class="theme_bin">
<?php
$themedir = __DIR__ . "/../public/themes/";
$themes = array_diff(scandir($themedir), array('..', '.'));
foreach ($themes as $t) {
if (!file_exists($themedir . "$t/theme.json")) {
continue;
}
$info = json_decode(file_get_contents($themedir . "$t/theme.json"), TRUE);
$ts = $sitedata["theme"] == $t ? " checked" : "";
?>
<label>
<input type="radio" name="style" value="<?php echo $t; ?>" <?php echo $ts; ?> />
<div class="card theme">
<div class="card-body m-0 p-1">
<b><?php echo $info['name']; ?></b><br />
<?php
lang("theme type");
echo ": ";
if ($info['singlepage'] == true) {
lang("single page");
} else {
lang("multiple page");
}
?><br />
<?php lang("templates");
echo ": " . count($info['templates']);
?><br />
<?php lang("color styles");
echo ": " . count($info['colors']);
?>
</div>
</div>
</label>
<?php } ?>
</div>
</div>
</div>
</div>
</div>
<input type="hidden" name="siteid" value="<?php echo htmlspecialchars($VARS['siteid']); ?>" />
<input type="hidden" name="action" value="sitesettings" />
<input type="hidden" name="source" value="sites" />
<div class="card-footer d-flex">
<button type="submit" class="btn btn-success mr-auto"><i class="fas fa-save"></i> <?php lang("save"); ?></button>
</div>
</div>
</form>

@ -19,12 +19,13 @@ include __DIR__ . "/themes/$theme/$template.php";
if (isset($_GET['edit'])) {
?>
<link href="<?php echo URL; ?>/static/css/summernote-lite.css" rel="stylesheet" />
<style><?php echo str_replace("./font/summernote", "../static/fonts/summernote", file_get_contents(__DIR__ . "/../static/css/summernote-lite.css")); ?></style>
<script src="<?php echo URL; ?>/static/js/jquery-3.3.1.min.js"></script>
<script src="<?php echo URL; ?>/static/js/summernote-lite.js"></script>
<script>
var save_url = "<?php echo URL; ?>/action.php";
var static_dir = "<?php echo URL; ?>/static";
var page_slug = "<?php getpageslug(); ?>";
static_dir = "<?php echo URL; ?>/static";
page_slug = "<?php echo getpageslug(); ?>";
site_id = "<?php echo getsiteid(); ?>";
</script>
<script src="<?php echo URL; ?>/static/js/editor.js"></script>
<?php

@ -1,5 +1,6 @@
{
"name": "Bootstrap",
"singlepage": false,
"templates": {
"default": {
"title": "Default",

@ -49,7 +49,7 @@ if ($_SESSION['mobile'] === TRUE) {
. "object-src 'none'; "
. "img-src * data:; "
. "media-src 'self'; "
. "frame-src 'none'; "
. "frame-src 'self'; "
. "font-src 'self'; "
. "connect-src *; "
. "style-src 'self' 'nonce-$SECURE_NONCE' $captcha_server; "

@ -4,11 +4,32 @@ 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/.
*/
.sw-text-input {
border: 2px dashed red;
input[type="text"].sw-text-input {
border: 2px dashed red !important;
width: 100%;
color: black !important;
background: white !important;
border-radius: 0px;
}
.note-editor {
border: 2px dashed red !important;
}
button.note-btn, .note-modal button {
box-shadow: none;
color: #333 !important;
}
.note-modal .close {
color: #000 !important;
}
.note-modal .checkbox label input[type="checkbox"] {
opacity: 1;
margin-right: 1px;
appearance: checkbox;
-moz-appearance: checkbox;
-webkit-appearance: checkbox;
-ms-appearance: checkbox;
}

@ -0,0 +1,12 @@
/*
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/.
*/
#editorframe {
border: 1px solid black;
width: 100%;
height: 1000px;
max-height: calc(100vh - 200px);
}

@ -0,0 +1,25 @@
/*
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/.
*/
.theme_bin {
max-height: 300px;
overflow-y: scroll;
padding: 5px;
}
.theme_bin label input[type=radio] {
visibility: hidden;
position: absolute;
}
.theme_bin label input[type=radio] + .theme {
cursor: pointer;
border: 3px solid white;
margin: 2px;
}
.theme_bin label input[type=radio]:checked + .theme {
border: 3px solid rgba(0,0,0,.8);
}

@ -4,9 +4,28 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function saveEdits() {
var components = {};
$(".sw-editable").each(function (e) {
components[$(this).data("component")] = $(this).summernote('code');
});
$(".sw-text-input").each(function (e) {
components[$(this).data("component")] = $(this).val();
});
var output = {
slug: page_slug,
site: site_id,
content: components
};
//console.log(output);
var json = JSON.stringify(output);
console.log("editor: sent page content");
parent.postMessage('save ' + json, "*");
}
$(document).ready(function () {
$("body").append("<link href=\"" + static_dir + "/css/editor.css\" rel=\"stylesheet\" />");
$(".sw-editable").each(function () {
// Remove leading whitespace added by the template
$(this).html($(this).html().trim());
@ -20,7 +39,7 @@ $(document).ready(function () {
['fontsize', ['fontsize']],
['para', ['ul', 'ol']],
['insert', ['link', 'picture']],
['misc', ['undo', 'redo', 'fullscreen', 'codeview']]
['misc', ['undo', 'redo', 'codeview']]
],
placeholder: 'Click to edit'
});
@ -30,21 +49,11 @@ $(document).ready(function () {
var component = $(this).data("component");
$(this).html("<input type=\"text\" data-component=\"" + component + "\" class=\"sw-text-input\" value=\"" + text + "\" placeholder=\"Click to edit\">");
});
});
function saveEdits() {
var components = [];
$(".sw-editable").each(function (e) {
components[$(this).data("component")] = $(this).summernote('code');
});
$(".sw-text-input").each(function (e) {
components[$(this).data("component")] = $(this).val();
});
var content = JSON.stringify(components);
console.log(components);
$.post(save_url, {
action: "saveedits",
page: "",
content: content
window.addEventListener('message', function (event) {
console.log("editor: received message: " + event.data);
if (event.data == "save") {
saveEdits();
}
});
}
});

@ -0,0 +1,38 @@
/*
* 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/.
*/
function save(json) {
var output = JSON.parse(json);
console.log(output);
$.post("action.php", {
action: "saveedits",
source: "editor",
slug: output["slug"],
site: output["site"],
content: output["content"]
}, function (data) {
if (data.status == "OK") {
alert("Saved");
} else {
alert(data.msg);
}
});
}
window.addEventListener('message', function (event) {
//console.log("parent: received message: " + event.data);
if (event.data.startsWith("save ")) {
save(event.data.slice(5));
}
});
$("#savebtn").click(function () {
triggerSave();
});
function triggerSave() {
document.getElementById("editorframe").contentWindow.postMessage("save", "*");
}

@ -0,0 +1,7 @@
/* 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/. */
$('#name').on('input propertychange paste', function () {
$('#name_title').text($('#name').val());
});
Loading…
Cancel
Save