Passed
Push — release-11.5.x ( 39fc07...8ccd81 )
by Markus
34:52 queued 29:33
created

FlexFormUserFunctions   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Test Coverage

Coverage 62.33%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 25
eloc 64
c 1
b 0
f 0
dl 0
loc 213
ccs 48
cts 77
cp 0.6233
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getTranslation() 0 3 1
A getTypoScriptTemplateKeyFromFieldName() 0 4 1
A getConfiguredFacetsForPage() 0 7 2
A getFieldNamesFromSolrMetaDataForPage() 0 3 1
A getAvailableTemplates() 0 15 3
A getConnection() 0 3 1
A getAvailablePluginNamespaces() 0 9 3
A getConfigurationFromPageId() 0 10 2
A getAvailableTemplateFromTypoScriptConfiguration() 0 4 1
A getFacetFieldsFromSchema() 0 13 2
A buildSelectItemsFromAvailableTemplate() 0 11 2
A getParsedSolrFieldsFromSchema() 0 29 6
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace ApacheSolrForTypo3\Solr\System\UserFunctions;
19
20
use ApacheSolrForTypo3\Solr\ConnectionManager;
21
use ApacheSolrForTypo3\Solr\NoSolrConnectionFoundException;
22
use ApacheSolrForTypo3\Solr\System\Configuration\ExtensionConfiguration;
23
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
24
use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection;
25
use Doctrine\DBAL\Driver\Exception as DBALDriverException;
26
use function str_starts_with;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
29
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
30
31
/**
32
 * This class contains all user functions for flexforms.
33
 *
34
 * @author Daniel Siepmann <[email protected]>
35
 */
