Skip to content
Merged
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
21 changes: 21 additions & 0 deletions ts/WoltLabSuite/Core/Api/Notices/DismissNotice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Dismiss a notice.
*
* @author Olaf Braun
* @copyright 2001-2025 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.3
*/

import { prepareRequest } from "WoltLabSuite/Core/Ajax/Backend";
import { ApiResult, apiResultFromError, apiResultFromValue } from "../Result";

export async function dismissNotice(noticeId: number): Promise<ApiResult<[]>> {
try {
await prepareRequest(`${window.WSC_RPC_API_URL}core/notices/${noticeId}/dismiss`).post().fetchAsJson();
} catch (e) {
return apiResultFromError(e);
}

return apiResultFromValue([]);
}
26 changes: 10 additions & 16 deletions ts/WoltLabSuite/Core/Controller/Notice/Dismiss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,28 @@
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @woltlabExcludeBundle tiny
*/

import * as Ajax from "../../Ajax";
import { dismissNotice } from "WoltLabSuite/Core/Api/Notices/DismissNotice";
import { promiseMutex } from "WoltLabSuite/Core/Helper/PromiseMutex";

/**
* Initializes dismiss buttons.
*/
export function setup(): void {
document.querySelectorAll(".jsDismissNoticeButton").forEach((button) => {
button.addEventListener("click", (ev) => click(ev));
document.querySelectorAll<HTMLElement>(".jsDismissNoticeButton").forEach((button) => {
button.addEventListener(
"click",
promiseMutex(() => click(button)),
);
});
}

/**
* Sends a request to dismiss a notice and removes it afterwards.
*/
function click(event: Event): void {
const button = event.currentTarget as HTMLElement;
async function click(button: HTMLElement): Promise<void> {
(await dismissNotice(parseInt(button.dataset.objectId!, 10))).unwrap();

Ajax.apiOnce({
data: {
actionName: "dismiss",
className: "wcf\\data\\notice\\NoticeAction",
objectIDs: [button.dataset.objectId!],
},
success: () => {
button.parentElement!.remove();
},
});
button.parentElement!.remove();
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ static function (\wcf\event\endpoint\ControllerCollecting $event) {
$event->register(new \wcf\system\endpoint\controller\core\notices\DeleteNotice());
$event->register(new \wcf\system\endpoint\controller\core\notices\GetShowOrder());
$event->register(new \wcf\system\endpoint\controller\core\notices\ChangeShowOrder());
$event->register(new \wcf\system\endpoint\controller\core\notices\DismissNotice());
$event->register(new \wcf\system\endpoint\controller\core\reactions\types\EnableType());
$event->register(new \wcf\system\endpoint\controller\core\reactions\types\DisableType());
$event->register(new \wcf\system\endpoint\controller\core\reactions\types\DeleteType());
Expand Down
59 changes: 59 additions & 0 deletions wcfsetup/install/files/lib/command/notice/DismissNotice.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace wcf\command\notice;

use wcf\data\notice\Notice;
use wcf\event\notice\NoticeDismissed;
use wcf\system\event\EventHandler;
use wcf\system\user\storage\UserStorageHandler;
use wcf\system\WCF;

/**
* Dismisses a notice.
*
* @author Olaf Braun
* @copyright 2001-2025 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.3
*/
final class DismissNotice
{
public function __construct(
private readonly Notice $notice,
) {}

public function __invoke(): void
{
if (WCF::getUser()->userID) {
$this->dismissForUser($this->notice, WCF::getUser()->userID);
} else {
$this->dismissForGuest($this->notice);
}

$event = new NoticeDismissed($this->notice);
EventHandler::getInstance()->fire($event);
}

private function dismissForUser(Notice $notice, int $userID): void
{
$sql = "INSERT IGNORE INTO wcf1_notice_dismissed
(noticeID, userID)
VALUES (?, ?)";
$statement = WCF::getDB()->prepare($sql);
$statement->execute([
$notice->noticeID,
$userID,
]);

UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'dismissedNotices');
}

private function dismissForGuest(Notice $notice): void
{
$sessionVar = WCF::getSession()->getVar('dismissedNotices') ?? '';
$dismissedNotices = @\unserialize($sessionVar) ?: [];
$dismissedNotices[] = $notice->noticeID;

WCF::getSession()->register('dismissedNotices', \serialize($dismissedNotices));
}
}
30 changes: 6 additions & 24 deletions wcfsetup/install/files/lib/data/notice/NoticeAction.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

use wcf\command\notice\DisableNotice;
use wcf\command\notice\EnableNotice;
use wcf\command\notice\DismissNotice;
use wcf\data\AbstractDatabaseObjectAction;
use wcf\data\IToggleAction;
use wcf\system\condition\ConditionHandler;
use wcf\system\user\storage\UserStorageHandler;
use wcf\system\WCF;

/**
* Executes notice-related actions.
Expand Down Expand Up @@ -75,32 +74,14 @@ public function delete()
* Dismisses a certain notice.
*
* @return int[]
* @deprecated 6.3 Use the `DismissNotice` command instead.
*/
public function dismiss()
{
if (WCF::getUser()->userID) {
$sql = "INSERT IGNORE INTO wcf1_notice_dismissed
(noticeID, userID)
VALUES (?, ?)";
$statement = WCF::getDB()->prepare($sql);
$statement->execute([
\reset($this->objectIDs),
WCF::getUser()->userID,
]);

UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'dismissedNotices');
} else {
$dismissedNotices = WCF::getSession()->getVar('dismissedNotices');
if ($dismissedNotices !== null) {
$dismissedNotices = @\unserialize($dismissedNotices);
$dismissedNotices[] = \reset($this->objectIDs);
} else {
$dismissedNotices = [
\reset($this->objectIDs),
];
}
$editor = $this->getSingleObject();

WCF::getSession()->register('dismissedNotices', \serialize($dismissedNotices));
if ($editor->isDismissible) {
(new DismissNotice($editor->getDecoratedObject()))();
}

return [
Expand All @@ -112,6 +93,7 @@ public function dismiss()
* Validates the 'dismiss' action.
*
* @return void
* @deprecated 6.3
*/
public function validateDismiss()
{
Expand Down
21 changes: 21 additions & 0 deletions wcfsetup/install/files/lib/event/notice/NoticeDismissed.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace wcf\event\notice;

use wcf\data\notice\Notice;
use wcf\event\IPsr14Event;

/**
* Indicates that a notice has been dismissed.
*
* @author Olaf Braun
* @copyright 2001-2025 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.3
*/
final class NoticeDismissed implements IPsr14Event
{
public function __construct(
public readonly Notice $notice
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace wcf\system\endpoint\controller\core\notices;

use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use wcf\data\notice\Notice;
use wcf\http\Helper;
use wcf\system\endpoint\IController;
use wcf\system\endpoint\PostRequest;
use wcf\system\exception\PermissionDeniedException;

/**
* Dismisses a notice.
*
* @author Olaf Braun
* @copyright 2001-2025 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.3
*/
#[PostRequest('/core/notices/{id:\d+}/dismiss')]
final class DismissNotice implements IController
{
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
{
$notice = Helper::fetchObjectFromRequestParameter($variables['id'], Notice::class);

$this->assertNoticeCanBeDismissed($notice);

(new \wcf\command\notice\DismissNotice($notice))();

return new JsonResponse([]);
}

private function assertNoticeCanBeDismissed(Notice $notice): void
{
if (!$notice->isDismissible) {
throw new PermissionDeniedException();
}
}
}