diff --git a/Classes/DataProcessing/GeoPointProcessing.php b/Classes/DataProcessing/GeoPointProcessing.php new file mode 100644 index 0000000..cbf6589 --- /dev/null +++ b/Classes/DataProcessing/GeoPointProcessing.php @@ -0,0 +1,34 @@ + + * + * 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 GeoPointProcessing implements ProcessorInterface +{ + public function processRecord(array $record, array $configuration) : array + { + $record[$configuration['to']] = [ + 'lat' => (float) $record[$configuration['fields']['lat']], + 'lon' => (float) $record[$configuration['fields']['lon']], + ]; + + return $record; + } +} diff --git a/Classes/DataProcessing/ProcessorInterface.php b/Classes/DataProcessing/ProcessorInterface.php new file mode 100644 index 0000000..4dc0794 --- /dev/null +++ b/Classes/DataProcessing/ProcessorInterface.php @@ -0,0 +1,34 @@ + + * + * 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. + */ + +/** + * All DataProcessing Processors should implement this interface, otherwise they + * will not be executed. + */ +interface ProcessorInterface +{ + /** + * Processes the given record. + * Also retrieves the configuration for this processor instance. + */ + public function processRecord(array $record, array $configuration) : array; +} diff --git a/Classes/Domain/Index/TcaIndexer/TcaTableService.php b/Classes/Domain/Index/TcaIndexer/TcaTableService.php index dae86aa..6b9024f 100644 --- a/Classes/Domain/Index/TcaIndexer/TcaTableService.php +++ b/Classes/Domain/Index/TcaIndexer/TcaTableService.php @@ -21,6 +21,7 @@ namespace Codappix\SearchCore\Domain\Index\TcaIndexer; */ use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; +use Codappix\SearchCore\DataProcessing\ProcessorInterface; use Codappix\SearchCore\Database\Doctrine\Join; use Codappix\SearchCore\Database\Doctrine\Where; use Codappix\SearchCore\Domain\Index\IndexingException; @@ -146,6 +147,17 @@ class TcaTableService { $this->relationResolver->resolveRelationsForRecord($this, $record); + try { + foreach ($this->configuration->get('indexing.' . $this->tableName . '.dataProcessing') as $configuration) { + $dataProcessor = GeneralUtility::makeInstance($configuration['_typoScriptNodeValue']); + if ($dataProcessor instanceof ProcessorInterface) { + $record = $dataProcessor->processRecord($record, $configuration); + } + } + } catch (InvalidConfigurationArgumentException $e) { + // Nothing to do. + } + if (isset($record['uid']) && !isset($record['search_identifier'])) { $record['search_identifier'] = $record['uid']; } @@ -181,7 +193,7 @@ class TcaTableService array_filter( array_keys($this->tca['columns']), function ($columnName) { - return !$this->isSystemField($columnName); + return !$this->isSystemField($columnName) && !$this->isUserField($columnName); } ) ); @@ -249,6 +261,12 @@ class TcaTableService return in_array($columnName, $systemFields); } + protected function isUserField(string $columnName) : bool + { + $config = $this->getColumnConfig($columnName); + return isset($config['type']) && $config['type'] === 'user'; + } + /** * @param string $columnName * @return array diff --git a/Classes/Domain/Model/SearchRequest.php b/Classes/Domain/Model/SearchRequest.php index 39e477c..fd76062 100644 --- a/Classes/Domain/Model/SearchRequest.php +++ b/Classes/Domain/Model/SearchRequest.php @@ -92,7 +92,22 @@ class SearchRequest implements SearchRequestInterface */ public function setFilter(array $filter) { - $this->filter = array_filter(array_map('strval', $filter)); + $this->filter = array_filter($filter); + + $this->mapGeoDistanceFilter(); + } + + public function mapGeoDistanceFilter() + { + if (isset($this->filter['geo_distance'])) { + foreach (array_keys($this->filter['geo_distance']) as $config) { + if (strpos($config, '_') !== false) { + $newKey = str_replace('_', '.', $config); + $this->filter['geo_distance'][$newKey] = $this->filter['geo_distance'][$config]; + unset($this->filter['geo_distance'][$config]); + } + } + } } /** diff --git a/Classes/Domain/Search/QueryFactory.php b/Classes/Domain/Search/QueryFactory.php index 9455f80..9f2f68a 100644 --- a/Classes/Domain/Search/QueryFactory.php +++ b/Classes/Domain/Search/QueryFactory.php @@ -164,6 +164,17 @@ class QueryFactory */ protected function addFactorBoost(array &$query) { + $query['sort'] = [ + '_geo_distance' => [ + 'location' => [ + 'lat' => 51.2014392, + 'lon' => 6.4302962, + ], + 'order' => 'asc', + 'unit' => 'km', + 'distance_type' => 'plane', + ] + ]; try { $query['query'] = [ 'function_score' => [ @@ -186,24 +197,33 @@ class QueryFactory return; } - $terms = []; + $filter = []; foreach ($searchRequest->getFilter() as $name => $value) { - $terms[] = [ - 'term' => [ - $name => $value, - ], - ]; + $filter[] = $this->buildFilter($name, $value); } $query = ArrayUtility::arrayMergeRecursiveOverrule($query, [ 'query' => [ 'bool' => [ - 'filter' => $terms, + 'filter' => $filter, ], ], ]); } + protected function buildFilter(string $name, $value) : array + { + if ($name === 'geo_distance') { + return [$name => $value]; + } + + return [ + 'term' => [ + $name => $value, + ], + ]; + } + /** * @param SearchRequestInterface $searchRequest * @param array $query