Skip to content
Snippets Groups Projects
Commit 835f253a authored by Dorian Merz's avatar Dorian Merz Committed by Robert Lange
Browse files

refs #17528 [master] refactor MungerInjection

* can now apply more than one type of pre munge
* works for other query handlers now
* TODO: adapt running instances
parent 97644d12
No related merge requests found
...@@ -98,11 +98,6 @@ retain_filters_by_default = true ...@@ -98,11 +98,6 @@ retain_filters_by_default = true
;default_filters[] = "institution:MyInstitution" ;default_filters[] = "institution:MyInstitution"
;default_filters[] = "(format:Book AND institution:MyInstitution)" ;default_filters[] = "(format:Book AND institution:MyInstitution)"
; the escaped_colon_searches is used by a listener on the search-pre event
; registered by the MungerInjectionFactory. This listener masks colons in the query string with a backslash
; whenever the search handler is one of the following
escaped_colon_searches[] = "Signatur"
[Cache] [Cache]
; This controls whether the parsed searchspecs.yaml file will be stored to ; This controls whether the parsed searchspecs.yaml file will be stored to
; improve search performance; legal options are APC (use APC cache), File (store ; improve search performance; legal options are APC (use APC cache), File (store
...@@ -677,3 +672,13 @@ height = 320 ...@@ -677,3 +672,13 @@ height = 320
;params = "qf=title,title_short,callnumber-label,topic,language,author,publishDate mintf=1 mindf=1"; ;params = "qf=title,title_short,callnumber-label,topic,language,author,publishDate mintf=1 mindf=1";
; This setting can be used to limit the maximum number of suggestions. Default is 5. ; This setting can be used to limit the maximum number of suggestions. Default is 5.
;count = 5 ;count = 5
; PreMunge is used by a listener on the search-pre event
; registered by the MungerInjectionDelegatorFactory. This listener applies
; the regex patterns as configured for the search handlers
; use the following configuration to define pattern and replacement as used in @see preg_replace
; Handler[pattern] = regex_pattern with delimiters (e.g. slashes at beginning and end)
; Handler[replace] = replacement
[PreMunge]
Signatur[pattern] = '/(?<=\:)\s/'
Signatur[replace] = '\ '
\ No newline at end of file
...@@ -56,9 +56,9 @@ class MungerInjectionDelegatorFactory implements DelegatorFactoryInterface ...@@ -56,9 +56,9 @@ class MungerInjectionDelegatorFactory implements DelegatorFactoryInterface
protected $instance; protected $instance;
/** /**
* @var array names of search handlers for which colons should be escaped * @var array configuration for pre-search munging
*/ */
protected $searches_to_escape; protected $preMungerConfig;
/** /**
* @var array shard configuration to register in all queries * @var array shard configuration to register in all queries
...@@ -86,16 +86,14 @@ class MungerInjectionDelegatorFactory implements DelegatorFactoryInterface ...@@ -86,16 +86,14 @@ class MungerInjectionDelegatorFactory implements DelegatorFactoryInterface
$searchConfig = $container->get('VuFind\Config')->get('searches'); $searchConfig = $container->get('VuFind\Config')->get('searches');
$e = $instance->getEventManager()->getSharedManager(); $e = $instance->getEventManager()->getSharedManager();
$handlers = $searchConfig->General->escaped_colon_searches; if ($this->validateMungerConfig($searchConfig)) {
if (!empty($handlers)) {
$this->searches_to_escape = $handlers->toArray();
$e->attach( $e->attach(
'VuFindSearch', 'VuFindSearch',
'pre', 'pre',
function (EventInterface $event) { function (EventInterface $event) {
$params = $event->getParams(); $params = $event->getParams();
if (isset($params['query'])) { if (isset($params['query'])) {
$params['query'] = $this->escapeColons($params['query']); $params['query'] = $this->preMunge($params['query']);
} }
} }
); );
...@@ -120,26 +118,53 @@ class MungerInjectionDelegatorFactory implements DelegatorFactoryInterface ...@@ -120,26 +118,53 @@ class MungerInjectionDelegatorFactory implements DelegatorFactoryInterface
* *
* @return mixed * @return mixed
*/ */
private function escapeColons($queryOrGroup) private function preMunge($queryOrGroup)
{ {
if ($queryOrGroup instanceof QueryGroup) { if ($queryOrGroup instanceof QueryGroup) {
$handler = $queryOrGroup->getReducedHandler(); $handler = $queryOrGroup->getReducedHandler();
if (is_null($handler) || in_array($handler, $this->searches_to_escape)) { if (is_null($handler) || isset($this->preMungerConfig[$handler])) {
foreach ($queryOrGroup->getQueries() as $query) { foreach ($queryOrGroup->getQueries() as $query) {
$this->escapeColons($query); $this->preMunge($query);
} }
} }
} elseif (in_array($queryOrGroup->getHandler(), $this->searches_to_escape)) { } elseif ($mungerConfig = $this->preMungerConfig[$queryOrGroup->getHandler()] ?? null) {
$queryOrGroup->setString( $queryOrGroup->setString(
// mask whitespaces that follow a colon // apply preg_replace as provided by config
// that avoids the removal of that very colon via preg_replace($mungerConfig['pattern'], $mungerConfig['replace'], $queryOrGroup->getString())
// \VuFindSearch\Backend\Solr\LuceneSyntaxHelper::normalizeColons
preg_replace('/(?<=\:)\s/', '\ ', $queryOrGroup->getString())
); );
} }
return $queryOrGroup; return $queryOrGroup;
} }
/**
* @param Config $searchConfig
*/
protected function validateMungerConfig($searchConfig) {
$config = $searchConfig->PreMunge;
if (empty($config)) {
// an empty configuration is always valid
return null;
}
$preMungerConfig = $config->toArray();
foreach ($preMungerConfig as $handler => $handlerConfig) {
if (!isset($handlerConfig['pattern'])
||
!isset($handlerConfig['replace'])
) {
throw new \ConfigurationException("PreMunge configuration for $handler is invalid");
}
try {
// try preg_replace so the regex engine tells us about more errors
preg_replace($handlerConfig['pattern'], $handlerConfig['replace'], '');
} catch (\ErrorException $e) {
throw new \ConfigurationException("PreMunge configuration for $handler is invalid. Regex error: ".'"'.$e->getMessage().'"');
}
}
$this->preMungerConfig = $preMungerConfig;
return true;
}
/** /**
* Event Listener on Search/Pre that registers all configured shards for every * Event Listener on Search/Pre that registers all configured shards for every
* search request * search request
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment