Passed
Pull Request — main (#3486)
by Sebastian
41:24
created

getFieldNamesFromSolrMetaDataForPage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
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\FrontendEnvironment;
22
use ApacheSolrForTypo3\Solr\NoSolrConnectionFoundException;
23
use ApacheSolrForTypo3\Solr\System\Configuration\ExtensionConfiguration;
24
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
25
use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection;
26
use Doctrine\DBAL\Driver\Exception as DBALDriverException;
27
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
28
use function str_starts_with;
29
use TYPO3\CMS\Core\Utility\GeneralUtility;
30
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
31
32
/**
33
 * This class contains all user functions for flexforms.
34
 *
35
 * @author Daniel Siepmann <[email protected]>
36
 */
37
class FlexFormUserFunctions
38
{
39
    /**
40
     * Provides all facet fields for a flexform select, enabling the editor to select one of them.
41
     *
42
     * @param array $parentInformation
43 7
     * @throws DBALDriverException
44
     * @throws NoSolrConnectionFoundException
45 7
     */
46
    public function getFacetFieldsFromSchema(array &$parentInformation)
47
    {
48
        $pageRecord = $parentInformation['flexParentDatabaseRow'];
49
        // @todo: Fix type hinting issue properly on whole call chain.
50
        $configuredFacets = $this->getConfiguredFacetsForPage($pageRecord['pid'] ?? null);
51
52
        if (!is_array($pageRecord)) {
53
            $parentInformation['items'] = [];
54
            return;
55 6
        }
56
57 6
        $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

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

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