Skip to content

Commit

Permalink
Disable and enable debug bar (#21)
Browse files Browse the repository at this point in the history
* Disable and enable debug bar using header, cookie, attribute
* Disable debug bar on redirect responses
  • Loading branch information
snapshotpl authored Apr 26, 2018
1 parent 6c06189 commit 6c2c461
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 130 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ $app->run($request, $response);

You don't need to copy any static assets from phpdebugbar vendor!

### How to force disable or enable PHP Debug Bar?

Sometimes you want to have control when enable (or not) PHP Debug Bar:
* custom content negotiation,
* allow to debug redirects responses.

We allow you to disable attaching phpdebugbar using `X-Enable-Debug-Bar: false` header, cookie or request attribute.
To force enable just send request with `X-Enable-Debug-Bar` header, cookie or request attribute with `true` value.

### How to install on Zend Expressive?

You need to register ConfigProvider and pipe provided middleware:
Expand Down
3 changes: 1 addition & 2 deletions src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ final class ConfigProvider
{
public static function getConfig(): array
{
$self = new self();
return $self();
return (new self())();
}

public function __invoke(): array
Expand Down
3 changes: 1 addition & 2 deletions src/JavascriptRendererFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ final class JavascriptRendererFactory
public function __invoke(ContainerInterface $container = null): JavascriptRenderer
{
if ($container === null || !$container->has(DebugBar::class)) {
$standardDebugBarFactory = new StandardDebugBarFactory();
$debugbar = $standardDebugBarFactory($container);
$debugbar = (new StandardDebugBarFactory())($container);
} else {
$debugbar = $container->get(DebugBar::class);
}
Expand Down
97 changes: 38 additions & 59 deletions src/PhpDebugBarMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

use DebugBar\JavascriptRenderer as DebugBarRenderer;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as ServerRequest;
use Psr\Http\Message\UriInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Http\Uri;
use Zend\Diactoros\Response;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Http\Uri as SlimUri;
use Zend\Diactoros\Response as DiactorosResponse;
use Zend\Diactoros\Response\HtmlResponse;
use Zend\Diactoros\Response\Serializer;
use Zend\Diactoros\Stream;
Expand All @@ -23,6 +23,8 @@
*/
final class PhpDebugBarMiddleware implements MiddlewareInterface
{
public const FORCE_KEY = 'X-Enable-Debug-Bar';

protected $debugBarRenderer;

public function __construct(DebugBarRenderer $debugbarRenderer)
Expand All @@ -33,15 +35,21 @@ public function __construct(DebugBarRenderer $debugbarRenderer)
/**
* @inheritDoc
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
public function process(ServerRequest $request, RequestHandler $handler): Response
{
if ($staticFile = $this->getStaticFile($request->getUri())) {
return $staticFile;
}

$response = $handler->handle($request);

if (!$this->isHtmlAccepted($request)) {
$forceHeaderValue = $request->getHeaderLine(self::FORCE_KEY);
$forceCookieValue = $request->getCookieParams()[self::FORCE_KEY] ?? '';
$forceAttibuteValue = $request->getAttribute(self::FORCE_KEY, '');
$isForceEnable = in_array('true', [$forceHeaderValue, $forceCookieValue, $forceAttibuteValue], true);
$isForceDisable = in_array('false', [$forceHeaderValue, $forceCookieValue, $forceAttibuteValue], true);

if ($isForceDisable || (!$isForceEnable && ($this->isRedirect($response) || !$this->isHtmlAccepted($request)))) {
return $response;
}

Expand All @@ -51,30 +59,27 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
return $this->prepareHtmlResponseWithDebugBar($response);
}

public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface
public function __invoke(ServerRequest $request, Response $response, callable $next): Response
{
$handler = new class($next, $response) implements RequestHandlerInterface {
$handler = new class($next, $response) implements RequestHandler {
private $next;
private $response;

public function __construct(callable $next, ResponseInterface $response)
public function __construct(callable $next, Response $response)
{
$this->next = $next;
$this->response = $response;
}

public function handle(ServerRequestInterface $request): ResponseInterface
public function handle(ServerRequest $request): Response
{
return ($this->next)($request, $this->response);
}
};
return $this->process($request, $handler);
}

/**
* @return HtmlResponse
*/
private function prepareHtmlResponseWithDebugBar(ResponseInterface $response)
private function prepareHtmlResponseWithDebugBar(Response $response): HtmlResponse
{
$head = $this->debugBarRenderer->renderHead();
$body = $this->debugBarRenderer->render();
Expand All @@ -86,10 +91,7 @@ private function prepareHtmlResponseWithDebugBar(ResponseInterface $response)
return new HtmlResponse($result);
}

/**
* @return ResponseInterface
*/
private function attachDebugBarToResponse(ResponseInterface $response)
private function attachDebugBarToResponse(Response $response): Response
{
$head = $this->debugBarRenderer->renderHead();
$body = $this->debugBarRenderer->render();
Expand All @@ -103,42 +105,34 @@ private function attachDebugBarToResponse(ResponseInterface $response)
return $response;
}

/**
* @return ResponseInterface|null
*/
private function getStaticFile(UriInterface $uri)
private function getStaticFile(UriInterface $uri): ?Response
{
$path = $this->extractPath($uri);

if (strpos($path, $this->debugBarRenderer->getBaseUrl()) !== 0) {
return;
return null;
}

$pathToFile = substr($path, strlen($this->debugBarRenderer->getBaseUrl()));

$fullPathToFile = $this->debugBarRenderer->getBasePath() . $pathToFile;

if (!file_exists($fullPathToFile)) {
return;
return null;
}

$contentType = $this->getContentTypeByFileName($fullPathToFile);
$stream = new Stream($fullPathToFile, 'r');

return new Response($stream, 200, [
return new DiactorosResponse($stream, 200, [
'Content-type' => $contentType,
]);
}

/**
* @param UriInterface $uri
*
* @return string
*/
private function extractPath(UriInterface $uri)
private function extractPath(UriInterface $uri): string
{
// Slim3 compatibility
if ($uri instanceof Uri) {
if ($uri instanceof SlimUri) {
$basePath = $uri->getBasePath();
if (!empty($basePath)) {
return $basePath;
Expand All @@ -147,12 +141,7 @@ private function extractPath(UriInterface $uri)
return $uri->getPath();
}

/**
* @param string $filename
*
* @return string
*/
private function getContentTypeByFileName($filename)
private function getContentTypeByFileName(string $filename): string
{
$ext = pathinfo($filename, PATHINFO_EXTENSION);

Expand All @@ -170,35 +159,25 @@ private function getContentTypeByFileName($filename)
return isset($map[$ext]) ? $map[$ext] : 'text/plain';
}

/**
* @param ResponseInterface $response
*
* @return bool
*/
private function isHtmlResponse(ResponseInterface $response)
private function isHtmlResponse(Response $response): bool
{
return $this->hasHeaderContains($response, 'Content-Type', 'text/html');
}

/**
* @param ServerRequestInterface $request
*
* @return bool
*/
private function isHtmlAccepted(ServerRequestInterface $request)
private function isHtmlAccepted(ServerRequest $request): bool
{
return $this->hasHeaderContains($request, 'Accept', 'text/html');
}

/**
* @param MessageInterface $message
* @param string $headerName
* @param string $value
*
* @return bool
*/
private function hasHeaderContains(MessageInterface $message, $headerName, $value)
private function hasHeaderContains(MessageInterface $message, string $headerName, string $value): bool
{
return strpos($message->getHeaderLine($headerName), $value) !== false;
}

private function isRedirect(Response $response): bool
{
$statusCode = $response->getStatusCode();

return ($statusCode >= 300 || $statusCode < 400) && $response->getHeaderLine('Location') !== '';
}
}
3 changes: 1 addition & 2 deletions src/PhpDebugBarMiddlewareFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ final class PhpDebugBarMiddlewareFactory
public function __invoke(ContainerInterface $container = null): PhpDebugBarMiddleware
{
if ($container === null || !$container->has(JavascriptRenderer::class)) {
$rendererFactory = new JavascriptRendererFactory();
$renderer = $rendererFactory($container);
$renderer = (new JavascriptRendererFactory())($container);
} else {
$renderer = $container->get(JavascriptRenderer::class);
}
Expand Down
40 changes: 0 additions & 40 deletions src/ResponseInjector/AlwaysInjector.php

This file was deleted.

15 changes: 0 additions & 15 deletions src/ResponseInjector/ResponseInjectorInterface.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/StandardDebugBarFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function __invoke(ContainerInterface $container = null): StandardDebugBar
if ($container !== null) {
$config = $container->has('config') ? $container->get('config') : [];

$collectors = isset($config['phpmiddleware']['phpdebugbar']['collectors']) ? $config['phpmiddleware']['phpdebugbar']['collectors'] : [];
$collectors = $config['phpmiddleware']['phpdebugbar']['collectors'] ?: [];

foreach ($collectors as $collectorName) {
$collector = $container->get($collectorName);
Expand Down
Loading

0 comments on commit 6c2c461

Please sign in to comment.