%s
+%s
+ + + ", + htmlspecialchars($level->value), + htmlspecialchars($title), + htmlspecialchars($body) + ); + } + UnityHTTPD::clearMessages(); if ( isset($_SESSION["is_admin"]) && $_SESSION["is_admin"] diff --git a/test/functional/PIMemberRequestTest.php b/test/functional/PIMemberRequestTest.php index cea66ae7..af37add5 100644 --- a/test/functional/PIMemberRequestTest.php +++ b/test/functional/PIMemberRequestTest.php @@ -1,7 +1,9 @@ assertTrue($SQL->requestExists($uid, $gid)); $this->cancelRequest($gid); $this->assertFalse($SQL->requestExists($uid, $gid)); + UnityHTTPD::clearMessages(); $this->requestMembership("asdlkjasldkj"); - $this->assertContains("This PI doesn't exist", $_SESSION["MODAL_ERRORS"]); + assertMessageExists( + $this, + UnityHTTPDMessageLevel::ERROR, + "/.*/", + "/^This PI doesn't exist$/", + ); $this->requestMembership($pi_group->getOwner()->getMail()); $this->assertTrue($SQL->requestExists($uid, $gid)); } finally { diff --git a/test/phpunit-bootstrap.php b/test/phpunit-bootstrap.php index 0643a7e8..7cd4273d 100644 --- a/test/phpunit-bootstrap.php +++ b/test/phpunit-bootstrap.php @@ -25,6 +25,9 @@ require_once __DIR__ . "/../resources/lib/exceptions/EncodingConversionException.php"; use UnityWebPortal\lib\UnityGroup; +use UnityWebPortal\lib\UnityHTTPD; +use UnityWebPortal\lib\UnityHTTPDMessageLevel; +use PHPUnit\Framework\TestCase; $_SERVER["HTTP_HOST"] = "phpunit"; // used for config override require_once __DIR__ . "/../resources/config.php"; @@ -323,3 +326,29 @@ function getAdminUser() { return ["user1@org1.test", "foo", "bar", "user1@org1.test"]; } + +function assertMessageExists( + TestCase $test_case, + UnityHTTPDMessageLevel $level, + string $title_regex, + string $body_regex, +) { + $messages = UnityHTTPD::getMessages(); + $error_msg = sprintf( + "message(level='%s' title_regex='%s' body_regex='%s'), not found. found messages: %s", + $level->value, + $title_regex, + $body_regex, + jsonEncode($messages), + ); + $messages_with_title = array_filter($messages, fn($x) => preg_match($title_regex, $x[0])); + $messages_with_title_and_body = array_filter( + $messages_with_title, + fn($x) => preg_match($body_regex, $x[1]), + ); + $messages_with_title_and_body_and_level = array_filter( + $messages_with_title_and_body, + fn($x) => $x[2] == $level, + ); + $test_case->assertNotEmpty($messages_with_title_and_body_and_level, $error_msg); +} diff --git a/webroot/css/messages.css b/webroot/css/messages.css new file mode 100644 index 00000000..012cfaf0 --- /dev/null +++ b/webroot/css/messages.css @@ -0,0 +1,52 @@ +.message { + border-radius: 10px; + padding: 10px 40px 10px 40px; + /* needed for button position: absolute */ + position: relative; + text-align: center; + /* width: fit-content; */ + /* subtract padding from indented width */ + width: 90% - 80px; + margin-left: auto; + margin-right: auto; + margin-bottom: 20px; +} + +.message h3 { + margin: 0; +} + +.message.debug { + color: #856404; + background-color: #fff3cd; +} + +.message.success { + color: #155724; + background-color: #d4edda; +} + +.message.info { + color: #0c5460; + background-color: #d1ecf1; +} + +.message.warning { + color: #856404; + background-color: #fff3cd; +} + +.message.error { + color: #721c24; + background-color: #f8d7da; +} + +.message button { + position: absolute; + top: 0; + right: 0; + background-color: inherit; + color: inherit; + font-size: 2rem; + border: none; +} diff --git a/webroot/css/modal.css b/webroot/css/modal.css index af0aa313..a7c2e0e5 100644 --- a/webroot/css/modal.css +++ b/webroot/css/modal.css @@ -30,17 +30,7 @@ span.modalTitle { font-size: 13pt; } -div.modalMessages { - color: var(--color-text-failure); - font-size: 11pt; -} - -div.modalMessages > * { - margin-top: 7px; - display: block; -} - -div.modalBody > * { +div.modalBody>* { margin: 0; } diff --git a/webroot/js/modal.js b/webroot/js/modal.js index d7c28b3d..4f057139 100644 --- a/webroot/js/modal.js +++ b/webroot/js/modal.js @@ -1,6 +1,5 @@ -function openModal(title, link, message = "") { +function openModal(title, link) { $("span.modalTitle").html(title); - $("div.modalMessages").html(message); $.ajax({ url: link, success: function (result) { diff --git a/webroot/panel/groups.php b/webroot/panel/groups.php index ec0f60ef..a04030d1 100644 --- a/webroot/panel/groups.php +++ b/webroot/panel/groups.php @@ -7,8 +7,6 @@ use UnityWebPortal\lib\UnityHTTPD; if ($_SERVER["REQUEST_METHOD"] == "POST") { - $modalErrors = array(); - if (isset($_POST["form_type"])) { if (isset($_POST["pi"])) { $pi_groupname = $_POST["pi"]; @@ -20,7 +18,11 @@ } $pi_account = new UnityGroup($pi_groupname, $LDAP, $SQL, $MAILER, $WEBHOOK); if (!$pi_account->exists()) { - array_push($modalErrors, "This PI doesn't exist"); + UnityHTTPD::messageError( + "Invalid Group Membership Request", + "This PI doesn't exist" + ); + UnityHTTPD::redirect(); } } @@ -31,30 +33,33 @@ } if ($pi_account->exists()) { if ($pi_account->requestExists($USER)) { - array_push($modalErrors, "You've already requested this"); + UnityHTTPD::messageError( + "Invalid Group Membership Request", + "You've already requested this" + ); + UnityHTTPD::redirect(); } if ($pi_account->memberExists($USER)) { - array_push($modalErrors, "You're already in this PI group"); + UnityHTTPD::messageError( + "Invalid Group Membership Request", + "You're already in this PI group" + ); + UnityHTTPD::redirect(); } } - if (empty($modalErrors)) { - $pi_account->newUserRequest($USER); - } + $pi_account->newUserRequest($USER); + UnityHTTPD::redirect(); break; case "removePIForm": $pi_account->removeUser($USER); + UnityHTTPD::redirect(); break; case "cancelPIForm": $pi_account->cancelGroupJoinRequest($USER); + UnityHTTPD::redirect(); break; } } - $_SESSION['MODAL_ERRORS'] = $modalErrors; -} else { - if (isset($_SESSION['MODAL_ERRORS'])) { - $modalErrors = $_SESSION['MODAL_ERRORS']; - $_SESSION['MODAL_ERRORS'] = array(); // Forget after shown - } } @@ -178,19 +183,6 @@ openModal("Add New PI", "/panel/modal/new_pi.php"); }); - 0) { - $errorHTML = ""; - foreach ($modalErrors as $error) { - $errorHTML .= "" . htmlentities($error) . ""; - } - - echo "openModal('Add New PI', '" . - CONFIG["site"]["prefix"] . "/panel/modal/new_pi.php', '" . $errorHTML . "');"; - } - ?> - // tables.js uses ajax_url to populate expandable tables var ajax_url = "/panel/ajax/get_group_members.php?gid=";