Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.24% covered (success)
95.24%
40 / 42
83.33% covered (success)
83.33%
10 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
Forms
95.24% covered (success)
95.24%
40 / 42
83.33% covered (success)
83.33%
10 / 12
21
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getFormData
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getTranslatedLanguages
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 updateInputFlags
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 getTranslations
83.33% covered (success)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
 editTranslation
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 deleteTranslation
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addTranslation
93.33% covered (success)
93.33%
14 / 15
0.00% covered (danger)
0.00%
0 / 1
3.00
 insertInputIntoDatabase
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getInsertQueries
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 saveActivateInputStatus
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 saveRequiredInputStatus
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * The main forms class.
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 * @author    Jan Harms <model_railroader@gmx-topmail.de>
13 * @copyright 2024-2026 phpMyFAQ Team
14 * @license   https://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
15 * @link      https://www.phpmyfaq.de
16 * @since     2024-03-21
17 */
18
19declare(strict_types=1);
20
21namespace phpMyFAQ;
22
23use phpMyFAQ\Form\FormsHelper;
24use phpMyFAQ\Form\FormsRepository;
25use phpMyFAQ\Form\FormsRepositoryInterface;
26use phpMyFAQ\Language\LanguageCodes;
27
28readonly class Forms
29{
30    /* @mago-expect[too-many-methods]: Backward-compatible wrappers retained until the next major release. */
31    private Translation $translation;
32
33    private FormsRepositoryInterface $formsRepository;
34
35    public function __construct(
36        private Configuration $configuration,
37        ?FormsRepositoryInterface $formsRepository = null,
38    ) {
39        $this->translation = Translation::getInstance();
40        $this->formsRepository = $formsRepository ?? new FormsRepository($this->configuration);
41    }
42
43    /**
44     * Get inputs of a given form.
45     *
46     * @param int $formId Form ID
47     */
48    public function getFormData(int $formId): array
49    {
50        $formData = $this->formsRepository->fetchFormDataByFormId($formId);
51        return new FormsHelper()->filterAndSortFormData($formData, $this->translation);
52    }
53
54    /**
55     * Get languages that are already translated for a given input
56     *
57     * @param int $formId Form ID
58     * @param int $inputId Input ID
59     */
60    public function getTranslatedLanguages(int $formId, int $inputId): array
61    {
62        $translations = $this->getTranslations($formId, $inputId);
63        $languages = [];
64
65        foreach ($translations as $translation) {
66            $languages[] = $translation->input_lang;
67        }
68
69        return $languages;
70    }
71
72    /**
73     * Update activation and required flags of a given input.
74     */
75    public function updateInputFlags(int $formId, int $inputId, ?int $activated = null, ?int $required = null): bool
76    {
77        $ok = true;
78        if ($activated !== null) {
79            $ok = $ok && $this->formsRepository->updateInputActive($formId, $inputId, $activated);
80        }
81
82        if ($required !== null) {
83            $ok = $ok && $this->formsRepository->updateInputRequired($formId, $inputId, $required);
84        }
85
86        return $ok;
87    }
88
89    /**
90     * Get translation strings of a given input
91     *
92     * @return array<int, \stdClass>
93     */
94    public function getTranslations(int $formId, int $inputId): array
95    {
96        $translations = $this->formsRepository->fetchTranslationsByFormAndInput($formId, $inputId);
97
98        foreach ($translations as $translation) {
99            if ($translation->input_lang !== 'default') {
100                continue;
101            }
102
103            $translation->input_label = Translation::get((string) $translation->input_label);
104        }
105
106        return $translations;
107    }
108
109    /**
110     * Edit a translation string
111     *
112     * @param string $label New translation string
113     * @param int $formId Form ID
114     * @param int $inputId Input ID
115     * @param string $lang Edited language
116     */
117    public function editTranslation(string $label, int $formId, int $inputId, string $lang): bool
118    {
119        return $this->formsRepository->updateTranslation($label, $formId, $inputId, $lang);
120    }
121
122    /**
123     * Delete a translation string
124     *
125     * @param int $formId Form ID
126     * @param int $inputId Input ID
127     * @param string $lang Deleted language
128     */
129    public function deleteTranslation(int $formId, int $inputId, string $lang): bool
130    {
131        return $this->formsRepository->deleteTranslation($formId, $inputId, $lang);
132    }
133
134    /**
135     * Add a translation string
136     *
137     * @param int $formId Form ID
138     * @param int $inputId Input ID
139     * @param string $lang Added language
140     * @param string $translation New translation string
141     */
142    public function addTranslation(int $formId, int $inputId, string $lang, string $translation): bool
143    {
144        $inputData = $this->formsRepository->fetchDefaultInputData($formId, $inputId);
145        if ($inputData === null) {
146            return false;
147        }
148
149        $languageKey = LanguageCodes::getKey($lang);
150        if ($languageKey === false) {
151            return false;
152        }
153
154        return $this->formsRepository->insertTranslationRow(
155            $formId,
156            $inputId,
157            (string) $inputData->input_type,
158            $translation,
159            (int) $inputData->input_active,
160            (int) $inputData->input_required,
161            (string) $languageKey,
162        );
163    }
164
165    /**
166     * Inserts a given input into the database (Only used in install-routine)
167     *
168     * @param array<string, mixed> $input Input array
169     */
170    public function insertInputIntoDatabase(array $input): bool
171    {
172        return $this->formsRepository->insertInput($input);
173    }
174
175    /**
176     * @param array<string, mixed> $input
177     */
178    public function getInsertQueries(array $input): string
179    {
180        return $this->formsRepository->buildInsertQuery($input);
181    }
182
183    /**
184     * Save the (de-)activation of a given input (legacy wrapper).
185     */
186    public function saveActivateInputStatus(int $formId, int $inputId, int $activated): bool
187    {
188        return $this->updateInputFlags($formId, $inputId, activated: $activated);
189    }
190
191    /**
192     * Save the requirement status of a given input (legacy wrapper).
193     */
194    public function saveRequiredInputStatus(int $formId, int $inputId, int $required): bool
195    {
196        return $this->updateInputFlags($formId, $inputId, required: $required);
197    }
198}