Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
QuestionService
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
5 / 5
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 prepareAskQuestionData
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 canUserAskQuestion
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 * Question 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\Forms;
26use phpMyFAQ\User\CurrentUser;
27
28/**
29 * Service class for question-related business logic.
30 */
31final class QuestionService
32{
33    public Category $category {
34        get {
35            return $this->category;
36        }
37    }
38
39    private Forms $forms;
40
41    public function __construct(
42        private readonly Configuration $configuration,
43        private readonly CurrentUser $currentUser,
44        private readonly array $currentGroups,
45    ) {
46        $this->category = new Category($this->configuration, $this->currentGroups);
47        $this->forms = new Forms($this->configuration);
48    }
49
50    /**
51     * Prepares data for asking a new question
52     *
53     * @return array<string, mixed>
54     */
55    public function prepareAskQuestionData(int $categoryId): array
56    {
57        // Build category tree
58        $this->category->transform(0);
59        $this->category->buildCategoryTree();
60
61        // Get form data
62        $formData = $this->forms->getFormData(FormIds::ASK_QUESTION->value);
63
64        // Get all category IDs
65        $categories = $this->category->getAllCategoryIds();
66
67        return [
68            'selectedCategory' => $categoryId,
69            'categories' => $this->category->getCategoryTree(),
70            'formData' => $formData,
71            'noCategories' => $categories === [],
72        ];
73    }
74
75    /**
76     * Checks if the current user can ask questions
77     */
78    public function canUserAskQuestion(): bool
79    {
80        // Guests can ask if allowed in configuration
81        if ($this->currentUser->getUserId() === -1) {
82            return (bool) $this->configuration->get('records.allowQuestionsForGuests');
83        }
84
85        // Logged-in users can always ask questions
86        return true;
87    }
88
89    /**
90     * Gets the default user email
91     */
92    public function getDefaultUserEmail(): string
93    {
94        return $this->currentUser->getUserId() > 0 ? (string) $this->currentUser->getUserData('email') : '';
95    }
96
97    /**
98     * Gets the default user name
99     */
100    public function getDefaultUserName(): string
101    {
102        return $this->currentUser->getUserId() > 0 ? (string) $this->currentUser->getUserData('display_name') : '';
103    }
104}