Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.83% covered (success)
95.83%
23 / 24
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
CommentController
95.83% covered (success)
95.83%
23 / 24
50.00% covered (danger)
50.00%
1 / 2
10
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 delete
95.65% covered (success)
95.65%
22 / 23
0.00% covered (danger)
0.00%
0 / 1
9
1<?php
2
3/**
4 * The Admin Comment Controller
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public License,
7 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
8 * obtain one at https://mozilla.org/MPL/2.0/.
9 *
10 * @package   phpMyFAQ
11 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
12 * @copyright 2023-2026 phpMyFAQ Team
13 * @license   https://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
14 * @link      https://www.phpmyfaq.de
15 * @since     2023-10-25
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Controller\Administration\Api;
21
22use Exception;
23use phpMyFAQ\Comments;
24use phpMyFAQ\Enums\AdminLogType;
25use phpMyFAQ\Enums\PermissionType;
26use phpMyFAQ\Session\Token;
27use phpMyFAQ\Translation;
28use Symfony\Component\HttpFoundation\JsonResponse;
29use Symfony\Component\HttpFoundation\Request;
30use Symfony\Component\HttpFoundation\Response;
31use Symfony\Component\Routing\Attribute\Route;
32
33final class CommentController extends AbstractAdministrationApiController
34{
35    public function __construct(
36        private readonly Comments $comments,
37    ) {
38        parent::__construct();
39    }
40
41    /**
42     * @throws Exception
43     */
44    #[Route(path: 'content/comments', name: 'admin.api.content.comments', methods: ['DELETE'])]
45    public function delete(Request $request): JsonResponse
46    {
47        $this->userHasPermission(PermissionType::COMMENT_DELETE);
48
49        $data = $this->getJsonObject($request);
50        $payload = $data->data instanceof \stdClass ? $data->data : null;
51
52        $rawCsrfToken = $payload->{'pmf-csrf-token'} ?? null;
53        $csrfToken = $rawCsrfToken !== null ? (string) $rawCsrfToken : null;
54        if (!Token::getInstance($this->session)->verifyToken('delete-comment', $csrfToken)) {
55            return $this->json(['error' => Translation::get(key: 'msgNoPermission')], Response::HTTP_UNAUTHORIZED);
56        }
57
58        $rawIds = $payload->{'comments[]'} ?? [];
59        $commentIds = is_array($rawIds) ? $rawIds : [$rawIds];
60
61        $type = (string) ($data->type ?? '');
62        $result = false;
63        foreach ($commentIds as $commentId) {
64            $commentId = filter_var($commentId, FILTER_VALIDATE_INT);
65            if ($commentId === false || $commentId === 0) {
66                continue;
67            }
68
69            $result = $this->comments->delete($type, $commentId);
70        }
71
72        if ($result) {
73            $this->adminLog?->log(
74                $this->currentUser,
75                AdminLogType::COMMENT_DELETE->value . ':'
76                    . implode(',', array_map(static fn(mixed $id): string => (string) $id, $commentIds)),
77            );
78        }
79
80        return $this->json(['success' => $result], Response::HTTP_OK);
81    }
82}