UnexpectedValueException: The stream or file "/var/www/kaj.kunigund.is/public_html/logs/grav.log" could not be opened: failed to open stream: Permission denied in /var/www/kaj.kunigund.is/public_html/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:108 Stack trace: #0 /var/www/kaj.kunigund.is/public_html/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(39): Monolog\Handler\StreamHandler->write(Array) #1 /var/www/kaj.kunigund.is/public_html/vendor/monolog/monolog/src/Monolog/Logger.php(344): Monolog\Handler\AbstractProcessingHandler->handle(Array) #2 /var/www/kaj.kunigund.is/public_html/vendor/monolog/monolog/src/Monolog/Logger.php(470): Monolog\Logger->addRecord(500, 'The directory "...', Array) #3 /var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Errors/Errors.php(61): Monolog\Logger->addCritical('The directory "...') #4 /var/www/kaj.kunigund.is/public_html/vendor/filp/whoops/src/Whoops/Handler/CallbackHandler.php(50): Grav\Common\Errors\Errors->Grav\Common\Errors\{closure}(Object(InvalidArgumentException), Object(Whoops\Exception\Inspector), Object(Whoops\Run)) #5 /var/www/kaj.kunigund.is/public_html/vendor/filp/whoops/src/Whoops/Run.php(296): Whoops\Handler\CallbackHandler->handle(Object(InvalidArgumentException)) #6 [internal function]: Whoops\Run->handleException(Object(InvalidArgumentException)) #7 {main} Crikey! There was an error...
InvalidArgumentException
The directory "/var/www/kaj.kunigund.is/public_html/cache/doctrine/0d7fe6a1" is not writable. InvalidArgumentException thrown with message "The directory "/var/www/kaj.kunigund.is/public_html/cache/doctrine/0d7fe6a1" is not writable." Stacktrace: #14 InvalidArgumentException in /var/www/kaj.kunigund.is/public_html/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php:91 #13 Doctrine\Common\Cache\FileCache:__construct in /var/www/kaj.kunigund.is/public_html/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php:26 #12 Doctrine\Common\Cache\FilesystemCache:__construct in /var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Cache.php:310 #11 Grav\Common\Cache:getCacheDriver in /var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Cache.php:141 #10 Grav\Common\Cache:init in /var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Cache.php:111 #9 Grav\Common\Cache:__construct in /var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Grav.php:538 #8 Grav\Common\Grav:Grav\Common\{closure} in /var/www/kaj.kunigund.is/public_html/vendor/pimple/pimple/src/Pimple/Container.php:118 #7 Pimple\Container:offsetGet in /var/www/kaj.kunigund.is/public_html/user/plugins/problems/classes/Problems/Base/ProblemChecker.php:20 #6 Grav\Plugin\Problems\Base\ProblemChecker:__construct in /var/www/kaj.kunigund.is/public_html/user/plugins/problems/problems.php:125 #5 Grav\Plugin\ProblemsPlugin:problemsFound in /var/www/kaj.kunigund.is/public_html/user/plugins/problems/problems.php:47 #4 Grav\Plugin\ProblemsPlugin:onFatalException in /var/www/kaj.kunigund.is/public_html/vendor/symfony/event-dispatcher/EventDispatcher.php:212 #3 Symfony\Component\EventDispatcher\EventDispatcher:doDispatch in /var/www/kaj.kunigund.is/public_html/vendor/symfony/event-dispatcher/EventDispatcher.php:44 #2 Symfony\Component\EventDispatcher\EventDispatcher:dispatch in /var/www/kaj.kunigund.is/public_html/vendor/rockettheme/toolbox/Event/src/EventDispatcher.php:23 #1 RocketTheme\Toolbox\Event\EventDispatcher:dispatch in /var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Grav.php:403 #0 Grav\Common\Grav:fireEvent in /var/www/kaj.kunigund.is/public_html/index.php:59
Stack frames (15)
14
InvalidArgumentException
/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php91
13
Doctrine\Common\Cache\FileCache __construct
/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php26
12
Doctrine\Common\Cache\FilesystemCache __construct
/system/src/Grav/Common/Cache.php310
11
Grav\Common\Cache getCacheDriver
/system/src/Grav/Common/Cache.php141
10
Grav\Common\Cache init
/system/src/Grav/Common/Cache.php111
9
Grav\Common\Cache __construct
/system/src/Grav/Common/Grav.php538
8
Grav\Common\Grav Grav\Common\{closure}
/vendor/pimple/pimple/src/Pimple/Container.php118
7
Pimple\Container offsetGet
/user/plugins/problems/classes/Problems/Base/ProblemChecker.php20
6
Grav\Plugin\Problems\Base\ProblemChecker __construct
/user/plugins/problems/problems.php125
5
Grav\Plugin\ProblemsPlugin problemsFound
/user/plugins/problems/problems.php47
4
Grav\Plugin\ProblemsPlugin onFatalException
/vendor/symfony/event-dispatcher/EventDispatcher.php212
3
Symfony\Component\EventDispatcher\EventDispatcher doDispatch
/vendor/symfony/event-dispatcher/EventDispatcher.php44
2
Symfony\Component\EventDispatcher\EventDispatcher dispatch
/vendor/rockettheme/toolbox/Event/src/EventDispatcher.php23
1
RocketTheme\Toolbox\Event\EventDispatcher dispatch
/system/src/Grav/Common/Grav.php403
0
Grav\Common\Grav fireEvent
/index.php59
/var/www/kaj.kunigund.is/public_html/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php
    public function __construct($directory, $extension = '', $umask = 0002)
    {
        // YES, this needs to be *before* createPathIfNeeded()
        if (! is_int($umask)) {
            throw new InvalidArgumentException(sprintf(
                'The umask parameter is required to be integer, was: %s',
                gettype($umask)
            ));
        }
        $this->umask = $umask;
 
        if (! $this->createPathIfNeeded($directory)) {
            throw new InvalidArgumentException(sprintf(
                'The directory "%s" does not exist and could not be created.',
                $directory
            ));
        }
 
        if (! is_writable($directory)) {
            throw new InvalidArgumentException(sprintf(
                'The directory "%s" is not writable.',
                $directory
            ));
        }
 
        // YES, this needs to be *after* createPathIfNeeded()
        $this->directory = realpath($directory);
        $this->extension = (string) $extension;
 
        $this->directoryStringLength = strlen($this->directory);
        $this->extensionStringLength = strlen($this->extension);
        $this->isRunningOnWindows    = defined('PHP_WINDOWS_VERSION_BUILD');
    }
 
    /**
     * Gets the cache directory.
     *
     * @return string
     */
    public function getDirectory()
