Add synonym feature for date search

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
This commit is contained in:
Daniel Siepmann 2021-07-13 12:11:47 +02:00
parent 77a10e7083
commit a332bffc25
3 changed files with 74 additions and 7 deletions

View file

@ -161,6 +161,8 @@ class DateController extends ActionController
if ($this->request->hasArgument('searchword') && $this->request->getArgument('searchword') != '') if ($this->request->hasArgument('searchword') && $this->request->getArgument('searchword') != '')
$demand->setSearchword((string)$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') != '') if ($this->request->hasArgument('start') && $this->request->getArgument('start') != '')
$demand->setStart(strtotime($this->request->getArgument('start') . ' 00:00')); $demand->setStart(strtotime($this->request->getArgument('start') . ' 00:00'));

View file

@ -2,6 +2,8 @@
namespace Wrm\Events\Domain\Model\Dto; namespace Wrm\Events\Domain\Model\Dto;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class DateDemand { class DateDemand {
/** /**
@ -59,6 +61,15 @@ class DateDemand {
*/ */
protected $searchword = ''; protected $searchword = '';
/**
* @var array
*
* Synonym1 => ['word1', 'word2', ],
* Synonym2 => ['word3', 'word4', ],
*
*/
protected $synonyms = [];
/** /**
* @var bool * @var bool
*/ */
@ -208,6 +219,39 @@ class DateDemand {
$this->searchword = $searchword; $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 * @return string
*/ */

View file

@ -1,6 +1,7 @@
<?php <?php
namespace Wrm\Events\Domain\Repository; namespace Wrm\Events\Domain\Repository;
use TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface;
use Wrm\Events\Domain\Model\Dto\DateDemand; use Wrm\Events\Domain\Model\Dto\DateDemand;
use Wrm\Events\Service\CategoryService; use Wrm\Events\Service\CategoryService;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
@ -70,12 +71,7 @@ class DateRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
} }
if ($demand->getSearchword() !== '') { if ($demand->getSearchword() !== '') {
$constraints['searchword'] = $query->logicalOr( $constraints['searchword'] = $this->getSearchwordConstraint($query, $demand);
[
$query->like('event.title', '%' . $demand->getSearchword() . '%'),
$query->like('event.teaser', '%' . $demand->getSearchword() . '%')
]
);
} }
if ($demand->getStart() !== '' && $demand->getEnd() != '') { if ($demand->getStart() !== '' && $demand->getEnd() != '') {
@ -103,6 +99,31 @@ class DateRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
return $query; 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 QueryInterface $query
* @param string $categories * @param string $categories