From bc291bee783a3124aa9c123de59b3acd4719b106 Mon Sep 17 00:00:00 2001
From: Dan Brown <ssddanbrown@googlemail.com>
Date: Fri, 5 Nov 2021 16:18:06 +0000
Subject: [PATCH] Added inital phpstan/larastan setup

---
 .github/workflows/phpstan.yml             |  41 +
 .gitignore                                |   3 +-
 app/Api/ApiDocsGenerator.php              |   2 +-
 app/Auth/User.php                         |   1 -
 app/Config/broadcasting.php               |  86 +-
 app/Config/cache.php                      |  68 +-
 app/Config/database.php                   |   2 +-
 app/Console/Commands/CreateAdmin.php      |  14 +-
 app/Entities/Repos/BookshelfRepo.php      |   3 +-
 app/Entities/Tools/SearchOptions.php      |   4 +-
 app/Entities/Tools/TrashCan.php           |   2 +
 app/Http/Controllers/StatusController.php |   4 +-
 app/Uploads/AttachmentService.php         |   8 +-
 app/Uploads/ImageRepo.php                 |   2 +-
 app/Uploads/ImageService.php              |   9 +-
 bootstrap/phpstan.php                     |   6 +
 composer.json                             |   5 +-
 composer.lock                             | 925 +++++++++++++++++++++-
 phpstan.neon.dist                         |  23 +
 tests/StatusTest.php                      |   2 +-
 20 files changed, 1086 insertions(+), 124 deletions(-)
 create mode 100644 .github/workflows/phpstan.yml
 create mode 100644 bootstrap/phpstan.php
 create mode 100644 phpstan.neon.dist

diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml
new file mode 100644
index 000000000..da9901bdc
--- /dev/null
+++ b/.github/workflows/phpstan.yml
@@ -0,0 +1,41 @@
+name: phpstan
+
+on:
+  push:
+    branches-ignore:
+      - l10n_master
+  pull_request:
+    branches-ignore:
+      - l10n_master
+
+jobs:
+  build:
+    runs-on: ubuntu-20.04
+    strategy:
+      matrix:
+        php: ['7.3']
+    steps:
+    - uses: actions/checkout@v1
+
+    - name: Setup PHP
+      uses: shivammathur/setup-php@v2
+      with:
+        php-version: ${{ matrix.php }}
+        extensions: gd, mbstring, json, curl, xml, mysql, ldap
+
+    - name: Get Composer Cache Directory
+      id: composer-cache
+      run: |
+        echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+    - name: Cache composer packages
+      uses: actions/cache@v1
+      with:
+        path: ${{ steps.composer-cache.outputs.dir }}
+        key: ${{ runner.os }}-composer-${{ matrix.php }}
+
+    - name: Install composer dependencies & Test
+      run: composer install --prefer-dist --no-interaction --ansi
+
+    - name: Run PHPStan
+      run: php${{ matrix.php }} ./vendor/bin/phpstan analyse --memory-limit=2G
diff --git a/.gitignore b/.gitignore
index fc0f10a00..0a858681c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,4 +23,5 @@ nbproject
 .settings/
 webpack-stats.json
 .phpunit.result.cache
-.DS_Store
\ No newline at end of file
+.DS_Store
+phpstan.neon
\ No newline at end of file
diff --git a/app/Api/ApiDocsGenerator.php b/app/Api/ApiDocsGenerator.php
index ea77ae450..0447cd731 100644
--- a/app/Api/ApiDocsGenerator.php
+++ b/app/Api/ApiDocsGenerator.php
@@ -28,7 +28,7 @@ class ApiDocsGenerator
         if (Cache::has($cacheKey) && config('app.env') === 'production') {
             $docs = Cache::get($cacheKey);
         } else {
-            $docs = (new static())->generate();
+            $docs = (new ApiDocsGenerator)->generate();
             Cache::put($cacheKey, $docs, 60 * 24);
         }
 
diff --git a/app/Auth/User.php b/app/Auth/User.php
index dc28aa9b7..540a8d7ab 100644
--- a/app/Auth/User.php
+++ b/app/Auth/User.php
@@ -178,7 +178,6 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
             ->leftJoin('permission_role', 'ru.role_id', '=', 'permission_role.role_id')
             ->leftJoin('role_permissions', 'permission_role.permission_id', '=', 'role_permissions.id')
             ->where('ru.user_id', '=', $this->id)
-            ->get()
             ->pluck('name');
 
         return $this->permissions;
diff --git a/app/Config/broadcasting.php b/app/Config/broadcasting.php
index be0d7376c..09189bb09 100644
--- a/app/Config/broadcasting.php
+++ b/app/Config/broadcasting.php
@@ -1,79 +1,51 @@
 <?php
 
 /**
- * Caching configuration options.
+ * Broadcasting configuration options.
  *
  * Changes to these config files are not supported by BookStack and may break upon updates.
  * Configuration should be altered via the `.env` file or environment variables.
  * Do not edit this file unless you're happy to maintain any changes yourself.
  */
 
