1
0
mirror of https://github.com/flextype/flextype.git synced 2025-08-10 07:06:45 +02:00

feat(core): add new code base for Whoops Error handling with updated settings

This commit is contained in:
Awilum
2021-09-03 22:27:21 +03:00
parent 50f1b44dbc
commit 578ddbe830
5 changed files with 220 additions and 40 deletions

View File

@@ -36,8 +36,6 @@
"slim/slim": "^4.8.1",
"filp/whoops": "^2.14",
"league/event": "^2.2.0",
"league/glide": "^2.0.0",
@@ -56,10 +54,11 @@
"slim/psr7": "^1.4",
"php-di/php-di": "^6.3.4",
"php-di/slim-bridge": "^3.1.1",
"middlewares/whoops": "^2.0",
"nette/neon": "^3.2",
"league/commonmark": "^2.0",
"siriusphp/upload": "^3.0"
"siriusphp/upload": "^3.0",
"filp/whoops": "^2.14"
},
"suggest": {
"ext-zend-opcache": "Recommended for better performance",

View File

@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype\Middlewares;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Flextype\WhoopsGuard;
class WhoopsMiddleware implements MiddlewareInterface {
protected $settings = [];
protected $handlers = [];
/**
* Instance the whoops middleware object
*
* @param array $settings
* @param array $handlers
*/
public function __construct(array $settings = [], array $handlers = []) {
$this->settings = $settings;
$this->handlers = $handlers;
}
/**
* Handle the requests
*
* @param ServerRequestInterface $request
* @param RequestHandlerInterface $handler
* @return ResponseInterface
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
$whoopsGuard = new WhoopsGuard($this->settings);
$whoopsGuard->setRequest($request);
$whoopsGuard->setHandlers($this->handlers);
$whoopsGuard->install();
return $handler->handle($request);
}
}

View File

@@ -0,0 +1,141 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype;
use Psr\Http\Message\ServerRequestInterface;
use Whoops\Run as WhoopsRun;
use Whoops\Util\Misc;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Handler\PlainTextHandler;
use Whoops\Handler\JsonResponseHandler;
use Whoops\Handler\XmlResponseHandler;
class WhoopsGuard {
protected $settings = [];
protected $request = null;
protected $handlers = [];
/**
* Instance the whoops guard object
*
* @param array $settings
*/
public function __construct(array $settings = []) {
$this->settings = array_merge([
'enable' => true,
'editor' => '',
'title' => '',
], $settings);
}
/**
* Set the server request object
*
* @param ServerRequestInterface $request
* @return void
*/
public function setRequest(ServerRequestInterface $request): void {
$this->request = $request;
}
/**
* Set the custom handlers for whoops
*
* @param array $handlers
* @return void
*/
public function setHandlers(array $handlers): void {
$this->handlers = $handlers;
}
/**
* Install the whoops guard object
*
* @return WhoopsRun|null
*/
public function install(): ?WhoopsRun {
if ($this->settings['enable'] === false) {
return null;
}
// Enable PrettyPageHandler with editor options
$prettyPageHandler = new PrettyPageHandler();
if (empty($this->settings['editor']) === false) {
$prettyPageHandler->setEditor($this->settings['editor']);
}
if (empty($this->settings['title']) === false) {
$prettyPageHandler->setPageTitle($this->settings['title']);
}
// Add more information to the PrettyPageHandler
$contentCharset = '<none>';
if (
method_exists($this->request, 'getContentCharset') === true &&
$this->request->getContentCharset() !== null
) {
$contentCharset = $this->request->getContentCharset();
}
$prettyPageHandler->addDataTable('Flextype', [
'Version' => Flextype::VERSION,
'Accept Charset' => $this->request->getHeader('ACCEPT_CHARSET') ?: '<none>',
'Content Charset' => $contentCharset,
'HTTP Method' => $this->request->getMethod(),
'Path' => $this->request->getUri()->getPath(),
'Query String' => $this->request->getUri()->getQuery() ?: '<none>',
'Base URL' => (string) $this->request->getUri(),
'Scheme' => $this->request->getUri()->getScheme(),
'Port' => $this->request->getUri()->getPort(),
'Host' => $this->request->getUri()->getHost(),
]);
// Set Whoops to default exception handler
$whoops = new \Whoops\Run;
switch ($this->settings['handler']) {
case 'json':
$whoops->pushHandler(new JsonResponseHandler());
break;
case 'xml':
$whoops->pushHandler(new XmlResponseHandler());
break;
case 'plain':
$whoops->pushHandler(new PlainTextHandler());
break;
case 'pretty':
default:
$whoops->pushHandler($prettyPageHandler);
break;
}
// Enable JsonResponseHandler when request is AJAX
if (Misc::isAjaxRequest() === true){
$whoops->pushHandler(new JsonResponseHandler());
}
// Add each custom handler to whoops handler stack
if (empty($this->handlers) === false) {
foreach($this->handlers as $handler) {
$whoops->pushHandler($handler);
}
}
$whoops->register();
return $whoops;
}
}

View File

@@ -16,7 +16,6 @@ use DateTimeZone;
use Flextype\Entries\Entries;
use Flextype\Handlers\HttpErrorHandler;
use Flextype\Handlers\ShutdownHandler;
use Flextype\Media\Media;
use Flextype\Parsers\Parsers;
use Flextype\Serializers\Serializers;
use Flextype\Tokens\Tokens;
@@ -57,6 +56,7 @@ use Slim\Psr7\Factory\StreamFactory;
use Slim\Psr7\Response;
use Slim\Psr7\Stream;
use Symfony\Component\Yaml\Yaml as SymfonyYaml;
use Flextype\Middlewares\WhoopsMiddleware;
use function app;
use function array_replace_recursive;
@@ -87,11 +87,11 @@ use function sys_get_temp_dir;
use function trim;
use function var_export;
// Init Flextype Instance
// Creates $app Application and $container Container objects
// Init Flextype Instance.
// Creates $app Application and $container Container objects.
flextype();
// Add Registry Service
// Add Registry Service.
container()->set('registry', registry());
// Init Flextype config (manifest and settings)
@@ -108,7 +108,7 @@ $f1 = file_exists($flextypeManifestFilePath) ? filemtime($flextypeManifestFilePa
$f2 = file_exists($defaultFlextypeSettingsFilePath) ? filemtime($defaultFlextypeSettingsFilePath) : '';
$f3 = file_exists($customFlextypeSettingsFilePath) ? filemtime($customFlextypeSettingsFilePath) : '';
// Create Unique Cache ID
// Create Unique Cache ID.
$cacheID = md5($flextypeManifestFilePath . $defaultFlextypeSettingsFilePath . $customFlextypeSettingsFilePath . $f1 . $f2 . $f3);
if (filesystem()->file($preflightFlextypePath . '/' . $cacheID . '.php')->exists()) {
@@ -194,15 +194,6 @@ if (registry()->get('flextype.settings.cache.routes')) {
app()->getRouteCollector()->setCacheFile(PATH['tmp'] . '/routes/routes.php');
}
$callableResolver = app()->getCallableResolver();
$responseFactory = app()->getResponseFactory();
$serverRequestCreator = ServerRequestCreatorFactory::create();
$request = $serverRequestCreator->createServerRequestFromGlobals();
$errorHandler = new HttpErrorHandler($callableResolver, $responseFactory);
$shutdownHandler = new ShutdownHandler($request, $errorHandler, registry()->get('flextype.settings.errors.display'));
register_shutdown_function($shutdownHandler);
// Add Session Service
container()->set('session', new Session());
@@ -216,8 +207,8 @@ container()->set('emitter', new Emitter());
container()->set('slugify', new Slugify([
'separator' => registry()->get('flextype.settings.slugify.separator'),
'lowercase' => registry()->get('flextype.settings.slugify.lowercase'),
'trim' => registry()->get('flextype.settings.slugify.trim'),
'regexp' => registry()->get('flextype.settings.slugify.regexp'),
'trim' => registry()->get('flextype.settings.slugify.trim'),
'regexp' => registry()->get('flextype.settings.slugify.regexp'),
'lowercase_after_regexp' => registry()->get('flextype.settings.slugify.lowercase_after_regexp'),
'strip_tags' => registry()->get('flextype.settings.slugify.strip_tags'),
]));
@@ -395,8 +386,8 @@ container()->set('images', static function () {
// Setup Glide server
$server = ServerFactory::create([
'source' => $source,
'cache' => $cache,
'api' => $api,
'cache' => $cache,
'api' => $api,
]);
// Set presets
@@ -482,11 +473,16 @@ if (registry()->get('flextype.settings.cors.enabled')) {
// Add Routing Middleware
app()->addRoutingMiddleware();
// Add Error Handling Middleware
app()->addErrorMiddleware(registry()->get('flextype.settings.errors.display'), false, false)->setDefaultErrorHandler($errorHandler);
// Run high priority event: onFlextypeBeforeRun before Flextype Application starts.
emitter()->emit('onFlextypeBeforeRun');
// Add Whoops Error Handling Middleware
app()->add(new WhoopsMiddleware([
'enable' => registry()->get('flextype.settings.errors.display'),
'editor' => registry()->get('flextype.settings.errors.editor'),
'title' => registry()->get('flextype.settings.errors.page_title'),
'handler' => registry()->get('flextype.settings.errors.handler'),
]));
// Run Flextype Application
app()->run();

View File

@@ -53,6 +53,15 @@ errors:
# Set true to display errors.
display: true
# Editor (emacs, idea, macvim, phpstorm, sublime, textmate, xdebug, vscode, atom, espresso)
editor: atom
# Error page title
page_title: Error!
# Handler (pretty, plain, json, xml)
handler: pretty
# Entries
entries:
directory: '/entries'
@@ -379,22 +388,8 @@ cache:
zenddisk: {}
zendshm: {}
# Whoops
#
# Error handler framework for PHP.
#
# - editor: emacs, idea, macvim, phpstorm, sublime, textmate, xdebug, vscode, atom, espresso
#
# - page_title: page title
whoops:
editor: atom
page_title: Error!
# Slim
#
# - display_error_details: When true, additional information about exceptions are
# displayed by the default error handler.
#
# - add_content_length_header: When true, Slim will add a Content-Length header to
# the response. If you are using a runtime analytics tool,
# such as New Relic, then this should be disabled.
@@ -413,7 +408,6 @@ whoops:
# If 'append' or 'prepend', then any echo or print statements
# are captured and are either appended or prepended to the Response
# returned from the route callable.
display_error_details: true
add_content_length_header: true
router_cache_file: false
determine_route_before_app_middleware: false