Compare commits

...

10 commits

25 changed files with 582 additions and 426 deletions

View file

@ -1,3 +1,9 @@
trinkey's fork of [notfire's qna](https://git.notfire.cc/notfire/qna)
has the same functionality but i added custom css support and made the code less messy
---
to set up, generally:
- make a database in postgres
- set up config.php based off of the example

View file

@ -4,74 +4,76 @@ $query = "
SELECT * FROM data;
";
$qresp = pg_query($db, $query);
$queryResponse = pg_query($db, $query);
$questions = pg_fetch_all($queryResponse);
asort($questions);
$rows = pg_fetch_all($qresp);
$properTitle = "{$pageTitle} — admin";
$CSSdownDirectory = 1;
include "../boilerplate/pageStart.php";
include "../boilerplate/question.php";
$totalUnresponded = 0;
$totalPriv = 0;
$totalRespondedPub = 0;
foreach (array_reverse($rows) as $i) {
if ($i["isrespondedto"] === "f" && $i["ispublic"] === "t") {
$totalUnresponded++;
} else if ($i["ispublic"] === "f") {
$totalPriv++;
} else {
$totalRespondedPub++;
}
}
echo("<h2 class=\"title\">" . $pageTitle . " admin</h2>");
echo("<h2 class=\"title\"> {$pageTitle} &mdash; admin</h2>");
if ($_GET["deleted"] == 1) {
echo("<span class=\"sentconf\">deleted!</span>");
echo("<div class=\"sentconf\">deleted!</div>");
}
if ($_GET["responded"] == 1) {
echo("<span class=\"sentconf\">response sent!</span>");
echo("<div class=\"sentconf\">response sent!</div>");
}
asort($rows);
echo("<h3 class=\"sect\">not responded to ({$totalUnresponded})</h3>");
foreach (array_reverse($rows) as $i){
if ($i["isrespondedto"] === "f" && $i["ispublic"] == "t") {
echo("<div class=\"question\">");
if ($i["iscwed"] === "t") {
echo("<details><summary>cw: " . $i["cw"] . "</summary><span class=\"cwfiller\"></span>");
if ($_GET["read"] == 1) {
echo("<div class=\"sentconf\">marked as read!</div>");
}
echo(htmlspecialchars($i["text"]));
echo("<div class=\"time\">" . $i["time"] . "</div>");
echo("<a class=\"permalink\" href=\"index.php?page=respond&id=" . $i["id"] . "&pw={$adminPassword}\">respond</a> / <a class=\"permalink\" href=\"index.php?page=delete&id=" . $i["id"] . "&pw={$adminPassword}\">delete</a></div>");
if ($_GET["unread"] == 1) {
echo("<div class=\"sentconf\">marked as unread!</div>");
}
if ($_GET["migrated"] == 1) {
echo("<div class=\"sentconf\">migrations have been run!</div>");
}
$totalUnresponded = 0;
$totalPriv = 0;
$totalPrivRead = 0;
$totalRespondedPub = 0;
$unresponded = "";
$private = "";
$privateRead = "";
$responded = "";
foreach (array_reverse($questions) as $question) {
if ($question["isrespondedto"] === "f" && $question["ispublic"] === "t") {
$totalUnresponded++;
$unresponded .= getQuestion($question, 0, 1, 0, $adminPassword);
} else if ($question["ispublic"] === "f") {
if ($question["isprivread"] === "t") {
$totalPrivRead++;
$privateRead .= getQuestion($question, 0, 1, 0, $adminPassword);
} else {
$totalPriv++;
$private .= getQuestion($question, 0, 1, 0, $adminPassword);
}
} else {
$totalRespondedPub++;
$responded .= getQuestion($question, 0, 1, 0, $adminPassword);
}
}
echo("<h3 class=\"sect\">private ({$totalPriv})</h3>");
foreach (array_reverse($rows) as $i){
if ($i["ispublic"] === "f") {
echo("<div class=\"question\">");
if ($i["iscwed"] === "t") {
echo("<details><summary>cw: " . $i["cw"] . "</summary><span class=\"cwfiller\"></span>");
}
echo(htmlspecialchars($i["text"]));
echo("<div class=\"time\">" . $i["time"] . "</div>");
echo("<a class=\"permalink\" href=\"index.php?page=delete&id=" . $i["id"] . "&pw={$adminPassword}\">delete</a></div>");
}
}
echo("
<h3 class=\"sect\">not responded to ({$totalUnresponded})</h3>
{$unresponded}
<h3 class=\"sect\">unread private ({$totalPriv})</h3>
{$private}
<h3 class=\"sect\">public ({$totalRespondedPub})</h3>
{$responded}
<h3 class=\"sect\">read private ({$totalPrivRead})</h3>
{$privateRead}
");
echo("<h3 class=\"sect\">public ({$totalRespondedPub})</h3>");
foreach (array_reverse($rows) as $i){
if ($i["ispublic"] === "t" && $i["isrespondedto"] === "t") {
echo("<div class=\"question\">");
if ($i["iscwed"] === "t") {
echo("<details><summary>cw: " . $i["cw"] . "</summary><span class=\"cwfiller\"></span>");
}
echo(htmlspecialchars($i["text"]));
echo("<div class=\"time\">" . $i["time"] . "</div>");
echo("<div class=\"response\">" . htmlspecialchars($i["responsetext"]) . "");
echo("<div class=\"time\">" . $i["responsetime"] . "</div></div>");
echo("<a class=\"permalink\" href=\"index.php?page=respond&responded=1&id=" . $i["id"] . "&pw={$adminPassword}\">edit response</a> / <a class=\"permalink\" href=\"index.php?page=delete&id=" . $i["id"] . "&pw={$adminPassword}\">delete</a></div>");
}
}
include '../boilerplate/pageEnd.php';
?>

View file

@ -1,6 +1,6 @@
<?php
$id = $_GET["id"];
$id = (int)$_GET["id"];
if ($id === null) {
exit();
@ -13,8 +13,6 @@ WHERE id = {$id};
pg_query($db, $query);
echo("done");
header("Location: index.php?deleted=1&pw={$adminPassword}");
?>

View file

@ -5,31 +5,43 @@ SELECT * FROM data
WHERE id = {$id};
";
$qresp = pg_query($db, $query);
$arr = pg_fetch_array($qresp);
$queryResponse = pg_query($db, $query);
$question = pg_fetch_array($queryResponse);
$url = "{$pageProto}://" . $_SERVER["HTTP_HOST"] . $pagePath . "/fetch.php?id={$id}";
if (strlen($question["fedipostid"]) == 0) {
$method = "POST";
$route = $fediAPIRoute;
} else {
$method = "PUT";
$route = $fediAPIRoute . "/" . $question["fedipostid"];
}
$cw = "anonymous question response (automated)";
if ($question["iscwed"] == "t") {
$cw .= "; cw: {$question['cw']}";
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$fediAPIRoute);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
array("Authorization: {$fediAPIToken}"));
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: {$fediAPIToken}"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $route);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
"status" => "question: {$question['text']}\n\nresponse: {$question['responsetext']}\n\nlink: {$url}",
"visibility" => $fediVisibility,
"spoiler_text" => $cw
)));
$contentO = $arr["text"];
$contentR = $arr["responsetext"];
$url = "{$pageProto}://" . $_SERVER["HTTP_HOST"] . $pagePath . "/fetch.php?id={$id}";
if ($arr["iscwed"] == "t") {
$contentCW = $arr["cw"];
curl_setopt($ch, CURLOPT_POSTFIELDS,
http_build_query(array('status' => "question: {$contentO}\n\nresponse: {$contentR}\n\nlink: {$url}", 'visibility' => "{$fediVisibility}", 'spoiler_text' => "anonymous question response (automated); cw: {$contentCW}")));
} else {
curl_setopt($ch, CURLOPT_POSTFIELDS,
http_build_query(array('status' => "question: {$contentO}\n\nresponse: {$contentR}\n\nlink: {$url}", 'visibility' => "{$fediVisibility}", 'spoiler_text' => "anonymous question response (automated)")));
$resp = curl_exec($ch);
if (strlen($question["fedipostid"]) == 0) {
$jsonResp = json_decode($resp, true);
$fediID = $jsonResp["id"];
pg_update($db, "data", array("fedipostid" => $fediID), array("id" => $id));
}
curl_exec($ch);
curl_close($ch);
?>

View file

@ -2,19 +2,25 @@
include '../config.php';
echo("<link rel=\"stylesheet\" href=\"../css/admin.css\">");
if ($_GET["pw"] === $adminPassword) {
if ($_GET["page"] === "delete") {
include 'delete.php';
} elseif ($_GET["page"] === "respond") {
include 'respond.php';
} else {
include 'all.php';
switch ($_GET["page"]) {
case "delete": include "delete.php"; break;
case "respond": include "respond.php"; break;
case "mark": include "mark.php"; break;
case "migrate": include "migrate.php"; break;
default: include "all.php";
}
} else {
echo("<h2 class=\"sect\">enter password</h2>");
echo("<form class=\"frm\" action=\"index.php\"><input id=\"passinput\" name=\"pw\" required=\"\"><br><button class=\"submitbutton\" type=\"submit\">login</button></form>");
$properTitle = $pageTitle . " &mdash; sign in";
$CSSdownDirectory = 1;
include "../boilerplate/pageStart.php";
echo("
<h2 class=\"sect\">enter password</h2>
<form class=\"frm\" action=\"index.php\"><input id=\"passinput\" name=\"pw\" required=\"\"><br><button class=\"submitbutton\" type=\"submit\">login</button></form>
");
include "../boilerplate/pageEnd.php";
}
?>

29
admin/mark.php Normal file
View file

@ -0,0 +1,29 @@
<?php
$id = (int)$_GET["id"];
if ($id === null) {
exit();
}
if ($_GET["action"] === "unread") {
$query = "
UPDATE data
SET isprivread = False
WHERE id = {$id};
";
$headerinfo = "Location: index.php?unread=1&pw={$adminPassword}";
} else if ($_GET["action"] === "read") {
$query = "
UPDATE data
SET isprivread = True
WHERE id = {$id};
";
$headerinfo = "Location: index.php?read=1&pw={$adminPassword}";
}
pg_query($db, $query);
header($headerinfo);
?>

26
admin/migrate.php Normal file
View file

@ -0,0 +1,26 @@
<?php
$query = "
SELECT * FROM migrations;
";
$queryResponse = pg_query($db, $query);
$rows = pg_fetch_all($queryResponse);
$migrations = array(
"20240218-AddMigrationsTable-40641e8d",
"20240218-AddMarkReadOption-a7e43358",
"20240218-AddFalsesToPrivRead-67d82b18",
"20250310-AddFediIDColumn-64520350"
);
foreach ($migrations as $mig) {
if (!in_array($mig, array_column($rows, 'id'))) {
include "../migrations/{$mig}.php";
}
}
header("Location: index.php?migrated=1&pw={$adminPassword}");
?>

View file

@ -1,6 +1,6 @@
<?php
$id = $_GET["id"];
$id = (int)$_GET["id"];
if ($id === null) {
exit();
@ -9,6 +9,7 @@ if ($id === null) {
if ($_GET["text"] !== null) {
$text = $_GET["text"];
$cdate = date("Y-m-d H:i:sP");
$query = "
UPDATE data
SET \"responsetime\" = timestamptz'{$cdate}', isrespondedto = True
@ -16,14 +17,14 @@ if ($_GET["text"] !== null) {
";
pg_query($db, $query);
pg_update($db, "data", array("responsetext" => $text), array("id" => $id));
if ($fediEnabled) {
include 'fedi.php';
include "fedi.php";
}
header("Location: index.php?responded=1&pw={$adminPassword}");
exit();
}
$query = "
@ -31,33 +32,27 @@ SELECT * FROM data
WHERE id = {$id};
";
$qresp = pg_query($db, $query);
$arr = pg_fetch_array($qresp);
$queryResponse = pg_query($db, $query);
$question = pg_fetch_array($queryResponse);
echo("<link rel=\"stylesheet\" href=\"css/indiv.css\">");
$properTitle = $pageTitle . " &mdash; respond to question #" . $id;
$CSSdownDirectory = 1;
include "../boilerplate/pageStart.php";
include "../boilerplate/question.php";
if ($arr["ispublic"] === "f") {
echo("<h2 class=\"title\">{$pageTitle} no such question exists</h2>");
echo("<a class=\"goback\" href=\"index.php\">(go back?)</a>");
if ($question["ispublic"] === "f") {
echo("
<h2 class=\"title\">{$pageTitle} &mdash; no such question exists</h2>
<a class=\"go-back\" href=\"index.php\">(go back?)</a>
");
http_response_code(404);
} else {
echo("<h2 class=\"title\">{$pageTitle} question number " . $arr["id"] . "</h2>");
echo("
<h2 class=\"title\">{$pageTitle} &mdash; question number {$question['id']}</h2>
<a class=\"go-back\" href=\"index.php?pw={$adminPassword}\">(go back?)</a>
");
echo("<a class=\"goback\" href=\"index.php?pw={$adminPassword}\">(go back?)</a>");
echo("<div class=\"question\">");
if ($arr["iscwed"] === "t") {
echo("<h3>cw: " . $arr["cw"] . "</h3>");
}
echo(htmlspecialchars($arr["text"]));
echo("<div class=\"time\">" . $arr["time"] . "</div>");
if ($_GET["responded"] == 1) {
echo("<div class=\"response\">" . htmlspecialchars($arr["responsetext"]) . "");
echo("<div class=\"time\">" . $arr["responsetime"] . "</div></div>");
echo("<h3>enter your edits</h3>");
} else {
echo("<h3>enter a response</h3>");
}
echo("<form class=\"frm\" action=\"index.php\"><input hidden name=\"id\" value=\"{$id}\"><input hidden name=\"page\" value=\"respond\"><input hidden name=\"pw\" value=\"{$adminPassword}\"><input id=\"passinput\" name=\"text\" required=\"\"><br><button class=\"submitbutton\" type=\"submit\">send</button></form>");
echo(getQuestion($question, 0, 0, 1, $adminPassword));
}
?>

2
boilerplate/pageEnd.php Normal file
View file

@ -0,0 +1,2 @@
</body>
</html>

14
boilerplate/pageStart.php Normal file
View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title><?php echo($properTitle) ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="<?php if ($CSSdownDirectory) { echo("../"); } ?>css/base.css">
<?php
if ($customCSSurl) {
echo("<link rel=\"stylesheet\" href=\"" . $customCSSurl . "\">");
}
?>
</head>
<body>

87
boilerplate/question.php Normal file
View file

@ -0,0 +1,87 @@
<?php
function getQuestion(
$question,
$includePermalink=1,
$isAdmin=0,
$isResponding=0,
$adminPassword=""
) {
$q = htmlspecialchars($question["text"]);
$q .= "<div class=\"time\">{$question['time']}</div>";
if ($question["responsetext"]) {
$q .= "<div class=\"response\">" . htmlspecialchars($question['responsetext']);
$q .= "<div class=\"time\">{$question['responsetime']}</div></div>";
}
if ($isResponding) {
if ($question["responsetext"]) {
$q .= "<h3>enter your edits</h3>";
} else {
$q .= "<h3>enter a response</h3>";
}
$q .= "
<form class=\"frm\" action=\"index.php\">
<input hidden name=\"id\" value=\"{$question['id']}\">
<input hidden name=\"page\" value=\"respond\">
<input hidden name=\"pw\" value=\"{$adminPassword}\">
<input id=\"passinput\" name=\"text\" value=\"{$question['responsetext']}\" autofocus required><br>
<button class=\"submitbutton\" type=\"submit\">send</button>
</form>
";
}
if ($includePermalink === 1) {
$q .= "<a class=\"permalink\" href=\"fetch.php?id={$question['id']}\">permalink</a>";
}
if ($isAdmin === 1) {
if ($question["ispublic"] === "t") {
$q .= "<a class=\"permalink\" href=\"index.php?page=respond&id={$question['id']}&pw={$adminPassword}\">";
if ($question["isrespondedto"] === "t") {
$q .= "edit response";
} else {
$q .= "respond";
}
$q .= "</a>";
} else {
$q .= "<a class=\"permalink\" href=\"index.php?page=mark&action=";
if ($question["isprivread"] === "t") {
$q .= "unread";
} else {
$q .= "read";
}
$q .= "&id={$question['id']}&pw={$adminPassword}\">mark ";
if ($question["isprivread"] === "t") {
$q .= "unread";
} else {
$q .= "read";
}
$q .= "</a>";
}
$q .= " / <a class=\"permalink\" href=\"index.php?page=delete&id={$question['id']}&pw={$adminPassword}\">delete</a>";
}
if ($question["iscwed"] === "t") {
$open = "";
if ($isResponding) {
$open = " open";
}
$q = "<details{$open}><summary>cw: " . htmlspecialchars($question["cw"]) . "</summary>{$q}</details>";
}
return "<div class=\"question\">{$q}</div>";
}
?>

View file

@ -1,7 +1,7 @@
<?php
// timezone (valid ones: https://www.php.net/manual/en/timezones.php)
date_default_timezone_set('America/New_York');
date_default_timezone_set("America/New_York");
// admin
$adminPassword = "setAPasswordHere!123";
@ -11,16 +11,20 @@ $pageTitle = "the cool qna";
$pageDomainEnabled = True;
$pageProto = "https";
$pagePath = "/qna";
$pageDomain = "example.com";
$pageDomainOther = $pageDomain; // you can comment out and change this to a subdomain you want to "go back to". eg your site is me.example.org but you want it to say example.org
//$pageDomainOther = "me.example.com";
$pageRoot = "/"; // path to go to
// set this to the url of any custom css
$customCSSurl = NULL;
// post to fedi?
$fediEnabled = False;
$fediAPIRoute = "https://example.com/api/v1/statuses";
$fediAPIToken = "Bearer AUTHTOKENGOESHERE";
$fediVisibility = "private";
$fediVisibility = "private"; // "direct", "private", "unlisted", "public"
// database setup
$dbHost = "localhost";
@ -28,7 +32,6 @@ $dbName = "postgres";
$dbUsername = "postgres";
$dbPassword = "postgres";
// !!! DON'T CHANGE ANYTHING AFTER THIS UNLESS YOU KNOW WHAT YOU'RE DOING !!!
$dbInfo = "host={$dbHost} dbname={$dbName} user={$dbUsername} password={$dbPassword}";
$db = pg_connect($dbInfo);

View file

@ -1,82 +0,0 @@
body {
background-image: url(https://notfire.cc/design/images/groundback.gif);
background-color: black;
color: white;
font-family: Arial, Helvetica, sans-serif;
}
.permalink {
color: #ff0000;
font-size: .9em;
}
.goback {
color: #ff0000;
}
.title {
margin-bottom: .1em;
}
.question {
margin-top: .7em;
background-color: #2c2c2c;
border-radius: 5px;
max-width: fit-content;
padding: .5em;
}
.response {
background-color: #505050;
border-radius: 5px;
margin-top: .3em;
padding: .4em;
margin-bottom: .25em;
}
.time {
font-size: .8em;
}
.cwfiller {
height: 1.3em;
display: inline-block;
}
.sect {
margin-top: .2em;
margin-bottom: .2em;
}
.sentconf {
color: lime;
margin-bottom: .3em;
}
.sendsum {
font-size: 1.17em;
font-weight: bold;
}
.sendmsg {
margin-top: 1em;
border-radius: 5px;
background-color: #2c2c2c;
max-width: fit-content;
padding: .7em;
}
#passinput, .submitbutton {
background-color: black;
color: white;
margin-bottom: .3em;
}
.submitbutton {
font-size: 1.17em;
margin-top: .3em;
}
.frm {
margin-bottom: 0px;
}

99
css/base.css Normal file
View file

@ -0,0 +1,99 @@
:root {
--background-color: #000000;
--text-color: #ffffff;
--hr-color: #808080;
--link-color: #ff0000;
--confirmation-color: #00ff00;
--question-background: #2c2c2c;
--response-background: #505050;
/* set to "none" to disable the background image */
--background-image: url("https://notfire.cc/design/images/groundback.gif");
--font-family: Arial, Helvetica, sans-serif;
}
body {
background-image: var(--background-image);
background-color: var(--background-color);
color: var(--text-color);
font-family: var(--font-family);
}
hr {
border: none;
height: 1.5px;
background-color: var(--hr-color);
}
.permalink {
color: var(--link-color);
font-size: .9em;
}
.go-back {
color: var(--link-color);
}
.title {
margin-bottom: .1em;
}
.question {
margin-top: .7em;
background-color: var(--question-background);
border-radius: 5px;
max-width: fit-content;
padding: .5em;
}
.response {
background-color: var(--response-background);
border-radius: 5px;
margin-top: .3em;
padding: .4em;
}
.time {
font-size: .8em;
}
.sect {
margin-top: .2em;
margin-bottom: .2em;
}
.sentconf {
color: var(--confirmation-color);
margin-bottom: .3em;
}
.sendsum {
font-size: 1.17em;
font-weight: bold;
}
.sendmsg {
margin-top: 1em;
border-radius: 5px;
background-color: var(--question-background);
max-width: fit-content;
padding: .7em;
}
#passinput,
#questioninput,
#cwinput,
.submitbutton {
background-color: var(--background-color);
color: var(--text-color);
margin-bottom: .3em;
}
.submitbutton {
font-size: 1.17em;
margin-top: .3em;
}
.frm {
margin-bottom: 0px;
}

View file

@ -1,38 +0,0 @@
body {
background-image: url(https://notfire.cc/design/images/groundback.gif);
background-color: black;
color: white;
font-family: Arial, Helvetica, sans-serif;
}
.goback {
color: #ff0000;
}
.title {
margin-bottom: .1em;
}
.question {
margin-top: .7em;
background-color: #2c2c2c;
border-radius: 5px;
max-width: fit-content;
padding: .5em;
}
.response {
background-color: #505050;
border-radius: 5px;
margin-top: .3em;
padding: .4em;
}
.time {
font-size: .8em;
}
.cwfiller {
height: 1.3em;
display: inline-block;
}

View file

@ -1,83 +0,0 @@
body {
background-image: url(https://notfire.cc/design/images/groundback.gif);
background-color: black;
color: white;
font-family: Arial, Helvetica, sans-serif;
}
.permalink {
color: #ff0000;
font-size: .9em;
}
.goback {
color: #ff0000;
}
.title {
margin-bottom: .1em;
}
.question {
margin-top: .7em;
background-color: #2c2c2c;
border-radius: 5px;
max-width: fit-content;
padding: .5em;
}
.response {
background-color: #505050;
border-radius: 5px;
margin-top: .3em;
padding: .4em;
margin-bottom: .25em;
}
.time {
font-size: .8em;
}
.cwfiller {
height: 1.3em;
display: inline-block;
}
.sect {
margin-bottom: .2em;
margin-top: .2em;
}
.sentconf {
color: lime;
margin-top: .3em;
margin-bottom: .3em;
}
.sendsum {
font-size: 1.17em;
font-weight: bold;
}
.sendmsg {
margin-top: 1em;
border-radius: 5px;
background-color: #2c2c2c;
max-width: fit-content;
padding: .7em;
}
#questioninput, #cwinput, .submitbutton {
background-color: black;
color: white;
margin-bottom: .3em;
}
.submitbutton {
font-size: 1.17em;
margin-top: .3em;
}
.frm {
margin-bottom: 0px;
}

View file

@ -1,8 +1,9 @@
<?php
include 'config.php';
include "config.php";
include "boilerplate/question.php";
$id = $_GET["id"];
$id = (int)$_GET["id"];
if ($id === null) {
exit();
@ -13,27 +14,28 @@ SELECT * FROM data
WHERE id = {$id};
";
$qresp = pg_query($db, $query);
$arr = pg_fetch_array($qresp);
$queryResponse = pg_query($db, $query);
$question = pg_fetch_array($queryResponse);
echo("<link rel=\"stylesheet\" href=\"css/indiv.css\">");
$properTitle = "{$pageTitle} &mdash; question #{$id}";
include "boilerplate/pageStart.php";
if (pg_num_rows($queryResponse) === 0 || $question["ispublic"] === "f" || $question["isrespondedto"] === "f") {
echo("
<h2 class=\"title\">{$pageTitle} &mdash; no such question exists</h2>
<a class=\"go-back\" href=\"index.php\">(go back?)</a>
");
if (pg_num_rows($qresp) === 0 || $arr["ispublic"] === "f" || $arr["isrespondedto"] === "f") {
echo("<h2 class=\"title\">{$pageTitle} no such question exists</h2>");
echo("<a class=\"goback\" href=\"index.php\">(go back?)</a>");
http_response_code(404);
} else {
echo("<h2 class=\"title\">{$pageTitle} question number " . $arr["id"] . "</h2>");
echo("
<h2 class=\"title\">{$pageTitle} &mdash; question number {$question['id']}</h2>
<a class=\"go-back\" href=\"index.php\">(go back?)</a>
");
echo("<a class=\"goback\" href=\"index.php\">(go back?)</a>");
echo("<div class=\"question\">");
if ($arr["iscwed"] === "t") {
echo("<details><summary>cw: " . $arr["cw"] . "</summary><span class=\"cwfiller\"></span>");
}
echo(htmlspecialchars($arr["text"]));
echo("<div class=\"time\">" . $arr["time"] . "</div>");
echo("<div class=\"response\">" . $arr["responsetext"] . "");
echo("<div class=\"time\">" . $arr["responsetime"] . "</div></div></div>");
echo(getQuestion($question));
}
include "boilerplate/pageEnd.php";
?>

View file

@ -1,49 +1,56 @@
<?php
include 'config.php';
include "config.php";
include "boilerplate/question.php";
$query = "
SELECT * FROM data;
SELECT * FROM data
WHERE ispublic=true
AND isrespondedto=true;
";
$qresp = pg_query($db, $query);
$queryResponse = pg_query($db, $query);
$questions = pg_fetch_all($queryResponse);
asort($questions);
$rows = pg_fetch_all($qresp);
echo("<link rel=\"stylesheet\" href=\"css/main.css\">");
$properTitle = "{$pageTitle} &mdash; all messages";
include "boilerplate/pageStart.php";
echo("<h2 class=\"title\">" . $pageTitle . "</h2>");
if ($pageDomainEnabled) {
echo("<a class=\"goback\" href=\"https://{$pageDomainOther}{$pageRoot}\">(go back to " . $pageDomain . "?)</a>");
echo("<a class=\"go-back\" href=\"https://{$pageDomainOther}{$pageRoot}\">(go back to " . $pageDomain . "?)</a>");
}
if ($_GET["sent"] == 1) {
echo("<span class=\"sentconf\"><br>message sent!</span>");
}
echo("<div class=\"sendmsg\"><details open=\"\"><summary class=\"sendsum\">send a message!</summary>");
?>
echo("<form class=\"frm\" action=\"send.php\"><label for=\"questioninput\">enter your message: </label><input id=\"questioninput\" name=\"text\" required=\"\"><br><label for=\"cwinput\">cw if applicable: </label><input id=\"cwinput\" name=\"cw\"><br><input type=\"checkbox\" id=\"pubbox\" name=\"public\" value=\"1\" checked> <label for=\"pubbox\">if this is checked, your message will be available publicly</label><br><button class=\"submitbutton\" type=\"submit\">send!</button></form></details></div>");
<div class="sendmsg">
<details open>
<summary class="sendsum">send a message!</summary>
<form class="frm" action="send.php">
<label for="questioninput">enter your message: </label>
<input id="questioninput" name="text" required><br>
<label for="cwinput">cw if applicable: </label>
<input id="cwinput" name="cw"><br>
<input type="checkbox" id="pubbox" name="public" value="1" checked>
<label for="pubbox">if this is checked, your message will be available publicly</label><br>
<button class="submitbutton" type="submit">send!</button>
</form>
</details>
</div>
<hr>
<h3 class="sect">all past messages</h3>
echo("<hr>");
<?php
echo("<h3 class=\"sect\">all past messages</h3>");
asort($rows);
foreach (array_reverse($rows) as $i){
if ($i["ispublic"] === "t" && $i["isrespondedto"] === "t") {
echo("<div class=\"question\">");
if ($i["iscwed"] === "t") {
echo("<details><summary>cw: " . $i["cw"] . "</summary><span class=\"cwfiller\"></span>");
}
echo(htmlspecialchars($i["text"]));
echo("<div class=\"time\">" . $i["time"] . "</div>");
echo("<div class=\"response\">" . htmlspecialchars($i["responsetext"]) . "");
echo("<div class=\"time\">" . $i["responsetime"] . "</div></div>");
echo("<a class=\"permalink\" href=\"fetch.php?id=" . $i["id"] . "\">permalink</a></div>");
}
foreach (array_reverse($questions) as $question){
echo(getQuestion($question));
}
include "boilerplate/pageEnd.php";
?>

View file

@ -0,0 +1,19 @@
<?php
// ensure already private messages still get shown
$query = "
UPDATE data
SET isprivread = False
WHERE ispublic IS FALSE;
";
pg_query($db, $query);
$dataArray = array(
"id" => "20240218-AddFalsesToPrivRead-67d82b18"
);
pg_insert($db, "migrations", $dataArray);
?>

View file

@ -0,0 +1,18 @@
<?php
// add "isprivread" to data columns
$query = "
ALTER TABLE data
ADD COLUMN isprivread BOOLEAN;
";
pg_query($db, $query);
$dataArray = array(
"id" => "20240218-AddMarkReadOption-a7e43358"
);
pg_insert($db, "migrations", $dataArray);
?>

View file

@ -0,0 +1,19 @@
<?php
// add migrations table to track migrations that have been run
$query = "
CREATE TABLE migrations (
id TEXT NOT NULL
);
";
pg_query($db, $query);
$dataArray = array(
"id" => "20240218-AddMigrationsTable-40641e8d"
);
pg_insert($db, "migrations", $dataArray);
?>

View file

@ -0,0 +1,18 @@
<?php
// add "fedipostid" column to data
$query = "
ALTER TABLE data
ADD COLUMN fedipostid TEXT;
";
pg_query($db, $query);
$dataArray = array(
"id" => "20250310-AddFediIDColumn-64520350"
);
pg_insert($db, "migrations", $dataArray);
?>

View file

@ -1,31 +1,17 @@
<?php
include 'config.php';
include "config.php";
if ($_GET["text"] === null) {
exit();
}
if ($_GET["cw"] === null || $_GET["cw"] === "") {
$iscw = False;
} else {
$iscw = True;
}
if ($_GET["public"] == 1) {
$isPublic = True;
} else {
$isPublic = False;
}
$curTime = date("Y-m-d H:i:sP");
$dataArray = array(
"text" => $_GET["text"],
"cw" => $_GET["cw"],
"iscwed" => $iscw,
"time" => $curTime,
"ispublic" => $isPublic,
"iscwed" => !($_GET["cw"] === null || $_GET["cw"] === ""),
"time" => date("Y-m-d H:i:sP"),
"ispublic" => $_GET["public"] == 1,
"isrespondedto" => False
);

View file

@ -1,6 +1,6 @@
<?php
include 'config.php';
include "config.php";
$query = "
CREATE TABLE data (
@ -12,12 +12,23 @@ CREATE TABLE data (
ispublic BOOLEAN NOT NULL,
isrespondedto BOOLEAN NOT NULL,
responsetext TEXT,
responsetime TIMESTAMPTZ
responsetime TIMESTAMPTZ,
isprivread BOOLEAN
);
";
pg_query($db, $query);
$query = "
CREATE TABLE migrations (
id TEXT NOT NULL
);
";
pg_query($db, $query);
include "admin/migrate.php";
echo "database set up";
?>