Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
83.87% covered (success)
83.87%
26 / 31
80.00% covered (success)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
FaqCreationService
83.87% covered (success)
83.87%
26 / 31
80.00% covered (success)
80.00%
4 / 5
10.42
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 prepareAddFaqData
78.26% covered (warning)
78.26%
18 / 23
0.00% covered (danger)
0.00%
0 / 1
3.09
 canUserAddFaq
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getDefaultUserEmail
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 getDefaultUserName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3/**
4 * FAQ Creation Service
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 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     2026-01-02
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Faq;
21
22use phpMyFAQ\Category;
23use phpMyFAQ\Configuration;
24use phpMyFAQ\Enums\Forms\FormIds;
25use phpMyFAQ\Enums\PermissionType;
26use phpMyFAQ\Forms;
27use phpMyFAQ\Question;
28use phpMyFAQ\Strings;
29use phpMyFAQ\User\CurrentUser;
30
31/**
32 * Service class for FAQ creation business logic.
33 */
34final class FaqCreationService
35{
36    public Category $category {
37        get {
38            return $this->category;
39        }
40    }
41
42    private Question $question;
43
44    private Forms $forms;
45
46    public function __construct(
47        private readonly Configuration $configuration,
48        private readonly CurrentUser $currentUser,
49        private readonly array $currentGroups,
50    ) {
51        $this->category = new Category($this->configuration, $this->currentGroups);
52        $this->question = new Question($this->configuration);
53        $this->forms = new Forms($this->configuration);
54    }
55
56    /**
57     * Prepares data for adding a new FAQ
58     *
59     * @return array<string, mixed>
60     */
61    public function prepareAddFaqData(?int $selectedQuestion, int $selectedCategory): array
62    {
63        $question = '';
64        $readonly = '';
65        $displayFullForm = false;
66
67        // Load question data if a question ID is provided
68        if ($selectedQuestion !== null) {
69            $questionData = $this->question->get($selectedQuestion);
70            $question = (string) ($questionData['question'] ?? '');
71            if (Strings::strlen($question) !== 0) {
72                $readonly = ' readonly';
73            }
74
75            // Display full form even if the user switched off single fields because of use together with answering
76            // open questions
77            $displayFullForm = true;
78        }
79
80        // Build category tree
81        $this->category->transform(0);
82        $this->category->buildCategoryTree();
83
84        // Get form data
85        $formData = $this->forms->getFormData(FormIds::ADD_NEW_FAQ->value);
86
87        // Get all category IDs
88        $categories = $this->category->getAllCategoryIds();
89
90        return [
91            'question' => $question,
92            'readonly' => $readonly,
93            'displayFullForm' => $displayFullForm,
94            'selectedQuestion' => $selectedQuestion,
95            'selectedCategory' => $selectedCategory,
96            'categories' => $this->category->getCategoryTree(),
97            'formData' => $formData,
98            'noCategories' => $categories === [],
99        ];
100    }
101
102    /**
103     * Checks if the current user can add FAQs
104     */
105    public function canUserAddFaq(): bool
106    {
107        // Guests can add if allowed in configuration
108        if ($this->currentUser->getUserId() === -1) {
109            return (bool) $this->configuration->get('records.allowNewFaqsForGuests');
110        }
111
112        // Logged-in users need the FAQ_ADD permission
113        return $this->currentUser->perm->hasPermission($this->currentUser->getUserId(), PermissionType::FAQ_ADD->value);
114    }
115
116    /**
117     * Gets the default user email
118     */
119    public function getDefaultUserEmail(): string
120    {
121        return $this->currentUser->getUserId() > 0 ? (string) $this->currentUser->getUserData('email') : '';
122    }
123
124    /**
125     * Gets the default user name
126     */
127    public function getDefaultUserName(): string
128    {
129        return $this->currentUser->getUserId() > 0 ? (string) $this->currentUser->getUserData('display_name') : '';
130    }
131}