Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
MarkdownController
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
1 / 1
 renderMarkdown
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3/**
4 * The Admin Markdown 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 League\CommonMark\Environment\Environment;
24use League\CommonMark\Exception\CommonMarkException;
25use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
26use League\CommonMark\Extension\GithubFlavoredMarkdownExtension;
27use League\CommonMark\MarkdownConverter;
28use phpMyFAQ\Enums\PermissionType;
29use phpMyFAQ\Filter;
30use Symfony\Component\HttpFoundation\JsonResponse;
31use Symfony\Component\HttpFoundation\Request;
32use Symfony\Component\HttpFoundation\Response;
33use Symfony\Component\Routing\Attribute\Route;
34
35final class MarkdownController extends AbstractAdministrationApiController
36{
37    /**
38     * @throws CommonMarkException
39     * @throws Exception
40     */
41    #[Route(path: 'content/markdown', name: 'admin.api.content.markdown', methods: ['POST'])]
42    public function renderMarkdown(Request $request): JsonResponse
43    {
44        $this->userHasPermission(PermissionType::FAQ_EDIT);
45
46        $data = json_decode($request->getContent());
47
48        if (!is_object($data) || !property_exists($data, 'text')) {
49            throw new Exception('Invalid JSON data');
50        }
51
52        $answer = Filter::filterVar($data->text, FILTER_SANITIZE_SPECIAL_CHARS, '');
53
54        $config = [
55            'html_input' => 'strip',
56            'allow_unsafe_links' => false,
57        ];
58
59        $environment = new Environment($config);
60        $environment->addExtension(new CommonMarkCoreExtension());
61        $environment->addExtension(new GithubFlavoredMarkdownExtension());
62
63        $markdownConverter = new MarkdownConverter($environment);
64
65        return $this->json(['success' => $markdownConverter->convert($answer)->getContent()], Response::HTTP_OK);
66    }
67}