36
class FlexFormUserFunctions
37
{
38
    /**
39
     * Provides all facet fields for a flexform select, enabling the editor to select one of them.
40
     *
41
     * @param array $parentInformation
42
     * @throws DBALDriverException
43
     * @throws NoSolrConnectionFoundException
44
     */
45 6
    public function getFacetFieldsFromSchema(array &$parentInformation)
46
    {
47 6
        $pageRecord = $parentInformation['flexParentDatabaseRow'];
48
        // @todo: Fix type hinting issue properly on whole call chain.
49 6
        $configuredFacets = $this->getConfiguredFacetsForPage($pageRecord['pid'] ?? null);
50
51 6
        if (!is_array($pageRecord)) {
52 1
            $parentInformation['items'] = [];
53 1
            return;
54
        }
55
56 5
        $newItems = $this->getParsedSolrFieldsFromSchema($configuredFacets, $pageRecord);
0 ignored issues
show
Bug introduced by
It seems like $configuredFacets can also be of type null; however, parameter $configuredFacets of ApacheSolrForTypo3\Solr\...dSolrFieldsFromSchema() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

56
        $newItems = $this->getParsedSolrFieldsFromSchema(/** @scrutinizer ignore-type */ $configuredFacets, $pageRecord);
Loading history...
57 5
        $parentInformation['items'] = $newItems;
58
    }
59
60
    /**
61
     * This method parses the solr schema fields into the required format for the backend flexform.
62
     *
63
     * @param array $configuredFacets
64
     * @param array $pageRecord
65
     * @return array
66
     * @throws DBALDriverException
67
     * @throws NoSolrConnectionFoundException
68
     */
69 5
    protected function getParsedSolrFieldsFromSchema(array $configuredFacets, array $pageRecord): array
70
    {
71 5
        $newItems = [];
72
73 5
        array_map(function ($fieldName) use (&$newItems, $configuredFacets) {
74 5
            $value = $fieldName;
75 5
            $label = $fieldName;
76
77 5
            $facetNameFilter = function ($facet) use ($fieldName) {
78 4
                return $facet['field'] === $fieldName;
79 5
            };
80 5
            $configuredFacets = array_filter($configuredFacets, $facetNameFilter);
81 5
            if (!empty($configuredFacets)) {
82 4
                $configuredFacet = array_values($configuredFacets);
83 4
                $label = $configuredFacet[0]['label'];
84
                // try to translate LLL: label or leave it unchanged
85 4
                if (str_starts_with($label, 'LLL:') && $this->getTranslation($label) != '') {
86 1
                    $label = $this->getTranslation($label);
87 4
                } elseif (!str_starts_with($label, 'LLL:') && ($configuredFacet[0]['label.'] ?? null)) {
88 1
                    $label = sprintf('cObject[...faceting.facets.%slabel]', array_keys($configuredFacets)[0]);
89
                }
90 4
                $label = sprintf('%s (Facet Label: "%s")', $value, $label);
91
            }
92
93 5
            $newItems[$value] = [$label, $value];
94 5
        }, $this->getFieldNamesFromSolrMetaDataForPage($pageRecord));
95
96 5
        ksort($newItems, SORT_NATURAL);
97 5
        return $newItems;
98
    }
99
100
    /**
101
     * Retrieves the configured facets for a page.
102
     *
103
     * @param int|null $pid
104
     * @return array
105
     * @throws DBALDriverException
106
     * @todo: Fix type hinting properly
107
     */
108
    protected function getConfiguredFacetsForPage(?int $pid = null): ?array
109
    {
110
        if ($pid === null) {
111
            return null;
112
        }
113
        $typoScriptConfiguration = $this->getConfigurationFromPageId($pid);
114
        return $typoScriptConfiguration->getSearchFacetingFacets();
115
    }
116
117
    /**
118
     * Retrieves the translation with the LocalizationUtility.
119
     *
120
     * @param string $label
121
     * @return string|null
122
     */
123
    protected function getTranslation(string $label): ?string
124
    {
125
        return LocalizationUtility::translate($label);
126
    }
127
128
    /**
129
     * Get solr connection.
130
     *
131
     * @param array $pageRecord
132
     *
133
     * @return SolrConnection
134
     * @throws DBALDriverException
135
     * @throws NoSolrConnectionFoundException
136
     */
137
    protected function getConnection(array $pageRecord): SolrConnection
138
    {
139
        return GeneralUtility::makeInstance(ConnectionManager::class)->getConnectionByPageId($pageRecord['pid'], $pageRecord['sys_language_uid']);
140
    }
141
142
    /**
143
     * Retrieves all fieldnames that occurs in the solr schema for one page.
144
     *
145
     * @param array $pageRecord
146
     * @return array
147
     * @throws DBALDriverException
148
     * @throws NoSolrConnectionFoundException
149
     */
150
    protected function getFieldNamesFromSolrMetaDataForPage(array $pageRecord): array
151
    {
152
        return array_keys((array)$this->getConnection($pageRecord)->getAdminService()->getFieldsMetaData());
153
    }
154
155
    /**
156
     * @param array $parentInformation
157
     * @throws DBALDriverException
158
     */
159 1
    public function getAvailableTemplates(array &$parentInformation)
160
    {
161 1
        $pageRecord = $parentInformation['flexParentDatabaseRow'];
162 1
        if (!is_array($pageRecord) || !isset($pageRecord['pid'])) {
163
            $parentInformation['items'] = [];
164
            return;
165
        }
166
167 1
        $pageId = $pageRecord['pid'];
168
169 1
        $templateKey = $this->getTypoScriptTemplateKeyFromFieldName($parentInformation);
170 1
        $availableTemplate = $this->getAvailableTemplateFromTypoScriptConfiguration($pageId, $templateKey);
0 ignored issues
show
Bug introduced by
It seems like $templateKey can also be of type string[]; however, parameter $templateKey of ApacheSolrForTypo3\Solr\...poScriptConfiguration() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
        $availableTemplate = $this->getAvailableTemplateFromTypoScriptConfiguration($pageId, /** @scrutinizer ignore-type */ $templateKey);
Loading history...
171 1
        $newItems = $this->buildSelectItemsFromAvailableTemplate($availableTemplate);
172
173 1
        $parentInformation['items'] = $newItems;
174
    }
175
176
    /**
177
     * @param array $parentInformation
178
     */
179
    public function getAvailablePluginNamespaces(array &$parentInformation)
180
    {
181
        $extensionConfiguration = GeneralUtility::makeInstance(ExtensionConfiguration::class);
182
        $namespaces = [];
183
        foreach ($extensionConfiguration->getAvailablePluginNamespaces() as $namespace) {
184
            $label = $namespace === 'tx_solr' ? 'Default' : '';
185
            $namespaces[$namespace] = [$label, $namespace];
186
        }
187
        $parentInformation['items'] = $namespaces;
188
    }
189
190
    /**
191
     * @param array $parentInformation
192
     * @return string|string[]
193
     */
194 1
    protected function getTypoScriptTemplateKeyFromFieldName(array $parentInformation)
195
    {
196 1
        $field = $parentInformation['field'];
197 1
        return str_replace('view.templateFiles.', '', $field);
198
    }
199
200
    /**
201
     * @param int|null $pid
202
     * @return TypoScriptConfiguration|null
203
     * @throws DBALDriverException
204
     * @todo: Fix type hinting properly
205
     */
206
    protected function getConfigurationFromPageId(?int $pid = null): ?TypoScriptConfiguration
207
    {
208
        if ($pid === null) {
209
            return null;
210
        }
211
212
        $configurationManager = GeneralUtility::makeInstance(ConfigurationManagerInterface::class);
213
        $typoScript = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
214
215
        return GeneralUtility::makeInstance(TypoScriptConfiguration::class, $typoScript);
216
    }
217
218
    /**
219
     * Retrieves the configured templates from TypoScript.
220
     *
221
     * @param int $pageId
222
     * @param string $templateKey
223
     * @return array
224
     * @throws DBALDriverException
225
     */
226
    protected function getAvailableTemplateFromTypoScriptConfiguration(int $pageId, string $templateKey): array
227
    {
228
        $configuration = $this->getConfigurationFromPageId($pageId);
229
        return $configuration->getAvailableTemplatesByFileKey($templateKey);
230
    }
231
232
    /**
233
     * Returns the available templates as needed for the flexform.
234
     *
235
     * @param array $availableTemplates
236
     * @return array
237
     */
238 1
    protected function buildSelectItemsFromAvailableTemplate(array $availableTemplates): array
239
    {
240 1
        $newItems = [];
241 1
        $newItems['Use Default'] = ['Use Default', null];
242 1
        foreach ($availableTemplates as $availableTemplate) {
243 1
            $label = $availableTemplate['label'] ?? '';
244 1
            $value = $availableTemplate['file'] ?? '';
245 1
            $newItems[$label] = [$label, $value];
246
        }
247
248 1
        return $newItems;
249
    }
250
}
251