-// MEMCACHED - Split out configuration into an array
-if (env('CACHE_DRIVER') === 'memcached') {
-    $memcachedServerKeys = ['host', 'port', 'weight'];
-    $memcachedServers = explode(',', trim(env('MEMCACHED_SERVERS', '127.0.0.1:11211:100'), ','));
-    foreach ($memcachedServers as $index => $memcachedServer) {
-        $memcachedServerDetails = explode(':', $memcachedServer);
-        if (count($memcachedServerDetails) < 2) {
-            $memcachedServerDetails[] = '11211';
-        }
-        if (count($memcachedServerDetails) < 3) {
-            $memcachedServerDetails[] = '100';
-        }
-        $memcachedServers[$index] = array_combine($memcachedServerKeys, $memcachedServerDetails);
-    }
-}
-
 return [
 
-    // Default cache store to use
-    // Can be overridden at cache call-time
-    'default' => env('CACHE_DRIVER', 'file'),
+    // Default Broadcaster
+    // This option controls the default broadcaster that will be used by the
+    // framework when an event needs to be broadcast. This can be set to
+    // any of the connections defined in the "connections" array below.
+    'default' => env('BROADCAST_DRIVER', 'pusher'),
 
-    // Available caches stores
-    'stores' => [
+    // Broadcast Connections
+    // Here you may define all of the broadcast connections that will be used
+    // to broadcast events to other systems or over websockets. Samples of
+    // each available type of connection are provided inside this array.
+    'connections' => [
 
-        'apc' => [
-            'driver' => 'apc',
-        ],
-
-        'array' => [
-            'driver'    => 'array',
-            'serialize' => false,
-        ],
-
-        'database' => [
-            'driver'          => 'database',
-            'table'           => 'cache',
-            'connection'      => null,
-            'lock_connection' => null,
-        ],
-
-        'file' => [
-            'driver' => 'file',
-            'path'   => storage_path('framework/cache'),
-        ],
-
-        'memcached' => [
-            'driver'  => 'memcached',
-            'servers' => env('CACHE_DRIVER') === 'memcached' ? $memcachedServers : [],
-            'options' => [],
+        'pusher' => [
+            'driver'  => 'pusher',
+            'key'     => env('PUSHER_APP_KEY'),
+            'secret'  => env('PUSHER_APP_SECRET'),
+            'app_id'  => env('PUSHER_APP_ID'),
+            'options' => [
+                'cluster' => env('PUSHER_APP_CLUSTER'),
+                'useTLS'  => true,
+            ],
         ],
 
         'redis' => [
-            'driver'          => 'redis',
-            'connection'      => 'default',
-            'lock_connection' => 'default',
+            'driver'     => 'redis',
+            'connection' => 'default',
         ],
 
-        'octane' => [
-            'driver' => 'octane',
+        'log' => [
+            'driver' => 'log',
+        ],
+
+        'null' => [
+            'driver' => 'null',
         ],
 
     ],
 
-    // Cache key prefix
-    // Used to prevent collisions in shared cache systems.
-    'prefix' => env('CACHE_PREFIX', 'bookstack_cache'),
-
-];
+];
\ No newline at end of file
diff --git a/app/Config/cache.php b/app/Config/cache.php
index 6fd4807da..ded1dcae6 100644
--- a/app/Config/cache.php
+++ b/app/Config/cache.php
@@ -2,35 +2,37 @@
 
 use Illuminate\Support\Str;
 
+/**
+ * Caching configuration options.
+ *
+ * Changes to these config files are not supported by BookStack and may break upon updates.
+ * Configuration should be altered via the `.env` file or environment variables.
+ * Do not edit this file unless you're happy to maintain any changes yourself.
+ */
+
+// MEMCACHED - Split out configuration into an array
+if (env('CACHE_DRIVER') === 'memcached') {
+    $memcachedServerKeys = ['host', 'port', 'weight'];
+    $memcachedServers = explode(',', trim(env('MEMCACHED_SERVERS', '127.0.0.1:11211:100'), ','));
+    foreach ($memcachedServers as $index => $memcachedServer) {
+        $memcachedServerDetails = explode(':', $memcachedServer);
+        if (count($memcachedServerDetails) < 2) {
+            $memcachedServerDetails[] = '11211';
+        }
+        if (count($memcachedServerDetails) < 3) {
+            $memcachedServerDetails[] = '100';
+        }
+        $memcachedServers[$index] = array_combine($memcachedServerKeys, $memcachedServerDetails);
+    }
+}
+
 return [
 
-    /*
-    |--------------------------------------------------------------------------
-    | Default Cache Store
-    |--------------------------------------------------------------------------
-    |
-    | This option controls the default cache connection that gets used while
-    | using this caching library. This connection is used when another is
-    | not explicitly specified when executing a given caching function.
-    |
-    */
-
+    // Default cache store to use
+    // Can be overridden at cache call-time
     'default' => env('CACHE_DRIVER', 'file'),
 
-    /*
-    |--------------------------------------------------------------------------
-    | Cache Stores
-    |--------------------------------------------------------------------------
-    |
-    | Here you may define all of the cache "stores" for your application as
-    | well as their drivers. You may even define multiple stores for the
-    | same cache driver to group types of items stored in your caches.
-    |
-    | Supported drivers: "apc", "array", "database", "file",
-    |         "memcached", "redis", "dynamodb", "octane", "null"
-    |
-    */
-
+    // Available caches stores
     'stores' => [
 
         'apc' => [
@@ -56,15 +58,10 @@ return [
 
         'memcached' => [
             'driver'        => 'memcached',
-            'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
-            'sasl'          => [
-                env('MEMCACHED_USERNAME'),
-                env('MEMCACHED_PASSWORD'),
-            ],
             'options' => [
                 // Memcached::OPT_CONNECT_TIMEOUT => 2000,
             ],
-            'servers' => env('CACHE_DRIVER') === 'memcached' ? $memcachedServers : [],
+            'servers' =>  $memcachedServers ?? [],
         ],
 
         'redis' => [
@@ -73,15 +70,6 @@ return [
             'lock_connection' => 'default',
         ],
 
-        'dynamodb' => [
-            'driver'   => 'dynamodb',
-            'key'      => env('AWS_ACCESS_KEY_ID'),
-            'secret'   => env('AWS_SECRET_ACCESS_KEY'),
-            'region'   => env('AWS_DEFAULT_REGION', 'us-east-1'),
-            'table'    => env('DYNAMODB_CACHE_TABLE', 'cache'),
-            'endpoint' => env('DYNAMODB_ENDPOINT'),
-        ],
-
         'octane' => [
             'driver' => 'octane',
         ],
diff --git a/app/Config/database.php b/app/Config/database.php
index 0c6966095..59ac0f31b 100644
--- a/app/Config/database.php
+++ b/app/Config/database.php
@@ -105,6 +105,6 @@ return [
     'migrations' => 'migrations',
 
     // Redis configuration to use if set
-    'redis' => env('REDIS_SERVERS', false) ? $redisConfig : [],
+    'redis' => $redisConfig ?? [],
 
 ];
diff --git a/app/Console/Commands/CreateAdmin.php b/app/Console/Commands/CreateAdmin.php
index a0fb8f315..b421c3add 100644
--- a/app/Console/Commands/CreateAdmin.php
+++ b/app/Console/Commands/CreateAdmin.php
@@ -4,6 +4,7 @@ namespace BookStack\Console\Commands;
 
 use BookStack\Auth\UserRepo;
 use Illuminate\Console\Command;
+use Symfony\Component\Console\Command\Command as SymfonyCommand;
 
 class CreateAdmin extends Command
 {
@@ -49,11 +50,13 @@ class CreateAdmin extends Command
             $email = $this->ask('Please specify an email address for the new admin user');
         }
         if (mb_strlen($email) < 5 || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
-            return $this->error('Invalid email address provided');
+            $this->error('Invalid email address provided');
+            return SymfonyCommand::FAILURE;
         }
 
         if ($this->userRepo->getByEmail($email) !== null) {
-            return $this->error('A user with the provided email already exists!');
+            $this->error('A user with the provided email already exists!');
+            return SymfonyCommand::FAILURE;
         }
 
         $name = trim($this->option('name'));
@@ -61,7 +64,8 @@ class CreateAdmin extends Command
             $name = $this->ask('Please specify an name for the new admin user');
         }
         if (mb_strlen($name) < 2) {
-            return $this->error('Invalid name provided');
+            $this->error('Invalid name provided');
+            return SymfonyCommand::FAILURE;
         }
 
         $password = trim($this->option('password'));
@@ -69,7 +73,8 @@ class CreateAdmin extends Command
             $password = $this->secret('Please specify a password for the new admin user');
         }
         if (mb_strlen($password) < 5) {
-            return $this->error('Invalid password provided, Must be at least 5 characters');
+            $this->error('Invalid password provided, Must be at least 5 characters');
+            return SymfonyCommand::FAILURE;
         }
 
         $user = $this->userRepo->create(['email' => $email, 'name' => $name, 'password' => $password]);
@@ -79,5 +84,6 @@ class CreateAdmin extends Command
         $user->save();
 
         $this->info("Admin account with email \"{$user->email}\" successfully created!");
+        return SymfonyCommand::SUCCESS;
     }
 }
diff --git a/app/Entities/Repos/BookshelfRepo.php b/app/Entities/Repos/BookshelfRepo.php
index 3990bfbdc..3146c7cba 100644
--- a/app/Entities/Repos/BookshelfRepo.php
+++ b/app/Entities/Repos/BookshelfRepo.php
@@ -124,7 +124,8 @@ class BookshelfRepo
 
         $syncData = Book::visible()
             ->whereIn('id', $bookIds)
-            ->get(['id'])->pluck('id')->mapWithKeys(function ($bookId) use ($numericIDs) {
+            ->pluck('id')
+            ->mapWithKeys(function ($bookId) use ($numericIDs) {
                 return [$bookId => ['order' => $numericIDs->search($bookId)]];
             });
 
diff --git a/app/Entities/Tools/SearchOptions.php b/app/Entities/Tools/SearchOptions.php
index 5ce64cc65..216f79b9c 100644
--- a/app/Entities/Tools/SearchOptions.php
+++ b/app/Entities/Tools/SearchOptions.php
@@ -32,7 +32,7 @@ class SearchOptions
     public static function fromString(string $search): self
     {
         $decoded = static::decode($search);
-        $instance = new static();
+        $instance = new SearchOptions;
         foreach ($decoded as $type => $value) {
             $instance->$type = $value;
         }
@@ -55,7 +55,7 @@ class SearchOptions
             return static::fromString($request->get('term'));
         }
 
-        $instance = new static();
+        $instance = new SearchOptions;
         $inputs = $request->only(['search', 'types', 'filters', 'exact', 'tags']);
         $instance->searches = explode(' ', $inputs['search'] ?? []);
         $instance->exacts = array_filter($inputs['exact'] ?? []);
diff --git a/app/Entities/Tools/TrashCan.php b/app/Entities/Tools/TrashCan.php
index 82569278e..8327c9489 100644
--- a/app/Entities/Tools/TrashCan.php
+++ b/app/Entities/Tools/TrashCan.php
@@ -323,6 +323,8 @@ class TrashCan
         if ($entity instanceof Bookshelf) {
             return $this->destroyShelf($entity);
         }
+
+        return 0;
     }
 
     /**
diff --git a/app/Http/Controllers/StatusController.php b/app/Http/Controllers/StatusController.php
index 336e063ab..ab4f67d0a 100644
--- a/app/Http/Controllers/StatusController.php
+++ b/app/Http/Controllers/StatusController.php
@@ -20,9 +20,9 @@ class StatusController extends Controller
             }),
             'cache' => $this->trueWithoutError(function () {
                 $rand = Str::random();
-                Cache::set('status_test', $rand);
+                Cache::add('status_test', $rand);
 
-                return Cache::get('status_test') === $rand;
+                return Cache::pull('status_test') === $rand;
             }),
             'session' => $this->trueWithoutError(function () {
                 $rand = Str::random();
diff --git a/app/Uploads/AttachmentService.php b/app/Uploads/AttachmentService.php
index 52954d24f..e62a18c82 100644
--- a/app/Uploads/AttachmentService.php
+++ b/app/Uploads/AttachmentService.php
@@ -4,9 +4,9 @@ namespace BookStack\Uploads;
 
 use BookStack\Exceptions\FileUploadException;
 use Exception;
-use Illuminate\Contracts\Filesystem\Factory as FileSystem;
 use Illuminate\Contracts\Filesystem\FileNotFoundException;
-use Illuminate\Contracts\Filesystem\Filesystem as FileSystemInstance;
+use Illuminate\Contracts\Filesystem\Filesystem as Storage;
+use Illuminate\Filesystem\FilesystemManager;
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Str;
 use League\Flysystem\Util;
@@ -19,7 +19,7 @@ class AttachmentService
     /**
      * AttachmentService constructor.
      */
-    public function __construct(FileSystem $fileSystem)
+    public function __construct(FilesystemManager $fileSystem)
     {
         $this->fileSystem = $fileSystem;
     }
@@ -27,7 +27,7 @@ class AttachmentService
     /**
      * Get the storage that will be used for storing files.
      */
-    protected function getStorageDisk(): FileSystemInstance
+    protected function getStorageDisk(): Storage
     {
         return $this->fileSystem->disk($this->getStorageDiskName());
     }
diff --git a/app/Uploads/ImageRepo.php b/app/Uploads/ImageRepo.php
index 5c6228b37..2a4ea424f 100644
--- a/app/Uploads/ImageRepo.php
+++ b/app/Uploads/ImageRepo.php
@@ -103,7 +103,7 @@ class ImageRepo
                 if ($filterType === 'page') {
                     $query->where('uploaded_to', '=', $contextPage->id);
                 } elseif ($filterType === 'book') {
-                    $validPageIds = $contextPage->book->pages()->visible()->get(['id'])->pluck('id')->toArray();
+                    $validPageIds = $contextPage->book->pages()->visible()->pluck('id')->toArray();
                     $query->whereIn('uploaded_to', $validPageIds);
                 }
             };
diff --git a/app/Uploads/ImageService.php b/app/Uploads/ImageService.php
index 644269731..6d4902589 100644
--- a/app/Uploads/ImageService.php
+++ b/app/Uploads/ImageService.php
@@ -6,10 +6,9 @@ use BookStack\Exceptions\ImageUploadException;
 use ErrorException;
 use Exception;
 use Illuminate\Contracts\Cache\Repository as Cache;
-use Illuminate\Contracts\Filesystem\Factory as FileSystem;
 use Illuminate\Contracts\Filesystem\FileNotFoundException;
-use Illuminate\Contracts\Filesystem\Filesystem as FileSystemInstance;
 use Illuminate\Contracts\Filesystem\Filesystem as Storage;
+use Illuminate\Filesystem\FilesystemManager;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Str;
@@ -33,7 +32,7 @@ class ImageService
     /**
      * ImageService constructor.
      */
-    public function __construct(Image $image, ImageManager $imageTool, FileSystem $fileSystem, Cache $cache)
+    public function __construct(Image $image, ImageManager $imageTool, FilesystemManager $fileSystem, Cache $cache)
     {
         $this->image = $image;
         $this->imageTool = $imageTool;
@@ -44,7 +43,7 @@ class ImageService
     /**
      * Get the storage that will be used for storing images.
      */
-    protected function getStorageDisk(string $imageType = ''): FileSystemInstance
+    protected function getStorageDisk(string $imageType = ''): Storage
     {
         return $this->fileSystem->disk($this->getStorageDiskName($imageType));
     }
@@ -352,7 +351,7 @@ class ImageService
     /**
      * Check whether a folder is empty.
      */
-    protected function isFolderEmpty(FileSystemInstance $storage, string $path): bool
+    protected function isFolderEmpty(Storage $storage, string $path): bool
     {
         $files = $storage->files($path);
         $folders = $storage->directories($path);
diff --git a/bootstrap/phpstan.php b/bootstrap/phpstan.php
new file mode 100644
index 000000000..1505fdb20
--- /dev/null
+++ b/bootstrap/phpstan.php
@@ -0,0 +1,6 @@
+<?php
+
+// Overwrite configuration that can interfere with the phpstan/larastan scanning.
+config()->set([
+    'filesystems.default' => 'local',
+]);
diff --git a/composer.json b/composer.json
index 07111d985..1efbbe1ac 100644
--- a/composer.json
+++ b/composer.json
@@ -47,9 +47,10 @@
         "fakerphp/faker": "^1.16",
         "itsgoingd/clockwork": "^5.1",
         "mockery/mockery": "^1.4",
+        "nunomaduro/collision": "^5.10",
+        "nunomaduro/larastan": "^1.0",
         "phpunit/phpunit": "^9.5",
-        "symfony/dom-crawler": "^5.3",
-        "nunomaduro/collision": "^5.10"
+        "symfony/dom-crawler": "^5.3"
     },
     "autoload": {
         "psr-4": {
diff --git a/composer.lock b/composer.lock
index 4323d89d5..ab0da94cd 100644
--- a/composer.lock
+++ b/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": "d7893ec647ed43e272a21c9c01a9b2cb",
+    "content-hash": "eff5a582fd0ffe2924664e933365a7b9",
     "packages": [
         {
             "name": "aws/aws-crt-php",
@@ -7452,6 +7452,473 @@
         }
     ],
     "packages-dev": [
+        {
+            "name": "composer/ca-bundle",
+            "version": "1.3.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/ca-bundle.git",
+                "reference": "4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/ca-bundle/zipball/4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b",
+                "reference": "4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b",
+                "shasum": ""
+            },
+            "require": {
+                "ext-openssl": "*",
+                "ext-pcre": "*",
+                "php": "^5.3.2 || ^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "^0.12.55",
+                "psr/log": "^1.0",
+                "symfony/phpunit-bridge": "^4.2 || ^5",
+                "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\CaBundle\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                }
+            ],
+            "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
+            "keywords": [
+                "cabundle",
+                "cacert",
+                "certificate",
+                "ssl",
+                "tls"
+            ],
+            "support": {
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/ca-bundle/issues",
+                "source": "https://github.com/composer/ca-bundle/tree/1.3.1"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-10-28T20:44:15+00:00"
+        },
+        {
+            "name": "composer/composer",
+            "version": "2.1.11",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/composer.git",
+                "reference": "ddc81bb4718747cc93330ccf832e6be8a6c1d015"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/composer/zipball/ddc81bb4718747cc93330ccf832e6be8a6c1d015",
+                "reference": "ddc81bb4718747cc93330ccf832e6be8a6c1d015",
+                "shasum": ""
+            },
+            "require": {
+                "composer/ca-bundle": "^1.0",
+                "composer/metadata-minifier": "^1.0",
+                "composer/semver": "^3.0",
+                "composer/spdx-licenses": "^1.2",
+                "composer/xdebug-handler": "^2.0",
+                "justinrainbow/json-schema": "^5.2.11",
+                "php": "^5.3.2 || ^7.0 || ^8.0",
+                "psr/log": "^1.0 || ^2.0",
+                "react/promise": "^1.2 || ^2.7",
+                "seld/jsonlint": "^1.4",
+                "seld/phar-utils": "^1.0",
+                "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0",
+                "symfony/filesystem": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0",
+                "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0",
+                "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0"
+            },
+            "require-dev": {
+                "phpspec/prophecy": "^1.10",
+                "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0"
+            },
+            "suggest": {
+                "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages",
+                "ext-zip": "Enabling the zip extension allows you to unzip archives",
+                "ext-zlib": "Allow gzip compression of HTTP requests"
+            },
+            "bin": [
+                "bin/composer"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.1-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\": "src/Composer"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nils Adermann",
+                    "email": "naderman@naderman.de",
+                    "homepage": "https://www.naderman.de"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "https://seld.be"
+                }
+            ],
+            "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.",
+            "homepage": "https://getcomposer.org/",
+            "keywords": [
+                "autoload",
+                "dependency",
+                "package"
+            ],
+            "support": {
+                "irc": "ircs://irc.libera.chat:6697/composer",
+                "issues": "https://github.com/composer/composer/issues",
+                "source": "https://github.com/composer/composer/tree/2.1.11"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-11-02T11:10:26+00:00"
+        },
+        {
+            "name": "composer/metadata-minifier",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/metadata-minifier.git",
+                "reference": "c549d23829536f0d0e984aaabbf02af91f443207"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/metadata-minifier/zipball/c549d23829536f0d0e984aaabbf02af91f443207",
+                "reference": "c549d23829536f0d0e984aaabbf02af91f443207",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "composer/composer": "^2",
+                "phpstan/phpstan": "^0.12.55",
+                "symfony/phpunit-bridge": "^4.2 || ^5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\MetadataMinifier\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                }
+            ],
+            "description": "Small utility library that handles metadata minification and expansion.",
+            "keywords": [
+                "composer",
+                "compression"
+            ],
+            "support": {
+                "issues": "https://github.com/composer/metadata-minifier/issues",
+                "source": "https://github.com/composer/metadata-minifier/tree/1.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-04-07T13:37:33+00:00"
+        },
+        {
+            "name": "composer/semver",
+            "version": "3.2.6",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/semver.git",
+                "reference": "83e511e247de329283478496f7a1e114c9517506"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/semver/zipball/83e511e247de329283478496f7a1e114c9517506",
+                "reference": "83e511e247de329283478496f7a1e114c9517506",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "^0.12.54",
+                "symfony/phpunit-bridge": "^4.2 || ^5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "3.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\Semver\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nils Adermann",
+                    "email": "naderman@naderman.de",
+                    "homepage": "http://www.naderman.de"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                },
+                {
+                    "name": "Rob Bast",
+                    "email": "rob.bast@gmail.com",
+                    "homepage": "http://robbast.nl"
+                }
+            ],
+            "description": "Semver library that offers utilities, version constraint parsing and validation.",
+            "keywords": [
+                "semantic",
+                "semver",
+                "validation",
+                "versioning"
+            ],
+            "support": {
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/semver/issues",
+                "source": "https://github.com/composer/semver/tree/3.2.6"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-10-25T11:34:17+00:00"
+        },
+        {
+            "name": "composer/spdx-licenses",
+            "version": "1.5.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/spdx-licenses.git",
+                "reference": "de30328a7af8680efdc03e396aad24befd513200"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/de30328a7af8680efdc03e396aad24befd513200",
+                "reference": "de30328a7af8680efdc03e396aad24befd513200",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\Spdx\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nils Adermann",
+                    "email": "naderman@naderman.de",
+                    "homepage": "http://www.naderman.de"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                },
+                {
+                    "name": "Rob Bast",
+                    "email": "rob.bast@gmail.com",
+                    "homepage": "http://robbast.nl"
+                }
+            ],
+            "description": "SPDX licenses list and validation library.",
+            "keywords": [
+                "license",
+                "spdx",
+                "validator"
+            ],
+            "support": {
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/spdx-licenses/issues",
+                "source": "https://github.com/composer/spdx-licenses/tree/1.5.5"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-12-03T16:04:16+00:00"
+        },
+        {
+            "name": "composer/xdebug-handler",
+            "version": "2.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/xdebug-handler.git",
+                "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/84674dd3a7575ba617f5a76d7e9e29a7d3891339",
+                "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0 || ^8.0",
+                "psr/log": "^1 || ^2 || ^3"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "^0.12.55",
+                "symfony/phpunit-bridge": "^4.2 || ^5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Composer\\XdebugHandler\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "John Stevenson",
+                    "email": "john-stevenson@blueyonder.co.uk"
+                }
+            ],
+            "description": "Restarts a process without Xdebug.",
+            "keywords": [
+                "Xdebug",
+                "performance"
+            ],
+            "support": {
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/xdebug-handler/issues",
+                "source": "https://github.com/composer/xdebug-handler/tree/2.0.2"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-07-31T17:03:58+00:00"
+        },
         {
             "name": "doctrine/instantiator",
             "version": "1.4.0",
@@ -7759,6 +8226,76 @@
             ],
             "time": "2021-11-01T17:38:35+00:00"
         },
+        {
+            "name": "justinrainbow/json-schema",
+            "version": "5.2.11",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/justinrainbow/json-schema.git",
+                "reference": "2ab6744b7296ded80f8cc4f9509abbff393399aa"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ab6744b7296ded80f8cc4f9509abbff393399aa",
+                "reference": "2ab6744b7296ded80f8cc4f9509abbff393399aa",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
+                "json-schema/json-schema-test-suite": "1.2.0",
+                "phpunit/phpunit": "^4.8.35"
+            },
+            "bin": [
+                "bin/validate-json"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "JsonSchema\\": "src/JsonSchema/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Bruno Prieto Reis",
+                    "email": "bruno.p.reis@gmail.com"
+                },
+                {
+                    "name": "Justin Rainbow",
+                    "email": "justin.rainbow@gmail.com"
+                },
+                {
+                    "name": "Igor Wiedler",
+                    "email": "igor@wiedler.ch"
+                },
+                {
+                    "name": "Robert Schönthal",
+                    "email": "seroscho@googlemail.com"
+                }
+            ],
+            "description": "A library to validate a json schema.",
+            "homepage": "https://github.com/justinrainbow/json-schema",
+            "keywords": [
+                "json",
+                "schema"
+            ],
+            "support": {
+                "issues": "https://github.com/justinrainbow/json-schema/issues",
+                "source": "https://github.com/justinrainbow/json-schema/tree/5.2.11"
+            },
+            "time": "2021-07-22T09:24:00+00:00"
+        },
         {
             "name": "mockery/mockery",
             "version": "1.4.4",
@@ -7976,6 +8513,104 @@
             ],
             "time": "2021-09-20T15:06:32+00:00"
         },
