[TASK] Use filter interface for custom added filter

This commit is contained in:
Benjamin Serfhos 2018-10-30 09:50:26 +01:00
parent 3a2c700ff1
commit ee1f235c2e
7 changed files with 154 additions and 53 deletions

View file

@ -1,6 +1,6 @@
<?php
namespace Codappix\SearchCore\Hook\Filter;
namespace Codappix\SearchCore\Domain\Search\Filter;
/*
* Copyright (C) 2018 Benjamin Serfhos <benjamin@serfhos.com>
@ -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();

View file

@ -0,0 +1,26 @@
<?php
namespace Codappix\SearchCore\Domain\Search\Filter;
/*
* Copyright (C) 2018 Benjamin Serfhos <benjamin@serfhos.com>
*
* 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
{
}

View file

@ -0,0 +1,33 @@
<?php
namespace Codappix\SearchCore\Domain\Search\Filter;
/*
* Copyright (C) 2018 Benjamin Serfhos <benjamin@serfhos.com>
*
* 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;
}

View file

@ -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;
}

View file

@ -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
}
}
}

View file

@ -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

View file

@ -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.