2026-02-13T02:31:01+03:00 CRIT: TypeError : VuFind\Controller\AbstractBase::isLocalUrl(): Argument #1 ($url) must be of type string, null given, called in /usr/local/vufind/module/VuFind/src/VuFind/Controller/SearchController.php on line 137
Server Context:
Array
(
[REDIRECT_SCRIPT_URL] => /Search/Email
[REDIRECT_SCRIPT_URI] => http://research.kwaretech.com/Search/Email
[REDIRECT_VUFIND_ENV] => development
[REDIRECT_VUFIND_LOCAL_DIR] => /usr/local/vufind/local
[REDIRECT_STATUS] => 200
[SCRIPT_URL] => /Search/Email
[SCRIPT_URI] => http://research.kwaretech.com/Search/Email
[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] => _opensaml_req_ss%3Amem%3A0b38d702d785d11d9e6bd2137bb4eb7676ca87c782d700c2c99c5f1af43feda7=_ad54409cb4cb42ed4a41100dd8accd47; 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/Email
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => GET
[QUERY_STRING] =>
[REQUEST_URI] => /Search/Email
[SCRIPT_NAME] => /index.php
[PHP_SELF] => /index.php
[REQUEST_TIME_FLOAT] => 1770939061.1207
[REQUEST_TIME] => 1770939061
)
Backtrace:
/usr/local/vufind/module/VuFind/src/VuFind/Controller/SearchController.php line 137 - class = VuFind\Controller\AbstractBase, function = isLocalUrl, args: none.
/usr/local/vufind/vendor/laminas/laminas-mvc/src/Controller/AbstractActionController.php line 72 - class = VuFind\Controller\SearchController, function = emailAction, 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.
* @return \Laminas\Http\Response
*/
protected function getRefreshResponse(bool $forceGet = false)
{
$response = $this->getResponse();
$response->setStatusCode(205);
if ($forceGet) {
$response->getHeaders()->addHeaderLine('X-VuFind-Refresh-Method', 'GET');
}
return $response;
}
/**
* Is the provided URL local to this instance?
*
* @param string $url URL to check
*
* @return bool
*/
protected function isLocalUrl(string $url): bool
{
$baseUrlNorm = $this->normalizeUrlForComparison($this->getServerUrl('home'));
return str_starts_with($this->normalizeUrlForComparison($url), $baseUrlNorm);
}
}
"VuFind\Controller\AbstractBase::isLocalUrl(): Argument #1 ($url) must be of type string, null given, called in /usr/local/vufind/module/VuFind/src/VuFind/Controller/SearchController.php on line 137"
}
/**
* Email action - Allows the email form to appear.
*
* @return mixed
*/
public function emailAction()
{
// If a URL was explicitly passed in, use that; otherwise, try to
// find the HTTP referrer.
$mailer = $this->getService(\VuFind\Mailer\Mailer::class);
$view = $this->createEmailViewModel(null, $mailer->getDefaultLinkSubject());
$mailer->setMaxRecipients($view->maxRecipients);
// Set up Captcha
$view->useCaptcha = $this->captcha()->active('email');
$view->url = $this->params()->fromPost('url')
?? $this->params()->fromQuery('url')
?? $this->getRequest()->getServer()->get('HTTP_REFERER');
if (!$this->isLocalUrl($view->url)) {
throw new \Exception('Unexpected value passed to emailAction: ' . $view->url);
}
$emailActionSettings = $this->getService(\VuFind\Config\AccountCapabilities::class)->getEmailActionSetting();
if ($emailActionSettings === 'disabled') {
throw new ForbiddenException('Email action disabled');
}
// Force login if necessary:
if (
$emailActionSettings !== 'enabled'
&& !$this->getUser()
) {
return $this->forceLogin(null, ['emailurl' => $view->url]);
}
// Check if we have a URL in login followup data -- this should override
// any existing referer to avoid emailing a login-related URL!
$followupUrl = $this->followup()->retrieveAndClear('emailurl');
if (!empty($followupUrl)) {
$view->url = $followupUrl;
*/
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();
}
| Key | Value |
| _opensaml_req_ss%3Amem%3A0b38d702d785d11d9e6bd2137bb4eb7676ca87c782d700c2c99c5f1af43feda7 | "_ad54409cb4cb42ed4a41100dd8accd47"
|
| VUFIND_SESSION | "gb47skhpp18v409ics8ikuv21k"
|
| VUFIND_SESSION_KEY | "XXuPfuFqj8O+Cou8Mqd/lnpJ0yED5eg+edMGKmZJSE3G5IAA9FoVUOSHVnYBrNoAiXsJD/lQgJ+/8xX4L9YFYA=="
|
| language | "ar"
|
| ui | "standard"
|
| Key | Value |
| __Laminas | array:4 [ "_REQUEST_ACCESS_TIME" => 1770939061.1527 "_VALID" => array:1 [ "Laminas\Session\Validator\Id" => "gb47skhpp18v409ics8ikuv21k" ] "FlashMessenger" => array:1 [ "EXPIRE_HOPS" => array:2 [ "hops" => 0 "ts" => 1770939060.9696 ] ] "csrf" => array:1 [ "EXPIRE" => 1770939360 ] ] |
| 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} |
| Key | Value |
| REDIRECT_SCRIPT_URL | "/Search/Email"
|
| REDIRECT_SCRIPT_URI | "http://research.kwaretech.com/Search/Email"
|
| REDIRECT_VUFIND_ENV | "development"
|
| REDIRECT_VUFIND_LOCAL_DIR | "/usr/local/vufind/local"
|
| REDIRECT_STATUS | "200"
|
| SCRIPT_URL | "/Search/Email"
|
| SCRIPT_URI | "http://research.kwaretech.com/Search/Email"
|
| 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 | "_opensaml_req_ss%3Amem%3A0b38d702d785d11d9e6bd2137bb4eb7676ca87c782d700c2c99c5f1af43feda7=_ad54409cb4cb42ed4a41100dd8accd47; 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/Email"
|
| GATEWAY_INTERFACE | "CGI/1.1"
|
| SERVER_PROTOCOL | "HTTP/1.1"
|
| REQUEST_METHOD | "GET"
|
| QUERY_STRING | "" |
| REQUEST_URI | "/Search/Email"
|
| SCRIPT_NAME | "/index.php"
|
| PHP_SELF | "/index.php"
|
| REQUEST_TIME_FLOAT | 1770939061.1207
|
| REQUEST_TIME | 1770939061
|