+        {
+            "name": "nunomaduro/larastan",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nunomaduro/larastan.git",
+                "reference": "a5a6bdae060c72a5909479fb37c04a7f9fd84533"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nunomaduro/larastan/zipball/a5a6bdae060c72a5909479fb37c04a7f9fd84533",
+                "reference": "a5a6bdae060c72a5909479fb37c04a7f9fd84533",
+                "shasum": ""
+            },
+            "require": {
+                "composer/composer": "^1.0 || ^2.0",
+                "ext-json": "*",
+                "illuminate/console": "^6.0 || ^7.0 || ^8.0 || ^9.0",
+                "illuminate/container": "^6.0 || ^7.0 || ^8.0 || ^9.0",
+                "illuminate/contracts": "^6.0 || ^7.0 || ^8.0 || ^9.0",
+                "illuminate/database": "^6.0 || ^7.0 || ^8.0 || ^9.0",
+                "illuminate/http": "^6.0 || ^7.0 || ^8.0 || ^9.0",
+                "illuminate/pipeline": "^6.0 || ^7.0 || ^8.0 || ^9.0",
+                "illuminate/support": "^6.0 || ^7.0 || ^8.0 || ^9.0",
+                "mockery/mockery": "^0.9 || ^1.0",
+                "php": "^7.2 || ^8.0",
+                "phpstan/phpstan": "^1.0",
+                "symfony/process": "^4.3 || ^5.0 || ^6.0"
+            },
+            "require-dev": {
+                "nikic/php-parser": "^4.13.0",
+                "orchestra/testbench": "^4.0 || ^5.0 || ^6.0 || ^7.0",
+                "phpunit/phpunit": "^7.3 || ^8.2 || ^9.3"
+            },
+            "suggest": {
+                "orchestra/testbench": "Using Larastan for analysing a package needs Testbench"
+            },
+            "type": "phpstan-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0-dev"
+                },
+                "phpstan": {
+                    "includes": [
+                        "extension.neon"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "NunoMaduro\\Larastan\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nuno Maduro",
+                    "email": "enunomaduro@gmail.com"
+                }
+            ],
+            "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel",
+            "keywords": [
+                "PHPStan",
+                "code analyse",
+                "code analysis",
+                "larastan",
+                "laravel",
+                "package",
+                "php",
+                "static analysis"
+            ],
+            "support": {
+                "issues": "https://github.com/nunomaduro/larastan/issues",
+                "source": "https://github.com/nunomaduro/larastan/tree/1.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/canvural",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/nunomaduro",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/nunomaduro",
+                    "type": "patreon"
+                }
+            ],
+            "time": "2021-11-01T12:39:49+00:00"
+        },
         {
             "name": "phar-io/manifest",
             "version": "2.0.3",
@@ -8314,6 +8949,70 @@
             },
             "time": "2021-09-10T09:02:12+00:00"
         },
