Commit f8e88912 authored by Stephan Kreutzer's avatar Stephan Kreutzer
Browse files

UI for revising pattern sections.

parent 86f578df
......@@ -25,6 +25,10 @@
define("LANG_LINKCAPTION_VIEWSOURCE", "Quelle");
define("LANG_LINKCAPTION_PATTERNINDEX", "Muster-Übersicht");
define("LANG_LINKCAPTION_EDIT", "bearbeiten");
define("LANG_LINKCAPTION_REVISIONS", "Änderungshistorie");
define("LANG_TABLECOLUMNCAPTION_TIMESTAMP", "Zeitstempel");
define("LANG_TABLECOLUMNCAPTION_VERSION", "Version");
......
......@@ -25,6 +25,10 @@
define("LANG_LINKCAPTION_VIEWSOURCE", "source");
define("LANG_LINKCAPTION_PATTERNINDEX", "Patterns");
define("LANG_LINKCAPTION_EDIT", "edit");
define("LANG_LINKCAPTION_REVISIONS", "Revisions");
define("LANG_TABLECOLUMNCAPTION_TIMESTAMP", "Timestamp");
define("LANG_TABLECOLUMNCAPTION_VERSION", "Version");
......
/* Copyright (C) 2019-2020 Stephan Kreutzer
*
* This file is part of pattern-server.
*
* pattern-server is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3 or any later version,
* as published by the Free Software Foundation.
*
* pattern-server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License 3 for more details.
*
* You should have received a copy of the GNU Affero General Public License 3
* along with pattern-server. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";
function LoadInputControl(idPattern, idSection, show)
{
let updateControlDiv = document.getElementById("update_control_" + idSection);
let revisionTextSpan = document.getElementById("revision_text_" + idSection);
if (updateControlDiv == null)
{
throw "ID 'update_control_" + idSection + "' not found.";
}
if (revisionTextSpan == null)
{
throw "ID 'revision_text_" + idSection + "' not found.";
}
for (let i = updateControlDiv.childNodes.length - 1; i >= 0; i--)
{
removeNode(updateControlDiv.childNodes[i], updateControlDiv);
}
if (show == true)
{
let form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", "pattern_view.php?id=" + idPattern + "&id_section=" + idSection);
let fieldset = document.createElement("fieldset");
let textarea = document.createElement("textarea");
textarea.setAttribute("name", "text");
textarea.setAttribute("rows", "24");
textarea.setAttribute("cols", "80");
{
let textareaText = document.createTextNode(revisionTextSpan.innerText);
textarea.appendChild(textareaText);
}
let submit = document.createElement("input");
submit.setAttribute("type", "submit");
submit.setAttribute("name", "submit");
submit.setAttribute("value", "Update");
let cancel = document.createElement("input");
cancel.setAttribute("type", "button");
cancel.setAttribute("onclick", "LoadInputControl(" + idPattern + ", " + idSection + ", false);");
cancel.setAttribute("value", "Cancel");
fieldset.appendChild(textarea);
fieldset.appendChild(submit);
fieldset.appendChild(cancel);
form.appendChild(fieldset);
updateControlDiv.appendChild(form);
}
return 0;
}
function ToggleRevisions(id)
{
let revisionsDiv = document.getElementById(id);
if (revisionsDiv == null)
{
return -1;
}
if (revisionsDiv.style.display === "block")
{
revisionsDiv.style.display = "none";
}
else
{
revisionsDiv.style.display = "block";
}
return 0;
}
// Stupid JavaScript has a cloneNode(deep), but no removeNode(deep).
function removeNode(element, parent)
{
// TODO: Reverse delete for performance.
while (element.hasChildNodes == true)
{
removeNode(element.lastChild, element);
}
parent.removeChild(element);
}
......@@ -26,15 +26,16 @@
require_once("./libraries/https.inc.php");
if (isset($_GET['id']) !== true)
if ($_SERVER['REQUEST_METHOD'] !== "GET" &&
$_SERVER['REQUEST_METHOD'] !== "POST")
{
http_response_code(400);
http_response_code(405);
return 0;
}
if ($_SERVER['REQUEST_METHOD'] !== "GET")
if (isset($_GET['id']) !== true)
{
http_response_code(405);
http_response_code(400);
return 0;
}
......@@ -48,6 +49,81 @@ if (Database::Get()->IsConnected() !== true)
return 1;
}
$sections = Database::Get()->Query("SELECT `".Database::Get()->GetPrefix()."pattern_section`.`id` AS `pattern_section_id`,\n".
" `".Database::Get()->GetPrefix()."pattern_section`.`id_template_section` AS `pattern_section_id_template_section`,\n".
" `".Database::Get()->GetPrefix()."template_section`.`name` AS `name`,\n".
" `".Database::Get()->GetPrefix()."template_section`.`title` AS `title`,\n".
" `".Database::Get()->GetPrefix()."template_section`.`id_template` AS `id_template`\n".
"FROM `".Database::Get()->GetPrefix()."pattern_section`\n".
"INNER JOIN `".Database::Get()->GetPrefix()."template_section` ON\n".
" `".Database::Get()->GetPrefix()."pattern_section`.`id_template_section`=\n".
" `".Database::Get()->GetPrefix()."template_section`.`id`\n".
"WHERE `".Database::Get()->GetPrefix()."pattern_section`.`id_pattern`=?\n".
"ORDER BY `".Database::Get()->GetPrefix()."pattern_section`.`id` ASC\n",
array($id),
array(Database::TYPE_INT));
if (is_array($sections) !== true)
{
http_response_code(500);
return 1;
}
$maxSections = count($sections);
if ($maxSections <= 0)
{
http_response_code(404);
return 0;
}
if ($_SERVER['REQUEST_METHOD'] === "POST")
{
if (isset($_GET['id_section']) !== true)
{
http_response_code(400);
return 0;
}
if (isset($_POST['text']) !== true)
{
http_response_code(400);
return 0;
}
$idSectionTarget = (int)$_GET['id_section'];
$sectionFound = false;
for ($i = 0; $i < $maxSections; $i++)
{
if (((int)$sections[$i]['pattern_section_id']) === $idSectionTarget)
{
$sectionFound = true;
break;
}
}
if ($sectionFound == false)
{
http_response_code(400);
return 0;
}
$idNewRevision = Database::Get()->Insert("INSERT INTO `".Database::Get()->GetPrefix()."pattern_section_revision` (`id`,\n".
" `text`,\n".
" `datetime_created`,\n".
" `id_pattern_section`)\n".
"VALUES (?, ?, UTC_TIMESTAMP(), ?)",
array(NULL, $_POST['text'], $idSectionTarget),
array(Database::TYPE_NULL, Database::TYPE_STRING, Database::TYPE_INT));
if ($idNewRevision <= 0)
{
http_response_code(500);
exit(1);
}
}
$revisions = Database::Get()->Query("SELECT `".Database::Get()->GetPrefix()."pattern_section`.`id` AS `pattern_section_id`,\n".
" `".Database::Get()->GetPrefix()."pattern_section`.`id_template_section` AS `pattern_section_id_template_section`,\n".
" `".Database::Get()->GetPrefix()."pattern_section_revision`.`id` AS `pattern_section_revision_id`,\n".
......@@ -77,33 +153,6 @@ if ($maxRevisions <= 0)
return 0;
}
$sections = Database::Get()->Query("SELECT `".Database::Get()->GetPrefix()."pattern_section`.`id_template_section` AS `pattern_section_id_template_section`,\n".
" `".Database::Get()->GetPrefix()."template_section`.`name` AS `name`,\n".
" `".Database::Get()->GetPrefix()."template_section`.`title` AS `title`,\n".
" `".Database::Get()->GetPrefix()."template_section`.`id_template` AS `id_template`\n".
"FROM `".Database::Get()->GetPrefix()."pattern_section`\n".
"INNER JOIN `".Database::Get()->GetPrefix()."template_section` ON\n".
" `".Database::Get()->GetPrefix()."pattern_section`.`id_template_section`=\n".
" `".Database::Get()->GetPrefix()."template_section`.`id`\n".
"WHERE `".Database::Get()->GetPrefix()."pattern_section`.`id_pattern`=?\n".
"ORDER BY `".Database::Get()->GetPrefix()."pattern_section`.`id` ASC\n",
array($id),
array(Database::TYPE_INT));
if (is_array($sections) !== true)
{
http_response_code(500);
return 1;
}
$maxSections = count($sections);
if ($maxSections <= 0)
{
http_response_code(404);
return 0;
}
$templateId = (int)$sections[0]['id_template'];
$template = Database::Get()->Query("SELECT `id`,\n".
......@@ -155,8 +204,15 @@ if (CONTENT_TYPE_REQUESTED === CONTENT_TYPE_SUPPORTED_XHTML)
" <head>\n".
" <meta http-equiv=\"content-type\" content=\"application/xhtml+xml; charset=UTF-8\"/>\n".
" <title>".$templateTitle."</title>\n".
" <link rel=\"stylesheet\" type=\"text/css\" href=\"mainstyle.css\"/>\n".
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n".
" <link rel=\"stylesheet\" type=\"text/css\" href=\"mainstyle.css\"/>\n".
" <style type=\"text/css\">\n".
" .revisions\n".
" {\n".
" display: none;\n".
" }\n".
" </style>\n".
" <script type=\"text/javascript\" src=\"pattern_section_controls.js\"></script>\n".
" </head>\n".
" <body>\n".
" <div class=\"mainbox\">\n".
......@@ -176,23 +232,51 @@ if (CONTENT_TYPE_REQUESTED === CONTENT_TYPE_SUPPORTED_XHTML)
return 1;
}
$sectionTitle = htmlspecialchars($sections[$i]['title'], ENT_XHTML, "UTF-8");
echo " <h2>".$sectionTitle."</h2>\n".
" <p>";
$firstFound = false;
/** @todo Optimize: $revisions is already ordered, $j doesn't need to restart from 0. */
for ($j = 0; $j < $maxRevisions; $j++)
{
if (((int)$revisions[$j]['pattern_section_id_template_section']) == ((int)$sections[$i]['pattern_section_id_template_section']))
{
echo htmlspecialchars($revisions[$j]['pattern_section_revision_text'], ENT_XHTML, "UTF-8");
break;
$revisionText = htmlspecialchars($revisions[$j]['pattern_section_revision_text'], ENT_XHTML, "UTF-8");
if ($firstFound == false)
{
$sectionTitle = htmlspecialchars($sections[$i]['title'], ENT_XHTML, "UTF-8");
echo " <h2>".$sectionTitle."</h2>\n".
" <div id=\"update_control_".$sections[$i]['pattern_section_id']."\"></div>\n".
" <p id=\"revision_text_".$sections[$i]['pattern_section_id']."\">".$revisionText."</p>\n".
" <a href=\"#\" onclick=\"LoadInputControl(".$id.", ".$sections[$i]['pattern_section_id'].", true);\">".LANG_LINKCAPTION_EDIT."</a> <a href=\"#\" onclick=\"ToggleRevisions('revisions_".$sections[$i]['pattern_section_id']."');\">".LANG_LINKCAPTION_REVISIONS."</a>\n".
" <div class=\"revisions\" id=\"revisions_".$sections[$i]['pattern_section_id']."\">\n".
" <table border=\"1\">\n".
" <thead>\n".
" <tr>\n".
" <th>".LANG_TABLECOLUMNCAPTION_TIMESTAMP." (UTC)</th>\n".
" <th>".LANG_TABLECOLUMNCAPTION_VERSION."</th>\n".
" </tr>\n".
" </thead>\n".
" <tbody>\n";
$firstFound = true;
}
echo " <tr>\n".
" <td>".$revisions[$j]['pattern_section_revision_datetime_created']."Z</td>\n".
" <td>".$revisionText."</td>\n".
" </tr>\n";
}
}
echo "</p>\n".
" </div>\n";
if ($firstFound == true)
{
echo " </tbody>\n".
" </table>\n".
" </div>\n";
}
echo " </div>\n";
}
echo " </div>\n".
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment