diff --git a/Classes/Hook/Filter/FrontendUserAccessFilter.php b/Classes/Domain/Search/Filter/FrontendUserAccessFilter.php similarity index 78% rename from Classes/Hook/Filter/FrontendUserAccessFilter.php rename to Classes/Domain/Search/Filter/FrontendUserAccessFilter.php index e96276f..42f9d2c 100644 --- a/Classes/Hook/Filter/FrontendUserAccessFilter.php +++ b/Classes/Domain/Search/Filter/FrontendUserAccessFilter.php @@ -1,6 +1,6 @@ @@ -25,26 +25,28 @@ use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication; /** * Filter: FrontendUserAccess - * @package Codappix\SearchCore\Hook\Filter */ -class FrontendUserAccessFilter +class FrontendUserAccessFilter implements SearchFilterInterface { - /** - * @param array $parameters - * @return void - */ - public function generate($parameters) + public function add(array $query, array $config, $value): array { - $this->appendQueryWithAccessFilter($parameters['query'], $parameters['value']); + return $this->addAccessFilter($query, $value); } - protected function appendQueryWithAccessFilter(array &$query, string $field) + /** + * Add simple boolean lookup for filtering on access groups + */ + protected function addAccessFilter(array $query, string $field): array { $query['query']['bool']['must'][] = [ 'terms' => [$field => $this->getUserGroups()] ]; + return $query; } + /** + * Get inherited user groups from logged in user or simulated user + */ protected function getUserGroups(): array { $feUser = $this->getFrontendUserAuthentication(); diff --git a/Classes/Domain/Search/Filter/InvalidSearchFilterException.php b/Classes/Domain/Search/Filter/InvalidSearchFilterException.php new file mode 100644 index 0000000..7199c58 --- /dev/null +++ b/Classes/Domain/Search/Filter/InvalidSearchFilterException.php @@ -0,0 +1,26 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +class InvalidSearchFilterException extends \InvalidArgumentException +{ +} diff --git a/Classes/Domain/Search/Filter/SearchFilterInterface.php b/Classes/Domain/Search/Filter/SearchFilterInterface.php new file mode 100644 index 0000000..fa781d6 --- /dev/null +++ b/Classes/Domain/Search/Filter/SearchFilterInterface.php @@ -0,0 +1,33 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +interface SearchFilterInterface +{ + /** + * @param array $query + * @param array $config + * @param mixed $value + * @return array Adjusted $query + */ + public function add(array $query, array $config, $value): array; +} diff --git a/Classes/Domain/Search/QueryFactory.php b/Classes/Domain/Search/QueryFactory.php index 66eaf16..0c0969f 100644 --- a/Classes/Domain/Search/QueryFactory.php +++ b/Classes/Domain/Search/QueryFactory.php @@ -25,8 +25,12 @@ use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; use Codappix\SearchCore\Configuration\ConfigurationUtility; use Codappix\SearchCore\Configuration\InvalidArgumentException; use Codappix\SearchCore\Connection\SearchRequestInterface; +use Codappix\SearchCore\Domain\Search\Filter\InvalidSearchFilterException; +use Codappix\SearchCore\Domain\Search\Filter\SearchFilterInterface; use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Object\ObjectManagerInterface; +use TYPO3\CMS\Extbase\Utility\DebuggerUtility; class QueryFactory { @@ -45,14 +49,21 @@ class QueryFactory */ protected $configurationUtility; + /** + * @var ObjectManagerInterface + */ + protected $objectManager; + public function __construct( \TYPO3\CMS\Core\Log\LogManager $logManager, ConfigurationContainerInterface $configuration, - ConfigurationUtility $configurationUtility + ConfigurationUtility $configurationUtility, + ObjectManagerInterface $objectManager ) { $this->logger = $logManager->getLogger(__CLASS__); $this->configuration = $configuration; $this->configurationUtility = $configurationUtility; + $this->objectManager = $objectManager; } /** @@ -231,50 +242,50 @@ class QueryFactory protected function addFilter(string $name, $value, array $config, array &$query): array { - if (!empty($config)) { - if ($config['type'] && $config['type'] === 'user') { - if (!isset($config['userFunc'])) { - throw new MissingAttributeException('No userFunc configured for filter type: user', 1539876182018); - } - - $parameters = [ - 'config' => $config, - 'value' => $value, - 'query' => &$query, - ]; - GeneralUtility::callUserFunction($config['userFunc'], $parameters, $this); - } else { - $filter = []; - if (isset($config['fields'])) { - foreach ($config['fields'] as $elasticField => $inputField) { - $filter[$elasticField] = $value[$inputField]; - } - } - - if (isset($config['raw'])) { - $filter = array_merge($config['raw'], $filter); - } - - if ($config['type'] === 'range') { - $query['query']['bool']['filter'][] = [ - 'range' => [ - $config['field'] => $filter - ] - ]; - } else { - $query['query']['bool']['filter'][] = [ - $config['field'] => $filter - ]; - } - } - } else { + if (empty($config)) { + // Fallback on default term query when no added configuration $query['query']['bool']['filter'][] = [ 'term' => [ $name => $value ] ]; + return $query; } + if ($config['custom'] && $config['type'] === 'custom') { + $customFilter = $this->objectManager->get($config['custom']); + if (!($customFilter instanceof SearchFilterInterface)) { + throw new InvalidSearchFilterException( + 'Custom filter (' . $config['custom'] . ') not instance of SearchFilterInterface', + 1539876182018 + ); + } + + return $customFilter->add($query, $config, $value); + } + + $filter = []; + if (isset($config['fields'])) { + foreach ($config['fields'] as $elasticField => $inputField) { + $filter[$elasticField] = $value[$inputField]; + } + } + + if (isset($config['raw'])) { + $filter = array_merge($config['raw'], $filter); + } + + if ($config['type'] === 'range') { + $query['query']['bool']['filter'][] = [ + 'range' => [ + $config['field'] => $filter + ] + ]; + } else { + $query['query']['bool']['filter'][] = [ + $config['field'] => $filter + ]; + } return $query; } diff --git a/Configuration/TypoScript/setup.typoscript b/Configuration/TypoScript/setup.typoscript index 981d033..671a071 100644 --- a/Configuration/TypoScript/setup.typoscript +++ b/Configuration/TypoScript/setup.typoscript @@ -47,8 +47,8 @@ plugin.tx_searchcore { mapping { filter { frontendUserAccess { - type = user - userFunc = Codappix\SearchCore\Hook\Filter\FrontendUserAccessFilter->generate + type = custom + custom = Codappix\SearchCore\Domain\Search\Filter\FrontendUserAccessFilter } } } diff --git a/Documentation/source/changelog/20181028-user-access-indexed.rst b/Documentation/source/changelog/20181028-user-access-indexed.rst index 966dacb..2456e1a 100644 --- a/Documentation/source/changelog/20181028-user-access-indexed.rst +++ b/Documentation/source/changelog/20181028-user-access-indexed.rst @@ -1,5 +1,5 @@ Feature "Added frontend user authentication access" -=============================================================== +=================================================== Indexation added based on page access via ``fe_group`` and inherited from ```extendToSubpages```. @@ -7,8 +7,8 @@ from ```extendToSubpages```. The searching is added via typoscript using the UserFunc filter:: frontendUserAccess { - type = user - userFunc = Codappix\SearchCore\Hook\Filter\FrontendUserAccessFilter->generate + type = custom + custom = Codappix\SearchCore\Domain\Search\Filter\FrontendUserAccessFilter } To bypass this filter simply unset default filter in searching.filter diff --git a/Documentation/source/changelog/20181030-custom-class-filter.rst b/Documentation/source/changelog/20181030-custom-class-filter.rst new file mode 100644 index 0000000..07a305d --- /dev/null +++ b/Documentation/source/changelog/20181030-custom-class-filter.rst @@ -0,0 +1,29 @@ +Feature "Manipulate search filter" +================================== + +You can manipulate the filter via a custom class through the ``custom`` type typoscript +mapping.:: + + plugin.tx_searchcore.settings.searching { + mapping { + filter { + frontendUserAccess { + type = custom + custom = Codappix\SearchCore\Domain\Search\Filter\FrontendUserAccessFilter + } + } + } + } + +If you want to force this filter on searching make sure to define them as default filters like::: + + plugin.tx_searchcore.settings.searching { + filter { + frontendUserAccess = search_access + } + } + +Example +------- +See ``Codappix\SearchCore\Domain\Search\Filter\FrontendUserAccessFilter`` as example. +