Completed
Branch master (33af51)
by Timo
04:12
created

FacetingCommand::renderAvailableFacets()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 45
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 7.7305

Importance

Changes 0
Metric Value
dl 0
loc 45
ccs 21
cts 33
cp 0.6364
rs 8.439
c 0
b 0
f 0
cc 6
eloc 25
nc 4
nop 0
crap 7.7305
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\Plugin\CommandPluginBase;
30
use ApacheSolrForTypo3\Solr\Plugin\PluginCommand;
31
use ApacheSolrForTypo3\Solr\Query\LinkBuilder;
32
use ApacheSolrForTypo3\Solr\Search;
33
use TYPO3\CMS\Core\Utility\GeneralUtility;
34
35
/**
36
 * facets view command
37
 *
38
 * @author Ingo Renner <[email protected]>
39
 */
40
class FacetingCommand implements PluginCommand
41
{
42
43
    /**
44
     * Search instance
45
     *
46
     * @var Search
47
     */
48
    protected $search;
49
50
    /**
51
     * Parent plugin
52
     *
53
     * @var Results
54
     */
55
    protected $parentPlugin;
56
57
    /**
58
     * Configuration
59
     *
60
     * @var array
61
     */
62
    protected $configuration;
63
64
    /**
65
     * Facets active: TRUE if any option of any facet has been selected.
66
     *
67
     * @var bool
68
     */
69
    protected $facetsActive = false;
70
71
    /**
72
     * Constructor.
73
     *
74
     * @param CommandPluginBase $parentPlugin Parent plugin object.
75
     */
76 20
    public function __construct(CommandPluginBase $parentPlugin)
77
    {
78 20
        $this->search = GeneralUtility::makeInstance('ApacheSolrForTypo3\\Solr\\Search');
79
80 20
        $this->parentPlugin = $parentPlugin;
0 ignored issues
show
Documentation Bug introduced by
$parentPlugin is of type object<ApacheSolrForTypo...ugin\CommandPluginBase>, but the property $parentPlugin was declared to be of type object<ApacheSolrForTypo...Plugin\Results\Results>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
81 20
        $this->configuration = $parentPlugin->typoScriptConfiguration;
0 ignored issues
show
Documentation Bug introduced by
It seems like $parentPlugin->typoScriptConfiguration of type object<ApacheSolrForTypo...ypoScriptConfiguration> is incompatible with the declared type array of property $configuration.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
82 20
    }
83
84
    /**
85
     * Executes the command, renders the template subpart markers if faceting
86
     * is activated.
87
     *
88
     * @return array|null Array of faceting markers or null if faceting is deactivated
89
     */
90 20
    public function execute()
91
    {
92 20
        $marker = array();
93
94 20
        if ($this->configuration->getSearchFaceting()
0 ignored issues
show
Bug introduced by
The method getSearchFaceting cannot be called on $this->configuration (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
95 20
            && ($this->search->getNumberOfResults() || $this->configuration->getSearchInitializeWithEmptyQuery() || $this->configuration->getSearchInitializeWithQuery())
0 ignored issues
show
Bug introduced by
The method getSearchInitializeWithEmptyQuery cannot be called on $this->configuration (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug introduced by
The method getSearchInitializeWithQuery cannot be called on $this->configuration (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
96
        ) {
97 18
            $marker['subpart_available_facets'] = $this->renderAvailableFacets();
98 18
            $marker['subpart_used_facets'] = $this->renderUsedFacets();
99 18
            $marker['active'] = $this->facetsActive ? '1' : '0';
100 18
            $marker['search_has_results'] = $this->search->getNumberOfResults() ? 1 : 0;
101
102 18
            $this->addFacetingJavascript();
103
        }
104
105 20
        if (count($marker) === 0) {
106
            // in case we didn't fill any markers - like when there are no
107
            // search results - we set markers to NULL to signal that we
108
            // want to have the subpart removed completely
109 2
            $marker = null;
110
        }
111
112 20
        return $marker;
113
    }
114
115
    /**
116
     * Renders user-selectable facets.
117
     *
118
     * @return string rendered facets subpart
119
     */
120 18
    protected function renderAvailableFacets()
121
    {
122 18
        $facetContent = '';
123
124 18
        $template = clone $this->parentPlugin->getTemplate();
125 18
        $template->workOnSubpart('available_facets');
126
127 18
        $configuredFacets = $this->configuration->getSearchFacetingFacets();
0 ignored issues
show
Bug introduced by
The method getSearchFacetingFacets cannot be called on $this->configuration (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
128
129 18
        $facetRendererFactory = GeneralUtility::makeInstance(
130 18
            'ApacheSolrForTypo3\\Solr\\Facet\\FacetRendererFactory',
131
            $configuredFacets
132
        );
133
        /** @var $facetRendererFactory FacetRendererFactory */
134 18
        foreach ($configuredFacets as $facetName => $facetConfiguration) {
135 18
            $facetName = substr($facetName, 0, -1);
136 18
            $facet = GeneralUtility::makeInstance('ApacheSolrForTypo3\\Solr\\Facet\\Facet',
137
                $facetName,
138 18
                $facetRendererFactory->getFacetInternalType($facetName)
139
            );
140
            /** @var $facet Facet */
141
            if (
142 18
                (isset($facetConfiguration['includeInAvailableFacets']) && $facetConfiguration['includeInAvailableFacets'] == '0')
143 18
                || !$facet->isRenderingAllowed()
144
            ) {
145
                // don't render facets that should not be included in available facets
146
                // or that do not meet their requirements to be rendered
147
                continue;
148
            }
149
150 18
            $facetRenderer = $facetRendererFactory->getFacetRendererByFacet($facet);
151 18
            $facetRenderer->setTemplate($template);
152 18
            $facetRenderer->setLinkTargetPageId($this->parentPlugin->getLinkTargetPageId());
153
154 18
            if ($facet->isActive()) {
155 1
                $this->facetsActive = true;
156
            }
157
158 18
            $facetContent .= $facetRenderer->renderFacet();
159
        }
160
161 18
        $template->addSubpart('single_facet', $facetContent);
162
163 18
        return $template->render();
164
    }
165
166
    /**
167
     * Renders facets selected by the user.
168
     *
169
     * @return string rendered selected facets subpart
170
     */
171 18
    protected function renderUsedFacets()
172
    {
173 18
        $template = clone $this->parentPlugin->getTemplate();
174 18
        $template->workOnSubpart('used_facets');
175
176 18
        $query = $this->search->getQuery();
177
178 18
        $queryLinkBuilder = GeneralUtility::makeInstance('ApacheSolrForTypo3\\Solr\\Query\\LinkBuilder',
179 18
            $this->search->getQuery());
180
        /* @var $queryLinkBuilder LinkBuilder */
181 18
        $queryLinkBuilder->setLinkTargetPageId($this->parentPlugin->getLinkTargetPageId());
182
183
        // URL parameters added to facet URLs may not need to be added to the facets reset URL
184 18
        $facetLinkUrlParameters = $this->configuration->getSearchFacetingFacetLinkUrlParametersAsArray();
0 ignored issues
show
Bug introduced by
The method getSearchFacetingFacetLinkUrlParametersAsArray cannot be called on $this->configuration (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
185 18
        $useForFacetResetLink = $this->configuration->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl();
0 ignored issues
show
Bug introduced by
The method getSearchFacetingFacetLi...UseForFacetResetLinkUrl cannot be called on $this->configuration (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
186
187 18
        if (count($facetLinkUrlParameters) > 0 && $useForFacetResetLink) {
188 18
            $addedUrlParameterKeys = array_keys($facetLinkUrlParameters);
189
190 18
            foreach ($addedUrlParameterKeys as $addedUrlParameterKey) {
191 18
                if (GeneralUtility::isFirstPartOfStr($addedUrlParameterKey, 'tx_solr')) {
192
                    $addedUrlParameterKey = substr($addedUrlParameterKey, 8, -1);
193 18
                    $queryLinkBuilder->addUnwantedUrlParameter($addedUrlParameterKey);
194
                }
195
            }
196
        }
197
198 18
        $resultParameters = GeneralUtility::_GET('tx_solr');
199 18
        $filterParameters = array();
200 18
        if (isset($resultParameters['filter'])) {
201 1
            $filterParameters = (array)array_map('urldecode',
202 1
                $resultParameters['filter']);
203
        }
204
205 18
        $facetsInUse = array();
206 18
        foreach ($filterParameters as $filter) {
207
            // only split by the first ":" to allow the use of colons in the filter value
208 1
            list($filterName, $filterValue) = explode(':', $filter, 2);
209
210 1
            $facetConfiguration = $this->configuration->getSearchFacetingFacetByName($filterName);
0 ignored issues
show
Bug introduced by
The method getSearchFacetingFacetByName cannot be called on $this->configuration (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
211
212
            // don't render facets that should not be included in used facets
213 1
            if (isset($facetConfiguration['includeInUsedFacets']) && $facetConfiguration['includeInUsedFacets'] == '0') {
214
                continue;
215
            }
216
217 1
            $usedFacetRenderer = GeneralUtility::makeInstance(
218 1
                'ApacheSolrForTypo3\\Solr\\Facet\\UsedFacetRenderer',
219
                $filterName,
220
                $filterValue,
221
                $filter,
222 1
                $this->parentPlugin->getTemplate(),
223
#FIXME usage of $query
224
                $query
225
            );
226 1
            $usedFacetRenderer->setLinkTargetPageId($this->parentPlugin->getLinkTargetPageId());
227
228 1
            $facetToRemove = $usedFacetRenderer->render();
229
230 1
            $facetsInUse[] = $facetToRemove;
231
        }
232 18
        $template->addLoop('facets_in_use', 'remove_facet', $facetsInUse);
233
234 18
        $template->addVariable('remove_all_facets', array(
235 18
            'url' => $queryLinkBuilder->getQueryUrl(array('filter' => array())),
236 18
            'text' => '###LLL:faceting_removeAllFilters###'
237
        ));
238
239 18
        $content = '';
240 18
        if (count($facetsInUse)) {
241 1
            $content = $template->render();
242
        }
243
244 18
        return $content;
245
    }
246
247
    /**
248
     * Adds the JavaScript necessary for some of the faceting features;
249
     * folding/unfolding a list of facet options that exceed the configured
250
     * limit of visible options
251
     *
252
     * @return void
253
     */
254 18
    protected function addFacetingJavascript()
255
    {
256 18
        $javascriptManager = $this->parentPlugin->getJavascriptManager();
257
258
        $expansionLabels = '
259
			var tx_solr_facetLabels = {
260 18
				\'showMore\' : \'' . $this->parentPlugin->pi_getLL('faceting_showMore') . '\',
261 18
				\'showFewer\' : \'' . $this->parentPlugin->pi_getLL('faceting_showFewer') . '\'
262
			};
263 18
		';
264 18
        $javascriptManager->addJavascript('tx_solr-facetingExpansionLabels',
265
            $expansionLabels);
266 18
        $javascriptManager->loadFile('faceting.limitExpansion');
267 18
    }
268
}
269