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 @@ $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 @@ +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);