Arguments
  1. "The directory "/var/www/kaj.kunigund.is/public_html/cache/doctrine/0d7fe6a1" is not writable."
    
/var/www/kaj.kunigund.is/public_html/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php
use function fgets;
use function fopen;
use function is_file;
use function serialize;
use function time;
use function unserialize;
 
/**
 * Filesystem cache driver.
 */
class FilesystemCache extends FileCache
{
    public const EXTENSION = '.doctrinecache.data';
 
    /**
     * {@inheritdoc}
     */
    public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
    {
        parent::__construct($directory, $extension, $umask);
    }
 
    /**
     * {@inheritdoc}
     */
    protected function doFetch($id)
    {
        $data     = '';
        $lifetime = -1;
        $filename = $this->getFilename($id);
 
        if (! is_file($filename)) {
            return false;
        }
 
        $resource = fopen($filename, 'r');
        $line     = fgets($resource);
 
        if ($line !== false) {
            $lifetime = (int) $line;
Arguments
  1. "/var/www/kaj.kunigund.is/public_html/cache/doctrine/0d7fe6a1"
    
  2. ".doctrinecache.data"
    
  3. 2
    
/var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Cache.php
                        $redis->connect($socket);
                    } else {
                        $redis->connect($this->config->get('system.cache.redis.server', 'localhost'),
                            $this->config->get('system.cache.redis.port', 6379));
                    }
 
                    // Authenticate with password if set
                    if ($password && !$redis->auth($password)) {
                        throw new \RedisException('Redis authentication failed');
                    }
 
                    $driver = new DoctrineCache\RedisCache();
                    $driver->setRedis($redis);
                } else {
                    throw new \LogicException('Redis PHP extension has not been installed');
                }
                break;
 
