$path,
$domain,
$secure,
$httpOnly,
$sameSite
) {
// Special case: in CLI -- don't actually write headers!
if ('cli' === PHP_SAPI) {
return true;
}
return setcookie(
$key,
$value ?? '',
[
'expires' => $expire,
'path' => $path,
'domain' => $domain,
'samesite' => $sameSite,
'secure' => $secure,
'httponly' => $httpOnly,
]
);
}
/**
* Support method for set() -- set the actual cookie in PHP.
*
* @param string $key Name of cookie to set
* @param mixed $value Value to set
* @param int $expire Cookie expiration time
* @param null|bool $httpOnly Whether the cookie should be "HTTP only"
* @param string $sameSite SameSite attribute to use (Lax, Strict or None)
*
* @return bool
*/
public function setGlobalCookie(
$key,
$value,
$expire,
$httpOnly = null,
$path,
$domain,
$secure,
$httpOnly,
$sameSite
) {
// Special case: in CLI -- don't actually write headers!
if ('cli' === PHP_SAPI) {
return true;
}
return setcookie(
$key,
$value ?? '',
[
'expires' => $expire,
'path' => $path,
'domain' => $domain,
'samesite' => $sameSite,
'secure' => $secure,
'httponly' => $httpOnly,
]
);
}
/**
* Support method for set() -- set the actual cookie in PHP.
*
* @param string $key Name of cookie to set
* @param mixed $value Value to set
* @param int $expire Cookie expiration time
* @param null|bool $httpOnly Whether the cookie should be "HTTP only"
* @param string $sameSite SameSite attribute to use (Lax, Strict or None)
*
* @return bool
*/
public function setGlobalCookie(
$key,
$value,
$expire,
$httpOnly = null,
*
* @return bool
*/
public function setGlobalCookie(
$key,
$value,
$expire,
$httpOnly = null,
$sameSite = null
) {
if (null === $httpOnly) {
$httpOnly = $this->httpOnly;
}
if (null === $sameSite) {
$sameSite = $this->sameSite;
}
// Simple case: flat value.
if (!is_array($value)) {
return $this->proxySetCookie(
$key,
$value,
$expire,
$this->path,
$this->domain,
$this->secure,
$httpOnly,
$sameSite
);
}
// Complex case: array of values.
$success = true;
foreach ($value as $i => $curr) {
$lastSuccess = $this->proxySetCookie(
$key . '[' . $i . ']',
$curr,
$expire,
$this->path,
$this->domain,
$this->secure,
/**
* Set a cookie.
*
* @param string $key Name of cookie to set
* @param mixed $value Value to set
* @param int $expire Cookie expiration time
* @param null|bool $httpOnly Whether the cookie should be "HTTP only"
* @param string $sameSite SameSite attribute to use (Lax, Strict or None)
*
* @return bool
*/
public function set(
$key,
$value,
$expire = 0,
$httpOnly = null,
$sameSite = null
) {
$success = $this
->setGlobalCookie($key, $value, $expire, $httpOnly, $sameSite);
if ($success) {
$this->cookies[$key] = $value;
}
return $success;
}
/**
* Clear a cookie.
*
* @param string $key Name of cookie to unset
*
* @return bool
*/
public function clear($key)
{
$value = $this->get($key);
if (is_array($value)) {
$success = true;
foreach (array_keys($value) as $i) {
if (!$this->clear($key . '[' . $i . ']')) {
? $this->config->mobile_theme : false;
// Find out if the user has a saved preference in the POST, URL or cookies:
$selectedUI = null;
if (isset($request)) {
$selectedUI = $request->getPost()->get(
'ui',
$request->getQuery()->get(
'ui',
$request->getCookie()->ui ?? null
)
);
}
if (empty($selectedUI)) {
$selectedUI = ($mobileTheme && $this->mobile->detect())
? 'mobile' : 'standard';
}
// Save the current setting to a cookie so it persists:
$this->cookieManager->set('ui', $selectedUI);
// Do we have a valid mobile selection?
if ($mobileTheme && $selectedUI == 'mobile') {
return $mobileTheme;
}
// Do we have a non-standard selection?
if (
$selectedUI != 'standard'
&& isset($this->config->alternate_themes)
) {
// Check the alternate theme settings for a match:
$parts = explode(',', $this->config->alternate_themes);
foreach ($parts as $part) {
$subparts = explode(':', $part);
if (
(trim($subparts[0]) == trim($selectedUI))
&& isset($subparts[1]) && !empty($subparts[1])
) {
return $subparts[1];
}
/**
* Initialize the theme. This needs to be triggered as part of the dispatch
* event.
*
* @throws \Exception
* @return void
*/
public function init()
{
// Make sure to initialize the theme just once
if (self::$themeInitialized) {
return;
}
self::$themeInitialized = true;
// Determine the current theme:
$currentTheme = $this->pickTheme(
isset($this->event) ? $this->event->getRequest() : null
);
// Determine theme options:
$this->sendThemeOptionsToView();
// Make sure the current theme is set correctly in the tools object:
$error = null;
try {
$this->tools->setTheme($currentTheme);
} catch (\Exception $error) {
// If an illegal value is passed in, the setter may throw an exception.
// We should ignore it for now and throw it after we have set up the
// theme (the setter will use a safe value instead of the illegal one).
}
// Using the settings we initialized above, actually configure the themes; we
// need to do this even if there is an error, since we need a theme in order
// to display an error message!
$this->setUpThemes(array_reverse($this->tools->getThemeInfo()));
($user = $authManager->isLoggedIn())
&& $user->last_language != $language
) {
$user->updateLastLanguage($language);
}
}
/**
* Set up theme handling.
*
* @return void
*/
protected function initTheme(): void
{
// Attach remaining theme configuration to the dispatch event at high
// priority (TODO: use priority constant once defined by framework):
$config = $this->config->Site;
$callback = function ($event) use ($config) {
$theme = new \VuFindTheme\Initializer($config, $event);
$theme->init();
};
$this->events->attach('dispatch.error', $callback, 9000);
$this->events->attach('dispatch', $callback, 9000);
}
/**
* Set up custom HTTP status based on exception information.
*
* @return void
*/
protected function initExceptionBasedHttpStatuses(): void
{
// HTTP statuses not needed in console mode:
if (PHP_SAPI == 'cli') {
return;
}
$callback = function ($e) {
$exception = $e->getParam('exception');
if ($exception instanceof \VuFind\Exception\HttpStatusInterface) {
}
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
<?php
// If the profiler is enabled, set it up now:
$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 {
$app->run();
}
Key | Value |
author | Tolkien, J. R. R. (John Ronald Reuel), 1892-1973 |
callnumber | |
size | large |
title | The Hobbit, or, There and back again / |
recordid | 441bbd83-57a3-597b-a74b-6cc4ef2a940b |
source | Solr |
isbns | Array ( [0] => 0345339681 [1] => 0345339681 [2] => 054792822X [3] => 0808520806 [4] => 0808520806 ) |
oclc | 117726 |
Key | Value |
__Laminas | Array ( [_REQUEST_ACCESS_TIME] => 1714479664.1494 [_VALID] => Array ( [Laminas\Session\Validator\Id] => ) ) |
SessionState | Laminas\Stdlib\ArrayObject Object ( [storage:protected] => Array ( [cookiePath] => / [sessionStartTime] => 1714479664 ) [flag:protected] => 2 [iteratorClass:protected] => ArrayIterator [protectedProperties:protected] => Array ( [0] => storage [1] => flag [2] => iteratorClass [3] => protectedProperties ) ) |
Key | Value |
REDIRECT_VUFIND_ENV | development |
REDIRECT_VUFIND_LOCAL_DIR | /usr/local/vufind/local |
REDIRECT_STATUS | 200 |
VUFIND_ENV | development |
VUFIND_LOCAL_DIR | /usr/local/vufind/local |
HTTP_HOST | catalog.spokanelibrary.org |
HTTP_CONNECTION | close |
HTTP_X_REAL_IP | 18.191.13.255 |
HTTP_X_FORWARDED_FOR | 18.191.13.255 |
HTTP_X_FORWARDED_PROTO | https |
HTTP_X_FORWARDED_SSL | on |
HTTP_X_FORWARDED_PORT | 443 |
HTTP_X_ORIGINAL_URI | /catalog/Cover/Show?author=Tolkien%2C+J.+R.+R.+%28John+Ronald+Reuel%29%2C+1892-1973&callnumber=&size=large&title=The+Hobbit%2C+or%2C+There+and+back+again+%2F&recordid=441bbd83-57a3-597b-a74b-6cc4ef2a940b&source=Solr&isbns%5B0%5D=0345339681&isbns%5B1%5D=0345339681&isbns%5B2%5D=054792822X&isbns%5B3%5D=0808520806&isbns%5B4%5D=0808520806&oclc=117726 |
HTTP_ACCEPT | */* |
HTTP_USER_AGENT | Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com) |
PATH | /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/composer2/vendor/bin:/root/composer1/vendor/bin |
SERVER_SIGNATURE | <address>Apache/2.4.56 (Debian) Server at catalog.spokanelibrary.org Port 80</address> |
SERVER_SOFTWARE | Apache/2.4.56 (Debian) |
SERVER_NAME | catalog.spokanelibrary.org |
SERVER_ADDR | 172.21.0.24 |
SERVER_PORT | 80 |
REMOTE_ADDR | 172.21.0.9 |
DOCUMENT_ROOT | /var/www/html |
REQUEST_SCHEME | http |
CONTEXT_PREFIX | /catalog |
CONTEXT_DOCUMENT_ROOT | /usr/local/vufind/public |
SERVER_ADMIN | webmaster@localhost |
SCRIPT_FILENAME | /usr/local/vufind/public/index.php |
REMOTE_PORT | 48194 |
REDIRECT_URL | /catalog/Cover/Show |
REDIRECT_QUERY_STRING | author=Tolkien%2C+J.+R.+R.+%28John+Ronald+Reuel%29%2C+1892-1973&callnumber=&size=large&title=The+Hobbit%2C+or%2C+There+and+back+again+%2F&recordid=441bbd83-57a3-597b-a74b-6cc4ef2a940b&source=Solr&isbns%5B0%5D=0345339681&isbns%5B1%5D=0345339681&isbns%5B2%5D=054792822X&isbns%5B3%5D=0808520806&isbns%5B4%5D=0808520806&oclc=117726 |
GATEWAY_INTERFACE | CGI/1.1 |
SERVER_PROTOCOL | HTTP/1.1 |
REQUEST_METHOD | GET |
QUERY_STRING | author=Tolkien%2C+J.+R.+R.+%28John+Ronald+Reuel%29%2C+1892-1973&callnumber=&size=large&title=The+Hobbit%2C+or%2C+There+and+back+again+%2F&recordid=441bbd83-57a3-597b-a74b-6cc4ef2a940b&source=Solr&isbns%5B0%5D=0345339681&isbns%5B1%5D=0345339681&isbns%5B2%5D=054792822X&isbns%5B3%5D=0808520806&isbns%5B4%5D=0808520806&oclc=117726 |
REQUEST_URI | /catalog/Cover/Show?author=Tolkien%2C+J.+R.+R.+%28John+Ronald+Reuel%29%2C+1892-1973&callnumber=&size=large&title=The+Hobbit%2C+or%2C+There+and+back+again+%2F&recordid=441bbd83-57a3-597b-a74b-6cc4ef2a940b&source=Solr&isbns%5B0%5D=0345339681&isbns%5B1%5D=0345339681&isbns%5B2%5D=054792822X&isbns%5B3%5D=0808520806&isbns%5B4%5D=0808520806&oclc=117726 |
SCRIPT_NAME | /catalog/index.php |
PHP_SELF | /catalog/index.php |
REQUEST_TIME_FLOAT | 1714479663.957 |
REQUEST_TIME | 1714479663 |
argv | Array ( [0] => author=Tolkien%2C [1] => J. [2] => R. [3] => R. [4] => %28John [5] => Ronald [6] => Reuel%29%2C [7] => 1892-1973&callnumber=&size=large&title=The [8] => Hobbit%2C [9] => or%2C [10] => There [11] => and [12] => back [13] => again [14] => %2F&recordid=441bbd83-57a3-597b-a74b-6cc4ef2a940b&source=Solr&isbns%5B0%5D=0345339681&isbns%5B1%5D=0345339681&isbns%5B2%5D=054792822X&isbns%5B3%5D=0808520806&isbns%5B4%5D=0808520806&oclc=117726 ) |
argc | 15 |
Key | Value |
HOSTNAME | 383091efdb19 |
PHP_VERSION | 8.0.29 |
APACHE_CONFDIR | /etc/apache2 |
PHP_INI_DIR | /usr/local/etc/php |
GPG_KEYS | 1729F83938DA44E27BA0F4D3DBDB397470D12172 BFDDD28642824F8118EF77909B67A5C12229118F 2C16C765DBE54A088130F1BC4B9B5F600B55F3B4 |
PHP_LDFLAGS | -Wl,-O1 -pie |
VUFIND_LOCAL_DIR | /usr/local/vufind/local |
PWD | /var/www/html |
APACHE_LOG_DIR | /var/log/apache2 |
LANG | C |
PHP_SHA256 | 14db2fbf26c07d0eb2c9fab25dbde7e27726a3e88452cca671f0896bbb683ca9 |
APACHE_PID_FILE | /var/run/apache2/apache2.pid |
PHPIZE_DEPS | autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c |
VIRTUAL_HOST | vufind.spokanelibrary.org,catalog.spokanelibrary.org |
PHP_URL | https://www.php.net/distributions/php-8.0.29.tar.xz |
APACHE_RUN_GROUP | www-data |
APACHE_LOCK_DIR | /var/lock/apache2 |
VUFIND_LOCAL_MODULES | SPLNewMaterials,SpokanePublic |
SHLVL | 0 |
COMPOSER_ALLOW_SUPERUSER | 1 |
PHP_CFLAGS | -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 |
VUFIND_HOME | /usr/local/vufind |
APACHE_RUN_DIR | /var/run/apache2 |
APACHE_ENVVARS | /etc/apache2/envvars |
APACHE_RUN_USER | www-data |
PATH | /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/composer2/vendor/bin:/root/composer1/vendor/bin |
PHP_ASC_URL | https://www.php.net/distributions/php-8.0.29.tar.xz.asc |
COMPOSER_HOME | /root/composer2 |
PHP_CPPFLAGS | -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 |