diff options
| author | Jonas Kohl | 2024-09-19 14:19:35 +0200 | 
|---|---|---|
| committer | Jonas Kohl | 2024-09-19 14:19:35 +0200 | 
| commit | 95bfdb59b6a1e04e474551c23c7caef619c79839 (patch) | |
| tree | 0fe7bf17c5767df5084dac05c61b4167781b9b1b | |
| parent | d7faf7053803aaa9eb8ae85a864ea1b2cccaa586 (diff) | |
Topic locking
| -rw-r--r-- | src/application/messages/de.msg | 9 | ||||
| -rw-r--r-- | src/application/mystic/forum/orm/Topic.php | 2 | ||||
| -rw-r--r-- | src/application/views/view_post.php | 3 | ||||
| -rw-r--r-- | src/application/views/view_search_results.php | 4 | ||||
| -rw-r--r-- | src/application/views/view_topic_locked.php | 4 | ||||
| -rw-r--r-- | src/application/views/view_topic_start.php | 31 | ||||
| -rw-r--r-- | src/application/views/view_topics.php | 7 | ||||
| -rw-r--r-- | src/application/views/view_user.php | 4 | ||||
| -rw-r--r-- | src/index.php | 94 | 
9 files changed, 153 insertions, 5 deletions
| diff --git a/src/application/messages/de.msg b/src/application/messages/de.msg index c2d8416..d1b2389 100644 --- a/src/application/messages/de.msg +++ b/src/application/messages/de.msg @@ -455,3 +455,12 @@ metadata({  : "Failed to send verification email"  = "Konnte Bestätigungsmail nicht versenden" + +: "This topic has been locked" += "Dieses Thema wurde gesperrt" + +: "Lock topic" += "Thema sperren" + +: "Unlock topic" += "Thema entsperren" diff --git a/src/application/mystic/forum/orm/Topic.php b/src/application/mystic/forum/orm/Topic.php index 421f5ec..cfd0c78 100644 --- a/src/application/mystic/forum/orm/Topic.php +++ b/src/application/mystic/forum/orm/Topic.php @@ -3,6 +3,7 @@ declare(strict_types=1);  namespace mystic\forum\orm; +use mystic\forum\attributes\DefaultValue;  use mystic\forum\attributes\PrimaryKey;  use mystic\forum\attributes\References;  use mystic\forum\attributes\Table; @@ -13,4 +14,5 @@ class Topic extends Entity {      public string $title;      public \DateTimeImmutable $creationDate;      #[References("public.users", onDelete: References::SET_NULL)] public ?string $createdBy; +    #[DefaultValue("false")] public bool $isLocked;  } diff --git a/src/application/views/view_post.php b/src/application/views/view_post.php index 62b2d18..0f86896 100644 --- a/src/application/views/view_post.php +++ b/src/application/views/view_post.php @@ -5,6 +5,7 @@ use mystic\forum\orm\Attachment;  /** @var mystic\forum\orm\Post $post */  /** @var mystic\forum\orm\User $postAuthor */ +/** @var mystic\forum\orm\Topic $topic */  $isImage = fn(string $m) => str_starts_with($m, "image/") || str_starts_with($m, "video/"); @@ -16,6 +17,8 @@ $canReply = $GLOBALS["currentUser"]?->hasPermission(UserPermissions::CREATE_OWN_  $canEdit = ($GLOBALS["currentUser"]?->id === $postAuthor?->id && $postAuthor?->hasPermission(UserPermissions::EDIT_OWN_POST))          || ($GLOBALS["currentUser"]?->hasPermission(UserPermissions::EDIT_OTHER_POST)); +$canEdit = $canEdit && !$topic->isLocked; +  $canDelete = ($GLOBALS["currentUser"]?->id === $postAuthor?->id && $postAuthor?->hasPermission(UserPermissions::DELETE_OWN_POST))            || ($GLOBALS["currentUser"]?->hasPermission(UserPermissions::DELETE_OTHER_POST)); diff --git a/src/application/views/view_search_results.php b/src/application/views/view_search_results.php index e21fbb8..914d2b2 100644 --- a/src/application/views/view_search_results.php +++ b/src/application/views/view_search_results.php @@ -20,7 +20,9 @@ use mystic\forum\utils\StringUtils;                  <span class="text-muted"><?= __("posted by %author% on %post_date% in %topic%", [                      "author" => '<em>' . htmlentities($users[$post->authorId]?->displayName ?? __("unknown")) . '</em>',                      "post_date" => '<span class="_time">' . htmlentities($post->postDate->format("c")) . '</span>', -                    "topic" => '<em>' . htmlentities($topics[$post->topicId]?->title ?? "unknown") . '</em>', +                    "topic" => '<em>' +                        . ($topics[$post->topicId]?->isLocked ? '<span class="glyphicon glyphicon-lock text-muted" aria-hidden="true"></span> ' : '') +                        . htmlentities($topics[$post->topicId]?->title ?? "unknown") . '</em>',                  ]) ?></span>              </a>          <?php endforeach; ?> diff --git a/src/application/views/view_topic_locked.php b/src/application/views/view_topic_locked.php new file mode 100644 index 0000000..ac59fcb --- /dev/null +++ b/src/application/views/view_topic_locked.php @@ -0,0 +1,4 @@ +<div class="well icon-well text-warning margin-top-4x"> +    <span class="glyphicon glyphicon-lock text-warning" aria-hidden="true"></span> +    <em><?= __("This topic has been locked") ?></em> +</div> diff --git a/src/application/views/view_topic_start.php b/src/application/views/view_topic_start.php index da8c0cd..fe85afa 100644 --- a/src/application/views/view_topic_start.php +++ b/src/application/views/view_topic_start.php @@ -1,5 +1,6 @@  <?php  use mystic\forum\orm\UserPermissions; +use mystic\forum\utils\RequestUtils;  $canReply = $GLOBALS["currentUser"]?->hasPermission(UserPermissions::CREATE_OWN_POST) ?? false; @@ -111,17 +112,45 @@ $canDelete = ($GLOBALS["currentUser"]?->id === $topicAuthor->id && $topicAuthor-      </script>  <?php endif; ?> +<?php +if (($_formError = RequestUtils::getAndClearFormError("updatetopic")) !== null) { +    _view("alert_error", ["message" => $_formError]); +} + +if (($_formError = RequestUtils::getAndClearFormError("locktopic")) !== null) { +    _view("alert_error", ["message" => $_formError]); +} +?> +  <div class="page-header margin-top-0 clearfix">      <div id="displayHeading">          <div role="heading" class="h1 seamless-inline"> +            <?php if ($topic->isLocked): ?> +                <span class="glyphicon glyphicon-lock text-muted" aria-hidden="true"></span> +            <?php endif; ?>              <?= htmlentities($topic->title) ?>              <div class="pull-right text-normal"> -                <?php if ($canEdit): ?> +                <?php if ($canEdit && !$topic->isLocked): ?>                      <button id="btn-edit-title" class="btn btn-default js-only"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> <?= __("Edit title") ?></button>                  <?php endif; ?>                  <?php if ($canReply): ?>                      <button id="btn-reply" class="btn btn-default js-only"><span class="glyphicon glyphicon-share-alt" aria-hidden="true"></span> <?= __("Reply") ?></button>                  <?php endif; ?> +                <?php if ($canEdit): ?> +                    <?php if ($topic->isLocked): ?> +                        <form action="?_action=locktopic" method="post" class="seamless-inline"> +                            <input type="hidden" name="topic" value="<?= htmlentities($topic->id) ?>"> +                            <input type="hidden" name="locked" value="false"> +                            <button type="submit" class="btn btn-success"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span> <?= __("Unlock topic") ?></button> +                        </form> +                    <?php else: ?> +                        <form action="?_action=locktopic" method="post" class="seamless-inline"> +                            <input type="hidden" name="topic" value="<?= htmlentities($topic->id) ?>"> +                            <input type="hidden" name="locked" value="true"> +                            <button type="submit" class="btn btn-warning"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span> <?= __("Lock topic") ?></button> +                        </form> +                    <?php endif; ?> +                <?php endif; ?>                  <?php if ($canDelete): ?>                      <form action="?_action=deletetopic" method="post" class="seamless-inline">                          <input type="hidden" name="topic" value="<?= htmlentities($topic->id) ?>"> diff --git a/src/application/views/view_topics.php b/src/application/views/view_topics.php index 291fbdc..a762f8c 100644 --- a/src/application/views/view_topics.php +++ b/src/application/views/view_topics.php @@ -12,7 +12,12 @@ if ($GLOBALS["currentUser"]?->hasPermission(UserPermissions::CREATE_OWN_TOPIC)):  <div class="list-group">  <?php /** @var Topic $topic */ foreach ($topics as $topic): ?>  <a class="list-group-item" href="?_action=viewtopic&topic=<?= htmlentities(urlencode($topic->id)) ?>"> -    <h4 class="list-group-item-heading"><?= htmlentities($topic->title) ?></h4> +    <h4 class="list-group-item-heading"> +        <?php if ($topic->isLocked): ?> +            <span class="glyphicon glyphicon-lock text-muted" aria-hidden="true"></span> +        <?php endif; ?> +        <?= htmlentities($topic->title) ?> +    </h4>      <p class="list-group-item-text _time"><?= htmlentities($topic->creationDate->format("c")) ?></p>  </a>  <?php endforeach; ?> diff --git a/src/application/views/view_user.php b/src/application/views/view_user.php index d3ebe04..5c89411 100644 --- a/src/application/views/view_user.php +++ b/src/application/views/view_user.php @@ -59,7 +59,9 @@ $emailPending = $isOwnProfile && $user->pendingEmail !== null;                          <?= htmlentities(StringUtils::truncate(strip_tags(renderPost($post->content)), 100)) ?><br>                          <span class="text-muted"><?= __("posted on %post_date% in %topic%", [                              "post_date" => '<span class="_time">' . htmlentities($post->postDate->format("c")) . '</span>', -                            "topic" => '<em>' . htmlentities($topics[$post->topicId]?->title ?? "unknown") . '</em>', +                            "topic" => '<em>' . +                                ($topics[$post->topicId]?->isLocked ? '<span class="glyphicon glyphicon-lock text-muted" aria-hidden="true"></span> ' : '') . +                                htmlentities($topics[$post->topicId]?->title ?? "unknown") . '</em>',                          ]) ?></span>                      </a>                  <?php endforeach; ?> diff --git a/src/index.php b/src/index.php index d651400..cc9e99d 100644 --- a/src/index.php +++ b/src/index.php @@ -572,6 +572,12 @@ if ($_action === "auth") {              msg_error("You need to be logged in to add new posts!");              exit;          } +         +        if ($topic->isLocked) { +            http_response_code(403); +            msg_error("This topic is locked!"); +            exit; +        }          $attachments = reArrayFiles($_FILES["files"]); @@ -658,12 +664,15 @@ if ($_action === "auth") {                  "postAuthor" => $postAuthor,                  "topicAuthor" => $topicAuthor,                  "attachments" => $attachments, +                "topic" => $topic,              ]);          }          _view("view_topic_end"); -        if ($currentUser) { +        if ($topic->isLocked) { +            _view("view_topic_locked"); +        } elseif ($currentUser) {              _view("form_addpost");          } else {              _view("view_logintoreply"); @@ -709,6 +718,7 @@ if ($_action === "auth") {          $topic->id = $db->generateId();          $topic->title = $title;          $topic->creationDate = new DateTimeImmutable(); +        $topic->isLocked = false;          $db->insert($topic); @@ -1169,6 +1179,12 @@ if ($_action === "auth") {      if (!$db->fetch($topicAuthor))          $topicAuthor = null; +    $topic = new Topic(); +    $topic->id = $post->topicId; + +    if (!$db->fetch($topic)) +        $topic = null; +      $canEdit = ($currentUser->id === $topicAuthor?->id && $topicAuthor?->hasPermission(UserPermissions::DELETE_OWN_POST))                || ($currentUser->hasPermission(UserPermissions::DELETE_OTHER_POST)); @@ -1217,6 +1233,7 @@ if ($_action === "auth") {              "postAuthor" => $topicAuthor,              "topicAuthor" => null,              "attachments" => $attachments, +            "topic" => $topic,          ]);          _view("template_end", [...getThemeAndLangInfo()]);      } @@ -1251,6 +1268,18 @@ if ($_action === "auth") {      $canEdit = ($currentUser->id === $topicAuthor?->id && $topicAuthor?->hasPermission(UserPermissions::EDIT_OWN_POST))                || ($currentUser->hasPermission(UserPermissions::EDIT_OTHER_POST)); +    $topic = new Topic(); +    $topic->id = $post->topicId; + +    if (!$db->fetch($topic)) +        $topic = null; + +    if ($topic->isLocked) { +        http_response_code(403); +        msg_error(__("This topic has been locked")); +        exit; +    } +      if (!$canEdit) {          http_response_code(403);          msg_error(__("You don't have permission to edit this post")); @@ -1360,6 +1389,12 @@ if ($_action === "auth") {      if (!$db->fetch($topicAuthor))          $topicAuthor = null; +    if ($topic->isLocked) { +        http_response_code(403); +        msg_error(__("This topic has been locked")); +        exit; +    } +      $canEdit = ($currentUser->id === $topicAuthor?->id && $topicAuthor?->hasPermission(UserPermissions::EDIT_OWN_TOPIC))              || ($currentUser->hasPermission(UserPermissions::EDIT_OTHER_TOPIC)); @@ -1378,6 +1413,63 @@ if ($_action === "auth") {      }      header("Location: ./?_action=viewtopic&topic=" . urlencode($topicId)); +} elseif ($_action === "locktopic") { +    RequestUtils::ensureRequestMethod("POST"); +    $topicId = $_POST["topic"] ?? null; +    if ($topicId === null) { +        http_response_code(400); +        msg_error(__("Missing topic id")); +        exit; +    } +    RequestUtils::setFormErrorDestination($dest = "Location: ./?_action=viewtopic&topic=" . urlencode($topicId)); + +    if (!$currentUser) { +        http_response_code(403); +        msg_error(__("You need to be logged in to lock topics!")); +        exit; +    } + +    $formId = "locktopic"; +    $locked = RequestUtils::getRequiredField("locked", $formId); +    if ($locked === "true") { +        $locked = true; +    } elseif ($locked === "false") { +        $locked = false; +    } else RequestUtils::triggerFormError("Invalid value", $formId); + +    $topic = new Topic(); +    $topic->id = $topicId; + +    if (!$db->fetch($topic)) { +        http_response_code(404); +        msg_error(__("No topic exists with this id")); +        exit; +    } + +    $topicAuthor = new User(); +    $topicAuthor->id = $topic->createdBy; + +    if (!$db->fetch($topicAuthor)) +        $topicAuthor = null; + +    $canEdit = ($currentUser->id === $topicAuthor?->id && $topicAuthor?->hasPermission(UserPermissions::EDIT_OWN_TOPIC)) +            || ($currentUser->hasPermission(UserPermissions::EDIT_OTHER_TOPIC)); + +    if (!$canEdit) { +        http_response_code(403); +        msg_error(__("You don't have permission to lock or unlock this topic")); +        exit; +    } + +    $topic->isLocked = $locked; + +    if (!$db->update($topic)) { +        http_response_code(500); +        msg_error(__("Failed to lock or unlock topic")); +        exit; +    } + +    header($dest);  } elseif ($_action === "search") {      $query = $_GET["query"] ?? null;      if ($query !== null) { |