Skip to content

Commit

Permalink
Allow for providers and middleware to be registered only for a given …
Browse files Browse the repository at this point in the history
…scope (dependent on app name)

General code improvements and error handling when developing rest api
  • Loading branch information
Jupiter committed Oct 29, 2018
1 parent b26a8a2 commit 61b0da9
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 78 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,12 @@ $cache->set("cacheKey", "some test value");
echo $cache->get("cacheKey");
```

## Changelog

V3.0.0
- Allow for providers and middleware to be registered only for a given scope (dependent on app name)
- general code improvements and error handling when developing rest api

## Roadmap

- [ ] more service providers / separate service providers in packages
Expand Down
2 changes: 1 addition & 1 deletion app/Handlers/Error.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function __invoke(Request $request, Response $response, \Exception $excep
$app->resolve(LoggerInterface::class)->error($exception);
}

if ($app->console && class_exists(Collision::class)) {
if ($app->isConsole() && class_exists(Collision::class)) {
throw $exception;
}

Expand Down
2 changes: 1 addition & 1 deletion app/Handlers/NotFound.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function __invoke(Request $request, Response $response)
$app->resolve(LoggerInterface::class)->error("URI '".$request->getUri()->getPath()."' not found");
}

if ($app->console) {
if ($app->isConsole()) {
return $response->write("Error: request does not match any command::method or mandatory params are not properly set\n");
}

Expand Down
8 changes: 4 additions & 4 deletions app/Handlers/PhpError.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
final class PhpError extends \Slim\Handlers\PhpError
{

public function __invoke(Request $request, Response $response, \Throwable $error)
{
public function __invoke(Request $request, Response $response, \Throwable $error)
{
$app = app();
$container = $app->getContainer();

Expand All @@ -21,7 +21,7 @@ public function __invoke(Request $request, Response $response, \Throwable $error
$app->resolve(LoggerInterface::class)->error($error);
}

if ($app->console && class_exists(Collision::class)) {
if ($app->isConsole() && class_exists(Collision::class)) {
throw $error;
}

Expand All @@ -34,6 +34,6 @@ public function __invoke(Request $request, Response $response, \Throwable $error
}

return parent::__invoke($request, $response, $error);
}
}

}
47 changes: 25 additions & 22 deletions app/ServiceProviders/Monolog.php
Original file line number Diff line number Diff line change
@@ -1,42 +1,45 @@
<?php

namespace App\ServiceProviders;
use Lib\Framework\App;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\ChromePHPHandler;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\LineFormatter;

class Monolog implements ProviderInterface
{

public static function register()
{
app()->getContainer()[LoggerInterface::class] = function($c) {
return function($logFilePath = null, $name = null, $level = LogLevel::DEBUG) {
$app = app();
$appName = $app->isConsole() ? 'console' : 'http';
$logFilePath = $logFilePath ?? $app->getConfig("settings.log.file");

$app = app();
$name = $name ?? $app->console;
$logFilePath = $logFilePath ?? $app->getConfig("settings.appLogFilePath");
$logger = new Logger($appName);

$logger = new Logger($name);

if (!empty($logFilePath)) {
$formatter = new \Monolog\Formatter\LineFormatter(null, null, true);
$formatter->includeStacktraces(false);
if (!empty($logFilePath)) {
$formatter = new LineFormatter(null, null, true);
$formatter->includeStacktraces(false);

$handler = new StreamHandler($logFilePath, $level);
$handler->setFormatter($formatter);
$handler = new StreamHandler($logFilePath, LogLevel::DEBUG);
$handler->setFormatter($formatter);
$logger->pushHandler($handler);
}

$logger->pushHandler($handler);
app()->getContainer()[LoggerInterface::class] = function($c) use($appName) {
return function($logFilePath = null, $name = null, $level = LogLevel::DEBUG) use($appName) {

if ((bool)app()->getConfig("settings.debug")) {
$handler2 = new ChromePHPHandler($level);
$app = app();
$name = $name ?? $appName;
$logFilePath = $logFilePath ?? $app->getConfig("settings.log.file");

$logger->pushHandler($handler2);
}
}
$logger = new Logger($name);
$formatter = new LineFormatter(null, null, true);
$formatter->includeStacktraces(false);
$handler = new StreamHandler($logFilePath, $level);
$handler->setFormatter($formatter);
$logger->pushHandler($handler);

return $logger;
};
Expand Down
16 changes: 5 additions & 11 deletions app/ServiceProviders/Whoops.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,17 @@
namespace App\ServiceProviders;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Run;
use NunoMaduro\Collision\Provider as Collision;

class Whoops implements ProviderInterface
{

public static function register()
{
if (app()->console && class_exists(Collision::class)) {
(new Collision)->register();
}
elseif (class_exists(Run::class)) {
$whoops = new Run;
$whoops->allowQuit(false);
$handler = new PrettyPageHandler;
$whoops->pushHandler($handler);
$whoops->register();
}
$whoops = new Run;
$whoops->allowQuit(false);
$handler = new PrettyPageHandler;
$whoops->pushHandler($handler);
$whoops->register();
}

}
17 changes: 9 additions & 8 deletions bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,37 @@
define('STORAGE_PATH', realpath(__DIR__.'/storage/').DS);
define('RESOURCES_PATH', realpath(__DIR__.'/resources/').DS);
define('PUBLIC_PATH', realpath(__DIR__.'/public/').DS);
define('LIB_PATH', realpath(__DIR__.'/lib/').DS);

require ROOT_PATH.'vendor'.DS.'autoload.php';

$console = PHP_SAPI == 'cli' ? true : false;
$appName = php_sapi_name() == 'cli' ? 'console' : 'http';

$settings = require CONFIG_PATH.'app.php';
$settingsEnv = require CONFIG_PATH.($settings['settings']['env']).'.php';
$settings = array_merge_recursive($settings, $settingsEnv);

if ($console) {
if ($appName == 'console') {

set_time_limit(0);
$argv = $GLOBALS['argv'];
array_shift($argv);

// Convert $argv to PATH_INFO and mock console environment
// Convert $argv to PATH_INFO and mock console environment
$settings['environment'] = \Slim\Http\Environment::mock([
'SCRIPT_NAME' => $_SERVER['SCRIPT_NAME'],
'REQUEST_URI' => count($argv) >= 2 ? "/{$argv[0]}/{$argv[1]}" : "/help"
]);
'SCRIPT_NAME' => $_SERVER['SCRIPT_NAME'],
'REQUEST_URI' => count($argv) >= 2 ? "/{$argv[0]}/{$argv[1]}" : "/help"
]);
}

// instance app
$app = app($settings, $console);
$app = app($appName, $settings);
// Set up dependencies
$app->registerProviders();
// Register middleware
$app->registerMiddleware();

if ($console) {
if ($appName == 'console') {
// include your routes for cli requests here
require CONFIG_PATH.'routes'.DS.'console.php';
}
Expand Down
29 changes: 16 additions & 13 deletions config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
'settings' => [
'env' => \Lib\Framework\App::DEVELOPMENT,
'addContentLengthHeader' => false,
// default timezone
// default timezone & locale
'timezone' => 'Europe/Lisbon',
'locale' => 'pt_PT',
// Only set this if you need access to route within middleware
'determineRouteBeforeAppMiddleware' => false,
// log file path
'appLogFilePath' => STORAGE_PATH."logs".DS."app_".date('Ymd').".log",
'log' => [
// log file path
'file' => STORAGE_PATH."logs".DS."app_".date('Ymd').".log",
],
// template folders
'templates' => [
'error' => RESOURCES_PATH."views".DS."http".DS."error",
Expand Down Expand Up @@ -64,21 +68,20 @@
],
],
// add your service providers here
// providers bellow are ALWAYS added
'providers' => [
App\ServiceProviders\Whoops::class,
App\ServiceProviders\Monolog::class,
App\ServiceProviders\Plates::class,
App\ServiceProviders\Twig::class,
App\ServiceProviders\Eloquent::class,
App\ServiceProviders\FileSystem::class,
App\ServiceProviders\Mailer::class,
App\ServiceProviders\Cache::class,
App\ServiceProviders\Monolog::class => 'http,console',
App\ServiceProviders\Whoops::class => 'http',
App\ServiceProviders\Collision::class => 'console',
App\ServiceProviders\Plates::class => 'http',
App\ServiceProviders\Twig::class => 'http',
App\ServiceProviders\Eloquent::class => 'http,console',
App\ServiceProviders\FileSystem::class => 'http,console',
App\ServiceProviders\Mailer::class => 'http,console',
App\ServiceProviders\Cache::class => 'http,console',
],
// add your middleware here
// middleware bellow are called for every route
'middleware' => [
App\Middleware\Session::class,
App\Middleware\Session::class => 'http',
],

];
51 changes: 35 additions & 16 deletions lib/Framework/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

class App
{
public $console = false;

public $appName;

const DEVELOPMENT = 'development';
const STAGING = 'staging';
Expand All @@ -24,19 +25,20 @@ class App


/**
* @param string $appName
* @param array $settings
* @param boolean $console
*/
protected function __construct($settings = [], $console = false)
protected function __construct($appName = '', $settings = [])
{
$this->appName = $appName;
$this->settings = $settings;
$this->console = $console;
$this->slim = new \Slim\App($settings);
$this->env = $settings['settings']['env'];
$container = $this->getContainer();
$displayErrorDetails = $settings['settings']['debug'];

date_default_timezone_set($settings['settings']['timezone']);
\Locale::setDefault($settings['settings']['locale']);

set_error_handler(function($errno, $errstr, $errfile, $errline) {
if (!($errno & error_reporting())) {
Expand All @@ -62,20 +64,31 @@ protected function __construct($settings = [], $console = false)
/**
* Application Singleton Factory
*
* @param string $appName
* @param array $settings
* @param boolean $console
* @return static
*/
final public static function instance($settings = [], $console = false)
final public static function instance($appName = '', $settings = [])
{
if (null === static::$instance) {
static::$instance = new static($settings, $console);
static::$instance = new static($appName, $settings);
}

return static::$instance;
}


/**
* get if running application is console
*
* @return boolean
*/
public function isConsole()
{
return php_sapi_name() == 'cli';
}


/**
* set configuration param
*
Expand Down Expand Up @@ -118,10 +131,13 @@ public function getConfig($param, $defaultValue = null)
*/
public function registerProviders()
{
foreach ($this->getConfig('providers') as $provider) {
/** @var $provider \App\ServiceProviders\ProviderInterface */
$provider::register();
}
$providers = (array)$this->getConfig('providers');
array_walk($providers, function(&$appName, $provider) {
if (strpos($appName, $this->appName) !== false) {
/** @var $provider \App\ServiceProviders\ProviderInterface */
$provider::register();
}
});
}

/**
Expand All @@ -131,9 +147,12 @@ public function registerProviders()
*/
public function registerMiddleware()
{
foreach (array_reverse($this->getConfig('middleware')) as $middleware) {
$this->slim->add(new $middleware);
}
$middlewares = array_reverse((array)$this->getConfig('middleware'));
array_walk($middlewares, function($appName, $middleware) {
if (strpos($appName, $this->appName) !== false) {
$this->slim->add(new $middleware);
}
});
}


Expand Down Expand Up @@ -345,7 +364,7 @@ public function notFound()
*/
function error($msg, $code = 500)
{
if ($this->console) {
if ($this->isConsole()) {
return $this->resolve('response')
->withStatus($code)
->withHeader('Content-type', 'text/plain')
Expand All @@ -360,7 +379,7 @@ function error($msg, $code = 500)
return $this->resolve('response')
->withHeader('Content-Type', 'application/json')
->withStatus($code)
->write(json_encode($msg));
->withJson($msg);
}

$resp = $this->resolve(\League\Plates\Engine::class)->render('error::500', ['code' => $code, 'message' => $msg]);
Expand Down
1 change: 1 addition & 0 deletions lib/Utils/DotNotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ public function getValues()

/**
* @param string $path
* @return mixed
*/
protected function explode($path)
{
Expand Down
Loading

0 comments on commit 61b0da9

Please sign in to comment.