From a332bffc2595293ecd57b77cc5eef708d47702e0 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 13 Jul 2021 12:11:47 +0200 Subject: [PATCH] Add synonym feature for date search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow configuration of synonyms via TypoScript. This is taken into account when searching dates via submitted demand. The configuration looks like the following: plugin.tx_events { settings { synonyms { 10 { word = Stadtführung synonyms = Tour, Stadtführungen, Führung } } } } The 10, 11, … is necessary as umlauts won't work as keys. So `synonyms.Stadtführung = Tour, Stadtführungen` will not work. Relates: #9158 --- Classes/Controller/DateController.php | 2 + Classes/Domain/Model/Dto/DateDemand.php | 44 ++++++++++++++++++++ Classes/Domain/Repository/DateRepository.php | 35 ++++++++++++---- 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/Classes/Controller/DateController.php b/Classes/Controller/DateController.php index 7b5d5f1..a44d68a 100644 --- a/Classes/Controller/DateController.php +++ b/Classes/Controller/DateController.php @@ -161,6 +161,8 @@ class DateController extends ActionController if ($this->request->hasArgument('searchword') && $this->request->getArgument('searchword') != '') $demand->setSearchword((string)$this->request->getArgument('searchword')); + $demand->setSynonyms($this->settings['synonyms'] ?? []); + if ($this->request->hasArgument('start') && $this->request->getArgument('start') != '') $demand->setStart(strtotime($this->request->getArgument('start') . ' 00:00')); diff --git a/Classes/Domain/Model/Dto/DateDemand.php b/Classes/Domain/Model/Dto/DateDemand.php index a1c3087..66152bd 100644 --- a/Classes/Domain/Model/Dto/DateDemand.php +++ b/Classes/Domain/Model/Dto/DateDemand.php @@ -2,6 +2,8 @@ namespace Wrm\Events\Domain\Model\Dto; +use TYPO3\CMS\Core\Utility\GeneralUtility; + class DateDemand { /** @@ -59,6 +61,15 @@ class DateDemand { */ protected $searchword = ''; + /** + * @var array + * + * Synonym1 => ['word1', 'word2', …], + * Synonym2 => ['word3', 'word4', …], + * … + */ + protected $synonyms = []; + /** * @var bool */ @@ -208,6 +219,39 @@ class DateDemand { $this->searchword = $searchword; } + /** + * @param array $synonyms + * [ + * [ + * 'word' => 'Word1', + * 'synonyms' => 'synonym1, synonym2', + * ], + * [ + * 'word' => 'Word2', + * 'synonyms' => 'synonym3, synonym4', + * ], + * … + * ] + */ + public function setSynonyms(array $synonyms): void + { + $this->synonyms = []; + foreach ($synonyms as $config) { + $synonymsForWord = GeneralUtility::trimExplode(',', $config['synonyms'], true); + foreach ($synonymsForWord as $synonym) { + $synonym = mb_strtolower($synonym); + $this->synonyms[$synonym][] = $config['word']; + $this->synonyms[$synonym] = array_unique($this->synonyms[$synonym]); + } + } + } + + public function getSynonymsForSearchword(): array + { + $searchWord = mb_strtolower($this->getSearchword()); + return $this->synonyms[$searchWord] ?? []; + } + /** * @return string */ diff --git a/Classes/Domain/Repository/DateRepository.php b/Classes/Domain/Repository/DateRepository.php index be63ddb..efb192d 100644 --- a/Classes/Domain/Repository/DateRepository.php +++ b/Classes/Domain/Repository/DateRepository.php @@ -1,6 +1,7 @@ getSearchword() !== '') { - $constraints['searchword'] = $query->logicalOr( - [ - $query->like('event.title', '%' . $demand->getSearchword() . '%'), - $query->like('event.teaser', '%' . $demand->getSearchword() . '%') - ] - ); + $constraints['searchword'] = $this->getSearchwordConstraint($query, $demand); } if ($demand->getStart() !== '' && $demand->getEnd() != '') { @@ -103,6 +99,31 @@ class DateRepository extends \TYPO3\CMS\Extbase\Persistence\Repository return $query; } + private function getSearchwordConstraint( + QueryInterface $query, + DateDemand $demand + ): ConstraintInterface { + $fieldsToSearch = [ + 'event.title', + 'event.teaser', + ]; + + $wordsToSearch = $demand->getSynonymsForSearchword(); + $wordsToSearch[] = $demand->getSearchword(); + $constraints = []; + + $queryBuilder = $this->objectManager->get(ConnectionPool::class) + ->getQueryBuilderForTable('tx_events_domain_model_date'); + + foreach ($wordsToSearch as $word) { + foreach ($fieldsToSearch as $field) { + $constraints[] = $query->like($field, '%' . $queryBuilder->escapeLikeWildcards($word) . '%'); + } + } + + return $query->logicalOr($constraints); + } + /** * @param QueryInterface $query * @param string $categories @@ -157,4 +178,4 @@ class DateRepository extends \TYPO3\CMS\Extbase\Persistence\Repository return $statement->execute()->fetchAll(); } -} \ No newline at end of file +}