Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions resources/autoload.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
require_once __DIR__ . "/lib/exceptions/EnsureException.php";
require_once __DIR__ . "/lib/exceptions/EncodingUnknownException.php";
require_once __DIR__ . "/lib/exceptions/EncodingConversionException.php";
require_once __DIR__ . "/lib/exceptions/UnityHTTPDMessageNotFoundException.php";

require_once __DIR__ . "/config.php";
require __DIR__ . "/init.php";
59 changes: 53 additions & 6 deletions resources/lib/UnityHTTPD.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use UnityWebPortal\lib\exceptions\NoDieException;
use UnityWebPortal\lib\exceptions\ArrayKeyException;
use UnityWebPortal\lib\exceptions\UnityHTTPDMessageNotFoundException;
use RuntimeException;

enum UnityHTTPDMessageLevel: string
Expand Down Expand Up @@ -226,13 +227,22 @@ public static function errorHandler(int $severity, string $message, string $file

public static function getPostData(string $key): mixed
{
try {
return $_POST[$key];
} catch (ArrayKeyException $e) {
self::badRequest('failed to get $_POST data', $e, [
'$_POST' => $_POST,
]);
if (!isset($_SERVER)) {
throw new RuntimeException('$_SERVER is unset');
}
if (!array_key_exists("REQUEST_METHOD", $_SERVER)) {
throw new RuntimeException('$_SERVER has no array key "REQUEST_METHOD"');
}
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
self::badRequest('$_SERVER["REQUEST_METHOD"] != "POST"');
}
if (!isset($_POST)) {
self::badRequest('$_POST is unset');
}
if (!array_key_exists($key, $_POST)) {
self::badRequest("\$_POST has no array key '$key'");
}
return $_POST[$key];
}

public static function getUploadedFileContents(
Expand Down Expand Up @@ -325,6 +335,43 @@ public static function getMessages()

public static function clearMessages()
{
self::ensureSessionMessagesSanity();
$_SESSION["messages"] = [];
}

private static function getMessageIndex(
UnityHTTPDMessageLevel $level,
string $title,
string $body,
) {
$messages = self::getMessages();
$error_msg = sprintf(
"message(level='%s' title='%s' body='%s'), not found. found messages: %s",
$level->value,
$title,
$body,
jsonEncode($messages),
);
foreach ($messages as $i => $message) {
if ($title == $message[0] && $body == $message[1] && $level == $message[2]) {
return $i;
}
}
throw new UnityHTTPDMessageNotFoundException($error_msg);
}

/* returns the 1st message that matches or throws UnityHTTPDMessageNotFoundException */
public static function getMessage(UnityHTTPDMessageLevel $level, string $title, string $body)
{
$index = self::getMessageIndex($level, $title, $body);
return $_SESSION["messages"][$index];
}

/* deletes the 1st message that matches or throws UnityHTTPDMessageNotFoundException */
public static function deleteMessage(UnityHTTPDMessageLevel $level, string $title, string $body)
{
$index = self::getMessageIndex($level, $title, $body);
unset($_SESSION["messages"][$index]);
$_SESSION["messages"] = array_values($_SESSION["messages"]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace UnityWebPortal\lib\exceptions;

class UnityHTTPDMessageNotFoundException extends \Exception {}
23 changes: 20 additions & 3 deletions resources/templates/header.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,32 @@
<div class='message %s'>
<h3>%s</h3>
<p>%s</p>
<button onclick=\"this.parentElement.style.display='none';\">×</button>
<button
onclick=\"
this.parentElement.style.display='none';
$.ajax({
url: '/panel/ajax/delete_message.php',
method: 'POST',
data: {
'level': '%s',
'title': '%s',
'body': '%s',
}
});
\"
>
×
</button>
</div>
",
htmlspecialchars($level->value),
htmlspecialchars($title),
htmlspecialchars($body)
htmlspecialchars($body),
htmlspecialchars($level->value),
htmlspecialchars($title),
htmlspecialchars($body),
);
}
UnityHTTPD::clearMessages();
if (
isset($_SESSION["is_admin"])
&& $_SESSION["is_admin"]
Expand Down
40 changes: 40 additions & 0 deletions test/functional/DeleteMessageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

use PHPUnit\Framework\TestCase;
use UnityWebPortal\lib\UnityHTTPD;
use UnityWebPortal\lib\UnityHTTPDMessageLevel;

class DeleteMessageTest extends TestCase
{
public function testDeleteMessage(): void
{
switchUser(...getBlankUser());
$initial = UnityHTTPD::getMessages();
$this->assertEmpty($initial);
UnityHTTPD::messageDebug("foo1", "bar1");
UnityHTTPD::messageDebug("foo2", "bar2");
UnityHTTPD::messageDebug("foo3", "bar3");
UnityHTTPD::messageError("foo", "bar");
UnityHTTPD::messageInfo("foo", "bar");
UnityHTTPD::messageSuccess("foo", "bar");
UnityHTTPD::messageWarning("foo", "bar");
try {
$before = array_map("jsonEncode", UnityHTTPD::getMessages());
http_post(
__DIR__ . "/../../webroot/panel/ajax/delete_message.php",
[
"level" => "debug",
"title" => "foo2",
"body" => "bar2",
],
enforce_PRG: false,
);
$after = array_map("jsonEncode", UnityHTTPD::getMessages());
$difference = array_diff($before, $after);
$message_expected_removed = ["foo2", "bar2", UnityHTTPDMessageLevel::DEBUG];
$this->assertEqualsCanonicalizing([jsonEncode($message_expected_removed)], $difference);
} finally {
UnityHTTPD::clearMessages();
}
}
}
9 changes: 6 additions & 3 deletions test/phpunit-bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
require_once __DIR__ . "/../resources/lib/exceptions/EnsureException.php";
require_once __DIR__ . "/../resources/lib/exceptions/EncodingUnknownException.php";
require_once __DIR__ . "/../resources/lib/exceptions/EncodingConversionException.php";
require_once __DIR__ . "/../resources/lib/exceptions/UnityHTTPDMessageNotFoundException.php";

use UnityWebPortal\lib\UnityGroup;
use UnityWebPortal\lib\UnityHTTPD;
Expand Down Expand Up @@ -96,7 +97,7 @@ function switchUser(
ensure(!is_null($USER));
}

function http_post(string $phpfile, array $post_data): void
function http_post(string $phpfile, array $post_data, bool $enforce_PRG = true): void
{
global $LDAP,
$SQL,
Expand Down Expand Up @@ -126,8 +127,10 @@ function http_post(string $phpfile, array $post_data): void
unset($_POST);
$_SERVER = $_PREVIOUS_SERVER;
}
// https://en.wikipedia.org/wiki/Post/Redirect/Get
ensure($post_did_redirect_or_die, "post did not redirect or die!");
if ($enforce_PRG) {
// https://en.wikipedia.org/wiki/Post/Redirect/Get
ensure($post_did_redirect_or_die, "post did not redirect or die!");
}
}

function http_get(string $phpfile, array $get_data = []): void
Expand Down
12 changes: 12 additions & 0 deletions webroot/panel/ajax/delete_message.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

require_once __DIR__ . "/../../../resources/autoload.php";

use UnityWebPortal\lib\UnityHTTPD;
use UnityWebPortal\lib\UnityHTTPDMessageLevel;

$level_str = UnityHTTPD::getPostData("level");
$level = UnityHTTPDMessageLevel::from($level_str);
$title = UnityHTTPD::getPostData("title");
$body = UnityHTTPD::getPostData("body");
UnityHTTPD::deleteMessage($level, $title, $body);