Browse Source

Change Cache for PSR-16

Visman 4 years ago
parent
commit
6ee99cdb89

+ 2 - 2
app/Core/Cache.php

@@ -2,7 +2,7 @@
 
 namespace ForkBB\Core;
 
-use ForkBB\Core\Cache\ProviderCacheInterface;
+use Psr\SimpleCache\CacheInterface;
 
 class Cache
 {
@@ -12,7 +12,7 @@ class Cache
      */
     protected $provider;
 
-    public function __construct(ProviderCacheInterface $provider)
+    public function __construct(CacheInterface $provider)
     {
         $this->provider = $provider;
     }

+ 131 - 45
app/Core/Cache/FileCache.php

@@ -2,13 +2,17 @@
 
 namespace ForkBB\Core\Cache;
 
+use Psr\SimpleCache\CacheInterface;
+use Psr\SimpleCache\CacheException;
+use Psr\SimpleCache\InvalidArgumentException;
+use DateInterval;
+use DateTime;
+use DateTimeZone;
 use RecursiveDirectoryIterator;
 use RecursiveIteratorIterator;
 use RegexIterator;
-use RuntimeException;
-use InvalidArgumentException;
 
-class FileCache implements ProviderCacheInterface
+class FileCache implements CacheInterface
 {
     /**
      * Директория кэша
@@ -18,25 +22,26 @@ class FileCache implements ProviderCacheInterface
 
     public function __construct(string $dir)
     {
-        if (
-            empty($dir)
-            || ! \is_string($dir)
-        ) {
-            throw new InvalidArgumentException('Cache directory must be set to a string');
+        $dir = \rtrim($dir, '/');
+
+        if (empty($dir)) {
+            throw new CacheException('Cache directory unset');
         } elseif (! \is_dir($dir)) {
-            throw new RuntimeException("`$dir`: Not a directory");
+            throw new CacheException("Not a directory: {$dir}");
         } elseif (! \is_writable($dir)) {
-            throw new RuntimeException("No write access to `$dir` directory");
+            throw new CacheException("No write access to directory: {$dir}");
         }
+
         $this->cacheDir = $dir;
     }
 
     /**
-     * Получение данных из кэша по ключу
+     * Получает данные из кэша по ключу
      */
-    public function get(string $key, /* mixed */ $default = null) /* : mixed */
+    public function get($key, $default = null)
     {
-        $file = $this->file($key);
+        $file = $this->path($key);
+
         if (\is_file($file)) {
             require $file;
 
@@ -55,15 +60,23 @@ class FileCache implements ProviderCacheInterface
     }
 
     /**
-     * Установка данных в кэш по ключу
+     * Устанавливает данные в кэш по ключу
      */
-    public function set(string $key, /* mixed */ $value, int $ttl = null): bool
+    public function set($key, $value, $ttl = null)
     {
-        $file    = $this->file($key);
-        $expire  = null === $ttl || $ttl < 1 ? 0 : \time() + $ttl;
-        $content = "<?php\n\n" . '$expire = ' . $expire . ";\n\n" . '$data = ' . \var_export($value, true) . ";\n";
+        $file = $this->path($key);
+
+        if ($ttl instanceof DateInterval) {
+            $expire = (new DateTime('now', new DateTimeZone('UTC')))->add($value)->getTimestamp();
+        } else {
+            $expire  = null === $ttl || $ttl < 1 ? 0 : \time() + $ttl; //????
+        }
+
+        $value   = \var_export($value, true);
+        $content = "<?php\n\n\$expire = {$expire};\n\n\$data = {$value};\n";
+
         if (false === \file_put_contents($file, $content, \LOCK_EX)) {
-            throw new RuntimeException("The key '$key' can not be saved");
+            return false;
         } else {
             $this->invalidate($file);
 
@@ -72,28 +85,28 @@ class FileCache implements ProviderCacheInterface
     }
 
     /**
-     * Удаление данных по ключу
+     * Удаляет данные по ключу
      */
-    public function delete(string $key): bool
+    public function delete($key)
     {
-        $file = $this->file($key);
-        if (\is_file($file)) {
-            if (\unlink($file)) {
-                $this->invalidate($file);
+        $file = $this->path($key);
 
-                return true;
-            } else {
-                throw new RuntimeException("The key `$key` could not be removed");
-            }
-        } else {
-            return true;
+        if (
+            \is_file($file)
+            && ! \unlink($file)
+        ) {
+            return false;
         }
+
+        $this->invalidate($file);
+
+        return true;
     }
 
     /**
-     * Очистка кэша
+     * Очищает папку кэша от php файлов (рекурсивно)
      */
-    public function clear(): bool
+    public function clear()
     {
         $dir      = new RecursiveDirectoryIterator($this->cacheDir, RecursiveDirectoryIterator::SKIP_DOTS);
         $iterator = new RecursiveIteratorIterator($dir);
@@ -108,29 +121,92 @@ class FileCache implements ProviderCacheInterface
     }
 
     /**
-     * Проверка наличия ключа
+     * Получает данные по списку ключей
      */
-    public function has(string $key): bool
+    public function getMultiple($keys, $default = null)
     {
-        return null !== $this->get($key);
+        $this->validateIterable($keys);
+
+        $result = [];
+        foreach ($keys as $key) {
+            $result[$key] = $this->get($key, $default);
+        }
+
+        return $result;
     }
 
     /**
-     * Генерация имени файла по ключу
+     * Устанавливает данные в кэш по списку ключ => значение
      */
-    protected function file(string $key): string
+    public function setMultiple($values, $ttl = null)
     {
-        if (
-            \is_string($key)
-            && \preg_match('%^[a-z0-9_-]+$%Di', $key)
-        ) {
-            return $this->cacheDir . '/cache_' . $key . '.php';
+        $this->validateIterable($keys);
+
+        $result = true;
+        foreach ($values as $key => $value) {
+            $result = $this->set($key, $value, $ttl) && $result;
         }
-        throw new InvalidArgumentException("Key '$key' contains invalid characters.");
+
+        return $result;
     }
 
     /**
-     * Очистка opcache и apc от закэшированного файла
+     * Удаляет данные по списку ключей
+     */
+    public function deleteMultiple($keys)
+    {
+        $this->validateIterable($keys);
+
+        $result = true;
+        foreach ($keys as $key) {
+            $result = $this->delete($key) && $result;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Проверяет кеш на наличие ключа
+     */
+    public function has($key)
+    {
+        $file = $this->path($key);
+
+        if (\is_file($file)) {
+            require $file;
+
+            if (
+                isset($expire, $data)
+                && (
+                    $expire < 1
+                    || $expire > \time()
+                )
+            ) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Проверяет ключ
+     * Генерирует путь до файла
+     */
+    protected function path($key): string
+    {
+        if (! \is_string($key)) {
+            throw new InvalidArgumentException('Expects a string, got: ' . \gettype($key));
+        }
+        if (! \preg_match('%^[a-z0-9_\.]+$%Di', $key)) {
+            throw new InvalidArgumentException('Key is not a legal value');
+        }
+
+        return $this->cacheDir . "/cache_{$key}.php";
+    }
+
+    /**
+     * Очищает opcache и apc от закэшированного файла
      */
     protected function invalidate(string $file): void
     {
@@ -140,4 +216,14 @@ class FileCache implements ProviderCacheInterface
             \apc_delete_file($file);
         }
     }
+
+    /**
+     * Проверяет, является ли переменная итерируемой
+     */
+    protected function validateIterable($iterable): void
+    {
+        if (! \is_iterable($iterable)) {
+            throw new InvalidArgumentException('Expects a iterable, got: ' . \gettype($iterable));
+        }
+    }
 }

+ 11 - 5
app/Models/AdminList/Model.php

@@ -3,6 +3,7 @@
 namespace ForkBB\Models\AdminList;
 
 use ForkBB\Models\Model as ParentModel;
+use RuntimeException;
 
 class Model extends ParentModel
 {
@@ -11,11 +12,14 @@ class Model extends ParentModel
      */
     public function init(): Model
     {
-        if ($this->c->Cache->has('admins')) {
-            $this->list = $this->c->Cache->get('admins');
-        } else {
+        $this->list = $this->c->Cache->get('admins');
+
+        if (! \is_array($this->list)) {
             $this->list = \array_flip($this->c->users->adminsIds());
-            $this->c->Cache->set('admins', $this->list);
+
+            if (true !== $this->c->Cache->set('admins', $this->list)) {
+                throw new RuntimeException('Unable to write value to cache - admins');
+            }
         }
 
         return $this;
@@ -26,7 +30,9 @@ class Model extends ParentModel
      */
     public function reset(): Model
     {
-        $this->c->Cache->delete('admins');
+        if (true !== $this->c->Cache->delete('admins')) {
+            throw new RuntimeException('Unable to remove key from cache - admins');
+        }
 
         return $this;
     }

+ 6 - 1
app/Models/BanList/Load.php

@@ -4,6 +4,7 @@ namespace ForkBB\Models\BanList;
 
 use ForkBB\Models\Method;
 use ForkBB\Models\BanList\Model as BanList;
+use RuntimeException;
 
 class Load extends Method
 {
@@ -77,13 +78,17 @@ class Load extends Method
         $this->model->userList  = $userList;
         $this->model->emailList = $emailList;
         $this->model->ipList    = $ipList;
-        $this->c->Cache->set('banlist', [
+        $result = $this->c->Cache->set('banlist', [
             'banList'   => $banList,
             'userList'  => $userList,
             'emailList' => $emailList,
             'ipList'    => $ipList,
         ]);
 
+        if (true !== $result) {
+            throw new RuntimeException('Unable to write value to cache - banlist');
+        }
+
         return $this->model;
     }
 }

+ 1 - 5
app/Models/BanList/Model.php

@@ -11,11 +11,7 @@ class Model extends ParentModel
      */
     public function init(): Model
     {
-        if ($this->c->Cache->has('banlist')) {
-            $list = $this->c->Cache->get('banlist');
-        } else {
-            $list = null;
-        }
+        $list = $this->c->Cache->get('banlist');
 
         if (isset($list['banList'], $list['userList'], $list['emailList'], $list['ipList'])) {
             $this->banList   = $list['banList'];

+ 3 - 2
app/Models/Censorship/Model.php

@@ -12,8 +12,9 @@ class Model extends ParentModel
     public function init(): Model
     {
         if ('1' == $this->c->config->o_censoring) {
-            if ($this->c->Cache->has('censorship')) {
-                $list              = $this->c->Cache->get('censorship');
+            $list = $this->c->Cache->get('censorship');
+
+            if (isset($list['searchList'], $list['replaceList'])) {
                 $this->searchList  = $list['searchList'];
                 $this->replaceList = $list['replaceList'];
             } else {

+ 6 - 1
app/Models/Censorship/Refresh.php

@@ -4,6 +4,7 @@ namespace ForkBB\Models\Censorship;
 
 use ForkBB\Models\Method;
 use ForkBB\Models\Censorship\Model as Censorship;
+use RuntimeException;
 
 class Refresh extends Method
 {
@@ -27,11 +28,15 @@ class Refresh extends Method
         }
         $this->model->searchList  = $search;
         $this->model->replaceList = $replace;
-        $this->c->Cache->set('censorship', [
+        $result = $this->c->Cache->set('censorship', [
             'searchList'  => $search,
             'replaceList' => $replace,
         ]);
 
+        if (true !== $result) {
+            throw new RuntimeException('Unable to write value to cache - censorship');
+        }
+
         return $this->model;
     }
 }

+ 4 - 1
app/Models/Censorship/Save.php

@@ -5,6 +5,7 @@ namespace ForkBB\Models\Censorship;
 use ForkBB\Models\Method;
 use ForkBB\Models\Censorship\Model as Censorship;
 use PDO;
+use RuntimeException;
 
 class Save extends Method
 {
@@ -61,7 +62,9 @@ class Save extends Method
             $this->c->DB->exec($query, $vars);
         }
 
-        $this->c->Cache->delete('censorship');
+        if (true !== $this->c->Cache->delete('censorship')) {
+            throw new RuntimeException('Unable to remove key from cache - censorship');
+        }
 
         return $this->model;
     }

+ 5 - 1
app/Models/Config/Load.php

@@ -5,6 +5,7 @@ namespace ForkBB\Models\Config;
 use ForkBB\Models\Method;
 use ForkBB\Models\Config\Model as Config;
 use PDO;
+use RuntimeException;
 
 class Load extends Method
 {
@@ -38,7 +39,10 @@ class Load extends Method
         }
 
         $this->model->setAttrs($config);
-        $this->c->Cache->set('config', $config);
+
+        if (true !== $this->c->Cache->set('config', $config)) {
+            throw new RuntimeException('Unable to write value to cache - config');
+        }
 
         return $this->model;
     }

+ 4 - 2
app/Models/Config/Model.php

@@ -11,8 +11,10 @@ class Model extends DataModel
      */
     public function init(): Model
     {
-        if ($this->c->Cache->has('config')) {
-            $this->setAttrs($this->c->Cache->get('config'));
+        $config = $this->c->Cache->get('config');
+
+        if (\is_array($config)) {
+            $this->setAttrs($config);
         } else {
             $this->load();
         }

+ 4 - 1
app/Models/Config/Save.php

@@ -4,6 +4,7 @@ namespace ForkBB\Models\Config;
 
 use ForkBB\Models\Method;
 use ForkBB\Models\Config\Model as Config;
+use RuntimeException;
 
 class Save extends Method
 {
@@ -73,7 +74,9 @@ class Save extends Method
                 $this->c->DB->exec($query, $vars);
             }
         }
-        $this->c->Cache->delete('config');
+        if (true !== $this->c->Cache->delete('config')) {
+            throw new RuntimeException('Unable to remove key from cache - config');
+        }
 
         return $this->model;
     }

+ 13 - 6
app/Models/DBMap/Model.php

@@ -3,6 +3,7 @@
 namespace ForkBB\Models\DBMap;
 
 use ForkBB\Models\Model as ParentModel;
+use RuntimeException;
 
 class Model extends ParentModel
 {
@@ -11,14 +12,18 @@ class Model extends ParentModel
      */
     public function init(): Model
     {
-        if ($this->c->Cache->has('db_map')) {
-            $this->setAttrs($this->c->Cache->get('db_map'));
-        } else {
+        $map = $this->c->Cache->get('db_map');
+
+        if (! \is_array($map)) {
             $map = $this->c->DB->getMap();
-            $this->c->Cache->set('db_map', $map);
-            $this->setAttrs($map);
+
+            if (true !== $this->c->Cache->set('db_map', $map)) {
+                throw new RuntimeException('Unable to write value to cache - db_map');
+            }
         }
 
+        $this->setAttrs($map);
+
         return $this;
     }
 
@@ -27,7 +32,9 @@ class Model extends ParentModel
      */
     public function reset(): Model
     {
-        $this->c->Cache->delete('db_map');
+        if (true !== $this->c->Cache->delete('db_map')) {
+            throw new RuntimeException('Unable to remove key from cache - db_map');
+        }
 
         return $this;
     }

+ 7 - 2
app/Models/Forum/Manager.php

@@ -36,7 +36,10 @@ class Manager extends ManagerModel
 
         $mark = $this->c->Cache->get('forums_mark');
         if (empty($mark)) {
-            $this->c->Cache->set('forums_mark', \time());
+            if (true !== $this->c->Cache->set('forums_mark', \time())) {
+                throw new RuntimeException('Unable to write value to cache - forums_mark');
+            }
+
             $list = $this->refresh($group);
         } else {
             $result = $this->c->Cache->get('forums_' . $gid);
@@ -113,7 +116,9 @@ class Manager extends ManagerModel
      */
     public function reset(): Manager
     {
-        $this->c->Cache->delete('forums_mark');
+        if (true !== $this->c->Cache->delete('forums_mark')) {
+            throw new RuntimeException('Unable to remove key from cache - forums_mark');
+        }
 
         return $this;
     }

+ 6 - 1
app/Models/Forum/Refresh.php

@@ -4,6 +4,7 @@ namespace ForkBB\Models\Forum;
 
 use ForkBB\Models\Action;
 use ForkBB\Models\Group\Model as Group;
+use RuntimeException;
 
 class Refresh extends Action
 {
@@ -50,11 +51,15 @@ class Refresh extends Action
             }
         }
 
-        $this->c->Cache->set('forums_' . $gid, [
+        $result = $this->c->Cache->set('forums_' . $gid, [
             'time' => \time(),
             'list' => $this->list,
         ]);
 
+        if (true !== $result) {
+            throw new RuntimeException('Unable to write value to cache - forums_' . $gid);
+        }
+
         return $this->list;
     }
 

+ 4 - 1
app/Models/Pages/Admin/Install.php

@@ -481,7 +481,10 @@ class Install extends Admin
     protected function installEnd(Validator $v): Page
     {
         @\set_time_limit(0);
-        $this->c->Cache->clear();
+
+        if (true !== $this->c->Cache->clear()) {
+            throw new RuntimeException('Unable to clear cache');
+        }
 
         // bans
         $schema = [

+ 3 - 1
app/Models/Pages/Admin/Update.php

@@ -363,7 +363,9 @@ class Update extends Admin
 
             $this->c->config->save();
 
-            $this->c->Cache->clear();
+            if (true !== $this->c->Cache->clear()) {
+                throw new RuntimeException('Unable to clear cache');
+            }
 
             return $this->c->Redirect->page('Index')->message('Successfully updated');
         } catch (ForkException $excp) {

+ 4 - 1
app/Models/Pages/Feed.php

@@ -6,6 +6,7 @@ use ForkBB\Models\Page;
 use ForkBB\Models\Forum\Model as Forum;
 use ForkBB\Models\Topic\Model as Topic;
 use ForkBB\Models\User\Model as User;
+use RuntimeException;
 use function \ForkBB\__;
 
 class Feed extends Page
@@ -130,7 +131,9 @@ class Feed extends Page
 
 
                 if (null !== $cacheId) {
-                    $this->c->Cache->set($cacheId, $feed, 60 * $this->c->config->o_feed_ttl);
+                    if (true !== $this->c->Cache->set($cacheId, $feed, 60 * $this->c->config->o_feed_ttl)) {
+                        throw new RuntimeException('Unable to write value to cache - feed');
+                    }
                 }
             }
         }

+ 6 - 4
app/Models/Report/Manager.php

@@ -74,9 +74,9 @@ class Manager extends ManagerModel
      */
     public function lastId(): int
     {
-        if ($this->c->Cache->has('report')) {
-            $last = $this->list = $this->c->Cache->get('report');
-        } else {
+        $last = $this->list = $this->c->Cache->get('report');
+
+        if (null === $last) {
             $query = 'SELECT r.id
                 FROM ::reports AS r
                 ORDER BY r.id DESC
@@ -84,7 +84,9 @@ class Manager extends ManagerModel
 
             $last = (int) $this->c->DB->query($query)->fetchColumn();
 
-            $this->c->Cache->set('report', $last);
+            if (true !== $this->c->Cache->set('report', $last)) {
+                throw new RuntimeException('Unable to write value to cache - report');
+            }
         }
 
         return $last;

+ 3 - 1
app/Models/Report/Save.php

@@ -80,7 +80,9 @@ class Save extends Action
         $report->id = (int) $this->c->DB->lastInsertId();
         $report->resModified();
 
-        $this->c->Cache->set('report', $report->id);
+        if (true !== $this->c->Cache->set('report', $report->id)) {
+            throw new RuntimeException('Unable to write value to cache - report');
+        }
 
         return $report->id;
     }

+ 4 - 1
app/Models/SmileyList/Load.php

@@ -5,6 +5,7 @@ namespace ForkBB\Models\SmileyList;
 use ForkBB\Models\Method;
 use ForkBB\Models\SmileyList\Model as SmileyList;
 use PDO;
+use RuntimeException;
 
 class Load extends Method
 {
@@ -22,7 +23,9 @@ class Load extends Method
 
         $this->model->list = $list;
 
-        $this->c->Cache->set('smilies', $list);
+        if (true !== $this->c->Cache->set('smilies', $list)) {
+            throw new RuntimeException('Unable to write value to cache - smilies');
+        }
 
         return $this->model;
     }

+ 7 - 4
app/Models/SmileyList/Model.php

@@ -3,6 +3,7 @@
 namespace ForkBB\Models\SmileyList;
 
 use ForkBB\Models\Model as ParentModel;
+use RuntimeException;
 
 class Model extends ParentModel
 {
@@ -11,9 +12,9 @@ class Model extends ParentModel
      */
     public function init(): Model
     {
-        if ($this->c->Cache->has('smilies')) {
-            $this->list = $this->c->Cache->get('smilies');
-        } else {
+        $this->list = $this->c->Cache->get('smilies');
+
+        if (! \is_array($this->list)) {
             $this->load();
         }
 
@@ -25,7 +26,9 @@ class Model extends ParentModel
      */
     public function reset(): Model
     {
-        $this->c->Cache->delete('smilies');
+        if (true !== $this->c->Cache->delete('smilies')) {
+            throw new RuntimeException('Unable to remove key from cache - smilies');
+        }
 
         return $this;
     }

+ 12 - 5
app/Models/Stats/Model.php

@@ -4,6 +4,7 @@ namespace ForkBB\Models\Stats;
 
 use ForkBB\Models\Model as ParentModel;
 use PDO;
+use RuntimeException;
 
 class Model extends ParentModel
 {
@@ -12,12 +13,16 @@ class Model extends ParentModel
      */
     public function init(): Model
     {
-        if ($this->c->Cache->has('stats')) {
-            $list = $this->c->Cache->get('stats');
-        } else {
+        $list = $this->c->Cache->get('stats');
+
+        if (! \is_array($list)) {
             $list = $this->c->users->stats();
-            $this->c->Cache->set('stats', $list);
+
+            if (true !== $this->c->Cache->set('stats', $list)) {
+                throw new RuntimeException('Unable to write value to cache - stats');
+            }
         }
+
         $this->userTotal = $list['total'];
         $this->userLast  = $list['last'];
 
@@ -34,7 +39,9 @@ class Model extends ParentModel
      */
     public function reset(): Model
     {
-        $this->c->Cache->delete('stats');
+        if (true !== $this->c->Cache->delete('stats')) {
+            throw new RuntimeException('Unable to remove key from cache - stats');
+        }
 
         return $this;
     }

+ 5 - 1
app/Models/Stopwords/Model.php

@@ -3,6 +3,7 @@
 namespace ForkBB\Models\Stopwords;
 
 use ForkBB\Models\Model as ParentModel;
+use RuntimeException;
 
 class Model extends ParentModel
 {
@@ -72,7 +73,10 @@ class Model extends ParentModel
         $stopwords = \array_filter($stopwords);
         $stopwords = \array_flip($stopwords);
 
-        $this->c->Cache->set('stopwords', ['id' => $id, 'stopwords' => $stopwords]);
+        if (true !== $this->c->Cache->set('stopwords', ['id' => $id, 'stopwords' => $stopwords])) {
+            throw new RuntimeException('Unable to write value to cache - stopwords');
+        }
+
         $this->list = $stopwords;
 
         return $this;

+ 2 - 1
composer.json

@@ -30,6 +30,7 @@
         "ext-fileinfo": "*",
         "artoodetoo/dirk": "dev-visman",
         "miovisman/parserus": "dev-master",
-        "miovisman/normemail": "dev-master"
+        "miovisman/normemail": "dev-master",
+        "psr/simple-cache": "*"
     }
 }

+ 52 - 3
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "dd233d78a2c422cc3c940a860acb6b41",
+    "content-hash": "8798521335e67d2195e6b1793d67a21c",
     "packages": [
         {
             "name": "artoodetoo/dirk",
@@ -146,6 +146,54 @@
                 "parser"
             ],
             "time": "2019-10-11T12:06:27+00:00"
+        },
+        {
+            "name": "psr/simple-cache",
+            "version": "dev-master",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/simple-cache.git",
+                "reference": "5a7b96b1dda5d957e01bc1bfe77dcca09c5a7474"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/5a7b96b1dda5d957e01bc1bfe77dcca09c5a7474",
+                "reference": "5a7b96b1dda5d957e01bc1bfe77dcca09c5a7474",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\SimpleCache\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interfaces for simple caching",
+            "keywords": [
+                "cache",
+                "caching",
+                "psr",
+                "psr-16",
+                "simple-cache"
+            ],
+            "time": "2020-04-21T06:43:17+00:00"
         }
     ],
     "packages-dev": [],
@@ -159,9 +207,10 @@
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": {
-        "php": ">=5.6.12",
+        "php": ">=7.3.0",
         "ext-gd": "*",
-        "ext-mbstring": "*"
+        "ext-mbstring": "*",
+        "ext-fileinfo": "*"
     },
     "platform-dev": []
 }

+ 1 - 0
vendor/composer/autoload_psr4.php

@@ -7,6 +7,7 @@ $baseDir = dirname($vendorDir);
 
 return array(
     'R2\\Templating\\' => array($vendorDir . '/artoodetoo/dirk/src'),
+    'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
     'MioVisman\\NormEmail\\' => array($vendorDir . '/miovisman/normemail/src'),
     'ForkBB\\' => array($baseDir . '/app'),
 );

+ 8 - 0
vendor/composer/autoload_static.php

@@ -11,6 +11,10 @@ class ComposerStaticInit90ad93c7251d4f60daa9e545879c49e7
         array (
             'R2\\Templating\\' => 14,
         ),
+        'P' => 
+        array (
+            'Psr\\SimpleCache\\' => 16,
+        ),
         'M' => 
         array (
             'MioVisman\\NormEmail\\' => 20,
@@ -26,6 +30,10 @@ class ComposerStaticInit90ad93c7251d4f60daa9e545879c49e7
         array (
             0 => __DIR__ . '/..' . '/artoodetoo/dirk/src',
         ),
+        'Psr\\SimpleCache\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/psr/simple-cache/src',
+        ),
         'MioVisman\\NormEmail\\' => 
         array (
             0 => __DIR__ . '/..' . '/miovisman/normemail/src',

+ 50 - 0
vendor/composer/installed.json

@@ -145,5 +145,55 @@
             "bbcode",
             "parser"
         ]
+    },
+    {
+        "name": "psr/simple-cache",
+        "version": "dev-master",
+        "version_normalized": "9999999-dev",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/php-fig/simple-cache.git",
+            "reference": "5a7b96b1dda5d957e01bc1bfe77dcca09c5a7474"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/5a7b96b1dda5d957e01bc1bfe77dcca09c5a7474",
+            "reference": "5a7b96b1dda5d957e01bc1bfe77dcca09c5a7474",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.0"
+        },
+        "time": "2020-04-21T06:43:17+00:00",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.0.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "Psr\\SimpleCache\\": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "PHP-FIG",
+                "homepage": "http://www.php-fig.org/"
+            }
+        ],
+        "description": "Common interfaces for simple caching",
+        "keywords": [
+            "cache",
+            "caching",
+            "psr",
+            "psr-16",
+            "simple-cache"
+        ]
     }
 ]

+ 12 - 0
vendor/psr/simple-cache/.editorconfig

@@ -0,0 +1,12 @@
+; This file is for unifying the coding style for different editors and IDEs.
+; More information at http://editorconfig.org
+
+root = true
+
+[*]
+charset = utf-8
+indent_size = 4
+indent_style = space
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true

+ 21 - 0
vendor/psr/simple-cache/LICENSE.md

@@ -0,0 +1,21 @@
+# The MIT License (MIT)
+
+Copyright (c) 2016 PHP Framework Interoperability Group
+
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.

+ 8 - 0
vendor/psr/simple-cache/README.md

@@ -0,0 +1,8 @@
+PHP FIG Simple Cache PSR
+========================
+
+This repository holds all interfaces related to PSR-16.
+
+Note that this is not a cache implementation of its own. It is merely an interface that describes a cache implementation. See [the specification](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-16-simple-cache.md) for more details.
+
+You can find implementations of the specification by looking for packages providing the [psr/simple-cache-implementation](https://packagist.org/providers/psr/simple-cache-implementation) virtual package.

+ 25 - 0
vendor/psr/simple-cache/composer.json

@@ -0,0 +1,25 @@
+{
+    "name": "psr/simple-cache",
+    "description": "Common interfaces for simple caching",
+    "keywords": ["psr", "psr-16", "cache", "simple-cache", "caching"],
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "PHP-FIG",
+            "homepage": "http://www.php-fig.org/"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Psr\\SimpleCache\\": "src/"
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.0.x-dev"
+        }
+    }
+}

+ 10 - 0
vendor/psr/simple-cache/src/CacheException.php

@@ -0,0 +1,10 @@
+<?php
+
+namespace Psr\SimpleCache;
+
+/**
+ * Interface used for all types of exceptions thrown by the implementing library.
+ */
+interface CacheException
+{
+}

+ 114 - 0
vendor/psr/simple-cache/src/CacheInterface.php

@@ -0,0 +1,114 @@
+<?php
+
+namespace Psr\SimpleCache;
+
+interface CacheInterface
+{
+    /**
+     * Fetches a value from the cache.
+     *
+     * @param string $key     The unique key of this item in the cache.
+     * @param mixed  $default Default value to return if the key does not exist.
+     *
+     * @return mixed The value of the item from the cache, or $default in case of cache miss.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if the $key string is not a legal value.
+     */
+    public function get($key, $default = null);
+
+    /**
+     * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
+     *
+     * @param string                 $key   The key of the item to store.
+     * @param mixed                  $value The value of the item to store, must be serializable.
+     * @param null|int|\DateInterval $ttl   Optional. The TTL value of this item. If no value is sent and
+     *                                      the driver supports TTL then the library may set a default value
+     *                                      for it or let the driver take care of that.
+     *
+     * @return bool True on success and false on failure.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if the $key string is not a legal value.
+     */
+    public function set($key, $value, $ttl = null);
+
+    /**
+     * Delete an item from the cache by its unique key.
+     *
+     * @param string $key The unique cache key of the item to delete.
+     *
+     * @return bool True if the item was successfully removed. False if there was an error.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if the $key string is not a legal value.
+     */
+    public function delete($key);
+
+    /**
+     * Wipes clean the entire cache's keys.
+     *
+     * @return bool True on success and false on failure.
+     */
+    public function clear();
+
+    /**
+     * Obtains multiple cache items by their unique keys.
+     *
+     * @param iterable $keys    A list of keys that can be obtained in a single operation.
+     * @param mixed    $default Default value to return for keys that do not exist.
+     *
+     * @return iterable A list of key => value pairs. Cache keys that do not exist or are stale will have $default as value.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if $keys is neither an array nor a Traversable,
+     *   or if any of the $keys are not a legal value.
+     */
+    public function getMultiple($keys, $default = null);
+
+    /**
+     * Persists a set of key => value pairs in the cache, with an optional TTL.
+     *
+     * @param iterable               $values A list of key => value pairs for a multiple-set operation.
+     * @param null|int|\DateInterval $ttl    Optional. The TTL value of this item. If no value is sent and
+     *                                       the driver supports TTL then the library may set a default value
+     *                                       for it or let the driver take care of that.
+     *
+     * @return bool True on success and false on failure.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if $values is neither an array nor a Traversable,
+     *   or if any of the $values are not a legal value.
+     */
+    public function setMultiple($values, $ttl = null);
+
+    /**
+     * Deletes multiple cache items in a single operation.
+     *
+     * @param iterable $keys A list of string-based keys to be deleted.
+     *
+     * @return bool True if the items were successfully removed. False if there was an error.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if $keys is neither an array nor a Traversable,
+     *   or if any of the $keys are not a legal value.
+     */
+    public function deleteMultiple($keys);
+
+    /**
+     * Determines whether an item is present in the cache.
+     *
+     * NOTE: It is recommended that has() is only to be used for cache warming type purposes
+     * and not to be used within your live applications operations for get/set, as this method
+     * is subject to a race condition where your has() will return true and immediately after,
+     * another script can remove it making the state of your app out of date.
+     *
+     * @param string $key The cache item key.
+     *
+     * @return bool
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if the $key string is not a legal value.
+     */
+    public function has($key);
+}

+ 13 - 0
vendor/psr/simple-cache/src/InvalidArgumentException.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace Psr\SimpleCache;
+
+/**
+ * Exception interface for invalid cache arguments.
+ *
+ * When an invalid argument is passed it must throw an exception which implements
+ * this interface
+ */
+interface InvalidArgumentException extends CacheException
+{
+}