            default:
                $driver = new DoctrineCache\FilesystemCache($this->cache_dir);
                break;
        }
 
        return $driver;
    }
 
    /**
     * Gets a cached entry if it exists based on an id. If it does not exist, it returns false
     *
     * @param  string $id the id of the cached entry
     *
     * @return object|bool     returns the cached entry, can be any type, or false if doesn't exist
     */
    public function fetch($id)
    {
        if ($this->enabled) {
            return $this->driver->fetch($id);
        }
 
        return false;
Arguments
  1. "/var/www/kaj.kunigund.is/public_html/cache/doctrine/0d7fe6a1"
    
/var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Cache.php
    {
        /** @var Config $config */
        $this->config = $grav['config'];
        $this->now = time();
 
        if (null === $this->enabled) {
            $this->enabled = (bool)$this->config->get('system.cache.enabled');
        }
 
        /** @var Uri $uri */
        $uri = $grav['uri'];
 
        $prefix = $this->config->get('system.cache.prefix');
        $uniqueness = substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION), 2, 8);
 
        // Cache key allows us to invalidate all cache on configuration changes.
        $this->key = ($prefix ? $prefix : 'g') . '-' . $uniqueness;
        $this->cache_dir = $grav['locator']->findResource('cache://doctrine/' . $uniqueness, true, true);
        $this->driver_setting = $this->config->get('system.cache.driver');
        $this->driver = $this->getCacheDriver();
        $this->driver->setNamespace($this->key);
 
        /** @var EventDispatcher $dispatcher */
        $dispatcher = Grav::instance()['events'];
        $dispatcher->addListener('onSchedulerInitialized', [$this, 'onSchedulerInitialized']);
    }
 
    /**
     * @return CacheInterface
     */
    public function getSimpleCache()
    {
        if (null === $this->simpleCache) {
            $cache = new \Grav\Framework\Cache\Adapter\DoctrineCache($this->driver, '', $this->getLifetime());
 
            // Disable cache key validation.
            $cache->setValidation(false);
 
            $this->simpleCache = $cache;
        }
/var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Cache.php
    protected static $images_remove = [
        'cache://images'
    ];
 
    protected static $cache_remove = [
        'cache://'
    ];
 
    protected static $tmp_remove = [
        'tmp://'
    ];
 
    /**
     * Constructor
     *
     * @param Grav $grav
     */
    public function __construct(Grav $grav)
    {
        $this->init($grav);
    }
 
    /**
     * Initialization that sets a base key and the driver based on configuration settings
     *
     * @param  Grav $grav
     *
     * @return void
     */
    public function init(Grav $grav)
    {
        /** @var Config $config */
        $this->config = $grav['config'];
        $this->now = time();
 
        if (null === $this->enabled) {
            $this->enabled = (bool)$this->config->get('system.cache.enabled');
        }
 
        /** @var Uri $uri */
Arguments
  1. Grav {#3}
    
/var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Grav.php
 
        return $container;
    }
 
    /**
     * Register all services
     * Services are defined in the diMap. They can either only the class
     * of a Service Provider or a pair of serviceKey => serviceClass that
     * gets directly mapped into the container.
     *
     * @return void
     */
    protected function registerServices()
    {
        foreach (self::$diMap as $serviceKey => $serviceClass) {
            if (\is_int($serviceKey)) {
                $this->register(new $serviceClass);
            } else {
                $this[$serviceKey] = function ($c) use ($serviceClass) {
                    return new $serviceClass($c);
                };
            }
        }
    }
 
    /**
     * This attempts to find media, other files, and download them
     *
     * @param string $path
     */
    public function fallbackUrl($path)
    {
        $this->fireEvent('onPageFallBackUrl');
 
        /** @var Uri $uri */
        $uri = $this['uri'];
 
        /** @var Config $config */
        $config = $this['config'];
 
Arguments
  1. Grav {#3}
    
/var/www/kaj.kunigund.is/public_html/vendor/pimple/pimple/src/Pimple/Container.php
    {
        if (!isset($this->keys[$id])) {
            throw new UnknownIdentifierException($id);
        }
 
        if (
            isset($this->raw[$id])
            || !\is_object($this->values[$id])
            || isset($this->protected[$this->values[$id]])
            || !\method_exists($this->values[$id], '__invoke')
        ) {
            return $this->values[$id];
        }
 
        if (isset($this->factories[$this->values[$id]])) {
            return $this->values[$id]($this);
        }
 
        $raw = $this->values[$id];
        $val = $this->values[$id] = $raw($this);
        $this->raw[$id] = $raw;
 
        $this->frozen[$id] = true;
 
        return $val;
    }
 
    /**
     * Checks if a parameter or an object is set.
     *
     * @param string $id The unique identifier for the parameter or object
     *
     * @return bool
     */
    public function offsetExists($id)
    {
        return isset($this->keys[$id]);
    }
 
    /**
Arguments
  1. Grav {#3}
    
/var/www/kaj.kunigund.is/public_html/user/plugins/problems/classes/Problems/Base/ProblemChecker.php
<?php
 
namespace Grav\Plugin\Problems\Base;
 
use Grav\Common\Cache;
use Grav\Common\Grav;
use RocketTheme\Toolbox\Event\Event;
 
class ProblemChecker
{
    const PROBLEMS_PREFIX = 'problem-check-';
 
    protected $problems = [];
    protected $status_file;
 
 
    public function __construct()
    {
        /** @var Cache $cache */
        $cache = Grav::instance()['cache'];
        $this->status_file = CACHE_DIR . $this::PROBLEMS_PREFIX . $cache->getKey() . '.json';
    }
 
    public function load()
    {
        if ($this->statusFileExists()) {
            $json = file_get_contents($this->status_file) ?: '';
            $data = json_decode($json, true);
            if (!is_array($data)) {
                return false;
            }
 
            foreach ($data as $problem) {
                $class = $problem['class'];
                $this->problems[] = new $class($problem);
            }
        }
 
        return true;
    }
Arguments
  1. "cache"
    
/var/www/kaj.kunigund.is/public_html/user/plugins/problems/problems.php
 
        /** @var \Twig_Environment $twig */
        $twig = $this->getTwig();
 
        $data = [
            'problems' => $this->problems,
            'base_url' => $baseUrlRelative = $uri->rootUrl(false),
            'problems_url' => $baseUrlRelative . '/user/plugins/problems',
        ];
 
        $reports['Grav Potential Problems'] = $twig->render('reports/problems-report.html.twig', $data);
 
        $this->grav['assets']->addCss('plugins://problems/css/admin.css');
        $this->grav['assets']->addCss('plugins://problems/css/spectre-icons.css');
    }
 
    private function problemsFound()
    {
        if (null === $this->checker) {
            $this->checker = new ProblemChecker();
        }
 
        $status = $this->checker->check(__DIR__ . '/classes/Problems');
        $this->problems = $this->checker->getProblems();
        
        return $status;
    }
 
    private function getTwig()
    {
        $loader = new \Twig_Loader_Filesystem(__DIR__ . '/templates');
        $twig = new \Twig_Environment($loader, ['debug' => true]);
        $twig->addExtension(New \Twig_Extension_Debug());
 
        return $twig;
    }
}
 
/var/www/kaj.kunigund.is/public_html/user/plugins/problems/problems.php
    }
 
    /**
     * [onPluginsInitialized:100000] Composer autoload.
     *
     * @return ClassLoader
     */
    public function autoload()
    {
        return require __DIR__ . '/vendor/autoload.php';
    }
 
    public function onFatalException()
    {
        if (\defined('GRAV_CLI') || $this->isAdmin()) {
            return;
        }
 
        // Run through potential issues
        if ($this->problemsFound()) {
            $this->renderProblems();
        }
    }
 
    public function onPluginsInitialized()
    {
        if (\defined('GRAV_CLI') || $this->isAdmin()) {
            return;
        }
 
        $this->checker = new ProblemChecker();
 
        if (!$this->checker->statusFileExists()) {
            // If no issues remain, save a state file in the cache
            if (!$this->problemsFound()) {
                // delete any existing validated files
                /** @var \SplFileInfo $fileInfo */
                foreach (new \GlobIterator(CACHE_DIR . ProblemChecker::PROBLEMS_PREFIX . '*') as $fileInfo) {
                    @unlink($fileInfo->getPathname());
                }
/var/www/kaj.kunigund.is/public_html/vendor/symfony/event-dispatcher/EventDispatcher.php
        }
    }
 
    /**
     * Triggers the listeners of an event.
     *
     * This method can be overridden to add functionality that is executed
     * for each listener.
     *
     * @param callable[] $listeners The event listeners
     * @param string     $eventName The name of the event to dispatch
     * @param Event      $event     The event object to pass to the event handlers/listeners
     */
    protected function doDispatch($listeners, $eventName, Event $event)
    {
        foreach ($listeners as $listener) {
            if ($event->isPropagationStopped()) {
                break;
            }
            $listener($event, $eventName, $this);
        }
    }
 
    /**
     * Sorts the internal list of listeners for the given event by priority.
     *
     * @param string $eventName The name of the event
     */
    private function sortListeners($eventName)
    {
        krsort($this->listeners[$eventName]);
        $this->sorted[$eventName] = [];
 
        foreach ($this->listeners[$eventName] as $priority => $listeners) {
            foreach ($listeners as $k => $listener) {
                if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
                    $listener[0] = $listener[0]();
                    $this->listeners[$eventName][$priority][$k] = $listener;
                }
                $this->sorted[$eventName][] = $listener;
Arguments
  1. Event {#91}
    
  2. "onFatalException"
    
  3. EventDispatcher {#131}
    
/var/www/kaj.kunigund.is/public_html/vendor/symfony/event-dispatcher/EventDispatcher.php
 * @author Jordi Boggiano <j.boggiano@seld.be>
 * @author Jordan Alliot <jordan.alliot@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class EventDispatcher implements EventDispatcherInterface
{
    private $listeners = [];
    private $sorted = [];
 
    /**
     * {@inheritdoc}
     */
    public function dispatch($eventName, Event $event = null)
    {
        if (null === $event) {
            $event = new Event();
        }
 
        if ($listeners = $this->getListeners($eventName)) {
            $this->doDispatch($listeners, $eventName, $event);
        }
 
        return $event;
    }
 
    /**
     * {@inheritdoc}
     */
    public function getListeners($eventName = null)
    {
        if (null !== $eventName) {
            if (empty($this->listeners[$eventName])) {
                return [];
            }
 
            if (!isset($this->sorted[$eventName])) {
                $this->sortListeners($eventName);
            }
 
            return $this->sorted[$eventName];
Arguments
  1. array:1 [
      0 => array:2 [
        0 => ProblemsPlugin {#106}
        1 => "onFatalException"
      ]
    ]
    
  2. "onFatalException"
    
  3. Event {#91}
    
/var/www/kaj.kunigund.is/public_html/vendor/rockettheme/toolbox/Event/src/EventDispatcher.php
use Symfony\Component\EventDispatcher\Event as BaseEvent;
use Symfony\Component\EventDispatcher\EventDispatcher as BaseEventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
/**
 * Implements Symfony EventDispatcher interface.
 *
 * @package RocketTheme\Toolbox\Event
 * @author RocketTheme
 * @license MIT
 */
class EventDispatcher extends BaseEventDispatcher implements EventDispatcherInterface
{
    public function dispatch($eventName, BaseEvent $event = null)
    {
        if (null === $event) {
            $event = new Event();
        }
 
        return parent::dispatch($eventName, $event);
    }
}
 
Arguments
  1. "onFatalException"
    
  2. Event {#91}
    
/var/www/kaj.kunigund.is/public_html/system/src/Grav/Common/Grav.php
            foreach ($values as $i => $value) {
                header($key . ': ' . $value, $i === 0);
            }
        }
    }
 
    /**
     * Fires an event with optional parameters.
     *
     * @param  string $eventName
     * @param  Event  $event
     *
     * @return Event
     */
    public function fireEvent($eventName, Event $event = null)
    {
        /** @var EventDispatcher $events */
        $events = $this['events'];
 
        return $events->dispatch($eventName, $event);
    }
 
    /**
     * Set the final content length for the page and flush the buffer
     *
     */
    public function shutdown()
    {
        // Prevent user abort allowing onShutdown event to run without interruptions.
        if (\function_exists('ignore_user_abort')) {
            @ignore_user_abort(true);
        }
 
        // Close the session allowing new requests to be handled.
        if (isset($this['session'])) {
            $this['session']->close();
        }
 
        if ($this['config']->get('system.debugger.shutdown.close_connection', true)) {
            // Flush the response and close the connection to allow time consuming tasks to be performed without leaving
Arguments
  1. "onFatalException"
    
  2. Event {#91}
    
/var/www/kaj.kunigund.is/public_html/index.php
$loader = require $autoload;
 
use Grav\Common\Grav;
use RocketTheme\Toolbox\Event\Event;
 
// Get the Grav instance
$grav = Grav::instance(
    array(
        'loader' => $loader
    )
);
 
// Process the page
try {
    $grav->process();
} catch (\Error $e) {
    $grav->fireEvent('onFatalException', new Event(array('exception' => $e)));
    throw $e;
} catch (\Exception $e) {
    $grav->fireEvent('onFatalException', new Event(array('exception' => $e)));
    throw $e;
}
 
Arguments
  1. "onFatalException"
    
  2. Event {#91}
    

Environment & details:

empty
empty
empty
empty
empty
Key Value
HTTPS
"on"
SSL_TLS_SNI
"kaj.kunigund.is"
HTTP_ACCEPT
"*/*"
HTTP_USER_AGENT
"claudebot"
HTTP_HOST
"kaj.kunigund.is"
PATH
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
SERVER_SIGNATURE
"<address>Apache/2.4.29 (Ubuntu) Server at kaj.kunigund.is Port 443</address>\n"
SERVER_SOFTWARE
"Apache/2.4.29 (Ubuntu)"
SERVER_NAME
"kaj.kunigund.is"
SERVER_ADDR
"139.59.132.210"
SERVER_PORT
"443"
REMOTE_ADDR
"44.220.251.57"
DOCUMENT_ROOT
"/var/www/kaj.kunigund.is/public_html/"
REQUEST_SCHEME
"https"
CONTEXT_PREFIX
""
CONTEXT_DOCUMENT_ROOT
"/var/www/kaj.kunigund.is/public_html/"
SERVER_ADMIN
"sigurdur@tl.is"
SCRIPT_FILENAME
"/var/www/kaj.kunigund.is/public_html/index.php"
REMOTE_PORT
"33854"
GATEWAY_INTERFACE
"CGI/1.1"
SERVER_PROTOCOL
"HTTP/1.1"
REQUEST_METHOD
"GET"
QUERY_STRING
""
REQUEST_URI
"/"
SCRIPT_NAME
"/index.php"
PHP_SELF
"/index.php"
REQUEST_TIME_FLOAT
1711704718.243
REQUEST_TIME
1711704718
empty
0. Whoops\Handler\PrettyPageHandler
1. Whoops\Handler\CallbackHandler