} /** * If an unexpected exception type was received, wrap it in a generic * BackendException to standardize upstream handling. * * @param \Exception $ex Exception * * @return \Exception */ protected function forceToBackendException($ex) { // Don't wrap specific backend exceptions.... if ($ex instanceof RemoteErrorException || $ex instanceof RequestErrorException || $ex instanceof HttpErrorException ) { return $ex; } return new BackendException('Problem connecting to Solr.', null, $ex); } /** * Try all Solr URLs until we find one that works (or throw an exception). * * @param string $method HTTP method to use * @param string $urlSuffix Suffix to append to all URLs tried * @param Callable $callback Callback to configure client (null for none) * * @return string Response body * * @throws RemoteErrorException SOLR signaled a server error (HTTP 5xx) * @throws RequestErrorException SOLR signaled a client error (HTTP 4xx) */ protected function trySolrUrls($method, $urlSuffix, $callback = null) { // This exception should never get thrown; it's just a safety in case // something unanticipated occurs. $exception = new \Exception('Unexpected exception.');
// Loop through all base URLs and try them in turn until one works. foreach ((array)$this->url as $base) { $client = $this->createClient($base . $urlSuffix, $method); if (is_callable($callback)) { $callback($client); } try { return $this->send($client); } 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); } /** * Send request the SOLR and return the response. * * @param HttpClient $client Prepared HTTP client * * @return string Response body * * @throws RemoteErrorException SOLR signaled a server error (HTTP 5xx) * @throws RequestErrorException SOLR signaled a client error (HTTP 4xx) */ protected function send(HttpClient $client) { $this->debug( sprintf('=> %s %s', $client->getMethod(), $client->getUri()) ); $time = microtime(true); $response = $client->send();
throw new AdapterException\InvalidArgumentException(sprintf( 'integer or numeric string expected, got %s', gettype($connectTimeout) )); } ErrorHandler::start(); $this->socket = stream_socket_client( $host . ':' . $port, $errno, $errstr, (int) $connectTimeout, $flags, $context ); $error = ErrorHandler::stop(); if (! $this->socket) { $this->close(); throw new AdapterException\RuntimeException( sprintf( 'Unable to connect to %s:%d%s', $host, $port, ($error ? ' . Error #' . $error->getCode() . ': ' . $error->getMessage() : '') ), 0, $error ); } // Set the stream timeout if (! stream_set_timeout($this->socket, (int) $this->config['timeout'])) { throw new AdapterException\RuntimeException('Unable to set the connection timeout'); } if ($secure || $this->config['sslusecontext']) { if ($this->config['ssltransport'] && isset(static::$sslCryptoTypes[$this->config['ssltransport']])) { $sslCryptoMethod = static::$sslCryptoTypes[$this->config['ssltransport']]; } else {
if ($this->config['persistent']) { $flags |= STREAM_CLIENT_PERSISTENT; } if (isset($this->config['connecttimeout'])) { $connectTimeout = $this->config['connecttimeout']; } else { $connectTimeout = $this->config['timeout']; } if ($connectTimeout !== null && ! is_numeric($connectTimeout)) { throw new AdapterException\InvalidArgumentException(sprintf( 'integer or numeric string expected, got %s', gettype($connectTimeout) )); } ErrorHandler::start(); $this->socket = stream_socket_client( $host . ':' . $port, $errno, $errstr, (int) $connectTimeout, $flags, $context ); $error = ErrorHandler::stop(); if (! $this->socket) { $this->close(); throw new AdapterException\RuntimeException( sprintf( 'Unable to connect to %s:%d%s', $host, $port, ($error ? ' . Error #' . $error->getCode() . ': ' . $error->getMessage() : '') ), 0, $error );
if ($this->config['persistent']) { $flags |= STREAM_CLIENT_PERSISTENT; } if (isset($this->config['connecttimeout'])) { $connectTimeout = $this->config['connecttimeout']; } else { $connectTimeout = $this->config['timeout']; } if ($connectTimeout !== null && ! is_numeric($connectTimeout)) { throw new AdapterException\InvalidArgumentException(sprintf( 'integer or numeric string expected, got %s', gettype($connectTimeout) )); } ErrorHandler::start(); $this->socket = stream_socket_client( $host . ':' . $port, $errno, $errstr, (int) $connectTimeout, $flags, $context ); $error = ErrorHandler::stop(); if (! $this->socket) { $this->close(); throw new AdapterException\RuntimeException( sprintf( 'Unable to connect to %s:%d%s', $host, $port, ($error ? ' . Error #' . $error->getCode() . ': ' . $error->getMessage() : '') ), 0, $error );
return $parameters; } /** * Separating this from send method allows subclasses to wrap * the interaction with the adapter * * @param Http $uri * @param string $method * @param bool $secure * @param array $headers * @param string $body * @return string the raw response * @throws Exception\RuntimeException */ protected function doRequest(Http $uri, $method, $secure = false, $headers = [], $body = '') { // Open the connection, send the request and read the response $this->adapter->connect($uri->getHost(), $uri->getPort(), $secure); if ($this->config['outputstream']) { if ($this->adapter instanceof Client\Adapter\StreamInterface) { $this->streamHandle = $this->openTempStream(); $this->adapter->setOutputStream($this->streamHandle); } else { throw new Exception\RuntimeException('Adapter does not support streaming'); } } // HTTP connection $this->lastRawRequest = $this->adapter->write( $method, $uri, $this->config['httpversion'], $headers, $body ); return $this->adapter->read(); }
// headers $headers = $this->prepareHeaders($body, $uri); $secure = $uri->getScheme() == 'https'; // cookies $cookie = $this->prepareCookies($uri->getHost(), $uri->getPath(), $secure); if ($cookie->getFieldValue()) { $headers['Cookie'] = $cookie->getFieldValue(); } // check that adapter supports streaming before using it if (is_resource($body) && ! ($adapter instanceof Client\Adapter\StreamInterface)) { throw new Client\Exception\RuntimeException('Adapter does not support streaming'); } $this->streamHandle = null; // calling protected method to allow extending classes // to wrap the interaction with the adapter $response = $this->doRequest($uri, $method, $secure, $headers, $body); $stream = $this->streamHandle; $this->streamHandle = null; if (! $response) { if ($stream !== null) { fclose($stream); } throw new Exception\RuntimeException('Unable to read response, or response is empty'); } if ($this->config['storeresponse']) { $this->lastRawResponse = $response; } else { $this->lastRawResponse = null; } if ($this->config['outputstream']) { if ($stream === null) { $stream = $this->getStream(); if (! is_resource($stream) && is_string($stream)) {
} /** * Send request the SOLR and return the response. * * @param HttpClient $client Prepared HTTP client * * @return string Response body * * @throws RemoteErrorException SOLR signaled a server error (HTTP 5xx) * @throws RequestErrorException SOLR signaled a client error (HTTP 4xx) */ protected function send(HttpClient $client) { $this->debug( sprintf('=> %s %s', $client->getMethod(), $client->getUri()) ); $time = microtime(true); $response = $client->send(); $time = microtime(true) - $time; $this->debug( sprintf( '<= %s %s', $response->getStatusCode(), $response->getReasonPhrase() ), ['time' => $time] ); if (!$response->isSuccess()) { throw HttpErrorException::createFromResponse($response); } return $response->getBody(); } /** * Create the HTTP client. * * @param string $url Target URL * @param string $method Request method
* * @return string Response body * * @throws RemoteErrorException SOLR signaled a server error (HTTP 5xx) * @throws RequestErrorException SOLR signaled a client error (HTTP 4xx) */ protected function trySolrUrls($method, $urlSuffix, $callback = null) { // This exception should never get thrown; it's just a safety in case // something unanticipated occurs. $exception = new \Exception('Unexpected exception.'); // Loop through all base URLs and try them in turn until one works. foreach ((array)$this->url as $base) { $client = $this->createClient($base . $urlSuffix, $method); if (is_callable($callback)) { $callback($client); } try { return $this->send($client); } 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); } /** * Send request the SOLR and return the response. * * @param HttpClient $client Prepared HTTP client * * @return string Response body *
*/ public function query($handler, ParamBag $params) { $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); } /** * Check if an exception from a Solr request should be thrown rather than retried * * @param \Exception $ex Exception * * @return bool */ protected function isRethrowableSolrException($ex) { return $ex instanceof TimeoutException || $ex instanceof RequestErrorException; } /** * If an unexpected exception type was received, wrap it in a generic * BackendException to standardize upstream handling. * * @param \Exception $ex Exception
*/ public function similar($id, ParamBag $params) { $handler = $this->map->getHandler(__FUNCTION__); $this->map->prepare(__FUNCTION__, $params); return $this->query($handler, $params); } /** * 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); } /** * 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); } /** * Write to the SOLR index. *
/** * 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 ) { $params = $params ?: new ParamBag(); $this->injectResponseWriter($params); $params->set('rows', $limit); $params->set('start', $offset); $params->mergeWith($this->getQueryBuilder()->build($query)); $response = $this->connector->search($params); $collection = $this->createRecordCollection($response); $this->injectSourceIdentifier($collection); return $collection; } /** * Get Random records * * @param AbstractQuery $query Search query * @param int $limit Search limit * @param ParamBag $params Search backend parameters * * @return RecordCollectionInterface */ public function random( AbstractQuery $query, $limit, ParamBag $params = null ) { $params = $params ?: new ParamBag(); $this->injectResponseWriter($params);
* @param string $backend Search backend identifier * @param Query\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($backend, Query\AbstractQuery $query, $offset = 0, $limit = 20, ParamBag $params = null ) { $params = $params ?: new ParamBag(); $context = __FUNCTION__; $args = compact('backend', 'query', 'offset', 'limit', 'params', 'context'); $backend = $this->resolve($backend, $args); $args['backend_instance'] = $backend; $this->triggerPre($backend, $args); try { $response = $backend->search($query, $offset, $limit, $params); } catch (BackendException $e) { $this->triggerError($e, $args); throw $e; } $this->triggerPost($response, $args); return $response; } /** * Retrieve a single record. * * @param string $backend Search backend identifier * @param string $id Record identifier * @param ParamBag $params Search backend parameters * * @return RecordCollectionInterface */ public function retrieve($backend, $id, ParamBag $params = null) { $params = $params ?: new ParamBag();
$this->spellingProcessor = $processor; } /** * Support method for performAndProcessSearch -- perform a search based on the * parameters passed to the object. * * @return void */ protected function performSearch() { $query = $this->getParams()->getQuery(); $limit = $this->getParams()->getLimit(); $offset = $this->getStartRecord() - 1; $params = $this->getParams()->getBackendParameters(); $searchService = $this->getSearchService(); try { $collection = $searchService ->search($this->backendId, $query, $offset, $limit, $params); } catch (\VuFindSearch\Backend\Exception\BackendException $e) { // If the query caused a parser error, see if we can clean it up: if ($e->hasTag('VuFind\Search\ParserError') && $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(); $collection = $searchService ->search($this->backendId, $newQuery, $offset, $limit, $params); } else { throw $e; } } $this->responseFacets = $collection->getFacets(); $this->resultTotal = $collection->getTotal(); // Process spelling suggestions $spellcheck = $collection->getSpellcheck();
{ $this->helpers[$key] = $value; } /** * 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): $this->resultTotal = 0; $this->results = []; $this->suggestions = []; // 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 */
public function getSpellingSuggestions() { 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) { // Make sure we have processed the search before proceeding: if (null === $this->responseFacets) { $this->performAndProcessSearch(); } // If there is no filter, we'll use all facets as the filter: if (null === $filter) { $filter = $this->getParams()->getFacetConfig(); } // Start building the facet list: $list = []; // Loop through every field returned by the result set $fieldFacets = $this->responseFacets->getFieldFacets(); $translatedFacets = $this->getOptions()->getTranslatedFacets(); foreach (array_keys($filter) as $field) { $data = $fieldFacets[$field] ?? []; // Skip empty arrays: if (count($data) < 1) { continue; } // Initialize the settings for the current field
// 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(); // 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']) == $limit + 1 ) { $more = true; array_pop($value['list']); } $result[$key] = ['more' => $more, 'data' => $value]; } // Send back data: return $result; } /** * Returns data on pivot facets for the last search
// Get parameters $facet = $this->params()->fromQuery('facet'); $page = (int)$this->params()->fromQuery('facetpage', 1); $options = $results->getOptions(); $facetSortOptions = $options->getFacetSortOptions(); $sort = $this->params()->fromQuery('facetsort', null); if ($sort === null || !in_array($sort, array_keys($facetSortOptions))) { $sort = empty($facetSortOptions) ? 'count' : current(array_keys($facetSortOptions)); } $config = $this->serviceLocator->get('VuFind\Config\PluginManager') ->get($options->getFacetsIni()); $limit = isset($config->Results_Settings->lightboxLimit) ? $config->Results_Settings->lightboxLimit : 50; $limit = $this->params()->fromQuery('facetlimit', $limit); $facets = $results->getPartialFieldFacets( [$facet], false, $limit, $sort, $page, $this->params()->fromQuery('facetop', 'AND') == 'OR' ); $list = $facets[$facet]['data']['list'] ?? []; $params->activateAllFacets(); $facetLabel = $params->getFacetLabel($facet); $view = $this->createViewModel( [ 'data' => $list, 'exclude' => $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'), ] );
*/ 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 Exception\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 ($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__, (is_object($eventName) ? get_class($eventName) : gettype($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(function ($test) { return ($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->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(get_class($controller)); $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 ($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__, (is_object($eventName) ? get_class($eventName) : gettype($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
// Ensure vendor/ is on include_path; some PEAR components may not load correctly // otherwise (i.e. File_MARC may cause a "Cannot redeclare class" error by pulling // from the shared PEAR directory instead of the local copy): $pathParts = []; $pathParts[] = APPLICATION_PATH . '/vendor'; $pathParts[] = get_include_path(); set_include_path(implode(PATH_SEPARATOR, $pathParts)); // Composer autoloading if (file_exists('vendor/autoload.php')) { $loader = include 'vendor/autoload.php'; } if (!class_exists('Zend\Loader\AutoloaderFactory')) { throw new RuntimeException('Unable to load Zend Framework autoloader.'); } // Run the application! Zend\Mvc\Application::init(require 'config/application.config.php')->run(); // Handle final profiling details, if necessary: if ($xhprof) { $xhprofData = extension_loaded('xhprof') ? xhprof_disable() : tideways_disable(); $xhprofRunId = uniqid(); $suffix = 'vufind'; $dir = ini_get('xhprof.output_dir'); if (empty($dir)) { $dir = sys_get_temp_dir(); } file_put_contents("$dir/$xhprofRunId.$suffix.xhprof", serialize($xhprofData)); $url = "$xhprof?run=$xhprofRunId&source=$suffix"; echo "<a href='$url'>Profiler output</a>"; }
Key | Value |
filter | Array ( [0] => format:"Book" ) |
type | AllFields |
facet | era_facet |
facetop | AND |
facetexclude | 0 |
Key | Value |
REDIRECT_SCRIPT_URL | /vufind/Search/FacetList |
REDIRECT_SCRIPT_URI | http://opac.cusat.ac.in/vufind/Search/FacetList |
REDIRECT_PERL5LIB | /usr/share/koha/lib |
REDIRECT_KOHA_CONF | /etc/koha/sites/ul/koha-conf.xml |
REDIRECT_MEMCACHED_SERVERS | |
REDIRECT_MEMCACHED_NAMESPACE | |
REDIRECT_VUFIND_ENV | development |
REDIRECT_VUFIND_LOCAL_DIR | /usr/local/vufind/local |
REDIRECT_STATUS | 200 |
SCRIPT_URL | /vufind/Search/FacetList |
SCRIPT_URI | http://opac.cusat.ac.in/vufind/Search/FacetList |
PERL5LIB | /usr/share/koha/lib |
KOHA_CONF | /etc/koha/sites/ul/koha-conf.xml |
MEMCACHED_SERVERS | |
MEMCACHED_NAMESPACE | |
VUFIND_ENV | development |
VUFIND_LOCAL_DIR | /usr/local/vufind/local |
HTTP_ACCEPT | */* |
HTTP_USER_AGENT | claudebot |
HTTP_HOST | opac.cusat.ac.in |
PATH | /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin |
SERVER_SIGNATURE | <address>Apache/2.4.41 (Ubuntu) Server at opac.cusat.ac.in Port 80</address> |
SERVER_SOFTWARE | Apache/2.4.41 (Ubuntu) |
SERVER_NAME | opac.cusat.ac.in |
SERVER_ADDR | 10.0.0.71 |
SERVER_PORT | 80 |
REMOTE_ADDR | 10.0.0.1 |
DOCUMENT_ROOT | /usr/share/koha/opac/htdocs |
REQUEST_SCHEME | http |
CONTEXT_PREFIX | /vufind |
CONTEXT_DOCUMENT_ROOT | /usr/local/vufind/public |
SERVER_ADMIN | [no address given] |
SCRIPT_FILENAME | /usr/local/vufind/public/index.php |
REMOTE_PORT | 56194 |
REDIRECT_URL | /vufind/Search/FacetList |
REDIRECT_QUERY_STRING | filter%5B%5D=format%3A%22Book%22&type=AllFields&facet=era_facet&facetop=AND&facetexclude=0 |
GATEWAY_INTERFACE | CGI/1.1 |
SERVER_PROTOCOL | HTTP/1.1 |
REQUEST_METHOD | GET |
QUERY_STRING | filter%5B%5D=format%3A%22Book%22&type=AllFields&facet=era_facet&facetop=AND&facetexclude=0 |
REQUEST_URI | /vufind/Search/FacetList?filter%5B%5D=format%3A%22Book%22&type=AllFields&facet=era_facet&facetop=AND&facetexclude=0 |
SCRIPT_NAME | /vufind/index.php |
PHP_SELF | /vufind/index.php |
REQUEST_TIME_FLOAT | 1711658128.554 |
REQUEST_TIME | 1711658128 |