2026-02-13T02:30:55+03:00 DEBUG: VuFindSearch\Backend\Solr\Connector: Query fl=%2A%2Cscore&spellcheck=false&facet=true&facet.limit=51&facet.field=&facet.sort=count&facet.mincount=1&hl=false&fq=-merged_boolean%3Atrue&wt=json&json.nl=arrarr&rows=0&start=0&qf=title_short%5E750+title_full_unstemmed%5E600+title_full%5E400+title%5E500+title_alt%5E200+title_new%5E100+series%5E50+series2%5E30+author%5E300+contents%5E10+topic_unstemmed%5E550+topic%5E500+geographic%5E300+genre%5E300+allfields_unstemmed%5E10+fulltext_unstemmed%5E10+allfields+fulltext+description+isbn+issn+long_lat_display&qt=edismax&mm=0%25&q=%2A%3A%2A
2026-02-13T02:30:55+03:00 DEBUG: VuFindSearch\Backend\Solr\Connector: => GET http://localhost:8983/solr/biblio/select?fl=%2A%2Cscore&spellcheck=false&facet=true&facet.limit=51&facet.field=&facet.sort=count&facet.mincount=1&hl=false&fq=-merged_boolean%3Atrue&wt=json&json.nl=arrarr&rows=0&start=0&qf=title_short%5E750+title_full_unstemmed%5E600+title_full%5E400+title%5E500+title_alt%5E200+title_new%5E100+series%5E50+series2%5E30+author%5E300+contents%5E10+topic_unstemmed%5E550+topic%5E500+geographic%5E300+genre%5E300+allfields_unstemmed%5E10+fulltext_unstemmed%5E10+allfields+fulltext+description+isbn+issn+long_lat_display&qt=edismax&mm=0%25&q=%2A%3A%2A
2026-02-13T02:30:55+03:00 DEBUG: VuFindSearch\Backend\Solr\Connector: <= 400 Bad Request
2026-02-13T02:30:55+03:00 CRIT: VuFindSearch\Backend\Exception\RequestErrorException : 400 Bad Request undefined field: ""
Server Context:
Array
(
    [REDIRECT_SCRIPT_URL] => /Search/FacetList
    [REDIRECT_SCRIPT_URI] => http://research.kwaretech.com/Search/FacetList
    [REDIRECT_VUFIND_ENV] => development
    [REDIRECT_VUFIND_LOCAL_DIR] => /usr/local/vufind/local
    [REDIRECT_STATUS] => 200
    [SCRIPT_URL] => /Search/FacetList
    [SCRIPT_URI] => http://research.kwaretech.com/Search/FacetList
    [VUFIND_ENV] => development
    [VUFIND_LOCAL_DIR] => /usr/local/vufind/local
    [HTTP_HOST] => research.kwaretech.com
    [HTTP_ACCEPT] => */*
    [HTTP_USER_AGENT] => Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
    [HTTP_COOKIE] => VUFIND_SESSION=gb47skhpp18v409ics8ikuv21k; VUFIND_SESSION_KEY=XXuPfuFqj8O%2BCou8Mqd%2FlnpJ0yED5eg%2BedMGKmZJSE3G5IAA9FoVUOSHVnYBrNoAiXsJD%2FlQgJ%2B%2F8xX4L9YFYA%3D%3D; language=ar; ui=standard
    [HTTP_ACCEPT_ENCODING] => gzip, br, zstd, deflate
    [HTTP_X_FORWARDED_FOR] => 216.73.216.83
    [HTTP_X_FORWARDED_HOST] => research.kwaretech.com
    [HTTP_X_FORWARDED_SERVER] => research.kwaretech.com
    [HTTP_CONNECTION] => Keep-Alive
    [PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    [SERVER_SIGNATURE] => 
Apache/2.4.52 (Ubuntu) Server at research.kwaretech.com Port 80
[SERVER_SOFTWARE] => Apache/2.4.52 (Ubuntu) [SERVER_NAME] => research.kwaretech.com [SERVER_ADDR] => 172.19.0.6 [SERVER_PORT] => 80 [REMOTE_ADDR] => 172.19.0.1 [DOCUMENT_ROOT] => /usr/local/vufind/public [REQUEST_SCHEME] => http [CONTEXT_PREFIX] => [CONTEXT_DOCUMENT_ROOT] => /usr/local/vufind/public [SERVER_ADMIN] => [no address given] [SCRIPT_FILENAME] => /usr/local/vufind/public/index.php [REMOTE_PORT] => 46378 [REDIRECT_URL] => /Search/FacetList [GATEWAY_INTERFACE] => CGI/1.1 [SERVER_PROTOCOL] => HTTP/1.1 [REQUEST_METHOD] => GET [QUERY_STRING] => [REQUEST_URI] => /Search/FacetList [SCRIPT_NAME] => /index.php [PHP_SELF] => /index.php [REQUEST_TIME_FLOAT] => 1770939055.0225 [REQUEST_TIME] => 1770939055 ) Backtrace: /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php line 446 - class = VuFindSearch\Backend\Solr\Connector, function = send, args: none. /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php line 330 - class = VuFindSearch\Backend\Solr\Connector, function = trySolrUrls, args: none. /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php line 254 - class = VuFindSearch\Backend\Solr\Connector, function = query, args: none. /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Backend.php line 170 - class = VuFindSearch\Backend\Solr\Connector, function = search, args: none. /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Backend.php line 141 - class = VuFindSearch\Backend\Solr\Backend, function = rawJsonSearch, args: none. unlisted file line unlisted - class = VuFindSearch\Backend\Solr\Backend, function = search, args: none. /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Command/CallMethodCommand.php line 137 - function = call_user_func, args: none. /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Service.php line 106 - class = VuFindSearch\Command\CallMethodCommand, function = execute, args: none. /usr/local/vufind/module/VuFind/src/VuFind/Search/Solr/Results.php line 218 - class = VuFindSearch\Service, function = invoke, args: none. /usr/local/vufind/module/VuFind/src/VuFind/Search/Base/Results.php line 334 - class = VuFind\Search\Solr\Results, function = performSearch, args: none. /usr/local/vufind/module/VuFind/src/VuFind/Search/Solr/Results.php line 356 - class = VuFind\Search\Base\Results, function = performAndProcessSearch, args: none. /usr/local/vufind/module/VuFind/src/VuFind/Search/Solr/Results.php line 437 - class = VuFind\Search\Solr\Results, function = getFacetList, args: none. /usr/local/vufind/module/VuFind/src/VuFind/Controller/AbstractSearch.php line 921 - class = VuFind\Search\Solr\Results, function = getPartialFieldFacets, args: none. /usr/local/vufind/vendor/laminas/laminas-mvc/src/Controller/AbstractActionController.php line 72 - class = VuFind\Controller\AbstractSearch, function = facetListAction, args: none. /usr/local/vufind/vendor/laminas/laminas-eventmanager/src/EventManager.php line 318 - class = Laminas\Mvc\Controller\AbstractActionController, function = onDispatch, args: none. /usr/local/vufind/vendor/laminas/laminas-eventmanager/src/EventManager.php line 176 - class = Laminas\EventManager\EventManager, function = triggerListeners, args: none. /usr/local/vufind/vendor/laminas/laminas-mvc/src/Controller/AbstractController.php line 105 - class = Laminas\EventManager\EventManager, function = triggerEventUntil, args: none. /usr/local/vufind/vendor/laminas/laminas-mvc/src/DispatchListener.php line 117 - class = Laminas\Mvc\Controller\AbstractController, function = dispatch, args: none. /usr/local/vufind/vendor/laminas/laminas-eventmanager/src/EventManager.php line 318 - class = Laminas\Mvc\DispatchListener, function = onDispatch, args: none. /usr/local/vufind/vendor/laminas/laminas-eventmanager/src/EventManager.php line 176 - class = Laminas\EventManager\EventManager, function = triggerListeners, args: none. /usr/local/vufind/vendor/laminas/laminas-mvc/src/Application.php line 319 - class = Laminas\EventManager\EventManager, function = triggerEventUntil, args: none. /usr/local/vufind/public/index.php line 23 - class = Laminas\Mvc\Application, function = run, args: none.
Whoops! There was an error.
VuFindSearch \ Backend \ Exception \ RequestErrorException (400)
400 Bad Request undefined field: "" VuFindSearch\Backend\Exception\RequestErrorException thrown with message "400 Bad Request undefined field: """ Stacktrace: #22 VuFindSearch\Backend\Exception\RequestErrorException in /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php:515 #21 VuFindSearch\Backend\Solr\Connector:send in /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php:446 #20 VuFindSearch\Backend\Solr\Connector:trySolrUrls in /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php:330 #19 VuFindSearch\Backend\Solr\Connector:query in /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php:254 #18 VuFindSearch\Backend\Solr\Connector:search in /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Backend.php:170 #17 VuFindSearch\Backend\Solr\Backend:rawJsonSearch in /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Backend.php:141 #16 VuFindSearch\Backend\Solr\Backend:search in /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Command/CallMethodCommand.php:137 #15 call_user_func in /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Command/CallMethodCommand.php:137 #14 VuFindSearch\Command\CallMethodCommand:execute in /usr/local/vufind/module/VuFindSearch/src/VuFindSearch/Service.php:106 #13 VuFindSearch\Service:invoke in /usr/local/vufind/module/VuFind/src/VuFind/Search/Solr/Results.php:218 #12 VuFind\Search\Solr\Results:performSearch in /usr/local/vufind/module/VuFind/src/VuFind/Search/Base/Results.php:334 #11 VuFind\Search\Base\Results:performAndProcessSearch in /usr/local/vufind/module/VuFind/src/VuFind/Search/Solr/Results.php:356 #10 VuFind\Search\Solr\Results:getFacetList in /usr/local/vufind/module/VuFind/src/VuFind/Search/Solr/Results.php:437 #9 VuFind\Search\Solr\Results:getPartialFieldFacets in /usr/local/vufind/module/VuFind/src/VuFind/Controller/AbstractSearch.php:921 #8 VuFind\Controller\AbstractSearch:facetListAction in /usr/local/vufind/vendor/laminas/laminas-mvc/src/Controller/AbstractActionController.php:72 #7 Laminas\Mvc\Controller\AbstractActionController:onDispatch in /usr/local/vufind/vendor/laminas/laminas-eventmanager/src/EventManager.php:318 #6 Laminas\EventManager\EventManager:triggerListeners in /usr/local/vufind/vendor/laminas/laminas-eventmanager/src/EventManager.php:176 #5 Laminas\EventManager\EventManager:triggerEventUntil in /usr/local/vufind/vendor/laminas/laminas-mvc/src/Controller/AbstractController.php:105 #4 Laminas\Mvc\Controller\AbstractController:dispatch in /usr/local/vufind/vendor/laminas/laminas-mvc/src/DispatchListener.php:117 #3 Laminas\Mvc\DispatchListener:onDispatch in /usr/local/vufind/vendor/laminas/laminas-eventmanager/src/EventManager.php:318 #2 Laminas\EventManager\EventManager:triggerListeners in /usr/local/vufind/vendor/laminas/laminas-eventmanager/src/EventManager.php:176 #1 Laminas\EventManager\EventManager:triggerEventUntil in /usr/local/vufind/vendor/laminas/laminas-mvc/src/Application.php:319 #0 Laminas\Mvc\Application:run in /usr/local/vufind/public/index.php:23
22
VuFindSearch\Backend\Exception\RequestErrorException
/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php515
21
VuFindSearch\Backend\Solr\Connector send
/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php446
20
VuFindSearch\Backend\Solr\Connector trySolrUrls
/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php330
19
VuFindSearch\Backend\Solr\Connector query
/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php254
18
VuFindSearch\Backend\Solr\Connector search
/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Backend.php170
17
VuFindSearch\Backend\Solr\Backend rawJsonSearch
/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Backend.php141
16
VuFindSearch\Backend\Solr\Backend search
/module/VuFindSearch/src/VuFindSearch/Command/CallMethodCommand.php137
15
call_user_func
/module/VuFindSearch/src/VuFindSearch/Command/CallMethodCommand.php137
14
VuFindSearch\Command\CallMethodCommand execute
/module/VuFindSearch/src/VuFindSearch/Service.php106
13
VuFindSearch\Service invoke
/module/VuFind/src/VuFind/Search/Solr/Results.php218
12
VuFind\Search\Solr\Results performSearch
/module/VuFind/src/VuFind/Search/Base/Results.php334
11
VuFind\Search\Base\Results performAndProcessSearch
/module/VuFind/src/VuFind/Search/Solr/Results.php356
10
VuFind\Search\Solr\Results getFacetList
/module/VuFind/src/VuFind/Search/Solr/Results.php437
9
VuFind\Search\Solr\Results getPartialFieldFacets
/module/VuFind/src/VuFind/Controller/AbstractSearch.php921
8
VuFind\Controller\AbstractSearch facetListAction
/vendor/laminas/laminas-mvc/src/Controller/AbstractActionController.php72
7
Laminas\Mvc\Controller\AbstractActionController onDispatch
/vendor/laminas/laminas-eventmanager/src/EventManager.php318
6
Laminas\EventManager\EventManager triggerListeners
/vendor/laminas/laminas-eventmanager/src/EventManager.php176
5
Laminas\EventManager\EventManager triggerEventUntil
/vendor/laminas/laminas-mvc/src/Controller/AbstractController.php105
4
Laminas\Mvc\Controller\AbstractController dispatch
/vendor/laminas/laminas-mvc/src/DispatchListener.php117
3
Laminas\Mvc\DispatchListener onDispatch
/vendor/laminas/laminas-eventmanager/src/EventManager.php318
2
Laminas\EventManager\EventManager triggerListeners
/vendor/laminas/laminas-eventmanager/src/EventManager.php176
1
Laminas\EventManager\EventManager triggerEventUntil
/vendor/laminas/laminas-mvc/src/Application.php319
0
Laminas\Mvc\Application run
/public/index.php23
        $time     = microtime(true) - $time;
 
        $this->debug(
            sprintf(
                '<= %s %s',
                $response->getStatusCode(),
                $response->getReasonPhrase()
            ),
            ['time' => $time]
        );
 
        if (!$response->isSuccess()) {
            // Return a more detailed error message for a 400 error:
            if ($response->getStatusCode() === 400) {
                $json = json_decode($response->getBody(), true);
                $msgParts = ['400', $response->getReasonPhrase()];
                if ($msg = $json['error']['msg'] ?? '') {
                    $msgParts[] = $msg;
                }
                throw new RequestErrorException(
                    implode(' ', $msgParts),
                    400,
                    $response
                );
            }
            throw HttpErrorException::createFromResponse($response);
        }
        return $response->getBody();
    }
}
 
Arguments
  1. "400 Bad Request undefined field: """
    
        $exception = new \Exception('Unexpected exception.');
 
        // Loop through all base URLs and try them in turn until one works.
        $cacheKey = null;
        foreach ((array)$this->url as $base) {
            $client = ($this->clientFactory)($base . $urlSuffix);
            $client->setMethod($method);
            if (is_callable($callback)) {
                $callback($client);
            }
            // Always create the cache key from the first server, and only after any
            // callback has been called above.
            if ($cacheable && $this->cache && null === $cacheKey) {
                $cacheKey = $this->getCacheKey($client);
                if ($result = $this->getCachedData($cacheKey)) {
                    return $result;
                }
            }
            try {
                $result = $this->send($client);
                if ($cacheKey) {
                    $this->putCachedData($cacheKey, $result);
                }
                return $result;
            } catch (\Exception $ex) {
                if ($this->isRethrowableSolrException($ex)) {
                    throw $this->forceToBackendException($ex);
                }
                $exception = $ex;
            }
        }
 
        // If we got this far, everything failed -- throw a BackendException with
        // the most recent exception caught above set as the previous exception.
        throw $this->forceToBackendException($exception);
    }
 
    /**
     * Extract the Solr core from the connector's URL.
     *
     */
    public function query($handler, ParamBag $params, bool $cacheable = false)
    {
        $urlSuffix = '/' . $handler;
        $paramString = implode('&', $params->request());
        if (strlen($paramString) > self::MAX_GET_URL_LENGTH) {
            $method = Request::METHOD_POST;
            $callback = function ($client) use ($paramString) {
                $client->setRawBody($paramString);
                $client->setEncType(HttpClient::ENC_URLENCODED);
                $client->setHeaders(['Content-Length' => strlen($paramString)]);
            };
        } else {
            $method = Request::METHOD_GET;
            $urlSuffix .= '?' . $paramString;
            $callback = null;
        }
 
        $this->debug(sprintf('Query %s', $paramString));
        return $this->trySolrUrls($method, $urlSuffix, $callback, $cacheable);
    }
 
    /**
     * Call a method with provided options for the HTTP client
     *
     * @param array  $options HTTP client options
     * @param string $method  Method to call
     * @param array  ...$args Method parameters
     *
     * @return mixed
     */
    public function callWithHttpOptions(
        array $options,
        string $method,
        ...$args
    ) {
        $reflectionMethod = new \ReflectionMethod($this, $method);
        if (!$reflectionMethod->isPublic()) {
            throw new InvalidArgumentException("Method '$method' is not public");
        }
            // If Solr was unable to fetch the record, just act like we have no similar records:
            if (str_contains($e->getMessage(), 'Could not fetch document with id')) {
                return '{}';
            }
            throw $e;
        }
    }
 
    /**
     * Execute a search.
     *
     * @param ParamBag $params Parameters
     *
     * @return string
     */
    public function search(ParamBag $params)
    {
        $handler = $this->map->getHandler(__FUNCTION__);
        $this->map->prepare(__FUNCTION__, $params);
        return $this->query($handler, $params, true);
    }
 
    /**
     * Extract terms from a SOLR index.
     *
     * @param ParamBag $params Parameters
     *
     * @return string
     */
    public function terms(ParamBag $params)
    {
        $handler = $this->map->getHandler(__FUNCTION__);
        $this->map->prepare(__FUNCTION__, $params);
 
        return $this->query($handler, $params, true);
    }
 
    /**
     * Write to the SOLR index.
     *
     * @param AbstractQuery $query  Search query
     * @param int           $offset Search offset
     * @param int           $limit  Search limit
     * @param ParamBag      $params Search backend parameters
     *
     * @return string
     */
    public function rawJsonSearch(
        AbstractQuery $query,
        $offset,
        $limit,
        ParamBag $params = null
    ) {
        $params = $params ?: new ParamBag();
        $this->injectResponseWriter($params);
 
        $params->set('rows', $limit);
        $params->set('start', $offset);
        $params->mergeWith($this->getQueryBuilder()->build($query, $params));
        return $this->connector->search($params);
    }
 
    /**
     * Returns some extra details about the search.
     *
     * @return array
     */
    public function getExtraRequestDetails()
    {
        return [
            'solrRequestUrl' => $this->connector->getLastUrl(),
        ];
    }
 
    /**
     * Clears all accumulated extra request details
     *
     * @return void
     */
    public function resetExtraRequestDetails()
    /**
     * Perform a search and return record collection.
     *
     * @param AbstractQuery $query  Search query
     * @param int           $offset Search offset
     * @param int           $limit  Search limit
     * @param ParamBag      $params Search backend parameters
     *
     * @return RecordCollectionInterface
     */
    public function search(
        AbstractQuery $query,
        $offset,
        $limit,
        ParamBag $params = null
    ) {
        if ($query instanceof WorkKeysQuery) {
            return $this->workKeysSearch($query, $offset, $limit, $params);
        }
        $json = $this->rawJsonSearch($query, $offset, $limit, $params);
        $collection = $this->createRecordCollection($json);
        $this->injectSourceIdentifier($collection);
 
        return $collection;
    }
 
    /**
     * Perform a search and return a raw response.
     *
     * @param AbstractQuery $query  Search query
     * @param int           $offset Search offset
     * @param int           $limit  Search limit
     * @param ParamBag      $params Search backend parameters
     *
     * @return string
     */
    public function rawJsonSearch(
        AbstractQuery $query,
        $offset,
        $limit,
     *
     * @return CommandInterface Command instance for method chaining
     */
    public function execute(BackendInterface $backend): CommandInterface
    {
        $this->validateBackend($backend);
        if (
            !($backend instanceof $this->interface)
            || !method_exists($this->interface, $this->method)
        ) {
            throw new BackendException(
                "$this->backendId does not support $this->method()"
            );
        }
        $args = $this->getArguments();
        if ($backend instanceof ExtraRequestDetailsInterface) {
            $backend->resetExtraRequestDetails();
        }
        $this->finalizeExecution(
            call_user_func([$backend, $this->method], ...$args)
        );
        if ($backend instanceof ExtraRequestDetailsInterface) {
            $this->extraRequestDetails = $backend->getExtraRequestDetails();
        }
        return $this;
    }
}
 
     *
     * @return CommandInterface Command instance for method chaining
     */
    public function execute(BackendInterface $backend): CommandInterface
    {
        $this->validateBackend($backend);
        if (
            !($backend instanceof $this->interface)
            || !method_exists($this->interface, $this->method)
        ) {
            throw new BackendException(
                "$this->backendId does not support $this->method()"
            );
        }
        $args = $this->getArguments();
        if ($backend instanceof ExtraRequestDetailsInterface) {
            $backend->resetExtraRequestDetails();
        }
        $this->finalizeExecution(
            call_user_func([$backend, $this->method], ...$args)
        );
        if ($backend instanceof ExtraRequestDetailsInterface) {
            $this->extraRequestDetails = $backend->getExtraRequestDetails();
        }
        return $this;
    }
}
 
    }
 
    /**
     * Invoke a command.
     *
     * @param CommandInterface $command Command
     *
     * @return CommandInterface
     */
    public function invoke(CommandInterface $command)
    {
        // The backend instance is no longer added as an event parameter.
        // All other legacy event parameters are accessible via the command object.
        $args = ['command' => $command];
 
        $backend = $this->resolve($command->getTargetIdentifier(), $args);
 
        $this->triggerPre($this, $args);
        try {
            $command->execute($backend);
        } catch (BackendException $e) {
            $args['error'] = $e;
            $this->triggerError($this, $args);
            throw $e;
        }
        $this->triggerPost($this, $args);
 
        return $command;
    }
 
    /**
     * Resolve a backend.
     *
     * @param string            $backendId Backend name
     * @param array|ArrayAccess $args      Service function arguments
     *
     * @return BackendInterface
     *
     * @throws Exception\RuntimeException Unable to resolve backend
     */
        $params = $this->getParams()->getBackendParameters();
        $searchService = $this->getSearchService();
        $cursorMark = $this->getCursorMark();
        if (null !== $cursorMark) {
            $params->set('cursorMark', '' === $cursorMark ? '*' : $cursorMark);
            // Override any default timeAllowed since it cannot be used with
            // cursorMark
            $params->set('timeAllowed', -1);
        }
 
        try {
            $command = new SearchCommand(
                $this->backendId,
                $query,
                $offset,
                $limit,
                $params
            );
 
            $collection = $searchService->invoke($command)->getResult();
        } catch (\VuFindSearch\Backend\Exception\BackendException $e) {
            // If the query caused a parser error, see if we can clean it up:
            if (
                $e->hasTag(ErrorListener::TAG_PARSER_ERROR)
                && $newQuery = $this->fixBadQuery($query)
            ) {
                // We need to get a fresh set of $params, since the previous one was
                // manipulated by the previous search() call.
                $params = $this->getParams()->getBackendParameters();
                $command = new SearchCommand(
                    $this->backendId,
                    $newQuery,
                    $offset,
                    $limit,
                    $params
                );
                $collection = $searchService->invoke($command)->getResult();
            } else {
                throw $e;
            }
    }
 
    /**
     * Actually execute the search.
     *
     * @return void
     */
    public function performAndProcessSearch()
    {
        // Initialize variables to defaults (to ensure they don't stay null
        // and cause unnecessary repeat processing):
        // The value of -1 indicates that resultTotal is not available.
        $this->resultTotal = -1;
        $this->results = [];
        $this->suggestions = [];
        $this->errors = [];
 
        // Run the search:
        $this->startQueryTimer();
        $this->performSearch();
        $this->stopQueryTimer();
    }
 
    /**
     * Returns the stored list of facets for the last search
     *
     * @param array $filter Array of field => on-screen description listing
     * all of the desired facet fields; set to null to get all configured values.
     *
     * @return array        Facets data arrays
     */
    abstract public function getFacetList($filter = null);
 
    /**
     * Abstract support method for performAndProcessSearch -- perform a search based
     * on the parameters passed to the object. This method is responsible for
     * filling in all of the key class properties: results, resultTotal, etc.
     *
     * @return void
     */
    {
        return $this->getSpellingProcessor()->processSuggestions(
            $this->getRawSuggestions(),
            $this->spellingQuery,
            $this->getParams()
        );
    }
 
    /**
     * Returns the stored list of facets for the last search
     *
     * @param array $filter Array of field => on-screen description listing
     * all of the desired facet fields; set to null to get all configured values.
     *
     * @return array        Facets data arrays
     */
    public function getFacetList($filter = null)
    {
        if (null === $this->responseFacets) {
            $this->performAndProcessSearch();
        }
        return $this->buildFacetList($this->responseFacets, $filter);
    }
 
    /**
     * Get counts of facet values filtered out by the HideFacetValueListener,
     * indexed by field name.
     *
     * @return array
     */
    public function getFilteredFacetCounts(): array
    {
        if (null === $this->filteredFacetCounts) {
            $this->performAndProcessSearch();
        }
        return $this->filteredFacetCounts;
    }
 
    /**
     * Get complete facet counts for several index fields
            // Clear existing filters for the selected field if necessary:
            if ($removeFilter) {
                $params->removeAllFilters($facetName);
            }
        }
 
        // Don't waste time on spellcheck:
        $params->getOptions()->spellcheckEnabled(false);
 
        // Don't fetch any records:
        $params->setLimit(0);
 
        // Disable highlighting:
        $params->getOptions()->disableHighlighting();
 
        // Disable sort:
        $params->setSort('', true);
 
        // Do search
        $result = $clone->getFacetList();
        $filteredCounts = $clone->getFilteredFacetCounts();
 
        // Reformat into a hash:
        foreach ($result as $key => $value) {
            // Detect next page and crop results if necessary
            $more = false;
            if (
                isset($page) && count($value['list']) > 0
                && (count($value['list']) + ($filteredCounts[$key] ?? 0)) == $limit + 1
            ) {
                $more = true;
                array_pop($value['list']);
            }
            $result[$key] = ['more' => $more, 'data' => $value];
        }
 
        // Send back data:
        return $result;
    }
 
        if ($sort === null || !in_array($sort, array_keys($facetSortOptions))) {
            $sort = empty($facetSortOptions)
                ? 'count'
                : current(array_keys($facetSortOptions));
        }
        $config = $this->getService(\VuFind\Config\PluginManager::class)
            ->get($options->getFacetsIni());
        $limit = $config->Results_Settings->lightboxLimit ?? 50;
        $limit = $this->params()->fromQuery('facetlimit', $limit);
        if (!empty($contains)) {
            $params->setFacetContains($contains);
            $params->setFacetContainsIgnoreCase(true);
        }
        $facets = $results->getPartialFieldFacets(
            [$facet],
            false,
            $limit,
            $sort,
            $page,
            $this->params()->fromQuery('facetop', 'AND') == 'OR'
        );
        $list = $facets[$facet]['data']['list'] ?? [];
        $facetLabel = $params->getFacetLabel($facet);
 
        $viewParams = [
            'contains' => $contains,
            'data' => $list,
            'exclude' => intval($this->params()->fromQuery('facetexclude', 0)),
            'facet' => $facet,
            'facetLabel' => $facetLabel,
            'operator' => $this->params()->fromQuery('facetop', 'AND'),
            'page' => $page,
            'results' => $results,
            'anotherPage' => $facets[$facet]['more'] ?? '',
            'sort' => $sort,
            'sortOptions' => $facetSortOptions,
            'baseUriExtra' => $this->params()->fromQuery('baseUriExtra'),
            'active' => $sort,
            'key' => $sort,
            'urlBase' => $urlBase,
     */
    public function onDispatch(MvcEvent $e)
    {
        $routeMatch = $e->getRouteMatch();
        if (! $routeMatch) {
            /**
             * @todo Determine requirements for when route match is missing.
             *       Potentially allow pulling directly from request metadata?
             */
            throw new DomainException('Missing route matches; unsure how to retrieve action');
        }
 
        $action = $routeMatch->getParam('action', 'not-found');
        $method = static::getMethodFromAction($action);
 
        if (! method_exists($this, $method)) {
            $method = 'notFoundAction';
        }
 
        $actionResponse = $this->$method();
 
        $e->setResult($actionResponse);
 
        return $actionResponse;
    }
}
 
        }
 
        if ($this->sharedManager) {
            foreach ($this->sharedManager->getListeners($this->identifiers, $name) as $priority => $listeners) {
                $listOfListenersByPriority[$priority][] = $listeners;
            }
        }
 
        // Sort by priority in reverse order
        krsort($listOfListenersByPriority);
 
        // Initial value of stop propagation flag should be false
        $event->stopPropagation(false);
 
        // Execute listeners
        $responses = new ResponseCollection();
        foreach ($listOfListenersByPriority as $listOfListeners) {
            foreach ($listOfListeners as $listeners) {
                foreach ($listeners as $listener) {
                    $response = $listener($event);
                    $responses->push($response);
 
                    // If the event was asked to stop propagating, do so
                    if ($event->propagationIsStopped()) {
                        $responses->setStopped(true);
                        return $responses;
                    }
 
                    // If the result causes our validation callback to return true,
                    // stop propagation
                    if (is_callable($callback) && $callback($response)) {
                        $responses->setStopped(true);
                        return $responses;
                    }
                }
            }
        }
 
        return $responses;
    }
            $event->setParams($argv);
        }
 
        return $this->triggerListeners($event, $callback);
    }
 
    /**
     * @inheritDoc
     */
    public function triggerEvent(EventInterface $event)
    {
        return $this->triggerListeners($event);
    }
 
    /**
     * @inheritDoc
     */
    public function triggerEventUntil(callable $callback, EventInterface $event)
    {
        return $this->triggerListeners($event, $callback);
    }
 
    /**
     * @inheritDoc
     */
    public function attach($eventName, callable $listener, $priority = 1)
    {
        if (! is_string($eventName)) {
            throw new Exception\InvalidArgumentException(sprintf(
                '%s expects a string for the event; received %s',
                __METHOD__,
                get_debug_type($eventName),
            ));
        }
 
        $this->events[$eventName][(int) $priority][0][] = $listener;
        return $listener;
    }
 
    /**
     * @events dispatch.pre, dispatch.post
     * @param  Request $request
     * @param  null|Response $response
     * @return Response|mixed
     */
    public function dispatch(Request $request, ?Response $response = null)
    {
        $this->request = $request;
        if (! $response) {
            $response = new HttpResponse();
        }
        $this->response = $response;
 
        $e = $this->getEvent();
        $e->setName(MvcEvent::EVENT_DISPATCH);
        $e->setRequest($request);
        $e->setResponse($response);
        $e->setTarget($this);
 
        $result = $this->getEventManager()->triggerEventUntil(static fn($test): bool => $test instanceof Response, $e);
 
        if ($result->stopped()) {
            return $result->last();
        }
 
        return $e->getResult();
    }
 
    /**
     * Get request object
     *
     * @return Request
     */
    public function getRequest()
    {
        if (! $this->request) {
            $this->request = new HttpRequest();
        }
 
        return $this->request;
            );
            return $this->complete($return, $e);
        } catch (Throwable $exception) {
            $return = $this->marshalBadControllerEvent($controllerName, $e, $application, $exception);
            return $this->complete($return, $e);
        } catch (Exception $exception) {  // @TODO clean up once PHP 7 requirement is enforced
            $return = $this->marshalBadControllerEvent($controllerName, $e, $application, $exception);
            return $this->complete($return, $e);
        }
 
        if ($controller instanceof InjectApplicationEventInterface) {
            $controller->setEvent($e);
        }
 
        $request  = $e->getRequest();
        $response = $application->getResponse();
        $caughtException = null;
 
        try {
            $return = $controller->dispatch($request, $response);
        } catch (Throwable $ex) {
            $caughtException = $ex;
        } catch (Exception $ex) {  // @TODO clean up once PHP 7 requirement is enforced
            $caughtException = $ex;
        }
 
        if ($caughtException !== null) {
            $e->setName(MvcEvent::EVENT_DISPATCH_ERROR);
            $e->setError($application::ERROR_EXCEPTION);
            $e->setController($controllerName);
            $e->setControllerClass($controller::class);
            $e->setParam('exception', $caughtException);
 
            $return = $application->getEventManager()->triggerEvent($e)->last();
            if (! $return) {
                $return = $e->getResult();
            }
        }
 
        return $this->complete($return, $e);
        }
 
        if ($this->sharedManager) {
            foreach ($this->sharedManager->getListeners($this->identifiers, $name) as $priority => $listeners) {
                $listOfListenersByPriority[$priority][] = $listeners;
            }
        }
 
        // Sort by priority in reverse order
        krsort($listOfListenersByPriority);
 
        // Initial value of stop propagation flag should be false
        $event->stopPropagation(false);
 
        // Execute listeners
        $responses = new ResponseCollection();
        foreach ($listOfListenersByPriority as $listOfListeners) {
            foreach ($listOfListeners as $listeners) {
                foreach ($listeners as $listener) {
                    $response = $listener($event);
                    $responses->push($response);
 
                    // If the event was asked to stop propagating, do so
                    if ($event->propagationIsStopped()) {
                        $responses->setStopped(true);
                        return $responses;
                    }
 
                    // If the result causes our validation callback to return true,
                    // stop propagation
                    if (is_callable($callback) && $callback($response)) {
                        $responses->setStopped(true);
                        return $responses;
                    }
                }
            }
        }
 
        return $responses;
    }
            $event->setParams($argv);
        }
 
        return $this->triggerListeners($event, $callback);
    }
 
    /**
     * @inheritDoc
     */
    public function triggerEvent(EventInterface $event)
    {
        return $this->triggerListeners($event);
    }
 
    /**
     * @inheritDoc
     */
    public function triggerEventUntil(callable $callback, EventInterface $event)
    {
        return $this->triggerListeners($event, $callback);
    }
 
    /**
     * @inheritDoc
     */
    public function attach($eventName, callable $listener, $priority = 1)
    {
        if (! is_string($eventName)) {
            throw new Exception\InvalidArgumentException(sprintf(
                '%s expects a string for the event; received %s',
                __METHOD__,
                get_debug_type($eventName),
            ));
        }
 
        $this->events[$eventName][(int) $priority][0][] = $listener;
        return $listener;
    }
 
    /**
            $response = $result->last();
            if ($response instanceof ResponseInterface) {
                $event->setName(MvcEvent::EVENT_FINISH);
                $event->setTarget($this);
                $event->setResponse($response);
                $event->stopPropagation(false); // Clear before triggering
                $events->triggerEvent($event);
                $this->response = $response;
                return $this;
            }
        }
 
        if ($event->getError()) {
            return $this->completeRequest($event);
        }
 
        // Trigger dispatch event
        $event->setName(MvcEvent::EVENT_DISPATCH);
        $event->stopPropagation(false); // Clear before triggering
        $result = $events->triggerEventUntil($shortCircuit, $event);
 
        // Complete response
        $response = $result->last();
        if ($response instanceof ResponseInterface) {
            $event->setName(MvcEvent::EVENT_FINISH);
            $event->setTarget($this);
            $event->setResponse($response);
            $event->stopPropagation(false); // Clear before triggering
            $events->triggerEvent($event);
            $this->response = $response;
            return $this;
        }
 
        $response = $this->response;
        $event->setResponse($response);
        return $this->completeRequest($event);
    }
 
    /**
     * Complete the request
$vufindProfiler = getenv('VUFIND_PROFILER_XHPROF');
if (!empty($vufindProfiler)) {
    include __DIR__ . '/../module/VuFind/functions/profiler.php';
    enableVuFindProfiling($vufindProfiler);
}
 
// Run the application!
$app = include __DIR__ . '/../config/application.php';
if (PHP_SAPI === 'cli') {
    return $app->getServiceManager()
        ->get(\VuFindConsole\ConsoleRunner::class)->run();
} else {
    // Setup remote code coverage if enabled:
    if (getenv('VUFIND_CODE_COVERAGE')) {
        $modules = $app->getServiceManager()
            ->get(\Laminas\ModuleManager\ModuleManager::class)->getModules();
        include __DIR__ . '/../module/VuFind/functions/codecoverage.php';
        setupVuFindRemoteCodeCoverage($modules);
    }
    $app->run();
}
 

Environment & details:

empty
empty
empty
Key Value
VUFIND_SESSION
"gb47skhpp18v409ics8ikuv21k"
VUFIND_SESSION_KEY
"XXuPfuFqj8O+Cou8Mqd/lnpJ0yED5eg+edMGKmZJSE3G5IAA9FoVUOSHVnYBrNoAiXsJD/lQgJ+/8xX4L9YFYA=="
language
"ar"
ui
"standard"
Key Value
__Laminas
array:4 [
  "_REQUEST_ACCESS_TIME" => 1770939055.0536
  "_VALID" => array:1 [
    "Laminas\Session\Validator\Id" => "gb47skhpp18v409ics8ikuv21k"
  ]
  "FlashMessenger" => array:1 [
    "EXPIRE_HOPS" => array:2 [
      "hops" => 1
      "ts" => 1770939054.8733
    ]
  ]
  "csrf" => array:1 [
    "EXPIRE" => 1770939354
  ]
]
SessionState
Laminas\Stdlib\ArrayObject {#937}
Folio_kware
Laminas\Stdlib\ArrayObject {#938}
Followup
Laminas\Stdlib\ArrayObject {#939}
FlashMessenger
Laminas\Stdlib\ArrayObject {#940}
csrf
Laminas\Stdlib\ArrayObject {#941}
SessionHelper
Laminas\Stdlib\ArrayObject {#942}
_IMMUTABLE
true
Key Value
REDIRECT_SCRIPT_URL
"/Search/FacetList"
REDIRECT_SCRIPT_URI
"http://research.kwaretech.com/Search/FacetList"
REDIRECT_VUFIND_ENV
"development"
REDIRECT_VUFIND_LOCAL_DIR
"/usr/local/vufind/local"
REDIRECT_STATUS
"200"
SCRIPT_URL
"/Search/FacetList"
SCRIPT_URI
"http://research.kwaretech.com/Search/FacetList"
VUFIND_ENV
"development"
VUFIND_LOCAL_DIR
"/usr/local/vufind/local"
HTTP_HOST
"research.kwaretech.com"
HTTP_ACCEPT
"*/*"
HTTP_USER_AGENT
"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)"
HTTP_COOKIE
"VUFIND_SESSION=gb47skhpp18v409ics8ikuv21k; VUFIND_SESSION_KEY=XXuPfuFqj8O%2BCou8Mqd%2FlnpJ0yED5eg%2BedMGKmZJSE3G5IAA9FoVUOSHVnYBrNoAiXsJD%2FlQgJ%2B%2F8xX4L9YFYA%3D%3D; language=ar; ui=standard"
HTTP_ACCEPT_ENCODING
"gzip, br, zstd, deflate"
HTTP_X_FORWARDED_FOR
"216.73.216.83"
HTTP_X_FORWARDED_HOST
"research.kwaretech.com"
HTTP_X_FORWARDED_SERVER
"research.kwaretech.com"
HTTP_CONNECTION
"Keep-Alive"
PATH
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
SERVER_SIGNATURE
"<address>Apache/2.4.52 (Ubuntu) Server at research.kwaretech.com Port 80</address>\n"
SERVER_SOFTWARE
"Apache/2.4.52 (Ubuntu)"
SERVER_NAME
"research.kwaretech.com"
SERVER_ADDR
"172.19.0.6"
SERVER_PORT
"80"
REMOTE_ADDR
"172.19.0.1"
DOCUMENT_ROOT
"/usr/local/vufind/public"
REQUEST_SCHEME
"http"
CONTEXT_PREFIX
""
CONTEXT_DOCUMENT_ROOT
"/usr/local/vufind/public"
SERVER_ADMIN
"[no address given]"
SCRIPT_FILENAME
"/usr/local/vufind/public/index.php"
REMOTE_PORT
"46378"
REDIRECT_URL
"/Search/FacetList"
GATEWAY_INTERFACE
"CGI/1.1"
SERVER_PROTOCOL
"HTTP/1.1"
REQUEST_METHOD
"GET"
QUERY_STRING
""
REQUEST_URI
"/Search/FacetList"
SCRIPT_NAME
"/index.php"
PHP_SELF
"/index.php"
REQUEST_TIME_FLOAT
1770939055.0225
REQUEST_TIME
1770939055
empty
0. Whoops\Handler\PrettyPageHandler