+        {
+            "name": "phpstan/phpstan",
+            "version": "1.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpstan/phpstan.git",
+                "reference": "e9e2a501102ba0b126b2f63a7f0a3b151056fe91"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e9e2a501102ba0b126b2f63a7f0a3b151056fe91",
+                "reference": "e9e2a501102ba0b126b2f63a7f0a3b151056fe91",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1|^8.0"
+            },
+            "conflict": {
+                "phpstan/phpstan-shim": "*"
+            },
+            "bin": [
+                "phpstan",
+                "phpstan.phar"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "PHPStan - PHP Static Analysis Tool",
+            "support": {
+                "issues": "https://github.com/phpstan/phpstan/issues",
+                "source": "https://github.com/phpstan/phpstan/tree/1.0.2"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/ondrejmirtes",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/phpstan",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/phpstan",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-11-03T16:09:51+00:00"
+        },
         {
             "name": "phpunit/php-code-coverage",
             "version": "9.2.8",
@@ -8735,6 +9434,56 @@
             ],
             "time": "2021-09-25T07:38:51+00:00"
         },
+        {
+            "name": "react/promise",
+            "version": "v2.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/reactphp/promise.git",
+                "reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/reactphp/promise/zipball/f3cff96a19736714524ca0dd1d4130de73dbbbc4",
+                "reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.0 || ^6.5 || ^5.7 || ^4.8.36"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "React\\Promise\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jan Sorgalla",
+                    "email": "jsorgalla@gmail.com"
+                }
+            ],
+            "description": "A lightweight implementation of CommonJS Promises/A for PHP",
+            "keywords": [
+                "promise",
+                "promises"
+            ],
+            "support": {
+                "issues": "https://github.com/reactphp/promise/issues",
+                "source": "https://github.com/reactphp/promise/tree/v2.8.0"
+            },
+            "time": "2020-05-12T15:16:56+00:00"
+        },
         {
             "name": "sebastian/cli-parser",
             "version": "1.0.1",
@@ -9699,6 +10448,117 @@
             ],
             "time": "2020-09-28T06:39:44+00:00"
         },
