Skip to content

Commit 583029e

Browse files
authored
Merge pull request #1 from AgentSoftware/claude/modernize-php8-laravel-aJuCg
Upgrade to Laravel 10+ and PHP 8.1+ with modern tooling
2 parents 70884c5 + 27e08b4 commit 583029e

41 files changed

Lines changed: 561 additions & 554 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/tests.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [2.0, 3.0, main, master]
6+
pull_request:
7+
branches: [2.0, 3.0, main, master]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
fail-fast: true
15+
matrix:
16+
php: [8.1, 8.2, 8.3]
17+
laravel: [10.*, 11.*, 12.*]
18+
include:
19+
- laravel: 10.*
20+
testbench: 8.*
21+
- laravel: 11.*
22+
testbench: 9.*
23+
- laravel: 12.*
24+
testbench: 10.*
25+
exclude:
26+
- php: 8.1
27+
laravel: 11.*
28+
- php: 8.1
29+
laravel: 12.*
30+
31+
name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }}
32+
33+
steps:
34+
- name: Checkout code
35+
uses: actions/checkout@v4
36+
37+
- name: Setup PHP
38+
uses: shivammathur/setup-php@v2
39+
with:
40+
php-version: ${{ matrix.php }}
41+
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite
42+
coverage: none
43+
44+
- name: Install dependencies
45+
run: |
46+
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update
47+
composer update --prefer-dist --no-interaction
48+
49+
- name: Execute tests
50+
run: vendor/bin/phpunit

.scrutinizer.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@ checks:
1818
fix_doc_comments: true
1919

2020
build:
21+
environment:
22+
php:
23+
version: 8.2
2124
tests:
2225
override:
2326
- php-scrutinizer-run
2427
-
25-
command: 'vendor/bin/phpunit --coverage-clover=some-file'
28+
command: 'vendor/bin/phpunit --coverage-clover=coverage.xml'
2629
coverage:
27-
file: 'some-file'
30+
file: 'coverage.xml'
2831
format: 'clover'

.styleci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
preset: laravel
22

3+
risky: true
4+
35
finder:
46
exclude:
5-
- "tests"
7+
- tests
68
name:
79
- "*.php"

.travis.yml

Lines changed: 0 additions & 59 deletions
This file was deleted.

README.md

Lines changed: 50 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
# Laravel Json Exception Handler
22

