Passed
Pull Request — master (#1249)
by
unknown
19:13
created

FacetingCommand   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 82.26%

Importance

Changes 0
Metric Value
wmc 26
c 0
b 0
f 0
lcom 1
cbo 10
dl 0
loc 229
ccs 102
cts 124
cp 0.8226
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
C execute() 0 24 8
B renderAvailableFacets() 0 45 6
C renderUsedFacets() 0 75 10
A addFacetingJavascript() 0 14 1
1
<?php
2
namespace ApacheSolrForTypo3\Solr\Plugin\Results;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2009-2015 Ingo Renner <[email protected]>
8
 *  All rights reserved
9
 *
10
 *  This script is part of the TYPO3 project. The TYPO3 project is
11
 *  free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  The GNU General Public License can be found at
17
 *  http://www.gnu.org/copyleft/gpl.html.
18
 *
19
 *  This script is distributed in the hope that it will be useful,
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 *  GNU General Public License for more details.
23
 *
24
 *  This copyright notice MUST APPEAR in all copies of the script!
25
 ***************************************************************/
26
27
use ApacheSolrForTypo3\Solr\Facet\Facet;
28
use ApacheSolrForTypo3\Solr\Facet\FacetRendererFactory;
29
use ApacheSolrForTypo3\Solr\Facet\UsedFacetRenderer;
30
use ApacheSolrForTypo3\Solr\Plugin\CommandPluginBase;
31
use ApacheSolrForTypo3\Solr\Plugin\PluginCommand;
32
use ApacheSolrForTypo3\Solr\Query\LinkBuilder;
33
use ApacheSolrForTypo3\Solr\Search;
34
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
35
use TYPO3\CMS\Core\Utility\GeneralUtility;
36
37
/**
38
 * facets view command
39
 *
40
 * @author Ingo Renner <[email protected]>
41
 */
42
class FacetingCommand implements PluginCommand
43
{
44
45
    /**
46
     * Search instance
47
     *
48
     * @var Search
49
     */
50
    protected $search;
51
52
    /**
53
     * Parent plugin
54
     *
55
     * @var CommandPluginBase
56
     */
57
    protected $parentPlugin;
58
59
    /**
60
     * Configuration
61
     *
62
     * @var TypoScriptConfiguration
63
     */
64
    protected $configuration;
65
66
    /**
67
     * Facets active: TRUE if any option of any facet has been selected.
68
     *
69
     * @var bool
70
     */
71
    protected $facetsActive = false;
72
73
    /**
74
     * Constructor.
75
     *
76
     * @param CommandPluginBase $parentPlugin Parent plugin object.
77
     */
78 20
    public function __construct(CommandPluginBase $parentPlugin)
79
    {
80 20
        $this->search = GeneralUtility::makeInstance(Search::class);
81
82 20
        $this->parentPlugin = $parentPlugin;
83 20
        $this->configuration = $parentPlugin->typoScriptConfiguration;
84 20
    }
85
86
    /**
87
     * Executes the command, renders the template subpart markers if faceting
88
     * is activated.
89
     *
90
     * @return array|null Array of faceting markers or null if faceting is deactivated
91
     */
92 20
    public function execute()
93
    {
94 20
        $marker = [];
95
96 20
        if ($this->configuration->getSearchFaceting()
97 20
            && ($this->search->getNumberOfResults() || $this->configuration->getSearchInitializeWithEmptyQuery() || $this->configuration->getSearchInitializeWithQuery())
98 20
        ) {
99 18
            $marker['subpart_available_facets'] = $this->renderAvailableFacets();
100 18
            $marker['subpart_used_facets'] = $this->renderUsedFacets();
101 18
            $marker['active'] = $this->facetsActive ? '1' : '0';
102 18
            $marker['search_has_results'] = $this->search->getNumberOfResults() ? 1 : 0;
103
104 18
            $this->addFacetingJavascript();
105 18
        }
106
107 20
        if (count($marker) === 0) {
108
            // in case we didn't fill any markers - like when there are no
109
            // search results - we set markers to NULL to signal that we
110
            // want to have the subpart removed completely
111 2
            $marker = null;
112 2
        }
113
114 20
        return $marker;
115
    }
116
117
    /**
118
     * Renders user-selectable facets.
119
     *
120
     * @return string rendered facets subpart
121
     */
122 18
    protected function renderAvailableFacets()
123
    {
124 18
        $facetContent = '';
125
126 18
        $template = clone $this->parentPlugin->getTemplate();
127 18
        $template->workOnSubpart('available_facets');
128
129 18
        $configuredFacets = $this->configuration->getSearchFacetingFacets();
130
131 18
        $facetRendererFactory = GeneralUtility::makeInstance(
132 18
            FacetRendererFactory::class,
133
            $configuredFacets
134 18
        );
135
        /** @var $facetRendererFactory FacetRendererFactory */
136 18
        foreach ($configuredFacets as $facetName => $facetConfiguration) {
137 18
            $facetName = substr($facetName, 0, -1);
138 18
            $facet = GeneralUtility::makeInstance(Facet::class,
139 18
                $facetName,
140 18
                $facetRendererFactory->getFacetInternalType($facetName)
141 18
            );
142
            /** @var $facet Facet */
143
            if (
144 18
                (isset($facetConfiguration['includeInAvailableFacets']) && $facetConfiguration['includeInAvailableFacets'] == '0')
145 18
                || !$facet->isRenderingAllowed()
146 18
            ) {
147
                // don't render facets that should not be included in available facets
148
                // or that do not meet their requirements to be rendered
149
                continue;
150
            }
151
152 18
            $facetRenderer = $facetRendererFactory->getFacetRendererByFacet($facet);
153 18
            $facetRenderer->setTemplate($template);
154 18
            $facetRenderer->setLinkTargetPageId($this->parentPlugin->getLinkTargetPageId());
155
156 18
            if ($facet->isActive()) {
157 1
                $this->facetsActive = true;
158 1
            }
159
160 18
            $facetContent .= $facetRenderer->renderFacet();
161 18
        }
162
163 18
        $template->addSubpart('single_facet', $facetContent);
164
165 18
        return $template->render();
166
    }
167
168
    /**
169
     * Renders facets selected by the user.
170
     *
171
     * @return string rendered selected facets subpart
172
     */
173 18
    protected function renderUsedFacets()
174
    {
175 18
        $template = clone $this->parentPlugin->getTemplate();
176 18
        $template->workOnSubpart('used_facets');
177
178 18
        $query = $this->search->getQuery();
179
180 18
        $queryLinkBuilder = GeneralUtility::makeInstance(LinkBuilder::class,
181 18
            $this->search->getQuery());
182
        /* @var $queryLinkBuilder LinkBuilder */
183 18
        $queryLinkBuilder->setLinkTargetPageId($this->parentPlugin->getLinkTargetPageId());
184
185
        // URL parameters added to facet URLs may not need to be added to the facets reset URL
186 18
        $facetLinkUrlParameters = $this->configuration->getSearchFacetingFacetLinkUrlParametersAsArray();
187 18
        $useForFacetResetLink = $this->configuration->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl();
188
189 18
        if (count($facetLinkUrlParameters) > 0 && $useForFacetResetLink) {
190 18
            $addedUrlParameterKeys = array_keys($facetLinkUrlParameters);
191
192 18
            foreach ($addedUrlParameterKeys as $addedUrlParameterKey) {
193 18
                if (GeneralUtility::isFirstPartOfStr($addedUrlParameterKey, 'tx_solr')) {
194
                    $addedUrlParameterKey = substr($addedUrlParameterKey, 8, -1);
195
                    $queryLinkBuilder->addUnwantedUrlParameter($addedUrlParameterKey);
196
                }
197 18
            }
198 18
        }
199
200 18
        $resultParameters = GeneralUtility::_GET('tx_solr');
201 18
        $filterParameters = [];
202 18
        if (isset($resultParameters['filter'])) {
203 1
            $filterParameters = (array)array_map('urldecode',
204 1
                $resultParameters['filter']);
205 1
        }
206
207 18
        $facetsInUse = [];
208 18
        foreach ($filterParameters as $filter) {
209
            // only split by the first ":" to allow the use of colons in the filter value
210 1
            list($filterName, $filterValue) = explode(':', $filter, 2);
211
212 1
            $facetConfiguration = $this->configuration->getSearchFacetingFacetByName($filterName);
213
214
            // don't render facets that should not be included in used facets
215 1
            if (isset($facetConfiguration['includeInUsedFacets']) && $facetConfiguration['includeInUsedFacets'] == '0') {
216
                continue;
217
            }
218
219 1
            $usedFacetRenderer = GeneralUtility::makeInstance(
220 1
                UsedFacetRenderer::class,
221 1
                $filterName,
222 1
                $filterValue,
223 1
                $filter,
224 1
                $this->parentPlugin->getTemplate(),
225
#FIXME usage of $query
226
                $query
227 1
            );
228 1
            $usedFacetRenderer->setLinkTargetPageId($this->parentPlugin->getLinkTargetPageId());
229
230 1
            $facetToRemove = $usedFacetRenderer->render();
231
232 1
            $facetsInUse[] = $facetToRemove;
233 18
        }
234 18
        $template->addLoop('facets_in_use', 'remove_facet', $facetsInUse);
235
236 18
        $template->addVariable('remove_all_facets', [
237 18
            'url' => $queryLinkBuilder->getQueryUrl(['filter' => []]),
238
            'text' => '###LLL:faceting_removeAllFilters###'
239 18
        ]);
240
241 18
        $content = '';
242 18
        if (count($facetsInUse)) {
243 1
            $content = $template->render();
244 1
        }
245
246 18
        return $content;
247
    }
248
249
    /**
250
     * Adds the JavaScript necessary for some of the faceting features;
251
     * folding/unfolding a list of facet options that exceed the configured
252
     * limit of visible options
253
     *
254
     * @return void
255
     */
256 18
    protected function addFacetingJavascript()
257
    {
258 18
        $javascriptManager = $this->parentPlugin->getJavascriptManager();
259
260
        $expansionLabels = '
261
			var tx_solr_facetLabels = {
262 18
				\'showMore\' : \'' . $this->parentPlugin->pi_getLL('faceting_showMore') . '\',
263 18
				\'showFewer\' : \'' . $this->parentPlugin->pi_getLL('faceting_showFewer') . '\'
264
			};
265 18
		';
266 18
        $javascriptManager->addJavascript('tx_solr-facetingExpansionLabels',
267 18
            $expansionLabels);
268 18
        $javascriptManager->loadFile('faceting.limitExpansion');
269 18
    }
270
}
271