+        {
+            "name": "seld/jsonlint",
+            "version": "1.8.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Seldaek/jsonlint.git",
+                "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9ad6ce79c342fbd44df10ea95511a1b24dee5b57",
+                "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3 || ^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+            },
+            "bin": [
+                "bin/jsonlint"
+            ],
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Seld\\JsonLint\\": "src/Seld/JsonLint/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                }
+            ],
+            "description": "JSON Linter",
+            "keywords": [
+                "json",
+                "linter",
+                "parser",
+                "validator"
+            ],
+            "support": {
+                "issues": "https://github.com/Seldaek/jsonlint/issues",
+                "source": "https://github.com/Seldaek/jsonlint/tree/1.8.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/Seldaek",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-11-11T09:19:24+00:00"
+        },
+        {
+            "name": "seld/phar-utils",
+            "version": "1.1.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Seldaek/phar-utils.git",
+                "reference": "749042a2315705d2dfbbc59234dd9ceb22bf3ff0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/749042a2315705d2dfbbc59234dd9ceb22bf3ff0",
+                "reference": "749042a2315705d2dfbbc59234dd9ceb22bf3ff0",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Seld\\PharUtils\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be"
+                }
+            ],
+            "description": "PHAR file format utilities, for when PHP phars you up",
+            "keywords": [
+                "phar"
+            ],
+            "support": {
+                "issues": "https://github.com/Seldaek/phar-utils/issues",
+                "source": "https://github.com/Seldaek/phar-utils/tree/1.1.2"
+            },
+            "time": "2021-08-19T21:01:38+00:00"
+        },
         {
             "name": "symfony/dom-crawler",
             "version": "v5.3.7",
@@ -9774,6 +10634,69 @@
             ],
             "time": "2021-08-29T19:32:13+00:00"
         },
