From f5ddb0f04ffb9ce1fdca2865843ccc0522ef30c6 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 19 May 2018 12:15:56 -0300 Subject: [PATCH 01/34] Changed way to map exceptions to be more extensible --- .editorconfig | 15 + composer.json | 16 +- composer.lock | 3482 ++++++++++++++++- .../json-exception-handler.php | 0 phpunit.xml | 23 +- .../lang/en}/exceptions.php | 2 +- .../lang/pt-br}/exceptions.php | 0 src/AuthenticationHandler.php | 22 - src/AuthorizationHandler.php | 51 - src/BadRequestHttpHandler.php | 24 - src/CieloRequestHandler.php | 31 - src/ClientHandler.php | 81 - src/Handlers/AbstractHandler.php | 158 + src/Handlers/AuthenticationHandler.php | 21 + src/Handlers/AuthorizationHandler.php | 21 + src/Handlers/BadRequestHttpHandler.php | 21 + src/Handlers/Handler.php | 21 + src/Handlers/MissingScopeHandler.php | 21 + src/{ => Handlers}/ModelNotFoundHandler.php | 40 +- src/Handlers/NotFoundHttpHandler.php | 39 + src/Handlers/OAuthServerHandler.php | 21 + src/Handlers/ValidationHandler.php | 82 + src/JsonApi/Error.php | 230 ++ src/JsonApi/ErrorCollection.php | 58 + src/JsonApi/InvalidContentException.php | 8 + src/JsonApi/Links.php | 18 + src/JsonApi/Response.php | 96 + src/JsonApi/Source.php | 76 + src/JsonHandler.php | 153 +- src/JsonHandlerServiceProvider.php | 8 +- src/MissingScopeHandler.php | 22 - src/NotFoundHttpHandler.php | 45 - src/OAuthServerHandler.php | 24 - src/Responses/JsonApiResponse.php | 45 - src/Traits/NotNullArrayable.php | 25 + src/ValidationHandler.php | 106 - tests/Feature/JsonHandlerTest.php | 123 + tests/Fixtures/Exceptions/Handler.php | 58 + tests/Fixtures/User.php | 10 + tests/TestCase.php | 37 + tests/Unit/AbstractHandlerTest.php | 16 + tests/Unit/HandlerTest.php | 19 + 42 files changed, 4726 insertions(+), 643 deletions(-) create mode 100644 .editorconfig rename {src/config => config}/json-exception-handler.php (100%) rename {src/resources/lang/pt-br => resources/lang/en}/exceptions.php (96%) rename {src/resources/lang/en => resources/lang/pt-br}/exceptions.php (100%) delete mode 100644 src/AuthenticationHandler.php delete mode 100644 src/AuthorizationHandler.php delete mode 100644 src/BadRequestHttpHandler.php delete mode 100644 src/CieloRequestHandler.php delete mode 100644 src/ClientHandler.php create mode 100644 src/Handlers/AbstractHandler.php create mode 100644 src/Handlers/AuthenticationHandler.php create mode 100644 src/Handlers/AuthorizationHandler.php create mode 100644 src/Handlers/BadRequestHttpHandler.php create mode 100644 src/Handlers/Handler.php create mode 100644 src/Handlers/MissingScopeHandler.php rename src/{ => Handlers}/ModelNotFoundHandler.php (52%) create mode 100644 src/Handlers/NotFoundHttpHandler.php create mode 100644 src/Handlers/OAuthServerHandler.php create mode 100644 src/Handlers/ValidationHandler.php create mode 100644 src/JsonApi/Error.php create mode 100644 src/JsonApi/ErrorCollection.php create mode 100644 src/JsonApi/InvalidContentException.php create mode 100644 src/JsonApi/Links.php create mode 100644 src/JsonApi/Response.php create mode 100644 src/JsonApi/Source.php delete mode 100644 src/MissingScopeHandler.php delete mode 100644 src/NotFoundHttpHandler.php delete mode 100644 src/OAuthServerHandler.php delete mode 100644 src/Responses/JsonApiResponse.php create mode 100644 src/Traits/NotNullArrayable.php delete mode 100644 src/ValidationHandler.php create mode 100644 tests/Feature/JsonHandlerTest.php create mode 100644 tests/Fixtures/Exceptions/Handler.php create mode 100644 tests/Fixtures/User.php create mode 100644 tests/TestCase.php create mode 100644 tests/Unit/AbstractHandlerTest.php create mode 100644 tests/Unit/HandlerTest.php diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6f313c6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.yml] +indent_size = 2 diff --git a/composer.json b/composer.json index 6794ccd..680d28d 100644 --- a/composer.json +++ b/composer.json @@ -15,14 +15,26 @@ }, "autoload": { "psr-4": { - "SMartins\\JsonHandler\\": "src/" + "SMartins\\Exceptions\\": "src/" + } + }, + "autoload-dev": { + "files": [ + "tests/TestCase.php" + ], + "psr-4": { + "SMartins\\Exceptions\\Tests\\": "tests/" } }, "extra": { "laravel": { "providers": [ - "SMartins\\JsonHandler\\JsonHandlerServiceProvider" + "SMartins\\Exceptions\\JsonHandlerServiceProvider" ] } + }, + "require-dev": { + "orchestra/testbench": "~3.0", + "phpunit/phpunit": "^7.1" } } diff --git a/composer.lock b/composer.lock index 714579d..48ba15d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,9 +4,3487 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "43813f6281c6804df66a42cd22b30c55", + "content-hash": "add54d97fbf3a6107d45451014b8591a", "packages": [], - "packages-dev": [], + "packages-dev": [ + { + "name": "doctrine/inflector", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "5527a48b7313d15261292c149e55e26eae771b0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a", + "reference": "5527a48b7313d15261292c149e55e26eae771b0a", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2018-01-09T20:05:19+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2017-07-22T11:58:36+00:00" + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09T13:34:57+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "3f00985deec8df53d4cc1e5c33619bda1ee309a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/3f00985deec8df53d4cc1e5c33619bda1ee309a5", + "reference": "3f00985deec8df53d4cc1e5c33619bda1ee309a5", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "time": "2018-04-06T15:51:55+00:00" + }, + { + "name": "egulias/email-validator", + "version": "2.1.4", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "8790f594151ca6a2010c6218e09d96df67173ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/8790f594151ca6a2010c6218e09d96df67173ad3", + "reference": "8790f594151ca6a2010c6218e09d96df67173ad3", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.0.1", + "php": ">= 5.5" + }, + "require-dev": { + "dominicsayers/isemail": "dev-master", + "phpunit/phpunit": "^4.8.35||^5.7||^6.0", + "satooshi/php-coveralls": "^1.0.1" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "EmailValidator" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "time": "2018-04-10T10:11:19+00:00" + }, + { + "name": "erusev/parsedown", + "version": "1.7.1", + "source": { + "type": "git", + "url": "https://github.com/erusev/parsedown.git", + "reference": "92e9c27ba0e74b8b028b111d1b6f956a15c01fc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/92e9c27ba0e74b8b028b111d1b6f956a15c01fc1", + "reference": "92e9c27ba0e74b8b028b111d1b6f956a15c01fc1", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35" + }, + "type": "library", + "autoload": { + "psr-0": { + "Parsedown": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "description": "Parser for Markdown.", + "homepage": "http://parsedown.org", + "keywords": [ + "markdown", + "parser" + ], + "time": "2018-03-08T01:11:30+00:00" + }, + { + "name": "fzaninotto/faker", + "version": "v1.7.1", + "source": { + "type": "git", + "url": "https://github.com/fzaninotto/Faker.git", + "reference": "d3ed4cc37051c1ca52d22d76b437d14809fc7e0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/d3ed4cc37051c1ca52d22d76b437d14809fc7e0d", + "reference": "d3ed4cc37051c1ca52d22d76b437d14809fc7e0d", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "ext-intl": "*", + "phpunit/phpunit": "^4.0 || ^5.0", + "squizlabs/php_codesniffer": "^1.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "time": "2017-08-15T16:48:10+00:00" + }, + { + "name": "laravel/framework", + "version": "v5.6.22", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "637fd797a6dde8d24a9f07da77e375ec251c5d24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/637fd797a6dde8d24a9f07da77e375ec251c5d24", + "reference": "637fd797a6dde8d24a9f07da77e375ec251c5d24", + "shasum": "" + }, + "require": { + "doctrine/inflector": "~1.1", + "dragonmantank/cron-expression": "~2.0", + "erusev/parsedown": "~1.7", + "ext-mbstring": "*", + "ext-openssl": "*", + "league/flysystem": "^1.0.8", + "monolog/monolog": "~1.12", + "nesbot/carbon": "1.25.*", + "php": "^7.1.3", + "psr/container": "~1.0", + "psr/simple-cache": "^1.0", + "ramsey/uuid": "^3.7", + "swiftmailer/swiftmailer": "~6.0", + "symfony/console": "~4.0", + "symfony/debug": "~4.0", + "symfony/finder": "~4.0", + "symfony/http-foundation": "~4.0", + "symfony/http-kernel": "~4.0", + "symfony/process": "~4.0", + "symfony/routing": "~4.0", + "symfony/var-dumper": "~4.0", + "tijsverkoyen/css-to-inline-styles": "^2.2.1", + "vlucas/phpdotenv": "~2.2" + }, + "conflict": { + "tightenco/collect": "<5.5.33" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version" + }, + "require-dev": { + "aws/aws-sdk-php": "~3.0", + "doctrine/dbal": "~2.6", + "filp/whoops": "^2.1.4", + "league/flysystem-cached-adapter": "~1.0", + "mockery/mockery": "~1.0", + "moontoast/math": "^1.1", + "orchestra/testbench-core": "3.6.*", + "pda/pheanstalk": "~3.0", + "phpunit/phpunit": "~7.0", + "predis/predis": "^1.1.1", + "symfony/css-selector": "~4.0", + "symfony/dom-crawler": "~4.0" + }, + "suggest": { + "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.6).", + "ext-pcntl": "Required to use all features of the queue worker.", + "ext-posix": "Required to use all features of the queue worker.", + "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", + "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~6.0).", + "laravel/tinker": "Required to use the tinker console command (~1.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", + "league/flysystem-cached-adapter": "Required to use the Flysystem cache (~1.0).", + "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).", + "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (~1.0).", + "nexmo/client": "Required to use the Nexmo transport (~1.0).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).", + "predis/predis": "Required to use the redis cache and queue drivers (~1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~3.0).", + "symfony/css-selector": "Required to use some of the crawler integration testing tools (~4.0).", + "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (~4.0).", + "symfony/psr-http-message-bridge": "Required to psr7 bridging features (~1.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "time": "2018-05-15T13:34:20+00:00" + }, + { + "name": "league/flysystem", + "version": "1.0.45", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "a99f94e63b512d75f851b181afcdf0ee9ebef7e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a99f94e63b512d75f851b181afcdf0ee9ebef7e6", + "reference": "a99f94e63b512d75f851b181afcdf0ee9ebef7e6", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "require-dev": { + "ext-fileinfo": "*", + "phpspec/phpspec": "^3.4", + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "ext-ftp": "Allows you to use FTP server storage", + "ext-openssl": "Allows you to use FTPS server storage", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", + "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", + "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ], + "time": "2018-05-07T08:44:23+00:00" + }, + { + "name": "monolog/monolog", + "version": "1.23.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "ruflin/elastica": ">=0.90 <3.0", + "sentry/sentry": "^0.13", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2017-06-19T01:22:40+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "nesbot/carbon", + "version": "1.25.0", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cbcf13da0b531767e39eb86e9687f5deba9857b4", + "reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/translation": "~2.6 || ~3.0 || ~4.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2", + "phpunit/phpunit": "^4.8.35 || ^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.23-dev" + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "http://nesbot.com" + } + ], + "description": "A simple API extension for DateTime.", + "homepage": "http://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "time": "2018-03-19T15:50:49+00:00" + }, + { + "name": "orchestra/testbench", + "version": "v3.6.4", + "source": { + "type": "git", + "url": "https://github.com/orchestral/testbench.git", + "reference": "242cc47d2e5d86ababe36d22519e2b948eff8f73" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/242cc47d2e5d86ababe36d22519e2b948eff8f73", + "reference": "242cc47d2e5d86ababe36d22519e2b948eff8f73", + "shasum": "" + }, + "require": { + "laravel/framework": "~5.6.13", + "orchestra/testbench-core": "~3.6.5", + "php": ">=7.1", + "phpunit/phpunit": "~7.0" + }, + "require-dev": { + "mockery/mockery": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.6-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com", + "homepage": "https://github.com/crynobone" + } + ], + "description": "Laravel Testing Helper for Packages Development", + "homepage": "http://orchestraplatform.com/docs/latest/components/testbench/", + "keywords": [ + "BDD", + "TDD", + "laravel", + "orchestra-platform", + "orchestral", + "testing" + ], + "time": "2018-03-27T09:27:00+00:00" + }, + { + "name": "orchestra/testbench-core", + "version": "v3.6.5", + "source": { + "type": "git", + "url": "https://github.com/orchestral/testbench-core.git", + "reference": "d089f0fd32a81764fbd98044148a193db828dd52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/d089f0fd32a81764fbd98044148a193db828dd52", + "reference": "d089f0fd32a81764fbd98044148a193db828dd52", + "shasum": "" + }, + "require": { + "fzaninotto/faker": "~1.4", + "php": ">=7.1" + }, + "require-dev": { + "laravel/framework": "~5.6.13", + "mockery/mockery": "~1.0", + "phpunit/phpunit": "~7.0" + }, + "suggest": { + "laravel/framework": "Required for testing (~5.6.13).", + "mockery/mockery": "Allow to use Mockery for testing (~1.0).", + "orchestra/testbench-browser-kit": "Allow to use legacy Laravel BrowserKit for testing (~3.6).", + "orchestra/testbench-dusk": "Allow to use Laravel Dusk for testing (~3.6).", + "phpunit/phpunit": "Allow to use PHPUnit for testing (~7.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Orchestra\\Testbench\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com", + "homepage": "https://github.com/crynobone" + } + ], + "description": "Testing Helper for Laravel Development", + "homepage": "http://orchestraplatform.com/docs/latest/components/testbench/", + "keywords": [ + "BDD", + "TDD", + "laravel", + "orchestra-platform", + "orchestral", + "testing" + ], + "time": "2018-03-27T08:00:28+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v2.0.12", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/258c89a6b97de7dfaf5b8c7607d0478e236b04fb", + "reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2018-04-04T21:24:14+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-30T07:14:17+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.7.6", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2018-04-18T13:57:24+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "6.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "52187754b0eed0b8159f62a6fa30073327e8c2ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/52187754b0eed0b8159f62a6fa30073327e8c2ca", + "reference": "52187754b0eed0b8159f62a6fa30073327e8c2ca", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.1", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-xdebug": "^2.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2018-04-29T14:59:09+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2018-02-01T13:07:23+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2018-02-01T13:16:43+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "7.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "ca64dba53b88aba6af32aebc6b388068db95c435" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ca64dba53b88aba6af32aebc6b388068db95c435", + "reference": "ca64dba53b88aba6af32aebc6b388068db95c435", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0.1", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.0", + "phpunit/phpunit-mock-objects": "^6.1.1", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-04-29T15:09:19+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "6.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "70c740bde8fd9ea9ea295be1cd875dd7b267e157" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/70c740bde8fd9ea9ea295be1cd875dd7b267e157", + "reference": "70c740bde8fd9ea9ea295be1cd875dd7b267e157", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "php": "^7.1", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2018-04-11T04:50:36+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10T12:19:37+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "ramsey/uuid", + "version": "3.7.3", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "44abcdad877d9a46685a3a4d221e3b2c4b87cb76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/44abcdad877d9a46685a3a4d221e3b2c4b87cb76", + "reference": "44abcdad877d9a46685a3a4d221e3b2c4b87cb76", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "^1.0|^2.0", + "php": "^5.4 || ^7.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "codeception/aspect-mock": "^1.0 | ~2.0.0", + "doctrine/annotations": "~1.2.0", + "goaop/framework": "1.0.0-alpha.2 | ^1.0 | ^2.1", + "ircmaxell/random-lib": "^1.1", + "jakub-onderka/php-parallel-lint": "^0.9.0", + "mockery/mockery": "^0.9.9", + "moontoast/math": "^1.1", + "php-mock/php-mock-phpunit": "^0.3|^1.1", + "phpunit/phpunit": "^4.7|^5.0", + "squizlabs/php_codesniffer": "^2.3" + }, + "suggest": { + "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", + "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", + "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", + "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marijn Huizendveld", + "email": "marijn.huizendveld@gmail.com" + }, + { + "name": "Thibaud Fabre", + "email": "thibaud@aztech.io" + }, + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", + "homepage": "https://github.com/ramsey/uuid", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "time": "2018-01-20T00:28:24+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ed5fd2281113729f1ebcc64d101ad66028aeb3d5", + "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-04-18T13:33:00+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/e09160918c66281713f1c324c1f4c4c3037ba1e8", + "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2018-02-01T13:45:15+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2017-04-03T13:19:02+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "swiftmailer/swiftmailer", + "version": "v6.0.2", + "source": { + "type": "git", + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "412333372fb6c8ffb65496a2bbd7321af75733fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/412333372fb6c8ffb65496a2bbd7321af75733fc", + "reference": "412333372fb6c8ffb65496a2bbd7321af75733fc", + "shasum": "" + }, + "require": { + "egulias/email-validator": "~2.0", + "php": ">=7.0.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.1", + "symfony/phpunit-bridge": "~3.3@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.0-dev" + } + }, + "autoload": { + "files": [ + "lib/swift_required.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Corbyn" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "http://swiftmailer.symfony.com", + "keywords": [ + "email", + "mail", + "mailer" + ], + "time": "2017-09-30T22:39:41+00:00" + }, + { + "name": "symfony/console", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "3e820bc2c520a87ca209ad8fa961c97f42e0b4ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/3e820bc2c520a87ca209ad8fa961c97f42e0b4ae", + "reference": "3e820bc2c520a87ca209ad8fa961c97f42e0b4ae", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "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": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2018-04-30T01:23:47+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "03f965583147957f1ecbad7ea1c9d6fd5e525ec2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/03f965583147957f1ecbad7ea1c9d6fd5e525ec2", + "reference": "03f965583147957f1ecbad7ea1c9d6fd5e525ec2", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "time": "2018-03-19T22:35:49+00:00" + }, + { + "name": "symfony/debug", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "e1d57cdb357e5b10f5fdacbb0b86689c0a435e6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/e1d57cdb357e5b10f5fdacbb0b86689c0a435e6e", + "reference": "e1d57cdb357e5b10f5fdacbb0b86689c0a435e6e", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": "<3.4" + }, + "require-dev": { + "symfony/http-kernel": "~3.4|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "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": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2018-04-30T16:59:37+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "63353a71073faf08f62caab4e6889b06a787f07b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/63353a71073faf08f62caab4e6889b06a787f07b", + "reference": "63353a71073faf08f62caab4e6889b06a787f07b", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "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": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2018-04-06T07:35:43+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", + "reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "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": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2018-04-04T05:10:37+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "014487772c22d893168e5d628a13e882009fea29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/014487772c22d893168e5d628a13e882009fea29", + "reference": "014487772c22d893168e5d628a13e882009fea29", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "symfony/expression-language": "~3.4|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "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": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com", + "time": "2018-04-30T01:05:59+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "8333264b6de323ea27a08627d5396aa564fb9c25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8333264b6de323ea27a08627d5396aa564fb9c25", + "reference": "8333264b6de323ea27a08627d5396aa564fb9c25", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/log": "~1.0", + "symfony/debug": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/http-foundation": "~3.4.4|~4.0.4" + }, + "conflict": { + "symfony/config": "<3.4", + "symfony/dependency-injection": "<3.4.5|<4.0.5,>=4", + "symfony/var-dumper": "<3.4", + "twig/twig": "<1.34|<2.4,>=2" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/cache": "~1.0", + "symfony/browser-kit": "~3.4|~4.0", + "symfony/config": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/css-selector": "~3.4|~4.0", + "symfony/dependency-injection": "^3.4.5|^4.0.5", + "symfony/dom-crawler": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0", + "symfony/routing": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0", + "symfony/templating": "~3.4|~4.0", + "symfony/translation": "~3.4|~4.0", + "symfony/var-dumper": "~3.4|~4.0" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/var-dumper": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "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": "Symfony HttpKernel Component", + "homepage": "https://symfony.com", + "time": "2018-04-30T19:45:57+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "3296adf6a6454a050679cde90f95350ad604b171" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171", + "reference": "3296adf6a6454a050679cde90f95350ad604b171", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2018-04-26T10:06:28+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "a4576e282d782ad82397f3e4ec1df8e0f0cafb46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/a4576e282d782ad82397f3e4ec1df8e0f0cafb46", + "reference": "a4576e282d782ad82397f3e4ec1df8e0f0cafb46", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-04-26T10:06:28+00:00" + }, + { + "name": "symfony/process", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25", + "reference": "d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "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": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2018-04-03T05:24:00+00:00" + }, + { + "name": "symfony/routing", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "1dfbfdf060bbc80da8dedc062050052e694cd027" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/1dfbfdf060bbc80da8dedc062050052e694cd027", + "reference": "1dfbfdf060bbc80da8dedc062050052e694cd027", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "conflict": { + "symfony/config": "<3.4", + "symfony/dependency-injection": "<3.4", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/common": "~2.2", + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/http-foundation": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/dependency-injection": "For loading routes from a service", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "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": "Symfony Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "time": "2018-04-20T06:20:23+00:00" + }, + { + "name": "symfony/translation", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "ad3abf08eb3450491d8d76513100ef58194cd13e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/ad3abf08eb3450491d8d76513100ef58194cd13e", + "reference": "ad3abf08eb3450491d8d76513100ef58194cd13e", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/config": "<3.4", + "symfony/dependency-injection": "<3.4", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/intl": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "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": "Symfony Translation Component", + "homepage": "https://symfony.com", + "time": "2018-04-30T01:23:47+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "3c34cf3f4bbac9e003d9325225e9ef1a49180a18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3c34cf3f4bbac9e003d9325225e9ef1a49180a18", + "reference": "3c34cf3f4bbac9e003d9325225e9ef1a49180a18", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php72": "~1.5" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" + }, + "require-dev": { + "ext-iconv": "*", + "twig/twig": "~1.34|~2.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "time": "2018-04-26T16:12:06+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "0ed4a2ea4e0902dac0489e6436ebcd5bbcae9757" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/0ed4a2ea4e0902dac0489e6436ebcd5bbcae9757", + "reference": "0ed4a2ea4e0902dac0489e6436ebcd5bbcae9757", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "time": "2017-11-27T11:13:29+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c", + "reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause-Attribution" + ], + "authors": [ + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "http://www.vancelucas.com" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "time": "2016-09-01T10:05:43+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2018-01-29T19:49:41+00:00" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], diff --git a/src/config/json-exception-handler.php b/config/json-exception-handler.php similarity index 100% rename from src/config/json-exception-handler.php rename to config/json-exception-handler.php diff --git a/phpunit.xml b/phpunit.xml index 57e0396..c31b987 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,25 +1,26 @@ - + processIsolation="false" + stopOnFailure="false"> - ./tests/ + ./tests/ - ./src + ./src/ - \ No newline at end of file + + + + + diff --git a/src/resources/lang/pt-br/exceptions.php b/resources/lang/en/exceptions.php similarity index 96% rename from src/resources/lang/pt-br/exceptions.php rename to resources/lang/en/exceptions.php index ed24ee2..cfba22d 100644 --- a/src/resources/lang/pt-br/exceptions.php +++ b/resources/lang/en/exceptions.php @@ -35,6 +35,6 @@ | */ 'models' => [ - 'User' => 'Usuário', + 'User' => 'User', ] ]; diff --git a/src/resources/lang/en/exceptions.php b/resources/lang/pt-br/exceptions.php similarity index 100% rename from src/resources/lang/en/exceptions.php rename to resources/lang/pt-br/exceptions.php diff --git a/src/AuthenticationHandler.php b/src/AuthenticationHandler.php deleted file mode 100644 index d409802..0000000 --- a/src/AuthenticationHandler.php +++ /dev/null @@ -1,22 +0,0 @@ - 401, - 'code' => $this->getCode('authentication'), - 'source' => ['pointer' => $exception->getFile().':'.$exception->getLine()], - 'title' => $exception->getMessage(), - 'detail' => __('exception::exceptions.authentication.detail'), - ]]; - - $this->jsonApiResponse->setStatus(401); - $this->jsonApiResponse->setErrors($error); - } -} diff --git a/src/AuthorizationHandler.php b/src/AuthorizationHandler.php deleted file mode 100644 index b323d14..0000000 --- a/src/AuthorizationHandler.php +++ /dev/null @@ -1,51 +0,0 @@ - 403, - 'code' => $this->getCode('authorization'), - 'source' => ['pointer' => $exception->getFile().':'.$exception->getLine()], - 'title' => __('exception::exceptions.authorization.title'), - 'detail' => $exception->getMessage(), - ]]; - - $this->jsonApiResponse->setStatus(403); - $this->jsonApiResponse->setErrors($error); - } - - public function generateDescription($traces) - { - $action = ''; - foreach ($traces as $trace) { - if ($trace['function'] === 'authorize') { - $action = $this->extractAction($trace['args']); - break; - } - } - } - - public function extractAction($args) - { - $action = reset($args); - - $this->getWord($action); - } - - public function getWords($action) - { - $words = explode('.', $action); - if (! (count($words) > 1)) { - $words = explode('-', $action); - if (! (count($words) > 1)) { - $words = preg_split('/(?=[A-Z])/', $action); - } - } - } -} diff --git a/src/BadRequestHttpHandler.php b/src/BadRequestHttpHandler.php deleted file mode 100644 index 122421a..0000000 --- a/src/BadRequestHttpHandler.php +++ /dev/null @@ -1,24 +0,0 @@ -getStatusCode(); - - $error = [[ - 'status' => $statusCode, - 'code' => $this->getCode('bad_request'), - 'source' => ['pointer' => $exception->getFile().':'.$exception->getLine()], - 'title' => 'bad_request', - 'detail' => $exception->getMessage(), - ]]; - - $this->jsonApiResponse->setStatus($statusCode); - $this->jsonApiResponse->setErrors($error); - } -} diff --git a/src/CieloRequestHandler.php b/src/CieloRequestHandler.php deleted file mode 100644 index 1f8d75d..0000000 --- a/src/CieloRequestHandler.php +++ /dev/null @@ -1,31 +0,0 @@ -getCode(); - do { - $cieloError = $e->getCieloError(); - $error = [ - 'status' => $e->getCode(), - 'code' => $this->getCode('cielo').$cieloError->getCode(), - 'source' => ['pointer' => $e->getFile().':'.$e->getLine()], - 'title' => $e->getMessage(), - 'detail' => $cieloError->getMessage(), - ]; - if (! in_array($error, $errors)) { - array_push($errors, $error); - } - $e = $e->getPrevious(); - } while (method_exists($e, 'getPrevious')); - - $this->jsonApiResponse->setStatus($code); - $this->jsonApiResponse->setErrors($errors); - } -} diff --git a/src/ClientHandler.php b/src/ClientHandler.php deleted file mode 100644 index 5bbf5b3..0000000 --- a/src/ClientHandler.php +++ /dev/null @@ -1,81 +0,0 @@ -getMessage(); - $code = $this->getCode(); - - if ($exception instanceof ClientException) { - $requestHost = $exception->getRequest()->getUri()->getHost(); - $clientCausers = $this->clientExceptionCausers(); - - $response = $exception->getResponse(); - - if ($clientCausers->isPagarme($requestHost)) { - $code = config('json-exception-handler.codes.client.pagarme') ?? 'pagarme'; - $errors = json_decode($response->getBody())->errors; - - $firstErrorMessage = ''; - foreach ($errors as $error) { - $firstErrorMessage = $error->message; - break; - } - - $detailedError = $firstErrorMessage.' #'.$code; - } elseif ($clientCausers->isMailgun($requestHost)) { - $code = config('json-exception-handler.codes.client.mailgun') ?? 'mailgun'; - $detailedError = json_decode($response->getBody())->message.' #'.$code; - } else { - // Unknown error - $code = config('json-exception-handler.codes.client.default'); - } - - if (App::environment('production')) { - $detail = __('exception::exceptions.client.unavailable').' #'.$code; - } else { - // Return more details about error - $detail = $detailedError ?? $detail; - $statusCode = $response->getStatusCode(); - } - } - - $error = [[ - 'status' => $statusCode, - 'code' => $code, - 'source' => ['pointer' => $exception->getFile().':'.$exception->getLine()], - 'title' => $title, - 'detail' => $detail, - ]]; - - $this->jsonApiResponse->setStatus($statusCode); - $this->jsonApiResponse->setErrors($error); - } - - public function clientExceptionCausers() - { - return new class() { - const PAGARME_HOST = 'api.pagar.me'; - - const MAILGUN_HOST = 'api.mailgun.net'; - - public function isPagarme($host) - { - return self::PAGARME_HOST == $host; - } - - public function isMailgun($host) - { - return self::MAILGUN_HOST == $host; - } - }; - } -} diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php new file mode 100644 index 0000000..ce6a37c --- /dev/null +++ b/src/Handlers/AbstractHandler.php @@ -0,0 +1,158 @@ + Handler::class, + ModelNotFoundException::class => ModelNotFoundHandler::class, + AuthenticationException::class => AuthenticationHandler::class, + AuthorizationException::class => AuthorizationHandler::class, + AuthorizationException::class => AuthorizationHandler::class, + ValidationException::class => ValidationHandler::class, + BadRequestHttpException::class => BadRequestHttpHandler::class, + NotFoundHttpException::class => NotFoundHttpHandler::class, + MissingScopeException::class => MissingScopeHandler::class, + OAuthServerException::class => OAuthServerHandler::class, + ]; + + public function __construct(Exception $e) + { + $this->exception = $e; + } + + /** + * Handle with an exception according to specific definitions. Returns one + * or more errors using the exception from $exceptions attribute. + * + * @return array|\Illuminate\Support\Collection| + * \Smartins\Exceptions\JsonApi\ErrorCollection| + * \SMartins\Exceptions\JsonApi\Error + */ + abstract public function handle(); + + /** + * Get error code. If code is empty from config file based on type. + * + * @param string $type Code type from config file + * @return int + */ + public function getCode($type = 'default') + { + $code = $this->exception->getCode(); + if (empty($this->exception->getCode())) { + $code = config('json-exception-handler.codes.'.$type); + } + + return $code; + } + + /** + * Return response with handled exception. + * + * @return \SMartins\Exceptions\JsonApi\Response + */ + public function handleException() + { + $handler = $this->getExceptionHandler(); + + $error = $handler->handle(); + + return new Response($error); + } + + /** + * Get the class the will handle the Exception from exceptionHandlers attributes. + * + * @return mixed + */ + public function getExceptionHandler() + { + $handlers = array_merge($this->exceptionHandlers, $this->internalExceptionHandlers); + + $handler = isset($handlers[get_class($this->exception)]) + ? $handlers[get_class($this->exception)] + : $this->defaultHandler(); + + return new $handler($this->exception); + } + + /** + * Get default pointer using file and line of exception. + * + * @return string + */ + public function getDefaultPointer() + { + return $this->exception->getFile().':'.$this->exception->getLine(); + } + + /** + * Get default title from exception. + * + * @return string + */ + public function getDefaultTitle() + { + return snake_case(class_basename($this->exception)); + } + + /** + * Get default http code. Check if exception has getStatusCode() methods. + * If not get from config file. + * + * @return int + */ + public function getStatusCode() + { + if (method_exists($this->exception, 'getStatusCode')) { + return $this->exception->getStatusCode(); + } + + return config('json-exception-handler.http_code'); + } + + /** + * The default handler to handle not treated exceptions. + * + * @return \SMartins\Exceptions\Handlers\Handler + */ + public function defaultHandler() + { + return new Handler($this->exception); + } +} diff --git a/src/Handlers/AuthenticationHandler.php b/src/Handlers/AuthenticationHandler.php new file mode 100644 index 0000000..b188698 --- /dev/null +++ b/src/Handlers/AuthenticationHandler.php @@ -0,0 +1,21 @@ +setStatus(401) + ->setCode($this->getCode('authentication')) + ->setSource((new Source())->setPointer($this->getDefaultPointer())) + ->setTitle($this->getDefaultTitle()) + ->setDetail(__('exception::exceptions.authentication.detail')); + } +} diff --git a/src/Handlers/AuthorizationHandler.php b/src/Handlers/AuthorizationHandler.php new file mode 100644 index 0000000..8248b4c --- /dev/null +++ b/src/Handlers/AuthorizationHandler.php @@ -0,0 +1,21 @@ +setStatus(403) + ->setCode($this->getCode('authorization')) + ->setSource((new Source())->setPointer($this->getDefaultPointer())) + ->setTitle(__('exception::exceptions.authorization.title')) + ->setDetail($this->exception->getMessage()); + } +} diff --git a/src/Handlers/BadRequestHttpHandler.php b/src/Handlers/BadRequestHttpHandler.php new file mode 100644 index 0000000..a4f8e3b --- /dev/null +++ b/src/Handlers/BadRequestHttpHandler.php @@ -0,0 +1,21 @@ +setStatus(400) + ->setCode($this->getCode('bad_request')) + ->setSource((new Source())->setPointer($this->getDefaultPointer())) + ->setTitle($this->getDefaultTitle()) + ->setDetail($this->exception->getMessage()); + } +} diff --git a/src/Handlers/Handler.php b/src/Handlers/Handler.php new file mode 100644 index 0000000..06b0f3e --- /dev/null +++ b/src/Handlers/Handler.php @@ -0,0 +1,21 @@ +setStatus($this->getStatusCode()) + ->setCode($this->getCode()) + ->setSource((new Source())->setPointer($this->getDefaultPointer())) + ->setTitle($this->getDefaultTitle()) + ->setDetail($this->exception->getMessage()); + } +} diff --git a/src/Handlers/MissingScopeHandler.php b/src/Handlers/MissingScopeHandler.php new file mode 100644 index 0000000..0cc04d0 --- /dev/null +++ b/src/Handlers/MissingScopeHandler.php @@ -0,0 +1,21 @@ +setStatus(403) + ->setCode($this->getCode('missing_scope')) + ->setSource((new Source())->setPointer($this->getDefaultPointer())) + ->setTitle($this->getDefaultTitle()) + ->setDetail($this->exception->getMessage()); + } +} diff --git a/src/ModelNotFoundHandler.php b/src/Handlers/ModelNotFoundHandler.php similarity index 52% rename from src/ModelNotFoundHandler.php rename to src/Handlers/ModelNotFoundHandler.php index 32bcd54..3882cce 100644 --- a/src/ModelNotFoundHandler.php +++ b/src/Handlers/ModelNotFoundHandler.php @@ -1,36 +1,30 @@ extractEntityName($exception->getModel()); - - $ids = implode($exception->getIds(), ','); + $entity = $this->extractEntityName($this->exception->getModel()); - $error = [[ - 'status' => 404, - 'code' => $this->getCode('model_not_found'), - 'source' => ['pointer' => 'data/id'], - 'title' => $exception->getMessage(), - 'detail' => __('exception::exceptions.model_not_found.title', ['model' => $entity]), - ]]; + $detail = __('exception::exceptions.model_not_found.title', ['model' => $entity]); - $this->jsonApiResponse->setStatus(404); - $this->jsonApiResponse->setErrors($error); + return (new Error)->setStatus(404) + ->setCode($this->getCode('model_not_found')) + ->setSource((new Source())->setPointer('data/id')) + ->setTitle(snake_case(class_basename($this->exception))) + ->setDetail($detail); } /** - * Get entitie name based on model path to mount the message. + * Get entity name based on model path to mount the message. * * @param string $model * @return string @@ -50,7 +44,8 @@ public function extractEntityName($model) /** * Check if entity returned on ModelNotFoundException has translation on - * exceptions file + * exceptions file. + * * @param string $entityName The model name to check if has translation * @return bool Has translation or not */ @@ -66,7 +61,8 @@ public function entityHasTranslation(string $entityName): bool } /** - * Get the models keys on exceptions lang file + * Get the models keys on exceptions lang file. + * * @return array An array with keys to translate */ private function translationModelKeys(): array diff --git a/src/Handlers/NotFoundHttpHandler.php b/src/Handlers/NotFoundHttpHandler.php new file mode 100644 index 0000000..21ef1ce --- /dev/null +++ b/src/Handlers/NotFoundHttpHandler.php @@ -0,0 +1,39 @@ +setStatus($this->getStatusCode()) + ->setCode($this->getCode('not_found_http')) + ->setSource((new Source())->setPointer($this->getDefaultPointer())) + ->setTitle($this->getDefaultTitle()) + ->setDetail($this->exception->getMessage()); + } + + /** + * Get message based on file. If file is RouteCollection return specific message. + * + * @return string + */ + public function getNotFoundMessage() + { + $message = ! empty($this->exception->getMessage()) + ? $this->exception->getMessage() + : class_basename($this->exception); + + if (basename($exception->getFile()) === 'RouteCollection.php') { + $message = __('exception::exceptions.not_found_http.message'); + } + + return $message; + } +} diff --git a/src/Handlers/OAuthServerHandler.php b/src/Handlers/OAuthServerHandler.php new file mode 100644 index 0000000..7441d06 --- /dev/null +++ b/src/Handlers/OAuthServerHandler.php @@ -0,0 +1,21 @@ +setStatus($this->getHttpStatusCode()) + ->setCode($this->getCode()) + ->setSource((new Source())->setPointer($this->getDefaultPointer())) + ->setTitle($this->exception->getErrorType()) + ->setDetail($this->exception->getMessage()); + } +} diff --git a/src/Handlers/ValidationHandler.php b/src/Handlers/ValidationHandler.php new file mode 100644 index 0000000..ced3cae --- /dev/null +++ b/src/Handlers/ValidationHandler.php @@ -0,0 +1,82 @@ +setStatusCode(400); + + $validationMessages = $this->getTreatedMessages(); + $validationFails = $this->getTreatedFails(); + + foreach ($validationMessages as $field => $messages) { + foreach ($messages as $key => $message) { + $attributes = $this->getValidationAttributes($validationFails, $key, $field); + + $error = (new Error)->setStatus(422) + ->setSource((new Source())->setPointer($field)) + ->setTitle($attributes['title']) + ->setDetail($message); + + if (! is_null($attributes['code'])) { + $error->setCode($attributes['code']); + } + + $errors->push($error); + } + } + + return $errors; + } + + public function getValidationAttributes(array $validationFails, $key, $field) + { + return [ + 'code' => $this->getValidationCode($validationFails, $key, $field), + 'title' => $this->getValidationTitle($validationFails, $key, $field), + ]; + } + + public function getValidationTitle(array $validationFails, $key, $field) + { + return __('exception::exceptions.validation.title', [ + 'fails' => array_keys($validationFails[$field])[$key], + 'field' => $field, + ]); + } + + public function getValidationCode(array $validationFails, $key, $field) + { + $rule = strtolower(array_keys($validationFails[$field])[$key]); + + return config('json-exception-handler.codes.validation_fields.'.$field.'.'.$rule); + } + + /** + * Get message based on exception type. If exception is generated by + * $this->validate() from default Controller methods the exception has the + * response object. If exception is generated by Validator::make() the + * messages are getted different. + * + * @return array + */ + public function getTreatedMessages() + { + return $this->exception->validator->messages()->messages(); + } + + public function getTreatedFails() + { + return $this->exception->validator->failed(); + } +} diff --git a/src/JsonApi/Error.php b/src/JsonApi/Error.php new file mode 100644 index 0000000..0765282 --- /dev/null +++ b/src/JsonApi/Error.php @@ -0,0 +1,230 @@ +id; + } + + /** + * Set a unique identifier for this particular occurrence of the problem. + * + * @param string $id + * + * @return self + */ + public function setId(string $id) + { + $this->id = $id; + + return $this; + } + + /** + * Get the value of links + * + * @return \SMartins\Exceptions\JsonApi\Links + */ + public function getLinks() + { + return $this->links; + } + + /** + * Set the value of links + * + * @param \SMartins\Exceptions\JsonApi\Links $links + * + * @return self + */ + public function setLinks(Links $links) + { + $this->links = $links; + + return $this; + } + + /** + * Get the HTTP status code applicable to this problem, expressed as a string value. + * + * @return string + */ + public function getStatus() + { + return $this->status; + } + + /** + * Set the HTTP status code applicable to this problem, expressed as a string value. + * + * @param string $status + * + * @return self + */ + public function setStatus(string $status) + { + $this->status = $status; + + return $this; + } + + /** + * Get an application-specific error code, expressed as a string value. + * + * @return string + */ + public function getCode() + { + return $this->code; + } + + /** + * Set an application-specific error code, expressed as a string value. + * + * @param string $code + * + * @return self + */ + public function setCode(string $code) + { + $this->code = $code; + + return $this; + } + + /** + * Get occurrence to occurrence of the problem, except for purposes of localization. + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Set occurrence to occurrence of the problem, except for purposes of localization. + * + * @param string $title + * + * @return self + */ + public function setTitle(string $title) + { + $this->title = $title; + + return $this; + } + + /** + * Get like title, this field’s value can be localized. + * + * @return string + */ + public function getDetail() + { + return $this->detail; + } + + /** + * Set like title, this field’s value can be localized. + * + * @param string $detail + * + * @return self + */ + public function setDetail(string $detail) + { + $this->detail = $detail; + + return $this; + } + + /** + * Get an object containing references to the source of the error. + * + * @return \SMartins\Exceptions\JsonApi\Source + */ + public function getSource() + { + return $this->source; + } + + /** + * Set an object containing references to the source of the error. + * + * @param \SMartins\Exceptions\JsonApi\Source $source + * + * @return self + */ + public function setSource(Source $source) + { + $this->source = $source; + + return $this; + } +} diff --git a/src/JsonApi/ErrorCollection.php b/src/JsonApi/ErrorCollection.php new file mode 100644 index 0000000..a5fcdf4 --- /dev/null +++ b/src/JsonApi/ErrorCollection.php @@ -0,0 +1,58 @@ +statusCode; + } + + /** + * Set the status code. + * + * @param string $statusCode + * + * @return self + */ + public function setStatusCode(string $statusCode) + { + $this->statusCode = $statusCode; + + return $this; + } + + /** + * Validate the content of items. All item should to be an instances of Error. + * + * @return self + * + * @throws \SMartins\Exceptions\JsonApi\CollectionInvalidContent + */ + public function validate() + { + foreach ($this->items as $item) { + if ($item instanceof Error === false) { + throw new InvalidContentException('All items on '.self::class.' must to be instances of '.Error::class, 1); + } + } + + return $this; + } +} diff --git a/src/JsonApi/InvalidContentException.php b/src/JsonApi/InvalidContentException.php new file mode 100644 index 0000000..6b0fce7 --- /dev/null +++ b/src/JsonApi/InvalidContentException.php @@ -0,0 +1,8 @@ +errors = $errors; + } elseif (is_array($errors) || $errors instanceof Collection) { + $this->errors = new ErrorCollection($errors); + } elseif ($errors instanceof Error) { + $this->errors = (new ErrorCollection)->push($errors); + $this->errors->setStatusCode($errors->getStatus()); + } + + if (! $this->errors instanceof ErrorCollection) { + throw new InvalidArgumentException('The errors must be an array, '.Collection::class.','.Error::class.' or '.ErrorCollection::class.'.'); + } + + $this->errors->validate(); + + $this->setStatus($this->errors->getStatusCode()); + } + + /** + * Get the HTTP status code. + * + * @return int + */ + public function getStatus() + { + return $this->status; + } + + /** + * Set the HTTP status code. + * + * @param int $status The HTTP status code. + * + * @return self + */ + public function setStatus(int $status) + { + $this->status = $status; + + return $this; + } + + /** + * Get the errors on response. + * + * @return array + */ + public function getErrors() + { + return $this->errors; + } + + /** + * Convert the object to its JSON representation. + * + * @param int $options + * @return string + */ + public function json() + { + return new JsonResponse( + ['errors' => $this->getErrors()->toArray()], + $this->getStatus() + ); + } +} diff --git a/src/JsonApi/Source.php b/src/JsonApi/Source.php new file mode 100644 index 0000000..fbfb8da --- /dev/null +++ b/src/JsonApi/Source.php @@ -0,0 +1,76 @@ +pointer; + } + + /** + * Set pointer. + * + * @param string $pointer + * + * @return self + */ + public function setPointer(string $pointer) + { + $this->pointer = $pointer; + + return $this; + } + + /** + * Get parameter. + * + * @return string + */ + public function getParameter() + { + return $this->parameter; + } + + /** + * Set parameter. + * + * @param string $parameter + * + * @return self + */ + public function setParameter(string $parameter) + { + $this->parameter = $parameter; + + return $this; + } +} diff --git a/src/JsonHandler.php b/src/JsonHandler.php index 873bc08..934c96b 100644 --- a/src/JsonHandler.php +++ b/src/JsonHandler.php @@ -1,114 +1,12 @@ $this->getStatusCode(), - 'code' => $this->getCode(), - 'source' => ['pointer' => $this->getDescription()], - 'title' => strtolower(class_basename($this->exception)), - 'detail' => $this->getMessage(), - ]]; - - $this->jsonApiResponse->setStatus($this->getStatusCode()); - $this->jsonApiResponse->setErrors($error); - } - - /** - * Get default message from exception. - * - * @return string Exception message - */ - public function getMessage() - { - return $this->exception->getMessage(); - } - - /** - * Mount the description with exception class, line and file. - * - * @return string - */ - public function getDescription() - { - return class_basename($this->exception). - ' line '.$this->exception->getLine(). - ' in '.$this->exception->getFile(); - } - - /** - * Get default http code. Check if exception has getStatusCode() methods. - * If not get from config file. - * - * @return int - */ - public function getStatusCode() - { - if (method_exists($this->exception, 'getStatusCode')) { - $httpCode = $this->exception->getStatusCode(); - } else { - $httpCode = config($this->configFile.'.http_code'); - } - - return $httpCode; - } - - /** - * Get error code. If code is empty from config file based on type. - * - * @param string $type Code type from config file - * @return int - */ - public function getCode($type = 'default') - { - $code = $this->exception->getCode(); - if (empty($this->exception->getCode())) { - $code = config($this->configFile.'.codes.'.$type); - } - - return $code; - } - /** * Handle the json response. Check if exception is treated. If true call * the specific handler. If false set the default response to be returned. @@ -118,51 +16,6 @@ public function getCode($type = 'default') */ public function jsonResponse(Exception $exception) { - $this->exception = $exception; - $this->jsonApiResponse = new JsonApiResponse; - - if ($this->exceptionIsTreated()) { - $this->callExceptionHandler(); - } else { - $this->setDefaultResponse(); - } - - return response()->json( - $this->jsonApiResponse->toArray(), - $this->jsonApiResponse->getStatus() - ); - } - - /** - * Check if method to treat exception exists. - * - * @param Exception $exception The exception to be checked - * @return bool If method is callable - */ - public function exceptionIsTreated() - { - return is_callable([$this, $this->methodName()]); - } - - /** - * Call the exception handler after of to check if the method exists. - * - * @param Exception $exception - * @return void Call the method - */ - public function callExceptionHandler() - { - $this->{$this->methodName()}($this->exception); - } - - /** - * The method name is the exception name with first letter in lower case. - * - * @param Exception $exception - * @return string The method name - */ - public function methodName() - { - return lcfirst(class_basename($this->exception)); + return (new Handler($exception))->handleException()->json(); } } diff --git a/src/JsonHandlerServiceProvider.php b/src/JsonHandlerServiceProvider.php index 7de8927..15436e3 100644 --- a/src/JsonHandlerServiceProvider.php +++ b/src/JsonHandlerServiceProvider.php @@ -1,6 +1,6 @@ configPath() => config_path('json-exception-handler.php'), ]); - $this->loadTranslationsFrom(__DIR__.'/resources/lang', 'exception'); + $this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'exception'); $this->publishes([ - __DIR__.'/resources/lang' => resource_path('lang/vendor/exception'), + __DIR__.'/../resources/lang' => resource_path('lang/vendor/exception'), ]); } @@ -26,6 +26,6 @@ public function register() public function configPath() { - return __DIR__.'/config/json-exception-handler.php'; + return __DIR__.'/../config/json-exception-handler.php'; } } diff --git a/src/MissingScopeHandler.php b/src/MissingScopeHandler.php deleted file mode 100644 index d1331f9..0000000 --- a/src/MissingScopeHandler.php +++ /dev/null @@ -1,22 +0,0 @@ - 403, - 'code' => $this->getCode('missing_scope'), - 'source' => ['pointer' => $exception->getFile().':'.$exception->getLine()], - 'title' => 'missing_scope', - 'detail' => $exception->getMessage(), - ]]; - - $this->jsonApiResponse->setStatus(403); - $this->jsonApiResponse->setErrors($error); - } -} diff --git a/src/NotFoundHttpHandler.php b/src/NotFoundHttpHandler.php deleted file mode 100644 index f3a9037..0000000 --- a/src/NotFoundHttpHandler.php +++ /dev/null @@ -1,45 +0,0 @@ -getStatusCode(); - $error = [[ - 'status' => $statuCode, - 'code' => $this->getCode('not_found_http'), - 'source' => ['pointer' => $exception->getFile().':'.$exception->getLine()], - 'title' => $this->getDescription($exception), - 'detail' => $this->getNotFoundMessage($exception), - ]]; - - $this->jsonApiResponse->setStatus($statuCode); - $this->jsonApiResponse->setErrors($error); - } - - /** - * Get message based on file. If file is RouteCollection return specific - * message. - * - * @param NotFoundHttpException $exception - * @return string - */ - public function getNotFoundMessage(NotFoundHttpException $exception) - { - $message = ! empty($exception->getMessage()) ? $exception->getMessage() : class_basename($exception); - if (basename($exception->getFile()) === 'RouteCollection.php') { - $message = __('exception::exceptions.not_found_http.message'); - } - - return $message; - } -} diff --git a/src/OAuthServerHandler.php b/src/OAuthServerHandler.php deleted file mode 100644 index 7ea7ad6..0000000 --- a/src/OAuthServerHandler.php +++ /dev/null @@ -1,24 +0,0 @@ -getHttpStatusCode(); - - $error = [[ - 'status' => $statusCode, - 'code' => $this->getCode('not_found_http'), - 'source' => ['pointer' => $exception->getFile().':'.$exception->getLine()], - 'title' => $exception->getErrorType(), - 'detail' => $exception->getMessage(), - ]]; - - $this->jsonApiResponse->setStatus($statusCode); - $this->jsonApiResponse->setErrors($error); - } -} diff --git a/src/Responses/JsonApiResponse.php b/src/Responses/JsonApiResponse.php deleted file mode 100644 index 63ce8e4..0000000 --- a/src/Responses/JsonApiResponse.php +++ /dev/null @@ -1,45 +0,0 @@ -status; - } - - public function status() - { - return $this->getStatus(); - } - - public function getErrors() - { - return $this->errors; - } - - public function errors() - { - return $this->getErrors(); - } - - public function setStatus($status) - { - $this->status = $status; - } - - public function setErrors($errors) - { - $this->errors = $errors; - } - - public function toArray() - { - return ['errors' => $this->errors()]; - } -} diff --git a/src/Traits/NotNullArrayable.php b/src/Traits/NotNullArrayable.php new file mode 100644 index 0000000..7b41c0d --- /dev/null +++ b/src/Traits/NotNullArrayable.php @@ -0,0 +1,25 @@ + $value) { + if (! is_null($value)) { + $array[$attribute] = $value instanceof Arrayable ? $value->toArray() : $value; + } + } + + return $array; + } +} diff --git a/src/ValidationHandler.php b/src/ValidationHandler.php deleted file mode 100644 index b273f79..0000000 --- a/src/ValidationHandler.php +++ /dev/null @@ -1,106 +0,0 @@ -jsonApiResponse->setStatus(422); - $this->jsonApiResponse->setErrors($this->jsonApiFormatErrorMessages($exception)); - } - - /** - * Get formatted errors on standard code, field, message to each field with - * error. - * - * @param ValidationException $exception - * @return array - */ - public function formattedErrors(ValidationException $exception) - { - return $this->jsonApiFormatErrorMessages($exception); - } - - public function jsonApiFormatErrorMessages(ValidationException $exception) - { - $validationMessages = $this->getTreatedMessages($exception); - $validationFails = $this->getTreatedFails($exception); - - $errors = []; - foreach ($validationMessages as $field => $messages) { - foreach ($messages as $key => $message) { - $attributes = $this->getValidationAttributes($validationFails, $key, $field); - $error = [ - 'status' => 422, - 'code' => $attributes['code'], - 'source' => ['parameter' => $field], - 'title' => $attributes['title'], - 'detail' => $message, - ]; - array_push($errors, $error); - } - } - - return $errors; - } - - public function getValidationAttributes(array $validationFails, $key, $field) - { - return [ - 'code' => $this->getValidationCode($validationFails, $key, $field), - 'title' => $this->getValidationTitle($validationFails, $key, $field), - ]; - } - - public function getValidationTitle(array $validationFails, $key, $field) - { - return __('exception::exceptions.validation.title', [ - 'fails' => array_keys($validationFails[$field])[$key], - 'field' => $field, - ]); - } - - public function getValidationCode(array $validationFails, $key, $field) - { - $rule = strtolower(array_keys($validationFails[$field])[$key]); - - return config($this->configFile.'.codes.validation_fields.'.$field.'.'.$rule); - } - - /** - * Get message based on exception type. If exception is generated by - * $this->validate() from default Controller methods the exception has the - * response object. If exception is generated by Validator::make() the - * messages are getted different. - * - * @param Exception $exception - * @return array - */ - public function getTreatedMessages($exception) - { - return $this->getMessagesFromValidator($exception); - } - - public function getMessagesFromValidator($exception) - { - return $exception->validator->messages()->messages(); - } - - public function getTreatedFails($exception) - { - return $this->getFailsFromValidator($exception); - } - - public function getFailsFromValidator($exception) - { - return $exception->validator->failed(); - } -} diff --git a/tests/Feature/JsonHandlerTest.php b/tests/Feature/JsonHandlerTest.php new file mode 100644 index 0000000..52fe5f5 --- /dev/null +++ b/tests/Feature/JsonHandlerTest.php @@ -0,0 +1,123 @@ +loadLaravelMigrations(['--database' => 'exceptions']); + + $this->setUpRoutes(); + } + + public function setUpRoutes() + { + Route::get('default_exception', function (Request $request) { + throw new Exception('Test message', 1); + }); + + Route::get('/model_not_found', function (Request $request) { + Model::findOrFail(1); + }); + + Route::middleware('auth')->get('/authentication', function (Request $request) { + // + }); + + Route::get('authorization', function (Request $request) { + throw new AuthorizationException('Forbidden'); + }); + + Route::get('validation', function (Request $request) { + Validator::make($request->all(), [ + 'name' => 'required', + 'email' => 'email', + ])->validate(); + }); + + Route::get('bad_request', function (Request $request) { + throw new BadRequestHttpException('Bad Request'); + }); + } + + public function testThrowsDefaultException() + { + $this->json('GET', 'default_exception') + ->assertStatus(500) + ->assertJsonStructure($this->defaultErrorStructure()); + } + + public function testThrowsModelNotFoundException() + { + $this->json('GET', 'model_not_found') + ->assertStatus(404) + ->assertJsonStructure($this->defaultErrorStructure()); + } + + public function testThrowsAuthenticationException() + { + $this->json('GET', 'authentication') + ->assertStatus(401) + ->assertJsonStructure($this->defaultErrorStructure()); + } + + public function testThrowsAuthorizationException() + { + $this->json('GET', 'authorization') + ->assertStatus(403) + ->assertJsonStructure($this->defaultErrorStructure()); + } + + public function testThrowsValidationExceptions() + { + $params = ['email' => str_repeat('a', 11)]; + + $this->json('GET', 'validation', $params) + ->assertStatus(400) + ->assertJsonStructure($this->defaultErrorStructure()); + } + + public function testThrowsBadRequestHttpException() + { + $this->json('GET', 'bad_request') + ->assertStatus(400) + ->assertJsonStructure($this->defaultErrorStructure()); + } + + public function testThrowsNotFoundHttpException() + { + $this->json('GET', 'not_found_route') + ->assertStatus(404) + ->assertJsonStructure($this->defaultErrorStructure()); + } + + /** + * The default json response error structure. + * + * @return array + */ + public function defaultErrorStructure() + { + return [ + 'errors' => [[ + 'status', + 'code', + 'title', + 'detail', + 'source' => ['pointer'] + ]], + ]; + } +} diff --git a/tests/Fixtures/Exceptions/Handler.php b/tests/Fixtures/Exceptions/Handler.php new file mode 100644 index 0000000..2135353 --- /dev/null +++ b/tests/Fixtures/Exceptions/Handler.php @@ -0,0 +1,58 @@ +expectsJson()) { + return $this->jsonResponse($exception); + } + + return parent::render($request, $exception); + } +} diff --git a/tests/Fixtures/User.php b/tests/Fixtures/User.php new file mode 100644 index 0000000..58f5e55 --- /dev/null +++ b/tests/Fixtures/User.php @@ -0,0 +1,10 @@ +singleton( + \Illuminate\Contracts\Debug\ExceptionHandler::class, + \SMartins\Exceptions\Tests\Fixtures\Exceptions\Handler::class + ); + + // Setup default database to use sqlite :memory: + $app['config']->set('database.default', 'exceptions'); + $app['config']->set('database.connections.exceptions', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + ]); + } + + protected function getPackageProviders($app) + { + return [ + JsonHandlerServiceProvider::class, + ]; + } +} diff --git a/tests/Unit/AbstractHandlerTest.php b/tests/Unit/AbstractHandlerTest.php new file mode 100644 index 0000000..47444a3 --- /dev/null +++ b/tests/Unit/AbstractHandlerTest.php @@ -0,0 +1,16 @@ +assertInstanceOf(Handler::class, $handler->getExceptionHandler()); + } +} diff --git a/tests/Unit/HandlerTest.php b/tests/Unit/HandlerTest.php new file mode 100644 index 0000000..560997f --- /dev/null +++ b/tests/Unit/HandlerTest.php @@ -0,0 +1,19 @@ +assertInstanceOf(Error::class, $handler->handle()); + } +} \ No newline at end of file From 24c83303d1b6f0c687759c84ccca83eddfa0d18b Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 19 May 2018 12:33:56 -0300 Subject: [PATCH 02/34] Added scrutinizer config file --- .scrutinizer.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .scrutinizer.yml diff --git a/.scrutinizer.yml b/.scrutinizer.yml new file mode 100644 index 0000000..6e70bb0 --- /dev/null +++ b/.scrutinizer.yml @@ -0,0 +1,27 @@ +filter: + excluded_paths: [tests/*] + +checks: + php: + remove_extra_empty_lines: true + remove_php_closing_tag: true + remove_trailing_whitespace: true + fix_use_statements: + remove_unused: true + preserve_multiple: false + preserve_blanklines: true + order_alphabetically: true + fix_php_opening_tag: true + fix_linefeed: true + fix_line_ending: true + fix_identation_4spaces: true + fix_doc_comments: true + +build: + tests: + override: + - + command: 'vendor/bin/phpunit --coverage-clover=some-file' + coverage: + file: 'some-file' + format: 'clover' From 5829086942f50659922d8be7cf18f0cd119a6e55 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 19 May 2018 12:41:21 -0300 Subject: [PATCH 03/34] Changed return definition on abstract handle method --- src/Handlers/AbstractHandler.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index ce6a37c..8cf1660 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -59,9 +59,7 @@ public function __construct(Exception $e) * Handle with an exception according to specific definitions. Returns one * or more errors using the exception from $exceptions attribute. * - * @return array|\Illuminate\Support\Collection| - * \Smartins\Exceptions\JsonApi\ErrorCollection| - * \SMartins\Exceptions\JsonApi\Error + * @return \SMartins\Exceptions\JsonApi\Error|\Smartins\Exceptions\JsonApi\ErrorCollection|array|\Illuminate\Support\Collection */ abstract public function handle(); From 9a6ec4d93a65c426231400a3ed14ebe4c9a8b41d Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 19 May 2018 13:14:25 -0300 Subject: [PATCH 04/34] Fixed many things --- src/Handlers/AbstractHandler.php | 5 +++++ src/Handlers/ModelNotFoundHandler.php | 11 +++++++++++ src/Handlers/NotFoundHttpHandler.php | 2 +- src/Handlers/OAuthServerHandler.php | 11 +++++++++++ src/Handlers/ValidationHandler.php | 2 +- src/JsonApi/Response.php | 5 +++-- src/JsonHandler.php | 5 +++-- 7 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 8cf1660..849d40f 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -50,6 +50,11 @@ abstract class AbstractHandler OAuthServerException::class => OAuthServerHandler::class, ]; + /** + * Create instance using the Exception to be handled. + * + * @param Exception $e + */ public function __construct(Exception $e) { $this->exception = $e; diff --git a/src/Handlers/ModelNotFoundHandler.php b/src/Handlers/ModelNotFoundHandler.php index 3882cce..dd52191 100644 --- a/src/Handlers/ModelNotFoundHandler.php +++ b/src/Handlers/ModelNotFoundHandler.php @@ -4,9 +4,20 @@ use SMartins\Exceptions\JSONAPI\Error; use SMartins\Exceptions\JSONAPI\Source; +use Illuminate\Database\Eloquent\ModelNotFoundException; class ModelNotFoundHandler extends AbstractHandler { + /** + * Create instance using the Exception to be handled. + * + * @param \Illuminate\Database\Eloquent\ModelNotFoundException $e + */ + public function __construct(ModelNotFoundException $e) + { + parent::__construct($e); + } + /** * {@inheritDoc} */ diff --git a/src/Handlers/NotFoundHttpHandler.php b/src/Handlers/NotFoundHttpHandler.php index 21ef1ce..0b79b17 100644 --- a/src/Handlers/NotFoundHttpHandler.php +++ b/src/Handlers/NotFoundHttpHandler.php @@ -30,7 +30,7 @@ public function getNotFoundMessage() ? $this->exception->getMessage() : class_basename($this->exception); - if (basename($exception->getFile()) === 'RouteCollection.php') { + if (basename($this->exception->getFile()) === 'RouteCollection.php') { $message = __('exception::exceptions.not_found_http.message'); } diff --git a/src/Handlers/OAuthServerHandler.php b/src/Handlers/OAuthServerHandler.php index 7441d06..1e9297a 100644 --- a/src/Handlers/OAuthServerHandler.php +++ b/src/Handlers/OAuthServerHandler.php @@ -4,9 +4,20 @@ use SMartins\Exceptions\JsonApi\Error; use SMartins\Exceptions\JsonApi\Source; +use League\OAuth2\Server\Exception\OAuthServerException; class OAuthServerHandler extends AbstractHandler { + /** + * Create instance using the Exception to be handled. + * + * @param \League\OAuth2\Server\Exception\OAuthServerException $e + */ + public function __construct(OAuthServerException $e) + { + parent::__construct($e); + } + /** * {@inheritDoc} */ diff --git a/src/Handlers/ValidationHandler.php b/src/Handlers/ValidationHandler.php index ced3cae..8354d2c 100644 --- a/src/Handlers/ValidationHandler.php +++ b/src/Handlers/ValidationHandler.php @@ -25,7 +25,7 @@ public function handle() $error = (new Error)->setStatus(422) ->setSource((new Source())->setPointer($field)) - ->setTitle($attributes['title']) + ->setTitle($attributes['title'] ?? $this->getDefaultTitle()) ->setDetail($message); if (! is_null($attributes['code'])) { diff --git a/src/JsonApi/Response.php b/src/JsonApi/Response.php index 58a007a..3c31dba 100644 --- a/src/JsonApi/Response.php +++ b/src/JsonApi/Response.php @@ -2,6 +2,7 @@ namespace SMartins\Exceptions\JsonApi; +use InvalidArgumentException; use Illuminate\Http\JsonResponse; use Illuminate\Support\Collection; @@ -17,9 +18,9 @@ class Response /** * The errors on response. * - * @var array + * @var \SMartins\Exceptions\JsonApi\ErrorCollection */ - protected $errors = []; + protected $errors; /** * Create new JsonApi response passing the errors. diff --git a/src/JsonHandler.php b/src/JsonHandler.php index 934c96b..7e49e5b 100644 --- a/src/JsonHandler.php +++ b/src/JsonHandler.php @@ -11,8 +11,9 @@ trait JsonHandler * Handle the json response. Check if exception is treated. If true call * the specific handler. If false set the default response to be returned. * - * @param Exception $exception - * @return JsonResponse + * @param \Exception $exception + * + * @return \Illuminate\Http\JsonResponse */ public function jsonResponse(Exception $exception) { From cbdc16520cfc373df71bae881c1a7b8c8d335b3a Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 19 May 2018 13:29:30 -0300 Subject: [PATCH 05/34] Fixed inconsistent code --- src/Handlers/ValidationHandler.php | 4 +++- src/JsonApi/Response.php | 7 ++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Handlers/ValidationHandler.php b/src/Handlers/ValidationHandler.php index 8354d2c..936171b 100644 --- a/src/Handlers/ValidationHandler.php +++ b/src/Handlers/ValidationHandler.php @@ -49,10 +49,12 @@ public function getValidationAttributes(array $validationFails, $key, $field) public function getValidationTitle(array $validationFails, $key, $field) { - return __('exception::exceptions.validation.title', [ + $title = __('exception::exceptions.validation.title', [ 'fails' => array_keys($validationFails[$field])[$key], 'field' => $field, ]); + + return is_array($title) ? $title[0] : $title; } public function getValidationCode(array $validationFails, $key, $field) diff --git a/src/JsonApi/Response.php b/src/JsonApi/Response.php index 3c31dba..a2d41c5 100644 --- a/src/JsonApi/Response.php +++ b/src/JsonApi/Response.php @@ -36,15 +36,13 @@ public function __construct($errors) } elseif ($errors instanceof Error) { $this->errors = (new ErrorCollection)->push($errors); $this->errors->setStatusCode($errors->getStatus()); - } - - if (! $this->errors instanceof ErrorCollection) { + } else { throw new InvalidArgumentException('The errors must be an array, '.Collection::class.','.Error::class.' or '.ErrorCollection::class.'.'); } $this->errors->validate(); - $this->setStatus($this->errors->getStatusCode()); + $this->setStatus((int) $this->errors->getStatusCode()); } /** @@ -84,7 +82,6 @@ public function getErrors() /** * Convert the object to its JSON representation. * - * @param int $options * @return string */ public function json() From 50041bf082f858cee8cee28014574f5e4892be09 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 19 May 2018 13:37:17 -0300 Subject: [PATCH 06/34] Removed reference not on dependencies class --- src/Handlers/AbstractHandler.php | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 849d40f..c31173b 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -8,9 +8,7 @@ use Illuminate\Auth\AuthenticationException; use Illuminate\Validation\ValidationException; use Illuminate\Auth\Access\AuthorizationException; -use Laravel\Passport\Exceptions\MissingScopeException; use Illuminate\Database\Eloquent\ModelNotFoundException; -use League\OAuth2\Server\Exception\OAuthServerException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -38,16 +36,16 @@ abstract class AbstractHandler * @var array */ protected $internalExceptionHandlers = [ - Exception::class => Handler::class, - ModelNotFoundException::class => ModelNotFoundHandler::class, - AuthenticationException::class => AuthenticationHandler::class, - AuthorizationException::class => AuthorizationHandler::class, - AuthorizationException::class => AuthorizationHandler::class, - ValidationException::class => ValidationHandler::class, - BadRequestHttpException::class => BadRequestHttpHandler::class, - NotFoundHttpException::class => NotFoundHttpHandler::class, - MissingScopeException::class => MissingScopeHandler::class, - OAuthServerException::class => OAuthServerHandler::class, + Exception::class => Handler::class, + ModelNotFoundException::class => ModelNotFoundHandler::class, + AuthenticationException::class => AuthenticationHandler::class, + AuthorizationException::class => AuthorizationHandler::class, + AuthorizationException::class => AuthorizationHandler::class, + ValidationException::class => ValidationHandler::class, + BadRequestHttpException::class => BadRequestHttpHandler::class, + NotFoundHttpException::class => NotFoundHttpHandler::class, + 'Laravel\Passport\Exceptions\MissingScopeException' => MissingScopeHandler::class, + 'League\OAuth2\Server\Exception\OAuthServerException' => OAuthServerHandler::class, ]; /** From cfd0e01b52cd4aca7ab88957d38522cf6707d361 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 19 May 2018 14:41:44 -0300 Subject: [PATCH 07/34] Fixed complexibility response --- src/Handlers/AbstractHandler.php | 31 ++++++++++++++- src/Handlers/ValidationHandler.php | 60 ++++++++++++++++++------------ src/JsonApi/ErrorCollection.php | 2 +- src/JsonApi/Response.php | 19 ++-------- 4 files changed, 69 insertions(+), 43 deletions(-) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index c31173b..68c3ae6 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -4,9 +4,13 @@ use Exception; use RuntimeException; +use InvalidArgumentException; +use Illuminate\Support\Collection; +use SMartins\Exceptions\JsonApi\Error; use SMartins\Exceptions\JsonApi\Response; use Illuminate\Auth\AuthenticationException; use Illuminate\Validation\ValidationException; +use SMartins\Exceptions\JsonApi\ErrorCollection; use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Database\Eloquent\ModelNotFoundException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -91,9 +95,32 @@ public function handleException() { $handler = $this->getExceptionHandler(); - $error = $handler->handle(); + $errors = $this->validatedHandledException($handler->handle()); - return new Response($error); + return new Response($errors); + } + + /** + * Validate response from handle method of handler class. + * + * @param mixed $errors + * @return \SMartins\Exceptions\JsonApi\ErrorCollection + * + * @throws \InvalidArgumentException + */ + public function validatedHandledException($errors) + { + if (is_array($errors) || get_class($errors) === Collection::class) { + $errors = new ErrorCollection($errors); + } elseif ($errors instanceof Error) { + $errors = (new ErrorCollection)->push($errors)->setStatusCode($errors->getStatus()); + } + + if (! $errors instanceof ErrorCollection) { + throw new InvalidArgumentException('The errors must be an array, ['.Collection::class.'], ['.Error::class.'] or ['.ErrorCollection::class.'].'); + } + + return $errors->validated(); } /** diff --git a/src/Handlers/ValidationHandler.php b/src/Handlers/ValidationHandler.php index 936171b..f9bd705 100644 --- a/src/Handlers/ValidationHandler.php +++ b/src/Handlers/ValidationHandler.php @@ -13,23 +13,22 @@ class ValidationHandler extends AbstractHandler */ public function handle() { - $errors = new ErrorCollection; - $errors->setStatusCode(400); + $errors = (new ErrorCollection)->setStatusCode(400); - $validationMessages = $this->getTreatedMessages(); - $validationFails = $this->getTreatedFails(); + $failedFieldsRules = $this->getFailedFieldsRules(); - foreach ($validationMessages as $field => $messages) { + foreach ($this->getFailedFieldsMessages() as $field => $messages) { foreach ($messages as $key => $message) { - $attributes = $this->getValidationAttributes($validationFails, $key, $field); + $code = $this->getValidationCode($failedFieldsRules, $key, $field); + $title = $this->getValidationTitle($failedFieldsRules, $key, $field); $error = (new Error)->setStatus(422) ->setSource((new Source())->setPointer($field)) - ->setTitle($attributes['title'] ?? $this->getDefaultTitle()) + ->setTitle($title ?? $this->getDefaultTitle()) ->setDetail($message); - if (! is_null($attributes['code'])) { - $error->setCode($attributes['code']); + if (! is_null($code)) { + $error->setCode($code); } $errors->push($error); @@ -39,27 +38,35 @@ public function handle() return $errors; } - public function getValidationAttributes(array $validationFails, $key, $field) - { - return [ - 'code' => $this->getValidationCode($validationFails, $key, $field), - 'title' => $this->getValidationTitle($validationFails, $key, $field), - ]; - } - - public function getValidationTitle(array $validationFails, $key, $field) + /** + * Get the title of response based on rules and field getting from translations. + * + * @param array $failedFieldsRules + * @param string $key + * @param string $field + * @return string|null + */ + public function getValidationTitle(array $failedFieldsRules, string $key, string $field) { $title = __('exception::exceptions.validation.title', [ - 'fails' => array_keys($validationFails[$field])[$key], + 'fails' => array_keys($failedFieldsRules[$field])[$key], 'field' => $field, ]); return is_array($title) ? $title[0] : $title; } - public function getValidationCode(array $validationFails, $key, $field) + /** + * Get the code of validation error from config. + * + * @param array $failedFieldsRules + * @param string $key + * @param string $field + * @return string|null + */ + public function getValidationCode(array $failedFieldsRules, string $key, string $field) { - $rule = strtolower(array_keys($validationFails[$field])[$key]); + $rule = strtolower(array_keys($failedFieldsRules[$field])[$key]); return config('json-exception-handler.codes.validation_fields.'.$field.'.'.$rule); } @@ -68,16 +75,21 @@ public function getValidationCode(array $validationFails, $key, $field) * Get message based on exception type. If exception is generated by * $this->validate() from default Controller methods the exception has the * response object. If exception is generated by Validator::make() the - * messages are getted different. + * messages are get different. * * @return array */ - public function getTreatedMessages() + public function getFailedFieldsMessages(): array { return $this->exception->validator->messages()->messages(); } - public function getTreatedFails() + /** + * Get the rules failed on fields. + * + * @return array + */ + public function getFailedFieldsRules(): array { return $this->exception->validator->failed(); } diff --git a/src/JsonApi/ErrorCollection.php b/src/JsonApi/ErrorCollection.php index a5fcdf4..a1419f2 100644 --- a/src/JsonApi/ErrorCollection.php +++ b/src/JsonApi/ErrorCollection.php @@ -45,7 +45,7 @@ public function setStatusCode(string $statusCode) * * @throws \SMartins\Exceptions\JsonApi\CollectionInvalidContent */ - public function validate() + public function validated() { foreach ($this->items as $item) { if ($item instanceof Error === false) { diff --git a/src/JsonApi/Response.php b/src/JsonApi/Response.php index a2d41c5..4bc9100 100644 --- a/src/JsonApi/Response.php +++ b/src/JsonApi/Response.php @@ -2,9 +2,7 @@ namespace SMartins\Exceptions\JsonApi; -use InvalidArgumentException; use Illuminate\Http\JsonResponse; -use Illuminate\Support\Collection; class Response { @@ -25,22 +23,11 @@ class Response /** * Create new JsonApi response passing the errors. * - * @param mixed $errors + * @param \SMartins\Exceptions\JsonApi\ErrorCollection $errors */ - public function __construct($errors) + public function __construct(ErrorCollection $errors) { - if ($errors instanceof ErrorCollection) { - $this->errors = $errors; - } elseif (is_array($errors) || $errors instanceof Collection) { - $this->errors = new ErrorCollection($errors); - } elseif ($errors instanceof Error) { - $this->errors = (new ErrorCollection)->push($errors); - $this->errors->setStatusCode($errors->getStatus()); - } else { - throw new InvalidArgumentException('The errors must be an array, '.Collection::class.','.Error::class.' or '.ErrorCollection::class.'.'); - } - - $this->errors->validate(); + $this->errors = $errors; $this->setStatus((int) $this->errors->getStatusCode()); } From 6127f1bd2fdba434c7584c2ce2865d523cbdaa3b Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 19 May 2018 15:05:19 -0300 Subject: [PATCH 08/34] Added tests to abstract handler class and fixed errors on validation --- src/Handlers/AbstractHandler.php | 4 +++- tests/Unit/AbstractHandlerTest.php | 38 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 68c3ae6..52a390f 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -110,7 +110,9 @@ public function handleException() */ public function validatedHandledException($errors) { - if (is_array($errors) || get_class($errors) === Collection::class) { + if (is_array($errors) || + (is_object($errors) && get_class($errors) === Collection::class) + ) { $errors = new ErrorCollection($errors); } elseif ($errors instanceof Error) { $errors = (new ErrorCollection)->push($errors)->setStatusCode($errors->getStatus()); diff --git a/tests/Unit/AbstractHandlerTest.php b/tests/Unit/AbstractHandlerTest.php index 47444a3..1cff8f9 100644 --- a/tests/Unit/AbstractHandlerTest.php +++ b/tests/Unit/AbstractHandlerTest.php @@ -2,8 +2,11 @@ namespace SMartins\Exceptions\Tests\Unit; +use InvalidArgumentException; +use SMartins\Exceptions\JsonApi\Error; use SMartins\Exceptions\Tests\TestCase; use SMartins\Exceptions\Handlers\Handler; +use SMartins\Exceptions\JsonApi\ErrorCollection; class AbstractHandlerTest extends TestCase { @@ -13,4 +16,39 @@ public function testShouldReturnsTheHandlerClassOnGetExceptionHandler() $this->assertInstanceOf(Handler::class, $handler->getExceptionHandler()); } + + public function testGetDefaultHandler() + { + $handler = new Handler(new \Exception); + + $this->assertInstanceOf(Handler::class, $handler->defaultHandler()); + } + + public function testValidateHandledExceptionWithArrayOfErrors() + { + $errors = [new Error]; + + $handler = new Handler(new \Exception); + $validated = $handler->validatedHandledException($errors); + + $this->assertInstanceOf(ErrorCollection::class, $validated); + } + + public function testValidateHandledExceptionWithCollectionOfErrors() + { + $errors = collect([new Error]); + + $handler = new Handler(new \Exception); + $validated = $handler->validatedHandledException($errors); + + $this->assertInstanceOf(ErrorCollection::class, $validated); + } + + public function testValidateHandledExceptionWithInvalidArgument() + { + $this->expectException(InvalidArgumentException::class); + + $handler = new Handler(new \Exception); + $handler->validatedHandledException('invalid'); + } } From 6cb80bc4c12588186574211a50c9d0eea67d1dd7 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 20 May 2018 15:56:44 -0300 Subject: [PATCH 09/34] Changed handler return params --- .gitignore | 3 ++- src/Handlers/AbstractHandler.php | 21 +++++++---------- src/Handlers/NotFoundHttpHandler.php | 2 +- src/Handlers/ValidationHandler.php | 6 ++--- src/JsonApi/Error.php | 2 -- src/JsonApi/ErrorCollection.php | 35 +++++++++++++++++++++++++--- src/JsonApi/Response.php | 8 +++++-- tests/Unit/AbstractHandlerTest.php | 20 ---------------- 8 files changed, 52 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index 81cded9..795fd97 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /node_modules /vendor -/.phpintel \ No newline at end of file +/.phpintel +/.idea diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 52a390f..11b1ee3 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -3,7 +3,6 @@ namespace SMartins\Exceptions\Handlers; use Exception; -use RuntimeException; use InvalidArgumentException; use Illuminate\Support\Collection; use SMartins\Exceptions\JsonApi\Error; @@ -66,7 +65,9 @@ public function __construct(Exception $e) * Handle with an exception according to specific definitions. Returns one * or more errors using the exception from $exceptions attribute. * - * @return \SMartins\Exceptions\JsonApi\Error|\Smartins\Exceptions\JsonApi\ErrorCollection|array|\Illuminate\Support\Collection + * @todo Change the return type to any interface to make more extensible. + * + * @return \SMartins\Exceptions\JsonApi\Error|\Smartins\Exceptions\JsonApi\ErrorCollection */ abstract public function handle(); @@ -103,26 +104,20 @@ public function handleException() /** * Validate response from handle method of handler class. * - * @param mixed $errors + * @param \SMartins\Exceptions\JsonApi\Error|\Smartins\Exceptions\JsonApi\ErrorCollection $errors * @return \SMartins\Exceptions\JsonApi\ErrorCollection * * @throws \InvalidArgumentException */ public function validatedHandledException($errors) { - if (is_array($errors) || - (is_object($errors) && get_class($errors) === Collection::class) - ) { - $errors = new ErrorCollection($errors); + if ($errors instanceof ErrorCollection) { + return $errors->validated(); } elseif ($errors instanceof Error) { - $errors = (new ErrorCollection)->push($errors)->setStatusCode($errors->getStatus()); - } - - if (! $errors instanceof ErrorCollection) { - throw new InvalidArgumentException('The errors must be an array, ['.Collection::class.'], ['.Error::class.'] or ['.ErrorCollection::class.'].'); + return (new ErrorCollection([$errors]))->setStatusCode($errors->getStatus()); } - return $errors->validated(); + throw new InvalidArgumentException('The errors must be an instance of ['.Error::class.'] or ['.ErrorCollection::class.'].'); } /** diff --git a/src/Handlers/NotFoundHttpHandler.php b/src/Handlers/NotFoundHttpHandler.php index 0b79b17..5576075 100644 --- a/src/Handlers/NotFoundHttpHandler.php +++ b/src/Handlers/NotFoundHttpHandler.php @@ -16,7 +16,7 @@ public function handle() ->setCode($this->getCode('not_found_http')) ->setSource((new Source())->setPointer($this->getDefaultPointer())) ->setTitle($this->getDefaultTitle()) - ->setDetail($this->exception->getMessage()); + ->setDetail($this->getNotFoundMessage()); } /** diff --git a/src/Handlers/ValidationHandler.php b/src/Handlers/ValidationHandler.php index f9bd705..48da109 100644 --- a/src/Handlers/ValidationHandler.php +++ b/src/Handlers/ValidationHandler.php @@ -41,9 +41,9 @@ public function handle() /** * Get the title of response based on rules and field getting from translations. * - * @param array $failedFieldsRules - * @param string $key - * @param string $field + * @param array $failedFieldsRules + * @param string $key + * @param string $field * @return string|null */ public function getValidationTitle(array $failedFieldsRules, string $key, string $field) diff --git a/src/JsonApi/Error.php b/src/JsonApi/Error.php index 0765282..0acedfe 100644 --- a/src/JsonApi/Error.php +++ b/src/JsonApi/Error.php @@ -2,8 +2,6 @@ namespace SMartins\Exceptions\JsonApi; -use SMartins\Exceptions\JsonApi\Links; -use SMartins\Exceptions\JsonApi\Source; use Illuminate\Contracts\Support\Arrayable; use SMartins\Exceptions\Traits\NotNullArrayable; diff --git a/src/JsonApi/ErrorCollection.php b/src/JsonApi/ErrorCollection.php index a1419f2..069747c 100644 --- a/src/JsonApi/ErrorCollection.php +++ b/src/JsonApi/ErrorCollection.php @@ -2,7 +2,6 @@ namespace SMartins\Exceptions\JsonApi; -use InvalidArgumentException; use Illuminate\Support\Collection; class ErrorCollection extends Collection @@ -15,7 +14,14 @@ class ErrorCollection extends Collection protected $statusCode; /** - * Get the status code. + * The HTTP headers on response. + * + * @var array + */ + protected $headers = []; + + /** + * Returns the status code. * * @return string */ @@ -24,6 +30,16 @@ public function getStatusCode() return $this->statusCode; } + /** + * Returns response headers. + * + * @return array headers + */ + public function getHeaders() + { + return $this->headers; + } + /** * Set the status code. * @@ -38,12 +54,25 @@ public function setStatusCode(string $statusCode) return $this; } + /** + * Set the headers of response. + * + * @param array $headers + * @return self + */ + public function setHeaders(array $headers) + { + $this->headers = $headers; + + return $this; + } + /** * Validate the content of items. All item should to be an instances of Error. * * @return self * - * @throws \SMartins\Exceptions\JsonApi\CollectionInvalidContent + * @throws \SMartins\Exceptions\JsonApi\InvalidContentException */ public function validated() { diff --git a/src/JsonApi/Response.php b/src/JsonApi/Response.php index 4bc9100..b2c3c77 100644 --- a/src/JsonApi/Response.php +++ b/src/JsonApi/Response.php @@ -24,6 +24,9 @@ class Response * Create new JsonApi response passing the errors. * * @param \SMartins\Exceptions\JsonApi\ErrorCollection $errors + * + * @todo Receives an abstraction. Create an interfaces that can abstract + * the necessary methods. */ public function __construct(ErrorCollection $errors) { @@ -59,7 +62,7 @@ public function setStatus(int $status) /** * Get the errors on response. * - * @return array + * @return \SMartins\Exceptions\JsonApi\ErrorCollection */ public function getErrors() { @@ -75,7 +78,8 @@ public function json() { return new JsonResponse( ['errors' => $this->getErrors()->toArray()], - $this->getStatus() + $this->getStatus(), + $this->getErrors()->getHeaders() ); } } diff --git a/tests/Unit/AbstractHandlerTest.php b/tests/Unit/AbstractHandlerTest.php index 1cff8f9..b6e1465 100644 --- a/tests/Unit/AbstractHandlerTest.php +++ b/tests/Unit/AbstractHandlerTest.php @@ -24,26 +24,6 @@ public function testGetDefaultHandler() $this->assertInstanceOf(Handler::class, $handler->defaultHandler()); } - public function testValidateHandledExceptionWithArrayOfErrors() - { - $errors = [new Error]; - - $handler = new Handler(new \Exception); - $validated = $handler->validatedHandledException($errors); - - $this->assertInstanceOf(ErrorCollection::class, $validated); - } - - public function testValidateHandledExceptionWithCollectionOfErrors() - { - $errors = collect([new Error]); - - $handler = new Handler(new \Exception); - $validated = $handler->validatedHandledException($errors); - - $this->assertInstanceOf(ErrorCollection::class, $validated); - } - public function testValidateHandledExceptionWithInvalidArgument() { $this->expectException(InvalidArgumentException::class); From 404407c38713feb15759c0e618951b2f3b771f97 Mon Sep 17 00:00:00 2001 From: Samuel Date: Tue, 22 May 2018 22:43:18 -0300 Subject: [PATCH 10/34] Added option to choose personalized exception handlers --- config/json-exception-handler.php | 17 ++++ src/Handlers/AbstractHandler.php | 90 ++++++++++++++----- src/JsonApi/Error.php | 18 ++-- src/JsonApi/ErrorCollection.php | 17 ++-- src/JsonApi/Response.php | 72 ++------------- src/JsonHandler.php | 8 +- src/Response/AbstractResponse.php | 76 ++++++++++++++++ src/Response/ErrorCollectionInterface.php | 11 +++ .../ErrorHandledCollectionInterface.php | 18 ++++ src/Response/ErrorHandledInterface.php | 22 +++++ .../InvalidContentException.php | 2 +- tests/Feature/JsonHandlerTest.php | 1 + tests/Fixtures/Exceptions/Handler.php | 15 ++++ tests/GettersAndSetters.php | 28 ++++++ tests/Unit/AbstractHandlerTest.php | 2 +- tests/Unit/SourceTest.php | 14 +++ 16 files changed, 305 insertions(+), 106 deletions(-) create mode 100644 src/Response/AbstractResponse.php create mode 100644 src/Response/ErrorCollectionInterface.php create mode 100644 src/Response/ErrorHandledCollectionInterface.php create mode 100644 src/Response/ErrorHandledInterface.php rename src/{JsonApi => Response}/InvalidContentException.php (62%) create mode 100644 tests/GettersAndSetters.php create mode 100644 tests/Unit/SourceTest.php diff --git a/config/json-exception-handler.php b/config/json-exception-handler.php index 1f67c05..430369d 100644 --- a/config/json-exception-handler.php +++ b/config/json-exception-handler.php @@ -55,4 +55,21 @@ */ 'http_code' => 500, + /* + |--------------------------------------------------------------------------- + | Response Handler + |--------------------------------------------------------------------------- + | + | Any class the extends of \SMartins\Exceptions\Response\AbstractResponse. + */ + 'response_handler' => \SMartins\Exceptions\JsonApi\Response::class, + + /* + |--------------------------------------------------------------------------- + | Exception Handler + |-------------------------------------------------------------------------- + | + | The class that will handler the exceptions. + */ + 'exception_handler' => \SMartins\Exceptions\Handlers\Handler::class, ]; diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 11b1ee3..89f5947 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -6,12 +6,13 @@ use InvalidArgumentException; use Illuminate\Support\Collection; use SMartins\Exceptions\JsonApi\Error; -use SMartins\Exceptions\JsonApi\Response; use Illuminate\Auth\AuthenticationException; use Illuminate\Validation\ValidationException; -use SMartins\Exceptions\JsonApi\ErrorCollection; use Illuminate\Auth\Access\AuthorizationException; +use SMartins\Exceptions\Response\ErrorHandledInterface; use Illuminate\Database\Eloquent\ModelNotFoundException; +use SMartins\Exceptions\JsonApi\Response as JsonApiResponse; +use SMartins\Exceptions\Response\ErrorHandledCollectionInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -42,11 +43,8 @@ abstract class AbstractHandler Exception::class => Handler::class, ModelNotFoundException::class => ModelNotFoundHandler::class, AuthenticationException::class => AuthenticationHandler::class, - AuthorizationException::class => AuthorizationHandler::class, - AuthorizationException::class => AuthorizationHandler::class, ValidationException::class => ValidationHandler::class, BadRequestHttpException::class => BadRequestHttpHandler::class, - NotFoundHttpException::class => NotFoundHttpHandler::class, 'Laravel\Passport\Exceptions\MissingScopeException' => MissingScopeHandler::class, 'League\OAuth2\Server\Exception\OAuthServerException' => OAuthServerHandler::class, ]; @@ -67,7 +65,7 @@ public function __construct(Exception $e) * * @todo Change the return type to any interface to make more extensible. * - * @return \SMartins\Exceptions\JsonApi\Error|\Smartins\Exceptions\JsonApi\ErrorCollection + * @return \SMartins\Exceptions\Response\ErrorHandledInterface|\Smartins\Exceptions\Response\ErrorHandledCollectionInterface */ abstract public function handle(); @@ -79,9 +77,8 @@ abstract public function handle(); */ public function getCode($type = 'default') { - $code = $this->exception->getCode(); - if (empty($this->exception->getCode())) { - $code = config('json-exception-handler.codes.'.$type); + if (empty($code = $this->exception->getCode())) { + return config('json-exception-handler.codes.'.$type); } return $code; @@ -90,7 +87,7 @@ public function getCode($type = 'default') /** * Return response with handled exception. * - * @return \SMartins\Exceptions\JsonApi\Response + * @return \SMartins\Exceptions\Response\AbstractResponse */ public function handleException() { @@ -98,26 +95,28 @@ public function handleException() $errors = $this->validatedHandledException($handler->handle()); - return new Response($errors); + $responseHandler = $this->getResponseHandler(); + + return new $responseHandler($errors); } /** * Validate response from handle method of handler class. * - * @param \SMartins\Exceptions\JsonApi\Error|\Smartins\Exceptions\JsonApi\ErrorCollection $errors - * @return \SMartins\Exceptions\JsonApi\ErrorCollection + * @param \SMartins\Exceptions\Response\ErrorHandledInterface|\Smartins\Exceptions\Response\ErrorHandledCollectionInterface + * @return \SMartins\Exceptions\Response\ErrorHandledCollectionInterface * * @throws \InvalidArgumentException */ - public function validatedHandledException($errors) + public function validatedHandledException($error) { - if ($errors instanceof ErrorCollection) { - return $errors->validated(); - } elseif ($errors instanceof Error) { - return (new ErrorCollection([$errors]))->setStatusCode($errors->getStatus()); + if ($error instanceof ErrorHandledCollectionInterface) { + return $error->validatedContent(ErrorHandledInterface::class); + } elseif ($error instanceof ErrorHandledInterface) { + return $error->toCollection()->setStatusCode($error->getStatus()); } - throw new InvalidArgumentException('The errors must be an instance of ['.Error::class.'] or ['.ErrorCollection::class.'].'); + throw new InvalidArgumentException('The errors must be an instance of ['.ErrorHandledInterface::class.'] or ['.ErrorHandledCollectionInterface::class.'].'); } /** @@ -127,15 +126,25 @@ public function validatedHandledException($errors) */ public function getExceptionHandler() { - $handlers = array_merge($this->exceptionHandlers, $this->internalExceptionHandlers); + $handlers = $this->getConfiguredHandlers(); $handler = isset($handlers[get_class($this->exception)]) ? $handlers[get_class($this->exception)] - : $this->defaultHandler(); + : $this->getDefaultHandler(); return new $handler($this->exception); } + /** + * Get exception handlers from internal and set on App\Exceptions\Handler.php + * + * @return array + */ + public function getConfiguredHandlers() + { + return array_merge($this->exceptionHandlers, $this->internalExceptionHandlers); + } + /** * Get default pointer using file and line of exception. * @@ -176,8 +185,45 @@ public function getStatusCode() * * @return \SMartins\Exceptions\Handlers\Handler */ - public function defaultHandler() + public function getDefaultHandler() { return new Handler($this->exception); } + + /** + * Get default response handler of the if any response handler was defined + * on config file. + * + * @return string + */ + public function getDefaultResponseHandler() + { + return JsonApiResponse::class; + } + + /** + * Get the response class that will handle the json response. + * + * @todo Check if the response_handler on config is an instance of + * \SMartins\Exceptions\Response\AbstractResponse + * @return string + */ + public function getResponseHandler() + { + $response = config('json-exception-handler.response_handler'); + + return $response ?? $this->getDefaultResponseHandler(); + } + + /** + * Set exception handlers. + * + * @param array $handlers + */ + public function setExceptionHandlers(array $handlers) + { + $this->exceptionHandlers = $handlers; + + return $this; + } } diff --git a/src/JsonApi/Error.php b/src/JsonApi/Error.php index 0acedfe..2b37ac7 100644 --- a/src/JsonApi/Error.php +++ b/src/JsonApi/Error.php @@ -4,8 +4,10 @@ use Illuminate\Contracts\Support\Arrayable; use SMartins\Exceptions\Traits\NotNullArrayable; +use SMartins\Exceptions\Response\ErrorHandledInterface; +use SMartins\Exceptions\Response\ErrorHandledCollectionInterface; -class Error implements Arrayable +class Error implements Arrayable, ErrorHandledInterface { use NotNullArrayable; @@ -107,11 +109,9 @@ public function setLinks(Links $links) } /** - * Get the HTTP status code applicable to this problem, expressed as a string value. - * - * @return string + * {@inheritDoc} */ - public function getStatus() + public function getStatus(): string { return $this->status; } @@ -225,4 +225,12 @@ public function setSource(Source $source) return $this; } + + /** + * {@inheritDoc} + */ + public function toCollection(): ErrorHandledCollectionInterface + { + return new ErrorCollection([$this]); + } } diff --git a/src/JsonApi/ErrorCollection.php b/src/JsonApi/ErrorCollection.php index 069747c..a908482 100644 --- a/src/JsonApi/ErrorCollection.php +++ b/src/JsonApi/ErrorCollection.php @@ -3,8 +3,11 @@ namespace SMartins\Exceptions\JsonApi; use Illuminate\Support\Collection; +use SMartins\Exceptions\Response\ErrorHandledInterface; +use SMartins\Exceptions\Response\InvalidContentException; +use SMartins\Exceptions\Response\ErrorHandledCollectionInterface; -class ErrorCollection extends Collection +class ErrorCollection extends Collection implements ErrorHandledCollectionInterface { /** * The HTTP status code applicable to this problem, expressed as a string value. @@ -68,17 +71,13 @@ public function setHeaders(array $headers) } /** - * Validate the content of items. All item should to be an instances of Error. - * - * @return self - * - * @throws \SMartins\Exceptions\JsonApi\InvalidContentException + * {@inheritDoc} */ - public function validated() + public function validatedContent(string $type): ErrorHandledCollectionInterface { foreach ($this->items as $item) { - if ($item instanceof Error === false) { - throw new InvalidContentException('All items on '.self::class.' must to be instances of '.Error::class, 1); + if (! $item instanceof $type) { + throw new InvalidContentException('All items on ['.self::class.'] must to be instances of ['.$type.'].'); } } diff --git a/src/JsonApi/Response.php b/src/JsonApi/Response.php index b2c3c77..3e2351d 100644 --- a/src/JsonApi/Response.php +++ b/src/JsonApi/Response.php @@ -3,78 +3,16 @@ namespace SMartins\Exceptions\JsonApi; use Illuminate\Http\JsonResponse; +use SMartins\Exceptions\Response\AbstractResponse; -class Response +class Response extends AbstractResponse { /** - * The HTTP status code. + * Returns JSON response. * - * @var int + * @return \Illuminate\Http\JsonResponse */ - protected $status; - - /** - * The errors on response. - * - * @var \SMartins\Exceptions\JsonApi\ErrorCollection - */ - protected $errors; - - /** - * Create new JsonApi response passing the errors. - * - * @param \SMartins\Exceptions\JsonApi\ErrorCollection $errors - * - * @todo Receives an abstraction. Create an interfaces that can abstract - * the necessary methods. - */ - public function __construct(ErrorCollection $errors) - { - $this->errors = $errors; - - $this->setStatus((int) $this->errors->getStatusCode()); - } - - /** - * Get the HTTP status code. - * - * @return int - */ - public function getStatus() - { - return $this->status; - } - - /** - * Set the HTTP status code. - * - * @param int $status The HTTP status code. - * - * @return self - */ - public function setStatus(int $status) - { - $this->status = $status; - - return $this; - } - - /** - * Get the errors on response. - * - * @return \SMartins\Exceptions\JsonApi\ErrorCollection - */ - public function getErrors() - { - return $this->errors; - } - - /** - * Convert the object to its JSON representation. - * - * @return string - */ - public function json() + public function json(): JsonResponse { return new JsonResponse( ['errors' => $this->getErrors()->toArray()], diff --git a/src/JsonHandler.php b/src/JsonHandler.php index 7e49e5b..69f6c39 100644 --- a/src/JsonHandler.php +++ b/src/JsonHandler.php @@ -17,6 +17,12 @@ trait JsonHandler */ public function jsonResponse(Exception $exception) { - return (new Handler($exception))->handleException()->json(); + $handler = new Handler($exception); + + if (property_exists($this, 'exceptionHandlers')) { + $handler->setExceptionHandlers($this->exceptionHandlers); + } + + return $handler->handleException()->json(); } } diff --git a/src/Response/AbstractResponse.php b/src/Response/AbstractResponse.php new file mode 100644 index 0000000..b846e58 --- /dev/null +++ b/src/Response/AbstractResponse.php @@ -0,0 +1,76 @@ +errors = $errors; + + $this->setStatus((int) $this->errors->getStatusCode()); + } + + /** + * Get the HTTP status code. + * + * @return int + */ + public function getStatus() + { + return $this->status; + } + + /** + * Set the HTTP status code. + * + * @param int $status The HTTP status code. + * + * @return self + */ + public function setStatus(int $status) + { + $this->status = $status; + + return $this; + } + + /** + * Get the errors on response. + * + * @return \SMartins\Exceptions\JsonApi\ErrorCollection + */ + public function getErrors() + { + return $this->errors; + } + + /** + * Returns JSON response. + * + * @return \Illuminate\Http\JsonResponse + */ + abstract public function json(): JsonResponse; +} diff --git a/src/Response/ErrorCollectionInterface.php b/src/Response/ErrorCollectionInterface.php new file mode 100644 index 0000000..4a8b907 --- /dev/null +++ b/src/Response/ErrorCollectionInterface.php @@ -0,0 +1,11 @@ + str_repeat('a', 11)]; + // dd($this->json('GET', 'validation', $params)->json()); $this->json('GET', 'validation', $params) ->assertStatus(400) ->assertJsonStructure($this->defaultErrorStructure()); diff --git a/tests/Fixtures/Exceptions/Handler.php b/tests/Fixtures/Exceptions/Handler.php index 2135353..5b5952e 100644 --- a/tests/Fixtures/Exceptions/Handler.php +++ b/tests/Fixtures/Exceptions/Handler.php @@ -4,12 +4,27 @@ use Exception; use SMartins\Exceptions\JsonHandler; +use Illuminate\Auth\Access\AuthorizationException; +use SMartins\Exceptions\Handlers\NotFoundHttpHandler; +use SMartins\Exceptions\Handlers\AuthorizationHandler; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class Handler extends ExceptionHandler { use JsonHandler; + /** + * An array where the key is the class exception and the value is the handler + * class that will treat the exception. + * + * @var array + */ + protected $exceptionHandlers = [ + AuthorizationException::class => AuthorizationHandler::class, + NotFoundHttpException::class => NotFoundHttpHandler::class, + ]; + /** * A list of the exception types that are not reported. * diff --git a/tests/GettersAndSetters.php b/tests/GettersAndSetters.php new file mode 100644 index 0000000..eef54de --- /dev/null +++ b/tests/GettersAndSetters.php @@ -0,0 +1,28 @@ +classToTest; + $reflect = new ReflectionClass($class); + $properties = $reflect->getProperties(); + + foreach ($properties as $property) { + $setter = 'set'.ucfirst($property->getName()); + $getter = 'get'.ucfirst($property->getName()); + + $this->assertInstanceOf($this->classToTest, $class->{$setter}('test')); + $this->assertEquals('test', $class->{$getter}()); + } + } +} diff --git a/tests/Unit/AbstractHandlerTest.php b/tests/Unit/AbstractHandlerTest.php index b6e1465..67acc67 100644 --- a/tests/Unit/AbstractHandlerTest.php +++ b/tests/Unit/AbstractHandlerTest.php @@ -21,7 +21,7 @@ public function testGetDefaultHandler() { $handler = new Handler(new \Exception); - $this->assertInstanceOf(Handler::class, $handler->defaultHandler()); + $this->assertInstanceOf(Handler::class, $handler->getDefaultHandler()); } public function testValidateHandledExceptionWithInvalidArgument() diff --git a/tests/Unit/SourceTest.php b/tests/Unit/SourceTest.php new file mode 100644 index 0000000..6ba6d03 --- /dev/null +++ b/tests/Unit/SourceTest.php @@ -0,0 +1,14 @@ + Date: Thu, 24 May 2018 22:11:02 -0300 Subject: [PATCH 11/34] Added more test coverage --- README.md | 148 +++++++++++++++++++---------- src/JsonApi/Error.php | 56 +++++------ tests/Feature/JsonHandlerTest.php | 2 +- tests/Unit/ErrorCollectionTest.php | 18 ++++ tests/Unit/ErrorTest.php | 61 ++++++++++++ tests/Unit/SourceTest.php | 1 - 6 files changed, 208 insertions(+), 78 deletions(-) create mode 100644 tests/Unit/ErrorCollectionTest.php create mode 100644 tests/Unit/ErrorTest.php diff --git a/README.md b/README.md index 9570d63..0805e72 100644 --- a/README.md +++ b/README.md @@ -16,17 +16,17 @@ Default error response: ```json { - "errors": [ - { - "status": 404, - "code": 15, - "source": { - "pointer": "" - }, - "title": "Route not found.", - "detail": "NotFoundHttpException line 179 in RouteCollection.php" - } - ] + "errors": [ + { + "status": "404", + "code": "13", + "title": "model_not_found_exception", + "detail": "User not found", + "source": { + "pointer": "data/id" + } + } + ] } ``` @@ -34,35 +34,26 @@ To `Illuminate\Validation\ValidationException`: ```json { - "errors": [ - { - "status": 422, - "code": 1411, - "source": { - "parameter": "name" - }, - "title": "Required validation failed on field name", - "detail": "The name field is required." - }, - { - "status": 422, - "code": 1433, - "source": { - "parameter": "password" - }, - "title": "Min validation failed on field password", - "detail": "The password must be at least 6 characters." - }, - { - "status": 422, - "code": 1432, - "source": { - "parameter": "password" - }, - "title": "Confirmed validation failed on field password", - "detail": "The password confirmation does not match." - } - ] + "errors": [ + { + "status": "422", + "code": "1411", + "title": "Required validation failed on field name", + "detail": "The name field is required.", + "source": { + "pointer": "name" + } + }, + { + "status": "422", + "code": "1421", + "title": "Email validation failed on field email", + "detail": "The email must be a valid email address.", + "source": { + "pointer": "email" + } + } + ] } ``` @@ -76,8 +67,6 @@ To `Illuminate\Validation\ValidationException`: - `League\OAuth2\Server\Exception\OAuthServerException` - `Symfony\Component\HttpKernel\Exception\NotFoundHttpException` - `Symfony\Component\HttpKernel\Exception\BadRequestHttpException` -- `GuzzleHttp\Exception\ClientException` -- `Cielo\API30\Ecommerce\Request\CieloRequestException` ## Installing and configuring @@ -92,7 +81,7 @@ If you are not using **Laravel 5.5** version add the `JsonHandlerServiceProvider ```php 'providers' => [ ... - SMartins\JsonHandler\JsonHandlerServiceProvider::class, + SMartins\Exceptions\JsonHandlerServiceProvider::class, ], ``` @@ -125,13 +114,13 @@ passing the `$exception` if `$request` expects a json response on `render()`meth ```php -use SMartins\JsonHandler\JsonHandler; +use SMartins\Exceptions\JsonHandler; class Handler extends ExceptionHandler { use JsonHandler; - ... + // ... public function render($request, Exception $exception) { @@ -142,7 +131,7 @@ class Handler extends ExceptionHandler return parent::render($request, $exception); } - ... + // ... ``` ### Use sample @@ -151,12 +140,12 @@ class Handler extends ExceptionHandler class UserController extends Controller { - ... + // ... public function store(Request $request) { // Validation - $request->validate($this->rules); // on Laravel 5.5 + $request->validate($this->rules); // or $this->validate($request, $this->rules); @@ -187,6 +176,69 @@ class UserController extends Controller ``` +## Extending + +You can too create your own handler to any Exception. E.g.: + +- Create a Handler class that extends of `AbstractHandler`: + +```php +use SMartins\Exceptions\Handlers\AbstractHandler; + +class MyExceptionHandler extends AbstractHandler +{ + +} +``` + +- You must implements the method `handle()` from `AbstractHandler` class. The method must return an instance of `Error` or `ErrorCollection`: + +```php +use SMartins\Exceptions\JsonAPI\Error; +use SMartins\Exceptions\JsonAPI\Source; +use SMartins\Exceptions\Handlers\AbstractHandler; + +class MyExceptionHandler extends AbstractHandler +{ + public function handle() + { + return (new Error)->setStatus(401) + ->setCode($this->getCode()) + ->setSource((new Source())->setPointer($this->getDefaultPointer())) + ->setTitle($this->getDefaultTitle()) + ->setDetail($this->exception->getMessage())); + } +} +``` + +```php +use SMartins\Exceptions\JsonAPI\Error; +use SMartins\Exceptions\JsonAPI\Source; +use SMartins\Exceptions\JsonAPI\ErrorCollection; +use SMartins\Exceptions\Handlers\AbstractHandler; + +class MyExceptionHandler extends AbstractHandler +{ + public function handle() + { + $errors = (new ErrorCollection)->setStatusCode(400); + + $exceptions = $this->getExceptions(); + + foreach ($exceptions as $exception) { + $error = (new Error)->setStatus(422) + ->setSource((new Source())->setPointer($field)) + ->setTitle($this->getDefaultTitle()) + ->setDetail($exception->getMessage()); + + $errors->push($error); + } + + return $errors; + } +} +``` + ## Response References: - http://jsonapi.org/format/#errors diff --git a/src/JsonApi/Error.php b/src/JsonApi/Error.php index 2b37ac7..370bec8 100644 --- a/src/JsonApi/Error.php +++ b/src/JsonApi/Error.php @@ -63,7 +63,7 @@ class Error implements Arrayable, ErrorHandledInterface /** * Get a unique identifier for this particular occurrence of the problem. * - * @return string + * @return string */ public function getId() { @@ -73,11 +73,11 @@ public function getId() /** * Set a unique identifier for this particular occurrence of the problem. * - * @param string $id + * @param string $id * - * @return self + * @return self */ - public function setId(string $id) + public function setId(string $id): self { $this->id = $id; @@ -87,7 +87,7 @@ public function setId(string $id) /** * Get the value of links * - * @return \SMartins\Exceptions\JsonApi\Links + * @return \SMartins\Exceptions\JsonApi\Links */ public function getLinks() { @@ -97,11 +97,11 @@ public function getLinks() /** * Set the value of links * - * @param \SMartins\Exceptions\JsonApi\Links $links + * @param \SMartins\Exceptions\JsonApi\Links $links * - * @return self + * @return self */ - public function setLinks(Links $links) + public function setLinks(Links $links): self { $this->links = $links; @@ -119,11 +119,11 @@ public function getStatus(): string /** * Set the HTTP status code applicable to this problem, expressed as a string value. * - * @param string $status + * @param string $status * - * @return self + * @return self */ - public function setStatus(string $status) + public function setStatus(string $status): self { $this->status = $status; @@ -133,7 +133,7 @@ public function setStatus(string $status) /** * Get an application-specific error code, expressed as a string value. * - * @return string + * @return string */ public function getCode() { @@ -143,11 +143,11 @@ public function getCode() /** * Set an application-specific error code, expressed as a string value. * - * @param string $code + * @param string $code * - * @return self + * @return self */ - public function setCode(string $code) + public function setCode(string $code): self { $this->code = $code; @@ -157,9 +157,9 @@ public function setCode(string $code) /** * Get occurrence to occurrence of the problem, except for purposes of localization. * - * @return string + * @return string */ - public function getTitle() + public function getTitle(): string { return $this->title; } @@ -167,11 +167,11 @@ public function getTitle() /** * Set occurrence to occurrence of the problem, except for purposes of localization. * - * @param string $title + * @param string $title * - * @return self + * @return self */ - public function setTitle(string $title) + public function setTitle(string $title): self { $this->title = $title; @@ -181,7 +181,7 @@ public function setTitle(string $title) /** * Get like title, this field’s value can be localized. * - * @return string + * @return string */ public function getDetail() { @@ -191,11 +191,11 @@ public function getDetail() /** * Set like title, this field’s value can be localized. * - * @param string $detail + * @param string $detail * - * @return self + * @return self */ - public function setDetail(string $detail) + public function setDetail(string $detail): self { $this->detail = $detail; @@ -205,7 +205,7 @@ public function setDetail(string $detail) /** * Get an object containing references to the source of the error. * - * @return \SMartins\Exceptions\JsonApi\Source + * @return \SMartins\Exceptions\JsonApi\Source */ public function getSource() { @@ -215,11 +215,11 @@ public function getSource() /** * Set an object containing references to the source of the error. * - * @param \SMartins\Exceptions\JsonApi\Source $source + * @param \SMartins\Exceptions\JsonApi\Source $source * - * @return self + * @return self */ - public function setSource(Source $source) + public function setSource(Source $source): self { $this->source = $source; diff --git a/tests/Feature/JsonHandlerTest.php b/tests/Feature/JsonHandlerTest.php index b2214aa..9199a2b 100644 --- a/tests/Feature/JsonHandlerTest.php +++ b/tests/Feature/JsonHandlerTest.php @@ -84,7 +84,7 @@ public function testThrowsValidationExceptions() { $params = ['email' => str_repeat('a', 11)]; - // dd($this->json('GET', 'validation', $params)->json()); + dd(json_encode($this->json('GET', 'validation', $params)->json())); $this->json('GET', 'validation', $params) ->assertStatus(400) ->assertJsonStructure($this->defaultErrorStructure()); diff --git a/tests/Unit/ErrorCollectionTest.php b/tests/Unit/ErrorCollectionTest.php new file mode 100644 index 0000000..0c48620 --- /dev/null +++ b/tests/Unit/ErrorCollectionTest.php @@ -0,0 +1,18 @@ +assertInstanceOf(ErrorCollection::class, $error->setHeaders(['foo' => 'bar'])); + + $this->assertEquals($error->getHeaders(), ['foo' => 'bar']); + } +} diff --git a/tests/Unit/ErrorTest.php b/tests/Unit/ErrorTest.php new file mode 100644 index 0000000..5e5b235 --- /dev/null +++ b/tests/Unit/ErrorTest.php @@ -0,0 +1,61 @@ +assertInstanceOf(Error::class, $error->setId(1)); + $this->assertEquals(1, $error->getId()); + } + + public function testGetAndSetLinks() + { + $error = new Error; + $this->assertInstanceOf(Error::class, $error->setLinks($links = new Links)); + $this->assertEquals($links, $error->getLinks()); + } + + public function testGetAndSetCode() + { + $error = new Error; + $this->assertInstanceOf(Error::class, $error->setCode(1)); + $this->assertEquals(1, $error->getCode()); + } + + public function testGetAndSetTitle() + { + $error = new Error; + $this->assertInstanceOf(Error::class, $error->setTitle('tests')); + $this->assertEquals('tests', $error->getTitle()); + } + + public function testGetAndSetDetail() + { + $error = new Error; + $this->assertInstanceOf(Error::class, $error->setDetail('detail')); + $this->assertEquals('detail', $error->getDetail()); + } + + public function testGetAndSerSource() + { + $error = new Error; + $this->assertInstanceOf(Error::class, $error->setSource($source = new Source)); + $this->assertEquals($source, $error->getSource()); + } + + public function testToCollection() + { + $error = new Error; + $this->assertInstanceOf(ErrorCollection::class, $error->toCollection()); + } +} diff --git a/tests/Unit/SourceTest.php b/tests/Unit/SourceTest.php index 6ba6d03..adf89e8 100644 --- a/tests/Unit/SourceTest.php +++ b/tests/Unit/SourceTest.php @@ -3,7 +3,6 @@ namespace SMartins\Exceptions\Tests\Unit; use SMartins\Exceptions\Tests\TestCase; -use SMartins\Exceptions\JsonApi\Source; use SMartins\Exceptions\Tests\GettersAndSetters; class SourceTest extends TestCase From 2cfe3a8f6eb2a8ad82406fe4df3cb07dc07956b9 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 27 May 2018 19:35:03 -0300 Subject: [PATCH 12/34] Added instructions to extends Exceptions --- README.md | 46 +++++++++++++++++++++++++------ config/json-exception-handler.php | 5 ---- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 0805e72..082f4a4 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,6 @@ class Handler extends ExceptionHandler ### Use sample ```php - class UserController extends Controller { // ... @@ -183,51 +182,80 @@ You can too create your own handler to any Exception. E.g.: - Create a Handler class that extends of `AbstractHandler`: ```php +namespace App\Exceptions; + +use GuzzleHttp\Exception\ClientException; use SMartins\Exceptions\Handlers\AbstractHandler; -class MyExceptionHandler extends AbstractHandler +class GuzzleClientHandler extends AbstractHandler { - + /** + * Create instance using the Exception to be handled. + * + * @param \GuzzleHttp\Exception\ClientException $e + */ + public function __construct(ClientException $e) + { + parent::__construct($e); + } } ``` - You must implements the method `handle()` from `AbstractHandler` class. The method must return an instance of `Error` or `ErrorCollection`: ```php +namespace App\Exceptions; + use SMartins\Exceptions\JsonAPI\Error; use SMartins\Exceptions\JsonAPI\Source; +use GuzzleHttp\Exception\ClientException; use SMartins\Exceptions\Handlers\AbstractHandler; -class MyExceptionHandler extends AbstractHandler +class GuzzleClientHandler extends AbstractHandler { + // ... + public function handle() { - return (new Error)->setStatus(401) + return (new Error)->setStatus($this->getStatusCode()) ->setCode($this->getCode()) ->setSource((new Source())->setPointer($this->getDefaultPointer())) ->setTitle($this->getDefaultTitle()) - ->setDetail($this->exception->getMessage())); + ->setDetail($this->exception->getMessage()); + } + + public function getCode() + { + // You can add a new type of code on `config/json-exception-handlers.php` + return config('json-exception-handler.codes.client.default'); } } ``` ```php +namespace App\Exceptions; + use SMartins\Exceptions\JsonAPI\Error; use SMartins\Exceptions\JsonAPI\Source; use SMartins\Exceptions\JsonAPI\ErrorCollection; use SMartins\Exceptions\Handlers\AbstractHandler; -class MyExceptionHandler extends AbstractHandler +class MyCustomizedHandler extends AbstractHandler { + public function __construct(MyCustomizedException $e) + { + parent::__construct($e); + } + public function handle() { $errors = (new ErrorCollection)->setStatusCode(400); - $exceptions = $this->getExceptions(); + $exceptions = $this->exception->getExceptions(); foreach ($exceptions as $exception) { $error = (new Error)->setStatus(422) - ->setSource((new Source())->setPointer($field)) + ->setSource((new Source())->setPointer($this->getDefaultPointer())) ->setTitle($this->getDefaultTitle()) ->setDetail($exception->getMessage()); diff --git a/config/json-exception-handler.php b/config/json-exception-handler.php index 430369d..bd624da 100644 --- a/config/json-exception-handler.php +++ b/config/json-exception-handler.php @@ -38,11 +38,6 @@ 'authentication' => 16, 'oauth_server' => 17, 'bad_request' => 18, - 'client' => [ - 'default' => 19, - 'pagarme' => 20, - 'mailgun' => 21, - ], ], /* From 18be831d01b70c94e9ece320ec5207ff2ca8548f Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 27 May 2018 20:11:33 -0300 Subject: [PATCH 13/34] Added travis ci support --- .travis.yml | 51 +++++++++++++++++++++++ src/JsonApi/ErrorCollection.php | 7 ++-- src/Response/AbstractResponse.php | 8 ++-- src/Response/ErrorCollectionInterface.php | 26 ++++++++++-- tests/Feature/JsonHandlerTest.php | 1 - 5 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..82364c8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,51 @@ +language: php + +env: + global: + - setup=stable + +matrix: + include: + - php: 7.0 + env: + - testbench=3.4.x + - phpunit=5.7.x + - php: 7.0 + env: + - testbench=3.5.x + - phpunit=6.0.x + - php: 7.1 + env: + - testbench=3.5.x + - phpunit=6.0.x + - php: 7.1 + env: + - testbench=3.6.x + - phpunit=7.0.x + - php: 7.1 + env: + - testbench=3.6.x + - phpunit=7.0.x + - php: 7.2 + env: + - testbench=3.5.x + - phpunit=6.0.x + - php: 7.2 + env: + - testbench=3.6.x + - phpunit=7.0.x + - php: 7.2 + env: + - testbench=3.6.x + - phpunit=7.0.x + +sudo: false + +install: + - composer require orchestra/testbench:${testbench} --dev --no-update + - composer require phpunit/phpunit:${phpunit} --dev --no-update + - if [[ $setup = 'stable' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-stable; fi + - if [[ $setup = 'lowest' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-lowest --prefer-stable; fi + +script: + - vendor/bin/phpunit diff --git a/src/JsonApi/ErrorCollection.php b/src/JsonApi/ErrorCollection.php index a908482..c1af209 100644 --- a/src/JsonApi/ErrorCollection.php +++ b/src/JsonApi/ErrorCollection.php @@ -26,7 +26,7 @@ class ErrorCollection extends Collection implements ErrorHandledCollectionInterf /** * Returns the status code. * - * @return string + * @return string|null */ public function getStatusCode() { @@ -38,7 +38,7 @@ public function getStatusCode() * * @return array headers */ - public function getHeaders() + public function getHeaders(): array { return $this->headers; } @@ -61,9 +61,10 @@ public function setStatusCode(string $statusCode) * Set the headers of response. * * @param array $headers + * * @return self */ - public function setHeaders(array $headers) + public function setHeaders(array $headers): self { $this->headers = $headers; diff --git a/src/Response/AbstractResponse.php b/src/Response/AbstractResponse.php index b846e58..29475a9 100644 --- a/src/Response/AbstractResponse.php +++ b/src/Response/AbstractResponse.php @@ -16,14 +16,14 @@ abstract class AbstractResponse /** * The errors on response. * - * @var \SMartins\Exceptions\JsonApi\ErrorCollection + * @var \SMartins\Exceptions\Response\ErrorHandledCollectionInterface */ protected $errors; /** - * Create new JsonApi response passing the errors. + * Create new Response response passing the errors. * - * @param \SMartins\Exceptions\JsonApi\ErrorCollection $errors + * @param \SMartins\Exceptions\Response\ErrorHandledCollectionInterface $errors * */ public function __construct(ErrorHandledCollectionInterface $errors) @@ -60,7 +60,7 @@ public function setStatus(int $status) /** * Get the errors on response. * - * @return \SMartins\Exceptions\JsonApi\ErrorCollection + * @return \SMartins\Exceptions\Response\ErrorHandledCollectionInterface */ public function getErrors() { diff --git a/src/Response/ErrorCollectionInterface.php b/src/Response/ErrorCollectionInterface.php index 4a8b907..3553d0e 100644 --- a/src/Response/ErrorCollectionInterface.php +++ b/src/Response/ErrorCollectionInterface.php @@ -3,9 +3,29 @@ namespace SMartins\Exceptions\Response; use Illuminate\Contracts\Support\Arrayable; -use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; -interface ErrorCollectionInterface extends Arrayable, HttpExceptionInterface +interface ErrorCollectionInterface extends Arrayable { - // + /** + * Returns response headers. + * + * @return array Response headers + */ + public function getHeaders(); + + /** + * Set HTTP status code of response. + * + * @param string $statusCode + * + * @return self + */ + public function setStatusCode(string $statusCode); + + /** + * Get the HTTP status code. + * + * @return string|null + */ + public function getStatusCode(); } diff --git a/tests/Feature/JsonHandlerTest.php b/tests/Feature/JsonHandlerTest.php index 9199a2b..52fe5f5 100644 --- a/tests/Feature/JsonHandlerTest.php +++ b/tests/Feature/JsonHandlerTest.php @@ -84,7 +84,6 @@ public function testThrowsValidationExceptions() { $params = ['email' => str_repeat('a', 11)]; - dd(json_encode($this->json('GET', 'validation', $params)->json())); $this->json('GET', 'validation', $params) ->assertStatus(400) ->assertJsonStructure($this->defaultErrorStructure()); From e8d0b619e5cf1a7fa3f60d3769b309cbe5a6e88a Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 27 May 2018 20:12:52 -0300 Subject: [PATCH 14/34] Fixed style ci --- .styleci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.styleci.yml b/.styleci.yml index 334ad18..473c31a 100644 --- a/.styleci.yml +++ b/.styleci.yml @@ -1,7 +1,5 @@ preset: laravel -linting: true - finder: exclude: - "tests" From 7d62eb386dff0ea8b9bc0b49a73ba0922943550e Mon Sep 17 00:00:00 2001 From: Samuel Martins Date: Sun, 27 May 2018 23:13:08 +0000 Subject: [PATCH 15/34] Apply fixes from StyleCI --- resources/lang/en/exceptions.php | 2 +- resources/lang/pt-br/exceptions.php | 2 +- src/Handlers/AbstractHandler.php | 5 +---- src/Handlers/AuthenticationHandler.php | 2 +- src/Handlers/AuthorizationHandler.php | 2 +- src/Handlers/BadRequestHttpHandler.php | 2 +- src/Handlers/Handler.php | 2 +- src/Handlers/MissingScopeHandler.php | 2 +- src/Handlers/ModelNotFoundHandler.php | 2 +- src/Handlers/NotFoundHttpHandler.php | 2 +- src/Handlers/OAuthServerHandler.php | 2 +- src/Handlers/ValidationHandler.php | 2 +- src/JsonApi/Error.php | 8 ++++---- src/JsonApi/ErrorCollection.php | 3 +-- src/JsonApi/Source.php | 1 - src/Response/AbstractResponse.php | 1 - 16 files changed, 17 insertions(+), 23 deletions(-) diff --git a/resources/lang/en/exceptions.php b/resources/lang/en/exceptions.php index cfba22d..90c622f 100644 --- a/resources/lang/en/exceptions.php +++ b/resources/lang/en/exceptions.php @@ -36,5 +36,5 @@ */ 'models' => [ 'User' => 'User', - ] + ], ]; diff --git a/resources/lang/pt-br/exceptions.php b/resources/lang/pt-br/exceptions.php index ed24ee2..9fbe0f3 100644 --- a/resources/lang/pt-br/exceptions.php +++ b/resources/lang/pt-br/exceptions.php @@ -36,5 +36,5 @@ */ 'models' => [ 'User' => 'Usuário', - ] + ], ]; diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 89f5947..405f381 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -4,16 +4,13 @@ use Exception; use InvalidArgumentException; -use Illuminate\Support\Collection; use SMartins\Exceptions\JsonApi\Error; use Illuminate\Auth\AuthenticationException; use Illuminate\Validation\ValidationException; -use Illuminate\Auth\Access\AuthorizationException; use SMartins\Exceptions\Response\ErrorHandledInterface; use Illuminate\Database\Eloquent\ModelNotFoundException; use SMartins\Exceptions\JsonApi\Response as JsonApiResponse; use SMartins\Exceptions\Response\ErrorHandledCollectionInterface; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; abstract class AbstractHandler @@ -136,7 +133,7 @@ public function getExceptionHandler() } /** - * Get exception handlers from internal and set on App\Exceptions\Handler.php + * Get exception handlers from internal and set on App\Exceptions\Handler.php. * * @return array */ diff --git a/src/Handlers/AuthenticationHandler.php b/src/Handlers/AuthenticationHandler.php index b188698..1d0d1ac 100644 --- a/src/Handlers/AuthenticationHandler.php +++ b/src/Handlers/AuthenticationHandler.php @@ -8,7 +8,7 @@ class AuthenticationHandler extends AbstractHandler { /** - * {@inheritDoc} + * {@inheritdoc} */ public function handle() { diff --git a/src/Handlers/AuthorizationHandler.php b/src/Handlers/AuthorizationHandler.php index 8248b4c..0ff9b8f 100644 --- a/src/Handlers/AuthorizationHandler.php +++ b/src/Handlers/AuthorizationHandler.php @@ -8,7 +8,7 @@ class AuthorizationHandler extends AbstractHandler { /** - * {@inheritDoc} + * {@inheritdoc} */ public function handle() { diff --git a/src/Handlers/BadRequestHttpHandler.php b/src/Handlers/BadRequestHttpHandler.php index a4f8e3b..9a3ffb5 100644 --- a/src/Handlers/BadRequestHttpHandler.php +++ b/src/Handlers/BadRequestHttpHandler.php @@ -8,7 +8,7 @@ class BadRequestHttpHandler extends AbstractHandler { /** - * {@inheritDoc} + * {@inheritdoc} */ public function handle() { diff --git a/src/Handlers/Handler.php b/src/Handlers/Handler.php index 06b0f3e..d9ee00b 100644 --- a/src/Handlers/Handler.php +++ b/src/Handlers/Handler.php @@ -8,7 +8,7 @@ class Handler extends AbstractHandler { /** - * {@inheritDoc} + * {@inheritdoc} */ public function handle() { diff --git a/src/Handlers/MissingScopeHandler.php b/src/Handlers/MissingScopeHandler.php index 0cc04d0..8819057 100644 --- a/src/Handlers/MissingScopeHandler.php +++ b/src/Handlers/MissingScopeHandler.php @@ -8,7 +8,7 @@ class MissingScopeHandler extends AbstractHandler { /** - * {@inheritDoc} + * {@inheritdoc} */ public function handle() { diff --git a/src/Handlers/ModelNotFoundHandler.php b/src/Handlers/ModelNotFoundHandler.php index dd52191..329ab92 100644 --- a/src/Handlers/ModelNotFoundHandler.php +++ b/src/Handlers/ModelNotFoundHandler.php @@ -19,7 +19,7 @@ public function __construct(ModelNotFoundException $e) } /** - * {@inheritDoc} + * {@inheritdoc} */ public function handle() { diff --git a/src/Handlers/NotFoundHttpHandler.php b/src/Handlers/NotFoundHttpHandler.php index 5576075..9eae341 100644 --- a/src/Handlers/NotFoundHttpHandler.php +++ b/src/Handlers/NotFoundHttpHandler.php @@ -8,7 +8,7 @@ class NotFoundHttpHandler extends AbstractHandler { /** - * {@inheritDoc} + * {@inheritdoc} */ public function handle() { diff --git a/src/Handlers/OAuthServerHandler.php b/src/Handlers/OAuthServerHandler.php index 1e9297a..7aaba84 100644 --- a/src/Handlers/OAuthServerHandler.php +++ b/src/Handlers/OAuthServerHandler.php @@ -19,7 +19,7 @@ public function __construct(OAuthServerException $e) } /** - * {@inheritDoc} + * {@inheritdoc} */ public function handle() { diff --git a/src/Handlers/ValidationHandler.php b/src/Handlers/ValidationHandler.php index 48da109..2091909 100644 --- a/src/Handlers/ValidationHandler.php +++ b/src/Handlers/ValidationHandler.php @@ -9,7 +9,7 @@ class ValidationHandler extends AbstractHandler { /** - * {@inheritDoc} + * {@inheritdoc} */ public function handle() { diff --git a/src/JsonApi/Error.php b/src/JsonApi/Error.php index 370bec8..df6b9e8 100644 --- a/src/JsonApi/Error.php +++ b/src/JsonApi/Error.php @@ -85,7 +85,7 @@ public function setId(string $id): self } /** - * Get the value of links + * Get the value of links. * * @return \SMartins\Exceptions\JsonApi\Links */ @@ -95,7 +95,7 @@ public function getLinks() } /** - * Set the value of links + * Set the value of links. * * @param \SMartins\Exceptions\JsonApi\Links $links * @@ -109,7 +109,7 @@ public function setLinks(Links $links): self } /** - * {@inheritDoc} + * {@inheritdoc} */ public function getStatus(): string { @@ -227,7 +227,7 @@ public function setSource(Source $source): self } /** - * {@inheritDoc} + * {@inheritdoc} */ public function toCollection(): ErrorHandledCollectionInterface { diff --git a/src/JsonApi/ErrorCollection.php b/src/JsonApi/ErrorCollection.php index c1af209..c7de286 100644 --- a/src/JsonApi/ErrorCollection.php +++ b/src/JsonApi/ErrorCollection.php @@ -3,7 +3,6 @@ namespace SMartins\Exceptions\JsonApi; use Illuminate\Support\Collection; -use SMartins\Exceptions\Response\ErrorHandledInterface; use SMartins\Exceptions\Response\InvalidContentException; use SMartins\Exceptions\Response\ErrorHandledCollectionInterface; @@ -72,7 +71,7 @@ public function setHeaders(array $headers): self } /** - * {@inheritDoc} + * {@inheritdoc} */ public function validatedContent(string $type): ErrorHandledCollectionInterface { diff --git a/src/JsonApi/Source.php b/src/JsonApi/Source.php index fbfb8da..dc7ea87 100644 --- a/src/JsonApi/Source.php +++ b/src/JsonApi/Source.php @@ -25,7 +25,6 @@ class Source implements Arrayable */ protected $parameter; - /** * Get pointer. * diff --git a/src/Response/AbstractResponse.php b/src/Response/AbstractResponse.php index 29475a9..abf2657 100644 --- a/src/Response/AbstractResponse.php +++ b/src/Response/AbstractResponse.php @@ -24,7 +24,6 @@ abstract class AbstractResponse * Create new Response response passing the errors. * * @param \SMartins\Exceptions\Response\ErrorHandledCollectionInterface $errors - * */ public function __construct(ErrorHandledCollectionInterface $errors) { From c46a58573a8c69c156fee981e4910e36a350e594 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 27 May 2018 20:47:29 -0300 Subject: [PATCH 16/34] Added upgrade guide to 2.0 from 1.0 --- UPGRADE.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 UPGRADE.md diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 0000000..29af089 --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,18 @@ +# Upgrade Guide + +## Upgrading to 2.0 from 1.0 + +### Updating Dependencies + +Update the `sfelix-martins/passport-multiauth` dependency to `^2.0` in your `composer.json` file. + +### Update Configs + +If you are not using Laravel 5.5 version change the `JsonHandlerServiceProvider` from your `config/app.php` providers array: + +```php + 'providers' => [ + ... + SMartins\Exceptions\JsonHandlerServiceProvider::class, + ], +``` From e464f66efc19a48c9073198a81d9cecf05f3826d Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 27 May 2018 20:58:36 -0300 Subject: [PATCH 17/34] Added requirements information to readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 082f4a4..c5d1bac 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,11 @@ Adds methods to your `App\Exceptions\Handler` to treat json responses. It is most useful if you are building APIs! +## Requirements + +* Laravel Framework >= 5.4 +* php >= 7.0 + ## JsonAPI Using [JsonAPI](http://jsonapi.org) standard to responses! From 1145e369e570d5e000ec21514164ea1e66c3739c Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 30 Dec 2018 12:46:50 -0200 Subject: [PATCH 18/34] Added some doc block comments and coverage config --- .scrutinizer.yml | 44 ++++++++++++----------- README.md | 2 +- composer.json | 2 +- src/Handlers/AbstractHandler.php | 13 ++++--- src/Response/ErrorCollectionInterface.php | 2 +- src/Response/ErrorHandledInterface.php | 2 +- tests/GettersAndSetters.php | 3 ++ 7 files changed, 36 insertions(+), 32 deletions(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 6e70bb0..a70a536 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -1,27 +1,29 @@ filter: - excluded_paths: [tests/*] + excluded_paths: [tests/*] checks: - php: - remove_extra_empty_lines: true - remove_php_closing_tag: true - remove_trailing_whitespace: true - fix_use_statements: - remove_unused: true - preserve_multiple: false - preserve_blanklines: true - order_alphabetically: true - fix_php_opening_tag: true - fix_linefeed: true - fix_line_ending: true - fix_identation_4spaces: true - fix_doc_comments: true + php: + remove_extra_empty_lines: true + remove_php_closing_tag: true + remove_trailing_whitespace: true + fix_use_statements: + remove_unused: true + preserve_multiple: false + preserve_blanklines: true + order_alphabetically: true + fix_php_opening_tag: true + fix_linefeed: true + fix_line_ending: true + fix_identation_4spaces: true + fix_doc_comments: true build: - tests: + nodes: + coverage: + tests: override: - - - command: 'vendor/bin/phpunit --coverage-clover=some-file' - coverage: - file: 'some-file' - format: 'clover' + - + command: 'vendor/bin/phpunit --coverage-clover=some-file' + coverage: + file: 'some-file' + format: 'clover' diff --git a/README.md b/README.md index c5d1bac..f6044c0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Laravel Json Exception Handler [![StyleCI](https://styleci.io/repos/101529653/shield)](https://styleci.io/repos/101529653) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/?branch=master) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/badges/quality-score.png?b=2.0)](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/?branch=master) Adds methods to your `App\Exceptions\Handler` to treat json responses. It is most useful if you are building APIs! diff --git a/composer.json b/composer.json index 680d28d..17a91b8 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ } ], "require": { - "php": ">=5.6.4" + "php": ">=7.0.0" }, "autoload": { "psr-4": { diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 405f381..f274326 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -4,7 +4,6 @@ use Exception; use InvalidArgumentException; -use SMartins\Exceptions\JsonApi\Error; use Illuminate\Auth\AuthenticationException; use Illuminate\Validation\ValidationException; use SMartins\Exceptions\Response\ErrorHandledInterface; @@ -60,9 +59,7 @@ public function __construct(Exception $e) * Handle with an exception according to specific definitions. Returns one * or more errors using the exception from $exceptions attribute. * - * @todo Change the return type to any interface to make more extensible. - * - * @return \SMartins\Exceptions\Response\ErrorHandledInterface|\Smartins\Exceptions\Response\ErrorHandledCollectionInterface + * @return ErrorHandledInterface|ErrorHandledCollectionInterface */ abstract public function handle(); @@ -85,6 +82,7 @@ public function getCode($type = 'default') * Return response with handled exception. * * @return \SMartins\Exceptions\Response\AbstractResponse + * @throws \SMartins\Exceptions\Response\InvalidContentException */ public function handleException() { @@ -100,10 +98,10 @@ public function handleException() /** * Validate response from handle method of handler class. * - * @param \SMartins\Exceptions\Response\ErrorHandledInterface|\Smartins\Exceptions\Response\ErrorHandledCollectionInterface - * @return \SMartins\Exceptions\Response\ErrorHandledCollectionInterface + * @param ErrorHandledInterface|ErrorHandledCollectionInterface + * @return ErrorHandledCollectionInterface * - * @throws \InvalidArgumentException + * @throws \SMartins\Exceptions\Response\InvalidContentException */ public function validatedHandledException($error) { @@ -216,6 +214,7 @@ public function getResponseHandler() * Set exception handlers. * * @param array $handlers + * @return AbstractHandler */ public function setExceptionHandlers(array $handlers) { diff --git a/src/Response/ErrorCollectionInterface.php b/src/Response/ErrorCollectionInterface.php index 3553d0e..f30861d 100644 --- a/src/Response/ErrorCollectionInterface.php +++ b/src/Response/ErrorCollectionInterface.php @@ -18,7 +18,7 @@ public function getHeaders(); * * @param string $statusCode * - * @return self + * @return static */ public function setStatusCode(string $statusCode); diff --git a/src/Response/ErrorHandledInterface.php b/src/Response/ErrorHandledInterface.php index 3425db6..c7fa0e6 100644 --- a/src/Response/ErrorHandledInterface.php +++ b/src/Response/ErrorHandledInterface.php @@ -9,7 +9,7 @@ interface ErrorHandledInterface * * @todo Maybe pass this method to another interface. * - * @return \SMartin\Exceptions\Response\ErrorHandledCollectionInterface + * @return \SMartins\Exceptions\Response\ErrorHandledCollectionInterface */ public function toCollection(): ErrorHandledCollectionInterface; diff --git a/tests/GettersAndSetters.php b/tests/GettersAndSetters.php index eef54de..2614529 100644 --- a/tests/GettersAndSetters.php +++ b/tests/GettersAndSetters.php @@ -7,6 +7,9 @@ trait GettersAndSetters { + /** + * @throws \ReflectionException + */ public function testGettersAndSetters() { if (! property_exists($this, 'classToTest')) { From 7c13d90e7f80bbdb789711e85e7e21cd906ef59e Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 30 Dec 2018 12:50:00 -0200 Subject: [PATCH 19/34] Fixed style ci badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6044c0..75913a5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Laravel Json Exception Handler -[![StyleCI](https://styleci.io/repos/101529653/shield)](https://styleci.io/repos/101529653) +[![StyleCI](https://styleci.io/repos/101529653/shield?style=plastic&branch=2.0)](https://styleci.io/repos/101529653?style=plastic&branch=2.0) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/badges/quality-score.png?b=2.0)](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/?branch=master) Adds methods to your `App\Exceptions\Handler` to treat json responses. From 569d459b65c435dafae132c68ef8daa652e2aee3 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 30 Dec 2018 12:55:14 -0200 Subject: [PATCH 20/34] Fixed scrutnizer and travis definitions --- .scrutinizer.yml | 17 ++++++++--------- .travis.yml | 8 ++++++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index a70a536..1960fab 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -18,12 +18,11 @@ checks: fix_doc_comments: true build: - nodes: - coverage: - tests: - override: - - - command: 'vendor/bin/phpunit --coverage-clover=some-file' - coverage: - file: 'some-file' - format: 'clover' + tests: + override: + - php-scrutinizer-run + - + command: 'vendor/bin/phpunit --coverage-clover=some-file' + coverage: + file: 'some-file' + format: 'clover' diff --git a/.travis.yml b/.travis.yml index 82364c8..b62eb3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,10 @@ matrix: env: - testbench=3.6.x - phpunit=7.0.x + - php: 7.1 + env: + - testbench=3.7.x + - phpunit=7.0.x - php: 7.2 env: - testbench=3.5.x @@ -38,6 +42,10 @@ matrix: env: - testbench=3.6.x - phpunit=7.0.x + - php: 7.2 + env: + - testbench=3.7.x + - phpunit=7.0.x sudo: false From 5a0c5cbbef0570cebcbb211179d1ef9584e3cfa1 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 30 Dec 2018 13:02:50 -0200 Subject: [PATCH 21/34] Added composer.lock to gitignore --- .gitignore | 1 + .scrutinizer.yml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 795fd97..1cf0c06 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /vendor /.phpintel /.idea +composer.lock diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 1960fab..9a78174 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -9,8 +9,8 @@ checks: fix_use_statements: remove_unused: true preserve_multiple: false - preserve_blanklines: true - order_alphabetically: true + preserve_blanklines: true + order_alphabetically: true fix_php_opening_tag: true fix_linefeed: true fix_line_ending: true From 3b0aee6059e521670120b897630c6712da74c385 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 30 Dec 2018 13:47:06 -0200 Subject: [PATCH 22/34] Added test to model not found not translated --- src/Handlers/ModelNotFoundHandler.php | 11 +++++-- tests/TestCase.php | 8 +++-- .../Handlers/ModelNotFoundHandlerTest.php | 31 +++++++++++++++++++ 3 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 tests/Unit/Handlers/ModelNotFoundHandlerTest.php diff --git a/src/Handlers/ModelNotFoundHandler.php b/src/Handlers/ModelNotFoundHandler.php index 329ab92..8f9bc0a 100644 --- a/src/Handlers/ModelNotFoundHandler.php +++ b/src/Handlers/ModelNotFoundHandler.php @@ -2,12 +2,17 @@ namespace SMartins\Exceptions\Handlers; -use SMartins\Exceptions\JSONAPI\Error; -use SMartins\Exceptions\JSONAPI\Source; +use SMartins\Exceptions\JsonApi\Error; +use SMartins\Exceptions\JsonApi\Source; use Illuminate\Database\Eloquent\ModelNotFoundException; class ModelNotFoundHandler extends AbstractHandler { + /** + * @var ModelNotFoundException + */ + protected $exception; + /** * Create instance using the Exception to be handled. * @@ -40,7 +45,7 @@ public function handle() * @param string $model * @return string */ - public function extractEntityName($model) + public function extractEntityName(string $model) { $classNames = (array) explode('\\', $model); diff --git a/tests/TestCase.php b/tests/TestCase.php index 883d9d2..7496354 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,8 +2,10 @@ namespace SMartins\Exceptions\Tests; -use SMartins\Exceptions\JsonHandlerServiceProvider; +use Illuminate\Contracts\Debug\ExceptionHandler; use Orchestra\Testbench\TestCase as BaseTestCase; +use SMartins\Exceptions\JsonHandlerServiceProvider; +use SMartins\Exceptions\Tests\Fixtures\Exceptions\Handler; abstract class TestCase extends BaseTestCase { @@ -16,8 +18,8 @@ abstract class TestCase extends BaseTestCase protected function getEnvironmentSetUp($app) { $app->singleton( - \Illuminate\Contracts\Debug\ExceptionHandler::class, - \SMartins\Exceptions\Tests\Fixtures\Exceptions\Handler::class + ExceptionHandler::class, + Handler::class ); // Setup default database to use sqlite :memory: diff --git a/tests/Unit/Handlers/ModelNotFoundHandlerTest.php b/tests/Unit/Handlers/ModelNotFoundHandlerTest.php new file mode 100644 index 0000000..d90358e --- /dev/null +++ b/tests/Unit/Handlers/ModelNotFoundHandlerTest.php @@ -0,0 +1,31 @@ +setModel(NotTranslated::class); + + $handler = new ModelNotFoundHandler($exception); + + $error = $handler->handle(); + + $this->assertEquals(404, $error->getStatus()); + $this->assertEquals( + 'NotTranslated not found', + $error->getDetail() + ); + } +} + +class NotTranslated extends Model {} From e15752e80d94fa31c06a3861cbe08ea8966e811c Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 5 Jan 2019 17:02:52 -0200 Subject: [PATCH 23/34] Fixed to App\Handler defitions of property $exceptionHandlers override internal definitions --- src/Handlers/AbstractHandler.php | 2 +- tests/Unit/HandlerTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index f274326..db17ba4 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -137,7 +137,7 @@ public function getExceptionHandler() */ public function getConfiguredHandlers() { - return array_merge($this->exceptionHandlers, $this->internalExceptionHandlers); + return array_merge($this->internalExceptionHandlers, $this->exceptionHandlers); } /** diff --git a/tests/Unit/HandlerTest.php b/tests/Unit/HandlerTest.php index 560997f..afe9d91 100644 --- a/tests/Unit/HandlerTest.php +++ b/tests/Unit/HandlerTest.php @@ -3,7 +3,7 @@ namespace SMartins\Exceptions\Tests\Unit; use Exception; -use SMartins\Exceptions\JSONAPI\Error; +use SMartins\Exceptions\JsonApi\Error; use SMartins\Exceptions\Tests\TestCase; use SMartins\Exceptions\Handlers\Handler; @@ -16,4 +16,4 @@ public function testHandle() $handler = new Handler($exception); $this->assertInstanceOf(Error::class, $handler->handle()); } -} \ No newline at end of file +} From 95cb1b614fb83c6b4175e10a68dbf6c13b02be45 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 5 Jan 2019 17:08:04 -0200 Subject: [PATCH 24/34] Added instructions how to registry new handlers --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 75913a5..e947de5 100644 --- a/README.md +++ b/README.md @@ -272,6 +272,27 @@ class MyCustomizedHandler extends AbstractHandler } ``` +- Now just registry your customized handler on `App\Exception\Handler` file on attribute `exceptionHandlers`. E.g: + +```php +namespace App\Exceptions; + +use Exception; +use GuzzleHttp\Exception\ClientException; +use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; +use SMartins\Exceptions\JsonHandler; + +class Handler extends ExceptionHandler +{ + use JsonHandler; + + protected $exceptionHandlers = [ + // Set on key the exception and on value the handler. + ClientException::class => GuzzleClientHandler::class, + ]; + +``` + ## Response References: - http://jsonapi.org/format/#errors From 6b5ac8bb92d646c69addad6588f4cda2afc0da37 Mon Sep 17 00:00:00 2001 From: Samuel Date: Thu, 28 Feb 2019 23:06:36 -0300 Subject: [PATCH 25/34] Fixed validation status code and title --- src/Handlers/ValidationHandler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Handlers/ValidationHandler.php b/src/Handlers/ValidationHandler.php index 2091909..f71f9db 100644 --- a/src/Handlers/ValidationHandler.php +++ b/src/Handlers/ValidationHandler.php @@ -13,7 +13,7 @@ class ValidationHandler extends AbstractHandler */ public function handle() { - $errors = (new ErrorCollection)->setStatusCode(400); + $errors = (new ErrorCollection)->setStatusCode(422); $failedFieldsRules = $this->getFailedFieldsRules(); @@ -49,7 +49,7 @@ public function handle() public function getValidationTitle(array $failedFieldsRules, string $key, string $field) { $title = __('exception::exceptions.validation.title', [ - 'fails' => array_keys($failedFieldsRules[$field])[$key], + 'fails' => strtolower(array_keys($failedFieldsRules[$field])[$key]), 'field' => $field, ]); From 606f245e2c7fa1fa53d89bfe9b0d86d8201c373a Mon Sep 17 00:00:00 2001 From: Samuel Martins Date: Wed, 18 Sep 2019 20:49:30 -0300 Subject: [PATCH 26/34] Fixed to do not show file and line on default source pointer --- src/Handlers/AbstractHandler.php | 2 +- tests/Feature/JsonHandlerTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index db17ba4..7799a21 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -147,7 +147,7 @@ public function getConfiguredHandlers() */ public function getDefaultPointer() { - return $this->exception->getFile().':'.$this->exception->getLine(); + return ''; } /** diff --git a/tests/Feature/JsonHandlerTest.php b/tests/Feature/JsonHandlerTest.php index 52fe5f5..2ded966 100644 --- a/tests/Feature/JsonHandlerTest.php +++ b/tests/Feature/JsonHandlerTest.php @@ -85,7 +85,7 @@ public function testThrowsValidationExceptions() $params = ['email' => str_repeat('a', 11)]; $this->json('GET', 'validation', $params) - ->assertStatus(400) + ->assertStatus(422) ->assertJsonStructure($this->defaultErrorStructure()); } From c2c422bab2d92786a8b9d0414bf1320a6845e3a2 Mon Sep 17 00:00:00 2001 From: Samuel Martins Date: Wed, 18 Sep 2019 22:06:50 -0300 Subject: [PATCH 27/34] Changed to snake_case helper to Str::snake() --- src/Handlers/AbstractHandler.php | 3 ++- src/Handlers/ModelNotFoundHandler.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 7799a21..2f7329e 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -3,6 +3,7 @@ namespace SMartins\Exceptions\Handlers; use Exception; +use Illuminate\Support\Str; use InvalidArgumentException; use Illuminate\Auth\AuthenticationException; use Illuminate\Validation\ValidationException; @@ -157,7 +158,7 @@ public function getDefaultPointer() */ public function getDefaultTitle() { - return snake_case(class_basename($this->exception)); + return Str::snake(class_basename($this->exception)); } /** diff --git a/src/Handlers/ModelNotFoundHandler.php b/src/Handlers/ModelNotFoundHandler.php index 8f9bc0a..f385ea4 100644 --- a/src/Handlers/ModelNotFoundHandler.php +++ b/src/Handlers/ModelNotFoundHandler.php @@ -2,6 +2,7 @@ namespace SMartins\Exceptions\Handlers; +use Illuminate\Support\Str; use SMartins\Exceptions\JsonApi\Error; use SMartins\Exceptions\JsonApi\Source; use Illuminate\Database\Eloquent\ModelNotFoundException; @@ -35,7 +36,7 @@ public function handle() return (new Error)->setStatus(404) ->setCode($this->getCode('model_not_found')) ->setSource((new Source())->setPointer('data/id')) - ->setTitle(snake_case(class_basename($this->exception))) + ->setTitle(Str::snake(class_basename($this->exception))) ->setDetail($detail); } From 04558ac90cc25b94afbe108c7f98f10ba382b8df Mon Sep 17 00:00:00 2001 From: Samuel Martins Date: Thu, 19 Sep 2019 13:10:02 -0300 Subject: [PATCH 28/34] Fixed package name on upgrade guide --- UPGRADE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADE.md b/UPGRADE.md index 29af089..3aa9e9e 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -4,7 +4,7 @@ ### Updating Dependencies -Update the `sfelix-martins/passport-multiauth` dependency to `^2.0` in your `composer.json` file. +Update the `sfelix-martins/json-exception-handler` dependency to `^2.0` in your `composer.json` file. ### Update Configs From e59571ec14b7b20732ca20388917224e707fd874 Mon Sep 17 00:00:00 2001 From: Samuel Martins Date: Thu, 19 Sep 2019 13:13:01 -0300 Subject: [PATCH 29/34] Updated badges --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e947de5..2f5277f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Laravel Json Exception Handler [![StyleCI](https://styleci.io/repos/101529653/shield?style=plastic&branch=2.0)](https://styleci.io/repos/101529653?style=plastic&branch=2.0) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/badges/quality-score.png?b=2.0)](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/?branch=master) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/badges/quality-score.png?b=2.0)](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/?branch=2.0) +[![Build Status](https://travis-ci.org/sfelix-martins/json-exception-handler.svg?branch=2.0)](https://travis-ci.org/sfelix-martins/json-exception-handler) Adds methods to your `App\Exceptions\Handler` to treat json responses. It is most useful if you are building APIs! From 871ec1ab3f7e1a6082ccacbe1515ab8b09bb445b Mon Sep 17 00:00:00 2001 From: Samuel Martins Date: Thu, 19 Sep 2019 13:24:41 -0300 Subject: [PATCH 30/34] Added handlers to Authorization and NotFoundHttpException --- src/Handlers/AbstractHandler.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 2f7329e..6cbdf30 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -3,6 +3,7 @@ namespace SMartins\Exceptions\Handlers; use Exception; +use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Support\Str; use InvalidArgumentException; use Illuminate\Auth\AuthenticationException; @@ -12,6 +13,7 @@ use SMartins\Exceptions\JsonApi\Response as JsonApiResponse; use SMartins\Exceptions\Response\ErrorHandledCollectionInterface; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; abstract class AbstractHandler { @@ -42,6 +44,8 @@ abstract class AbstractHandler AuthenticationException::class => AuthenticationHandler::class, ValidationException::class => ValidationHandler::class, BadRequestHttpException::class => BadRequestHttpHandler::class, + AuthorizationException::class => AuthorizationHandler::class, + NotFoundHttpException::class => NotFoundHttpHandler::class, 'Laravel\Passport\Exceptions\MissingScopeException' => MissingScopeHandler::class, 'League\OAuth2\Server\Exception\OAuthServerException' => OAuthServerHandler::class, ]; From d0b98edb2380489ddd36d62cb43336db48855a71 Mon Sep 17 00:00:00 2001 From: "d[esign]Void" Date: Tue, 26 May 2020 08:55:49 +0100 Subject: [PATCH 31/34] Update JsonHandler.php --- src/JsonHandler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/JsonHandler.php b/src/JsonHandler.php index 69f6c39..89c7ff8 100644 --- a/src/JsonHandler.php +++ b/src/JsonHandler.php @@ -11,11 +11,11 @@ trait JsonHandler * Handle the json response. Check if exception is treated. If true call * the specific handler. If false set the default response to be returned. * - * @param \Exception $exception + * @param \Throwable $exception * * @return \Illuminate\Http\JsonResponse */ - public function jsonResponse(Exception $exception) + public function jsonResponse(Throwable $exception) { $handler = new Handler($exception); From 9289852c78396c88bfb97e1a7d056dcb282089c8 Mon Sep 17 00:00:00 2001 From: "d[esign]Void" Date: Fri, 29 May 2020 17:12:13 +0100 Subject: [PATCH 32/34] Update JsonHandler.php --- src/JsonHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JsonHandler.php b/src/JsonHandler.php index 89c7ff8..af19e7c 100644 --- a/src/JsonHandler.php +++ b/src/JsonHandler.php @@ -2,8 +2,8 @@ namespace SMartins\Exceptions; -use Exception; use SMartins\Exceptions\Handlers\Handler; +use Throwable; trait JsonHandler { From 77daea05d946d0b07954a2c63b972dba0786083a Mon Sep 17 00:00:00 2001 From: Samuel Martins Date: Tue, 14 Jul 2020 23:46:52 +0000 Subject: [PATCH 33/34] Apply fixes from StyleCI --- src/Handlers/AbstractHandler.php | 8 ++++---- src/Handlers/ModelNotFoundHandler.php | 2 +- src/Handlers/OAuthServerHandler.php | 2 +- src/Handlers/ValidationHandler.php | 2 +- src/JsonApi/Error.php | 4 ++-- src/JsonApi/ErrorCollection.php | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 6cbdf30..31508a2 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -4,14 +4,14 @@ use Exception; use Illuminate\Auth\Access\AuthorizationException; -use Illuminate\Support\Str; -use InvalidArgumentException; use Illuminate\Auth\AuthenticationException; -use Illuminate\Validation\ValidationException; -use SMartins\Exceptions\Response\ErrorHandledInterface; use Illuminate\Database\Eloquent\ModelNotFoundException; +use Illuminate\Support\Str; +use Illuminate\Validation\ValidationException; +use InvalidArgumentException; use SMartins\Exceptions\JsonApi\Response as JsonApiResponse; use SMartins\Exceptions\Response\ErrorHandledCollectionInterface; +use SMartins\Exceptions\Response\ErrorHandledInterface; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/src/Handlers/ModelNotFoundHandler.php b/src/Handlers/ModelNotFoundHandler.php index f385ea4..4a24563 100644 --- a/src/Handlers/ModelNotFoundHandler.php +++ b/src/Handlers/ModelNotFoundHandler.php @@ -2,10 +2,10 @@ namespace SMartins\Exceptions\Handlers; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Support\Str; use SMartins\Exceptions\JsonApi\Error; use SMartins\Exceptions\JsonApi\Source; -use Illuminate\Database\Eloquent\ModelNotFoundException; class ModelNotFoundHandler extends AbstractHandler { diff --git a/src/Handlers/OAuthServerHandler.php b/src/Handlers/OAuthServerHandler.php index 7aaba84..9b752f0 100644 --- a/src/Handlers/OAuthServerHandler.php +++ b/src/Handlers/OAuthServerHandler.php @@ -2,9 +2,9 @@ namespace SMartins\Exceptions\Handlers; +use League\OAuth2\Server\Exception\OAuthServerException; use SMartins\Exceptions\JsonApi\Error; use SMartins\Exceptions\JsonApi\Source; -use League\OAuth2\Server\Exception\OAuthServerException; class OAuthServerHandler extends AbstractHandler { diff --git a/src/Handlers/ValidationHandler.php b/src/Handlers/ValidationHandler.php index f71f9db..b22b3b2 100644 --- a/src/Handlers/ValidationHandler.php +++ b/src/Handlers/ValidationHandler.php @@ -3,8 +3,8 @@ namespace SMartins\Exceptions\Handlers; use SMartins\Exceptions\JsonApi\Error; -use SMartins\Exceptions\JsonApi\Source; use SMartins\Exceptions\JsonApi\ErrorCollection; +use SMartins\Exceptions\JsonApi\Source; class ValidationHandler extends AbstractHandler { diff --git a/src/JsonApi/Error.php b/src/JsonApi/Error.php index df6b9e8..7af2385 100644 --- a/src/JsonApi/Error.php +++ b/src/JsonApi/Error.php @@ -3,9 +3,9 @@ namespace SMartins\Exceptions\JsonApi; use Illuminate\Contracts\Support\Arrayable; -use SMartins\Exceptions\Traits\NotNullArrayable; -use SMartins\Exceptions\Response\ErrorHandledInterface; use SMartins\Exceptions\Response\ErrorHandledCollectionInterface; +use SMartins\Exceptions\Response\ErrorHandledInterface; +use SMartins\Exceptions\Traits\NotNullArrayable; class Error implements Arrayable, ErrorHandledInterface { diff --git a/src/JsonApi/ErrorCollection.php b/src/JsonApi/ErrorCollection.php index c7de286..8efb248 100644 --- a/src/JsonApi/ErrorCollection.php +++ b/src/JsonApi/ErrorCollection.php @@ -3,8 +3,8 @@ namespace SMartins\Exceptions\JsonApi; use Illuminate\Support\Collection; -use SMartins\Exceptions\Response\InvalidContentException; use SMartins\Exceptions\Response\ErrorHandledCollectionInterface; +use SMartins\Exceptions\Response\InvalidContentException; class ErrorCollection extends Collection implements ErrorHandledCollectionInterface { From a1960014956ce9d01bdd26030426cf3237379883 Mon Sep 17 00:00:00 2001 From: tyler-relocity Date: Tue, 17 Aug 2021 17:03:24 -0700 Subject: [PATCH 34/34] Update AbstractHandler constructor --- src/Handlers/AbstractHandler.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Handlers/AbstractHandler.php b/src/Handlers/AbstractHandler.php index 31508a2..a820d42 100644 --- a/src/Handlers/AbstractHandler.php +++ b/src/Handlers/AbstractHandler.php @@ -14,6 +14,7 @@ use SMartins\Exceptions\Response\ErrorHandledInterface; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Throwable; abstract class AbstractHandler { @@ -53,9 +54,9 @@ abstract class AbstractHandler /** * Create instance using the Exception to be handled. * - * @param Exception $e + * @param Throwable $e */ - public function __construct(Exception $e) + public function __construct(Throwable $e) { $this->exception = $e; }