generated from spatie/package-skeleton-laravel
-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(laravel-api-problem): add class, exception and http laravel api …
…problem and stubs
- Loading branch information
1 parent
504d49a
commit d4395eb
Showing
11 changed files
with
579 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Pedrosalpr\LaravelApiProblem\Commands; | ||
|
||
use Illuminate\Console\GeneratorCommand; | ||
|
||
class LaravelApiProblemCommand extends GeneratorCommand | ||
{ | ||
public $signature = 'laravel-api-problem:extend {name}'; | ||
|
||
public $description = 'Extend class api problem'; | ||
|
||
protected $type = 'LaravelApiProblem'; | ||
|
||
protected function getStub(): string | ||
{ | ||
return $this->resolveStubPath('/Stubs/dummy.stub'); | ||
} | ||
|
||
protected function resolveStubPath(string $stub): string | ||
{ | ||
return file_exists($customPath = $this->laravel->basePath(trim($stub, '/'))) | ||
? $customPath | ||
: __DIR__ . $stub; | ||
} | ||
|
||
protected function getDefaultNamespace($rootNamespace): string | ||
{ | ||
return "{$rootNamespace}\\ApiProblem"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Pedrosalpr\LaravelApiProblem\Commands; | ||
|
||
use Illuminate\Console\GeneratorCommand; | ||
use Symfony\Component\Console\Input\InputArgument; | ||
|
||
class LaravelApiProblemExceptionCommand extends GeneratorCommand | ||
{ | ||
public $signature = 'laravel-api-problem:exception {name}'; | ||
|
||
public $description = 'Make class api problem exception'; | ||
|
||
protected $type = 'LaravelApiProblemException'; | ||
|
||
protected function getStub(): string | ||
{ | ||
return $this->resolveStubPath('/Stubs/exception.stub'); | ||
} | ||
|
||
protected function resolveStubPath(string $stub): string | ||
{ | ||
return file_exists($customPath = $this->laravel->basePath(trim($stub, '/'))) | ||
? $customPath | ||
: __DIR__ . $stub; | ||
} | ||
|
||
protected function getDefaultNamespace($rootNamespace): string | ||
{ | ||
return "{$rootNamespace}\\Exceptions\\ApiProblem"; | ||
} | ||
|
||
protected function replaceClass($stub, $name) | ||
{ | ||
$class = str_replace($this->getNamespace($name) . '\\', '', $name); | ||
|
||
// Do string replacement | ||
return str_replace('{{ class }}', $class, $stub); | ||
} | ||
|
||
protected function getArguments() | ||
{ | ||
return [ | ||
['name', InputArgument::REQUIRED, 'The name and root of the file.'], | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
namespace {{ namespace }}; | ||
|
||
use Illuminate\Http\Request; | ||
use Illuminate\Http\Response; | ||
use Pedrosalpr\LaravelApiProblem\Http\LaravelHttpApiProblem; | ||
use Pedrosalpr\LaravelApiProblem\LaravelApiProblem; | ||
|
||
class {{ class }} extends LaravelApiProblem | ||
{ | ||
public function __construct( | ||
protected \Throwable $exception, | ||
protected Request $request | ||
) { | ||
match (get_class($exception)) { | ||
\Exception::class => $this->dummy(), | ||
default => parent::__construct($exception, $request) | ||
}; | ||
} | ||
|
||
protected function dummy() | ||
{ | ||
$extensions = [ | ||
'errors' => "Dummy", | ||
]; | ||
$this->apiProblem = new LaravelHttpApiProblem( | ||
Response::HTTP_I_AM_A_TEAPOT, | ||
$this->exception->getMessage(), | ||
$this->getUriInstance(), | ||
$extensions | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?php | ||
|
||
namespace {{ namespace }}; | ||
|
||
use Pedrosalpr\LaravelApiProblem\Exceptions\LaravelApiProblemException; | ||
|
||
class {{ class }} extends LaravelApiProblemException | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Pedrosalpr\LaravelApiProblem\Exceptions; | ||
|
||
use Pedrosalpr\LaravelApiProblem\Http\LaravelHttpApiProblem; | ||
|
||
class LaravelApiProblemException extends \Exception | ||
{ | ||
public function __construct( | ||
protected int $statusCode, | ||
protected string $detail, | ||
protected string $instance, | ||
protected array $extensions = [], | ||
protected ?string $title = null, | ||
protected string $type = LaravelHttpApiProblem::TYPE_ABOUT_BLANK, | ||
int $code = 0, | ||
?\Throwable $previous = null, | ||
) { | ||
parent::__construct($detail, $code, $previous); | ||
} | ||
|
||
public function getStatusCode(): int | ||
{ | ||
return $this->statusCode; | ||
} | ||
|
||
public function getDetail(): string | ||
{ | ||
return $this->detail; | ||
} | ||
|
||
public function getInstance(): string | ||
{ | ||
return $this->instance; | ||
} | ||
|
||
public function getExtensions(): array | ||
{ | ||
return $this->extensions; | ||
} | ||
|
||
public function getTitle(): ?string | ||
{ | ||
return $this->title; | ||
} | ||
|
||
public function getType(): string | ||
{ | ||
return $this->type; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Pedrosalpr\LaravelApiProblem\Http; | ||
|
||
use Illuminate\Support\Carbon; | ||
use Pedrosalpr\LaravelApiProblem\LaravelApiProblemInterface; | ||
|
||
class LaravelHttpApiProblem implements LaravelApiProblemInterface | ||
{ | ||
public const TYPE_ABOUT_BLANK = 'about:blank'; | ||
|
||
private const HEADER_PROBLEM_JSON = 'application/problem+json'; | ||
|
||
private static $statusTitles = [ | ||
// CLIENT ERROR | ||
400 => 'Bad Request', | ||
401 => 'Unauthorized', | ||
402 => 'Payment Required', | ||
403 => 'Forbidden', | ||
404 => 'Not Found', | ||
405 => 'Method Not Allowed', | ||
406 => 'Not Acceptable', | ||
407 => 'Proxy Authentication Required', | ||
408 => 'Request Time-out', | ||
409 => 'Conflict', | ||
410 => 'Gone', | ||
411 => 'Length Required', | ||
412 => 'Precondition Failed', | ||
413 => 'Request Entity Too Large', | ||
414 => 'Request-URI Too Large', | ||
415 => 'Unsupported Media Type', | ||
416 => 'Requested range not satisfiable', | ||
417 => 'Expectation Failed', | ||
418 => 'I\'m a teapot', | ||
419 => 'Page Expired', | ||
422 => 'Unprocessable Entity', | ||
423 => 'Locked', | ||
424 => 'Failed Dependency', | ||
425 => 'Unordered Collection', | ||
426 => 'Upgrade Required', | ||
428 => 'Precondition Required', | ||
429 => 'Too Many Requests', | ||
431 => 'Request Header Fields Too Large', | ||
444 => 'Connection Closed Without Response', | ||
451 => 'Unavailable For Legal Reasons', | ||
499 => 'Client Closed Request', | ||
// SERVER ERROR | ||
500 => 'Internal Server Error', | ||
501 => 'Not Implemented', | ||
502 => 'Bad Gateway', | ||
503 => 'Service Unavailable', | ||
504 => 'Gateway Time-out', | ||
505 => 'HTTP Version not supported', | ||
506 => 'Variant Also Negotiates', | ||
507 => 'Insufficient Storage', | ||
508 => 'Loop Detected', | ||
511 => 'Network Authentication Required', | ||
]; | ||
|
||
private Carbon $timestamp; | ||
|
||
public function __construct( | ||
private int $statusCode, | ||
private string $detail, | ||
private string $instance, | ||
private array $extensions = [], | ||
private ?string $title = null, | ||
private string $type = self::TYPE_ABOUT_BLANK | ||
) { | ||
if ($this->statusCode < 400 || $this->statusCode > 599) { | ||
$this->statusCode = 400; | ||
} | ||
if (!filter_var($this->type, FILTER_VALIDATE_URL) || empty($this->title)) { | ||
$this->title = $this->getTitleForStatusCode($this->statusCode); | ||
$this->type = self::TYPE_ABOUT_BLANK; | ||
} | ||
$this->timestamp = Carbon::now(); | ||
} | ||
|
||
public function getTitle(): string | ||
{ | ||
return $this->title; | ||
} | ||
|
||
public function getType(): string | ||
{ | ||
return $this->type; | ||
} | ||
|
||
public function getDetail(): string | ||
{ | ||
return $this->detail; | ||
} | ||
|
||
public function getStatusCode(): int | ||
{ | ||
return $this->statusCode; | ||
} | ||
|
||
public function getExtensions(): array | ||
{ | ||
return $this->extensions; | ||
} | ||
|
||
public function toArray(): array | ||
{ | ||
return array_merge( | ||
[ | ||
'status' => $this->statusCode, | ||
'type' => $this->type, | ||
'title' => $this->title, | ||
'detail' => $this->detail, | ||
'instance' => $this->instance, | ||
'timestamp' => $this->timestamp->toJSON() | ||
], | ||
$this->extensions | ||
); | ||
} | ||
|
||
public function getHeaderProblemJson(): string | ||
{ | ||
return self::HEADER_PROBLEM_JSON; | ||
} | ||
|
||
private function getTitleForStatusCode(int $statusCode): string | ||
{ | ||
return self::$statusTitles[$statusCode] ?? 'Unknown'; | ||
} | ||
} |
Oops, something went wrong.