+        {
+            "name": "symfony/filesystem",
+            "version": "v5.3.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/filesystem.git",
+                "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/343f4fe324383ca46792cae728a3b6e2f708fb32",
+                "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Filesystem\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides basic utilities for the filesystem",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/filesystem/tree/v5.3.4"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-07-21T12:40:44+00:00"
+        },
         {
             "name": "theseer/tokenizer",
             "version": "1.2.1",
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 000000000..815b1c187
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,23 @@
+includes:
+    - ./vendor/nunomaduro/larastan/extension.neon
+
+parameters:
+
+    paths:
+        - app
+
+    # The level 8 is the highest level
+    level: 1
+
+    phpVersion: 70300
+
+    bootstrapFiles:
+      - bootstrap/phpstan.php
+
+    ignoreErrors:
+#        - '#Unsafe usage of new static#'
+
+    excludePaths:
+        - ./Config/**/*.php
+
+    checkMissingIterableValueType: false
\ No newline at end of file
diff --git a/tests/StatusTest.php b/tests/StatusTest.php
index 09882759c..37b1b15a1 100644
--- a/tests/StatusTest.php
+++ b/tests/StatusTest.php
@@ -34,7 +34,7 @@ class StatusTest extends TestCase
     {
         $mockStore = Mockery::mock(new ArrayStore())->makePartial();
         Cache::swap($mockStore);
-        $mockStore->shouldReceive('get')->andReturn('cat');
+        $mockStore->shouldReceive('pull')->andReturn('cat');
 
         $resp = $this->get('/status');
         $resp->assertStatus(500);