Skip to content
This repository has been archived by the owner on Jul 31, 2022. It is now read-only.

Commit

Permalink
Several changes
Browse files Browse the repository at this point in the history
- refined composer.json
- fixed travis ci
- reorganized structure
- callabled instead of viewhelpers
- added view extension interface
- added and refiened unit tests
  • Loading branch information
tbreuss authored Oct 9, 2018
2 parents 9d343fa + 2187ca9 commit 4f19599
Show file tree
Hide file tree
Showing 18 changed files with 450 additions and 114 deletions.
26 changes: 18 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
{
"name": "tebe/pvc",
"description": "PVC - A minimal P[HP] [M]VC framework",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Thomas Breuss",
"email": "[email protected]"
}
],
"require": {
"php": ">=7.2.0",
"php": ">=7.2",
"ext-json": "*",
"psr/http-message": "^1.0",
"psr/http-server-middleware": "^1.0",
"tebe/http-factory": "@dev"
},
"require-dev": {
"zendframework/zend-diactoros": "^1.8",
"phpunit/phpunit": "^6.4",
"squizlabs/php_codesniffer": "^3.1"
"phpmd/phpmd": "^2.6",
"phpunit/phpunit": "^6.5",
"squizlabs/php_codesniffer": "^3.3",
"zendframework/zend-diactoros": "^1.8"
},
"autoload": {
"psr-4": {
Expand All @@ -21,10 +29,12 @@
},
"scripts": {
"test": [
"@phpunit",
"@phpcs"
"@phpcs",
"@phpunit"
],
"phpunit": "./vendor/bin/phpunit",
"phpcs": "./vendor/bin/phpcs"
"phpcbf": "./vendor/bin/phpcbf",
"phpcs": "./vendor/bin/phpcs",
"phpmd": "./vendor/bin/phpmd ./src text codesize,design,naming,unusedcode",
"phpunit": "./vendor/bin/phpunit"
}
}
38 changes: 36 additions & 2 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Tebe\Pvc\Event\EventDispatcher;
use Tebe\Pvc\Event\EventHandler;
use Tebe\Pvc\Helper\UrlHelper;
use Tebe\Pvc\Middleware\MiddlewarePipe;
use Tebe\Pvc\Middleware\RequestHandler;
use Tebe\Pvc\View\ViewExtension;
use Tebe\Pvc\View\ViewHelpers;
use Tebe\Pvc\View\View;

class Application
{
Expand All @@ -32,6 +38,11 @@ class Application
*/
private $view;

/**
* @var array
*/
private $viewExtensions;

/**
* @var MiddlewareInterface[]
*/
Expand Down Expand Up @@ -114,7 +125,20 @@ public function getView(): View
{
if (is_null($this->view)) {
$viewsPath = $this->config->get('viewsPath');
$view = new View($viewsPath);
$helpers = new ViewHelpers();
$view = new View($viewsPath, $helpers);

$view->registerHelper('escape', function (string $string) {
return htmlspecialchars($string);
});
$view->registerHelper('url', function ($args) {
return UrlHelper::to($args);
});

foreach ($this->viewExtensions as $viewExtension) {
$view->registerExtension($viewExtension);
}

$this->setView($view);
}
return $this->view;
Expand Down Expand Up @@ -170,7 +194,7 @@ public function addEventHandler(string $eventName, EventHandler $eventHandler):
}

/**
* Run
* @throws Exception\SystemException
*/
public function run(): void
{
Expand Down Expand Up @@ -219,4 +243,14 @@ private function getMiddlewarePipe(): MiddlewarePipe
$middlewarePipe = MiddlewarePipe::create($this->middlewares);
return $middlewarePipe;
}

/**
* @param ViewExtension[] $viewExtensions
* @return Application
*/
public function setViewExtensions(array $viewExtensions)
{
$this->viewExtensions = $viewExtensions;
return $this;
}
}
13 changes: 8 additions & 5 deletions src/Controller.php → src/Controller/BaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

declare(strict_types=1);

namespace Tebe\Pvc;
namespace Tebe\Pvc\Controller;

abstract class Controller
use Tebe\Pvc\Exception\SystemException;
use Tebe\Pvc\View\View;