3-
[![StyleCI](https://styleci.io/repos/101529653/shield?style=plastic&branch=2.0)](https://styleci.io/repos/101529653?style=plastic&branch=2.0)
4-
[![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)
5-
[![Build Status](https://travis-ci.org/sfelix-martins/json-exception-handler.svg?branch=2.0)](https://travis-ci.org/sfelix-martins/json-exception-handler)
3+
[![StyleCI](https://styleci.io/repos/101529653/shield?style=plastic&branch=3.0)](https://styleci.io/repos/101529653?style=plastic&branch=3.0)
4+
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/badges/quality-score.png?b=3.0)](https://scrutinizer-ci.com/g/sfelix-martins/json-exception-handler/?branch=3.0)
5+
[![Tests](https://github.com/sfelix-martins/json-exception-handler/actions/workflows/tests.yml/badge.svg)](https://github.com/sfelix-martins/json-exception-handler/actions/workflows/tests.yml)
66

77
Adds methods to your `App\Exceptions\Handler` to treat json responses.
88
It is most useful if you are building APIs!
99

1010
## Requirements
1111

12-
* Laravel Framework >= 5.4
13-
* php >= 7.0
12+
* PHP >= 8.1
13+
* Laravel Framework 10.x, 11.x, or 12.x
1414

1515
## JsonAPI
1616

17-
Using [JsonAPI](http://jsonapi.org) standard to responses!
17+
Using [JsonAPI](http://jsonapi.org) standard to responses!
1818

1919
## Features
2020

@@ -76,26 +76,18 @@ To `Illuminate\Validation\ValidationException`:
7676

7777
## Installing and configuring
7878

79-
Install the package
79+
Install the package
8080

8181
```console
8282
$ composer require sfelix-martins/json-exception-handler
8383
```
8484

85-
If you are not using **Laravel 5.5** version add the `JsonHandlerServiceProvider` to your `config/app.php` providers array:
86-
87-
```php
88-
'providers' => [
89-
...
90-
SMartins\Exceptions\JsonHandlerServiceProvider::class,
91-
],
92-
```
85+
The package uses Laravel's auto-discovery feature, so the service provider will be automatically registered.
9386

9487
Publish the config to set your own exception codes
9588

9689
```sh
97-
98-
$ php artisan vendor:publish --provider="SMartins\JsonHandler\JsonHandlerServiceProvider"
90+
$ php artisan vendor:publish --provider="SMartins\Exceptions\JsonHandlerServiceProvider"
9991
```
10092

10193
Set your exception codes on `config/json-exception-handler.php` on codes array.
@@ -115,28 +107,28 @@ In `resources/lang/vendor/exception/lang/$locale` in `exceptions` file you can s
115107

116108
## Using
117109

118-
Use the trait on your `App\Exception\Handler` and add method `jsonResponse()`
119-
passing the `$exception` if `$request` expects a json response on `render()`method
110+
Use the trait on your `App\Exception\Handler` and add method `jsonResponse()`
111+
passing the `$exception` if `$request` expects a json response on `render()` method
120112

121113
```php
122-
123114
use SMartins\Exceptions\JsonHandler;
115+
use Throwable;
124116

125117
class Handler extends ExceptionHandler
126118
{
127119
use JsonHandler;
128120

129121
// ...
130122

131-
public function render($request, Exception $exception)
132-
{
123+
public function render($request, Throwable $e)
124+
{
133125
if ($request->expectsJson()) {
134-
return $this->jsonResponse($exception);
126+
return $this->jsonResponse($e);
135127
}
136128

137-
return parent::render($request, $exception);
129+
return parent::render($request, $e);
138130
}
139-
131+
140132
// ...
141133
```
142134

@@ -173,7 +165,7 @@ class UserController extends Controller
173165
{
174166
// If not found the default response is called
175167
$user = User::findOrFail($id);
176-
168+
177169
// Gate define on AuthServiceProvider
178170
// Generate an AuthorizationException if fail
179171
$this->authorize('users.view', $user->id);
@@ -183,68 +175,55 @@ class UserController extends Controller
183175

184176
## Extending
185177

186-
You can too create your own handler to any Exception. E.g.:
178+
You can create your own handler for any Exception. E.g.:
187179

188-
- Create a Handler class that extends of `AbstractHandler`:
180+
- Create a Handler class that extends `AbstractHandler`:
189181

190182
```php
191183
namespace App\Exceptions;
192184

193185
use GuzzleHttp\Exception\ClientException;
194186
use SMartins\Exceptions\Handlers\AbstractHandler;
187+
use SMartins\Exceptions\JsonApi\Error;
188+
use SMartins\Exceptions\JsonApi\Source;
189+
use SMartins\Exceptions\Response\ErrorHandledCollectionInterface;
190+
use SMartins\Exceptions\Response\ErrorHandledInterface;
195191

196192
class GuzzleClientHandler extends AbstractHandler
197193
{
198-
/**
199-
* Create instance using the Exception to be handled.
200-
*
201-
* @param \GuzzleHttp\Exception\ClientException $e
202-
*/
203194
public function __construct(ClientException $e)
204195
{
205196
parent::__construct($e);
206197
}
207-
}
208-
```
209-
210-
- You must implements the method `handle()` from `AbstractHandler` class. The method must return an instance of `Error` or `ErrorCollection`:
211-
212-
```php
213-
namespace App\Exceptions;
214-
215-
use SMartins\Exceptions\JsonAPI\Error;
216-
use SMartins\Exceptions\JsonAPI\Source;
217-
use GuzzleHttp\Exception\ClientException;
218-
use SMartins\Exceptions\Handlers\AbstractHandler;
219198

220-
class GuzzleClientHandler extends AbstractHandler
221-
{
222-
// ...
223-
224-
public function handle()
199+
public function handle(): ErrorHandledInterface|ErrorHandledCollectionInterface
225200
{
226-
return (new Error)->setStatus($this->getStatusCode())
227-
->setCode($this->getCode())
201+
return (new Error)->setStatus((string) $this->getStatusCode())
202+
->setCode((string) $this->getCode())
228203
->setSource((new Source())->setPointer($this->getDefaultPointer()))
229204
->setTitle($this->getDefaultTitle())
230205
->setDetail($this->exception->getMessage());
231206
}
232207

233-
public function getCode()
208+
public function getCode(string $type = 'default'): int|string
234209
{
235210
// You can add a new type of code on `config/json-exception-handlers.php`
236211
return config('json-exception-handler.codes.client.default');
237212
}
238213
}
239214
```
240215

216+
- For returning multiple errors:
217+
241218
```php
242219
namespace App\Exceptions;
243220

244-
use SMartins\Exceptions\JsonAPI\Error;
245-
use SMartins\Exceptions\JsonAPI\Source;
246-
use SMartins\Exceptions\JsonAPI\ErrorCollection;
221+
use SMartins\Exceptions\JsonApi\Error;
222+
use SMartins\Exceptions\JsonApi\Source;
223+
use SMartins\Exceptions\JsonApi\ErrorCollection;
247224
use SMartins\Exceptions\Handlers\AbstractHandler;
225+
use SMartins\Exceptions\Response\ErrorHandledCollectionInterface;
226+
use SMartins\Exceptions\Response\ErrorHandledInterface;
248227

249228
class MyCustomizedHandler extends AbstractHandler
250229
{
@@ -253,14 +232,14 @@ class MyCustomizedHandler extends AbstractHandler
253232
parent::__construct($e);
254233
}
255234

256-
public function handle()
235+
public function handle(): ErrorHandledInterface|ErrorHandledCollectionInterface
257236
{
258-
$errors = (new ErrorCollection)->setStatusCode(400);
237+
$errors = (new ErrorCollection)->setStatusCode('400');
259238

260239
$exceptions = $this->exception->getExceptions();
261240

262241
foreach ($exceptions as $exception) {
263-
$error = (new Error)->setStatus(422)
242+
$error = (new Error)->setStatus('422')
264243
->setSource((new Source())->setPointer($this->getDefaultPointer()))
265244
->setTitle($this->getDefaultTitle())
266245
->setDetail($exception->getMessage());
@@ -273,15 +252,15 @@ class MyCustomizedHandler extends AbstractHandler
273252
}
274253
```
275254

276-
- Now just registry your customized handler on `App\Exception\Handler` file on attribute `exceptionHandlers`. E.g:
255+
- Now just register your customized handler on `App\Exception\Handler` file on attribute `exceptionHandlers`. E.g:
277256

278257
```php
279258
namespace App\Exceptions;
280259

281-
use Exception;
282260
use GuzzleHttp\Exception\ClientException;
283261
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
284262
use SMartins\Exceptions\JsonHandler;
263+
use Throwable;
285264

286265
class Handler extends ExceptionHandler
287266
{
@@ -291,9 +270,18 @@ class Handler extends ExceptionHandler
291270
// Set on key the exception and on value the handler.
292271
ClientException::class => GuzzleClientHandler::class,
293272
];
294-
295273
```
296274

275+
## Upgrading from 2.x
276+
277+
If you're upgrading from version 2.x, note the following changes:
278+
279+
1. PHP 8.1+ is now required
280+
2. Laravel 10, 11, or 12 is required
281+
3. The `render()` method signature now uses `Throwable` instead of `Exception`
282+
4. All handler classes now use strict types and proper return type declarations
283+
5. Status codes are now always strings in the JSON response (as per JsonAPI spec)
284+
297285
## Response References:
298286

299287
- http://jsonapi.org/format/#errors

0 commit comments

Comments
 (0)