Skip to content

Commit

Permalink
Replaced AbstractProvider with ProviderInterface + Updated tests
Browse files Browse the repository at this point in the history
  • Loading branch information
designcise committed Jun 7, 2020
1 parent 53487f2 commit 6c4f85b
Show file tree
Hide file tree
Showing 17 changed files with 125 additions and 110 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ new ErrorHandler(
```

1. The first argument to the constructor must be an instance of `Psr\Http\Message\ResponseFactoryInterface`;
1. The second argument to the constructor must be the name of the handler provider class (which extends `\BitFrame\Whoops\Provider\AbstractProvider`)
1. The second argument to the constructor must be an implementation of `\BitFrame\Whoops\Provider\ProviderInterface`;
1. The third argument to the constructor is an optional array of options to specify the following:
1. `catchGlobalErrors`: When set to `true` errors will be handled outside of current batch of middleware set.
1. Other options are simply method names in `Whoops\Handler\*Handler.php` and `BitFrame\Whoops\Handler\*Handler.php`. For example, to set `Whoops\Handler\JsonResponseHandler::setJsonApi()` you would pass in: `['setJsonApi' => false]`, etc.
Expand Down
24 changes: 16 additions & 8 deletions src/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use Psr\Http\Message\{ResponseFactoryInterface, ServerRequestInterface, ResponseInterface};
use Psr\Http\Server\{RequestHandlerInterface, MiddlewareInterface};
use Whoops\{Run, RunInterface};
use BitFrame\Whoops\Provider\{AbstractProvider, HandlerProviderNegotiator};
use BitFrame\Whoops\Provider\{HandlerProviderNegotiator, ProviderInterface};
use Throwable;
use InvalidArgumentException;

Expand All @@ -34,7 +34,8 @@ class ErrorHandler implements MiddlewareInterface

private ResponseFactoryInterface $responseFactory;

private string $handlerProvider;
/** @var ProviderInterface|string */
private $handlerProvider;

private array $options;

Expand All @@ -51,17 +52,22 @@ public static function fromNegotiator(
);
}

/**
* @param ResponseFactoryInterface $responseFactory
* @param string|ProviderInterface $handlerProvider
* @param array $options
*/
public function __construct(
ResponseFactoryInterface $responseFactory,
string $handlerProvider = HandlerProviderNegotiator::class,
$handlerProvider = HandlerProviderNegotiator::class,
array $options = []
) {
$this->responseFactory = $responseFactory;
$this->handlerProvider = $handlerProvider;

if (! is_a($this->handlerProvider, AbstractProvider::class, true)) {
if (! is_a($this->handlerProvider, ProviderInterface::class, true)) {
throw new InvalidArgumentException(
'Handler provider must be instance of ' . AbstractProvider::class
'Handler provider must be instance of ' . ProviderInterface::class
);
}

Expand All @@ -79,8 +85,10 @@ public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
$handlerProvider = new $this->handlerProvider($request);
$errorHandler = $handlerProvider->getHandler();
$handlerProvider = ($this->handlerProvider instanceof ProviderInterface)
? $this->handlerProvider
: new $this->handlerProvider();
$errorHandler = $handlerProvider->getHandler($request);

$this->applyOptions($errorHandler);
$this->whoops->pushHandler($errorHandler);
Expand All @@ -98,7 +106,7 @@ public function process(
$response = $handler->handle($request);
} catch (Throwable $e) {
$response = $this->handleException($e)
->withHeader('Content-Type', $handlerProvider->getPreferredContentType());
->withHeader('Content-Type', $handlerProvider->getPreferredContentType($request));
}

if (! $this->catchGlobalErrors) {
Expand Down
33 changes: 0 additions & 33 deletions src/Provider/AbstractProvider.php

This file was deleted.

21 changes: 10 additions & 11 deletions src/Provider/HandlerProviderNegotiator.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* Detect any of the supported preferred formats from an
* HTTP request.
*/
class HandlerProviderNegotiator extends AbstractProvider
class HandlerProviderNegotiator implements ProviderInterface
{
/** @var string */
public const HTML = 'html';
Expand All @@ -48,36 +48,35 @@ class HandlerProviderNegotiator extends AbstractProvider
self::XML => XmlHandlerProvider::class,
];

private ?AbstractProvider $activeProvider = null;
private ?ProviderInterface $activeProvider = null;

public function add(string $type, string $provider): void
{
if (! is_a($provider, AbstractProvider::class, true)) {
if (! is_a($provider, ProviderInterface::class, true)) {
throw new InvalidArgumentException(
'Handler provider must be instance of ' . AbstractProvider::class
'Handler provider must be instance of ' . ProviderInterface::class
);
}

$this->handlerProviders[$type] = $provider;
}

public function getHandler(): HandlerInterface
public function getHandler(ServerRequestInterface $request): HandlerInterface
{
return $this->getPreferredProvider()->getHandler();
return $this->getPreferredProvider($request)->getHandler($request);
}

public function getPreferredContentType(): string
public function getPreferredContentType(ServerRequestInterface $request): string
{
return $this->getPreferredProvider()->getPreferredContentType();
return $this->getPreferredProvider($request)->getPreferredContentType($request);
}

public function getPreferredProvider(): AbstractProvider
public function getPreferredProvider(ServerRequestInterface $request): ProviderInterface
{
if ($this->activeProvider instanceof AbstractProvider) {
if ($this->activeProvider instanceof ProviderInterface) {
return $this->activeProvider;
}

$request = $this->getRequest();
$acceptTypes = $request->getHeader('accept');
$default = $this->handlerProviders[self::HTML];

Expand Down
8 changes: 4 additions & 4 deletions src/Provider/HtmlHandlerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@

namespace BitFrame\Whoops\Provider;

use Psr\Http\Message\ServerRequestInterface;
use Whoops\Handler\{HandlerInterface, PrettyPageHandler};

class HtmlHandlerProvider extends AbstractProvider
class HtmlHandlerProvider implements ProviderInterface
{
/** @var string */
public const DATA_TABLE_NAME = 'Request Data';

/** @var string[] */
public const MIMES = ['text/html', 'application/xhtml+xml'];

public function getHandler(): HandlerInterface
public function getHandler(ServerRequestInterface $request): HandlerInterface
{
$request = $this->getRequest();
$handler = new PrettyPageHandler();

$handler->addDataTable(self::DATA_TABLE_NAME, [
Expand All @@ -39,7 +39,7 @@ public function getHandler(): HandlerInterface
return $handler;
}

public function getPreferredContentType(): string
public function getPreferredContentType(ServerRequestInterface $request): string
{
return self::MIMES[0];
}
Expand Down
7 changes: 4 additions & 3 deletions src/Provider/JsonHandlerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@

namespace BitFrame\Whoops\Provider;

use Psr\Http\Message\ServerRequestInterface;
use Whoops\Handler\{HandlerInterface, JsonResponseHandler};

class JsonHandlerProvider extends AbstractProvider
class JsonHandlerProvider implements ProviderInterface
{
/** @var string[] */
public const MIMES = ['application/json', 'text/json', 'application/x-json'];

public function getHandler(): HandlerInterface
public function getHandler(ServerRequestInterface $request): HandlerInterface
{
return new JsonResponseHandler();
}

public function getPreferredContentType(): string
public function getPreferredContentType(ServerRequestInterface $request): string
{
return self::MIMES[0];
}
Expand Down
8 changes: 4 additions & 4 deletions src/Provider/JsonpHandlerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@

namespace BitFrame\Whoops\Provider;

use Psr\Http\Message\ServerRequestInterface;
use Whoops\Handler\HandlerInterface;
use BitFrame\Whoops\Handler\JsonpResponseHandler;
use RuntimeException;

class JsonpHandlerProvider extends AbstractProvider
class JsonpHandlerProvider implements ProviderInterface
{
/** @var string[] */
public const MIMES = ['application/javascript'];

public function getHandler(): HandlerInterface
public function getHandler(ServerRequestInterface $request): HandlerInterface
{
$request = $this->getRequest();
$queryParams = $request->getQueryParams();
$method = $request->getMethod();

Expand All @@ -34,7 +34,7 @@ public function getHandler(): HandlerInterface
return new JsonpResponseHandler($queryParams['callback']);
}

public function getPreferredContentType(): string
public function getPreferredContentType(ServerRequestInterface $request): string
{
return self::MIMES[0];
}
Expand Down
25 changes: 25 additions & 0 deletions src/Provider/ProviderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* BitFrame Framework (https://www.bitframephp.com)
*
* @author Daniyal Hamid
* @copyright Copyright (c) 2017-2020 Daniyal Hamid (https://designcise.com)
* @license https://bitframephp.com/about/license MIT License
*/

namespace BitFrame\Whoops\Provider;

use Psr\Http\Message\ServerRequestInterface;
use Whoops\Handler\HandlerInterface;

interface ProviderInterface
{
public function getHandler(
ServerRequestInterface $request
): HandlerInterface;

public function getPreferredContentType(
ServerRequestInterface $request
): string;
}
7 changes: 4 additions & 3 deletions src/Provider/TextHandlerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@

namespace BitFrame\Whoops\Provider;

use Psr\Http\Message\ServerRequestInterface;
use Whoops\Handler\{HandlerInterface, PlainTextHandler};

class TextHandlerProvider extends AbstractProvider
class TextHandlerProvider implements ProviderInterface
{
/** @var string[] */
public const MIMES = ['text/plain'];

public function getHandler(): HandlerInterface
public function getHandler(ServerRequestInterface $request): HandlerInterface
{
return new PlainTextHandler();
}

public function getPreferredContentType(): string
public function getPreferredContentType(ServerRequestInterface $request): string
{
return self::MIMES[0];
}
Expand Down
7 changes: 4 additions & 3 deletions src/Provider/XmlHandlerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@

namespace BitFrame\Whoops\Provider;

use Psr\Http\Message\ServerRequestInterface;
use Whoops\Handler\{HandlerInterface, XmlResponseHandler};

class XmlHandlerProvider extends AbstractProvider
class XmlHandlerProvider implements ProviderInterface
{
/** @var string[] */
public const MIMES = ['text/xml', 'application/xml', 'application/x-xml'];

public function getHandler(): HandlerInterface
public function getHandler(ServerRequestInterface $request): HandlerInterface
{
return new XmlResponseHandler();
}

public function getPreferredContentType(): string
public function getPreferredContentType(ServerRequestInterface $request): string
{
return self::MIMES[0];
}
Expand Down
2 changes: 1 addition & 1 deletion test/ErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function ($args) use ($response, $phpunit, $expectedError) {
);

$middlewares = [
new ErrorHandler($responseFactory->reveal(), HandlerProviderNegotiator::class, [
new ErrorHandler($responseFactory->reveal(), new HandlerProviderNegotiator(), [
'setJsonApi' => false,
]),
$middleware,
Expand Down
Loading

0 comments on commit 6c4f85b

Please sign in to comment.