abstract class BaseController
{
/**
* @var View
Expand All @@ -28,7 +31,7 @@ abstract class Controller
*/
public function __construct(View $view, string $pathInfo)
{
list ($controllerName, $actionName) = explode('/', $pathInfo);
[$controllerName, $actionName] = explode('/', $pathInfo);
$this->setView($view);
$this->setControllerName($controllerName);
$this->setActionName($actionName);
Expand All @@ -54,7 +57,7 @@ private function setView(View $view)
* @param string $viewName
* @param array $params
* @return string
* @throws Exception\SystemException
* @throws SystemException
*/
protected function render(string $viewName, array $params = []): string
{
Expand All @@ -68,7 +71,7 @@ protected function render(string $viewName, array $params = []): string
* @param string $viewName
* @param array $params
* @return string
* @throws Exception\SystemException
* @throws SystemException
*/
protected function renderPartial(string $viewName, array $params = []): string
{
Expand Down
24 changes: 20 additions & 4 deletions src/ErrorController.php → src/Controller/ErrorController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

declare(strict_types=1);

namespace Tebe\Pvc;
namespace Tebe\Pvc\Controller;

use Tebe\Pvc\Application;
use Tebe\Pvc\Exception\SystemException;
use Throwable;

class ErrorController extends Controller
class ErrorController extends BaseController
{
/**
* @var Throwable
Expand All @@ -23,10 +25,24 @@ public function setError(Throwable $error)

/**
* @return string
* @throws Exception\SystemException
* @throws SystemException
*/
public function errorAction(): string
public function errorAction()
{
$request = Application::instance()->getRequest();
$acceptHeaders = $request->getHeaderLine('Accept');

// json output
if (strpos($acceptHeaders, 'application/json') !== false) {
return [
'code' => $this->error->getCode(),
'file' => $this->error->getFile(),
'line' => $this->error->getLine(),
'message' => $this->error->getMessage(),
'trace' => $this->error->getTraceAsString(),
];
}

// user view file
$viewName = $this->getViewName($this->error->getCode());
if (!empty($viewName)) {
Expand Down
2 changes: 1 addition & 1 deletion src/Event.php → src/Event/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Tebe\Pvc;
namespace Tebe\Pvc\Event;

class Event
{
Expand Down
2 changes: 1 addition & 1 deletion src/EventDispatcher.php → src/Event/EventDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Tebe\Pvc;
namespace Tebe\Pvc\Event;

class EventDispatcher
{
Expand Down
2 changes: 1 addition & 1 deletion src/EventHandler.php → src/Event/EventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Tebe\Pvc;
namespace Tebe\Pvc\Event;

interface EventHandler
{
Expand Down
1 change: 1 addition & 0 deletions src/Exception/HttpException.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Tebe\Pvc\Exception;

use Exception;
use Psr\Http\Message\ResponseInterface;

class HttpException extends Exception
{
Expand Down
22 changes: 21 additions & 1 deletion src/Helper/UrlHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,39 @@

namespace Tebe\Pvc\Helper;

use InvalidArgumentException;

// @todo implement class properly

class UrlHelper
{
/**
* @param mixed $url
* @return string
* @throws InvalidArgumentException
*/
public static function to($url = ''): string
{
if (is_array($url)) {
return static::toRoute($url);
}
return $url;
if (is_string($url)) {
return $url;
}
throw new InvalidArgumentException('Only array or string allowed');
}

/**
* @param array $route
* @return string
* @throws InvalidArgumentException
*/
public static function toRoute(array $route): string
{
if (empty($route)) {
throw new InvalidArgumentException('The given route is empty');
}

$urlParts = [$_SERVER['SCRIPT_NAME']];

$r = trim(array_shift($route), '/');
Expand Down
42 changes: 25 additions & 17 deletions src/Middleware/RequestHandler.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php
<?php /** @noinspection PhpIncludeInspection */

declare(strict_types=1);

Expand All @@ -8,11 +8,11 @@
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Tebe\HttpFactory\HttpFactory;
use Tebe\Pvc\Controller;
use Tebe\Pvc\ErrorController;
use Tebe\Pvc\Controller\BaseController;
use Tebe\Pvc\Controller\ErrorController;
use Tebe\Pvc\Exception\HttpException;
use Tebe\Pvc\Exception\SystemException;
use Tebe\Pvc\View;
use Tebe\Pvc\View\View;

class RequestHandler implements RequestHandlerInterface
{
Expand Down Expand Up @@ -59,27 +59,35 @@ public function handle(ServerRequestInterface $request): ResponseInterface

try {
$controller = $this->resolveController($pathInfo);
$html = $this->executeAction($controller);
$mixed = $this->executeAction($controller);
} catch (\Throwable $t) {
// handle errors with built-in error controller
$controller = new ErrorController($this->view, 'error/error');
$controller->setError($t);
$html = $this->executeAction($controller);
$mixed = $this->executeAction($controller);
$response = $response->withStatus($t->getCode());
}

$response->getBody()->write($html);
if (is_array($mixed)) {
$response = $response->withHeader('Content-Type', 'application/json');
$response->getBody()->write(json_encode($mixed));
} elseif (is_string($mixed)) {
$response->getBody()->write($mixed);
} else {
throw new \Exception('Unsupported content type');
}

return $response;
}

/**
* @param string $pathInfo
* @return Controller
* @return BaseController
* @throws HttpException
*/
private function resolveController(string $pathInfo): Controller
private function resolveController(string $pathInfo): BaseController
{
list($controllerName) = explode('/', $pathInfo);
[$controllerName] = explode('/', $pathInfo);

$controllerPath = sprintf('%s/%sController.php', $this->controllersPath, ucfirst($controllerName));

Expand All @@ -95,12 +103,12 @@ private function resolveController(string $pathInfo): Controller
}

/**
* @param Controller $controller
* @return string
* @param BaseController $controller
* @return mixed
* @throws HttpException
* @throws SystemException
*/
private function executeAction(Controller $controller): string
private function executeAction(BaseController $controller)
{
$actionMethod = $controller->getActionMethod();

Expand Down Expand Up @@ -130,12 +138,12 @@ private function executeAction(Controller $controller): string
/**
* Get the HTTP GET vars which are requested by the method using method parameters (a kind of injecting the get
* vars into the action method name).
* @param Controller $controller
* @param BaseController $controller
* @param string $methodName
* @return array
* @throws \ReflectionException
*/
private function getHttpGetVars(Controller $controller, string $methodName): array
private function getHttpGetVars(BaseController $controller, string $methodName): array
{
$requestParams = [];
$reflectionMethod = new \ReflectionMethod($controller, $methodName);
Expand All @@ -152,11 +160,11 @@ private function getHttpGetVars(Controller $controller, string $methodName): arr
}

/**
* @param Controller $controller
* @param BaseController $controller
* @param string $httpMethod
* @return bool
*/
private function testForHttpMethod(Controller $controller, string $httpMethod)
private function testForHttpMethod(BaseController $controller, string $httpMethod)
{
$httpMethod = strtoupper($httpMethod);
if ($controller->getControllerName() == 'error') {
Expand Down
Loading

0 comments on commit 4f19599

Please sign in to comment.