Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
33.33% |
1 / 3 |
|
38.89% |
7 / 18 |
CRAP | |
56.25% |
63 / 112 |
| Api | |
0.00% |
0 / 1 |
|
43.75% |
7 / 16 |
121.04 | |
63.00% |
63 / 100 |
| __construct( Router $router, DependencyResolverInterface $dependencyResolver, SerializerInterface $serializer, CryptographyInterface $encrypter = null, Loggable $logger = null) | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
| anonymous function($errno, $errstr, $errfile, $errline, array $errcontext) | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
| setControllerEnding($string) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| run() | |
0.00% |
0 / 1 |
5.15 | |
81.82% |
18 / 22 |
|||
| _getApplicationResponse($apiRequest) | |
0.00% |
0 / 1 |
2.09 | |
71.43% |
5 / 7 |
|||
| _getActionDependencies($controller, $action) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| _logError($e) | |
100.00% |
1 / 1 |
2 | |
100.00% |
2 / 2 |
|||
| _logDebug($message) | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 2 |
|||
| _getControllerName($controllerName) | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| _getTemplateControllerName($controllerName) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| _getFactory() | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| _injectAdditionalDependencies($controller) | |
0.00% |
0 / 1 |
2.86 | |
40.00% |
2 / 5 |
|||
| _getController($controllerName) | |
0.00% |
0 / 1 |
6.33 | |
47.37% |
9 / 19 |
|||
| setTemplateDependencyName($dependcyName) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| _getFullActionName($controller, $action) | |
0.00% |
0 / 1 |
7.91 | |
37.50% |
3 / 8 |
|||
| _callControllerAction($controller, $action, $args) | |
0.00% |
0 / 1 |
17.44 | |
52.94% |
9 / 17 |
|||
| DynamicResolutionException | |
100.00% |
1 / 1 |
0 | ||||||
| DynamicResolver | |
0.00% |
0 / 1 |
|
0.00% |
0 / 2 |
20 | |
0.00% |
0 / 12 |
| getControllerName() | |
0.00% |
0 / 1 |
12 | |
0.00% |
0 / 9 |
|||
| resolve($controller) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
| <?php | |
| /** | |
| * | |
| */ | |
| namespace aae\dispatch { | |
| use \aae\dispatch\Router as Router; | |
| use \aae\serialize\SerializerInterface as SerializerInterface; | |
| use \aae\encrypt\CryptographyInterface as CryptographyInterface; | |
| use \aae\log\Loggable as Loggable; | |
| use \aae\di\DependencyResolverInterface as DependencyResolverInterface; | |
| use \aae\ui\Markdown as Markdown; | |
| /** | |
| * @author Axel Ancona Esselmann | |
| * @package aae\dispatch | |
| * | |
| * Exposes all public methods on all classes as the API. | |
| */ | |
| class Api /*implements \aae\dispatch\ApiInterface */{ | |
| use \aae\log\LoggableTrait; | |
| protected $_controllerAppend = "", $_actionAppend = "", $_controller; | |
| private $_router, $_dependencyResolver, $_serializer = null, $_encrypter = null, $_response = null, $_templateDependencyName = null; | |
| public $headers = null; | |
| public function __construct( | |
| Router $router, | |
| DependencyResolverInterface $dependencyResolver, | |
| SerializerInterface $serializer, | |
| CryptographyInterface $encrypter = null, | |
| Loggable $logger = null) | |
| { | |
| $this->setLogger($logger); | |
| $this->_router = $router; | |
| $this->_dependencyResolver = $dependencyResolver; | |
| $this->_serializer = $serializer; | |
| $this->_encrypter = $encrypter; | |
| set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) { | |
| if (0 === error_reporting()) return false; | |
| throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); | |
| }); | |
| } | |
| public function setControllerEnding($string) { | |
| $this->_controllerAppend = $string; | |
| } | |
| public function run() { | |
| $apiCallResult = array('response' => false, 'errorCode' => 0); | |
| try { | |
| $apiRequest = $this->_router->getCall(); | |
| $response = $this->_getApplicationResponse($apiRequest); | |
| $apiCallResult['response'] = $response; | |
| $apiCallResult['errorCode'] = $this->_controller->getErrorCode(); | |
| } catch (\Exception $e) { | |
| $apiCallResult["errorCode"] = $e->getCode(); | |
| $apiCallResult["errorMessage"] = $e->getMessage(); | |
| $this->_logError($e); | |
| // TODO who provides the default error? also remove from applicaiton! | |
| try { | |
| $apiRequest = new \aae\api\APIRequest('\aae\ui\DefaultError', '', [$e->getMessage(), $e->getCode()]); | |
| $response = $this->_getApplicationResponse($apiRequest); | |
| } catch (\Exception $e) { | |
| $response = "View controller error ".$e->getCode()." with message: ".$e->getMessage(); | |
| } | |
| $apiCallResult['response'] = $response; | |
| } | |
| $response = $this->_serializer->serialize($apiCallResult); | |
| if ($this->_encrypter) { | |
| $response = $this->_encrypter->encrypt($response); | |
| } | |
| if (!is_null($this->headers)) { | |
| $this->headers->send(); | |
| } | |
| return $response; | |
| } | |
| protected function _getApplicationResponse($apiRequest) { | |
| $actionName = $apiRequest->getAction(); | |
| $controller = $this->_getController($apiRequest->getController()); | |
| $actionReturn = $this->_callControllerAction($controller, $actionName, $apiRequest->getArgs()); | |
| if ($actionReturn === NULL) { | |
| # The action did not explicitly return anything | |
| # TODO: this is going to be changed once controllers do not interact directly with templates any more | |
| $actionReturn = call_user_func(array($controller,"getView")); | |
| } | |
| return $actionReturn; | |
| } | |
| protected function _getActionDependencies($controller, $action) { | |
| $dependencyResolver = new \aae\di\ArgNameDependencyResolver($this->_router->getRequestArray()); | |
| return $dependencyResolver->resolveAllowNoMatch(get_class($controller), $action); | |
| } | |
| protected function _logError($e) { | |
| if ($this->_logger) $this->_logger->logError($e); | |
| } | |
| protected function _logDebug($message) { | |
| if ($this->_logger) $this->_logger->logDebug($message); | |
| } | |
| protected function _getControllerName($controllerName) { | |
| return $controllerName.$this->_controllerAppend; | |
| } | |
| protected function _getTemplateControllerName($controllerName) { | |
| return $controllerName."TemplateController"; | |
| } | |
| protected function _getFactory() { | |
| return new \aae\std\SimpleFactory($this->_dependencyResolver); | |
| } | |
| protected function _injectAdditionalDependencies($controller) { | |
| if (method_exists($controller, "dependencies")) { | |
| $dependencies = $this->_dependencyResolver->resolve(get_class($controller), "dependencies"); | |
| call_user_func_array(array($controller, "dependencies"), $dependencies); | |
| } | |
| } | |
| protected function _getController($controllerName) { | |
| $controllerFactory = $this->_getFactory(); | |
| $substituteDependencyNames = (is_null($this->_templateDependencyName)) ? [] : ["template" => $this->_templateDependencyName]; | |
| try { | |
| $controller = $controllerFactory->buildWithResolvedDependencies( | |
| $this->_getControllerName($controllerName), | |
| $substituteDependencyNames | |
| ); | |
| } catch (\aae\di\ClassNotDefinedException $e) { | |
| // TODO: Allow settings to disallow automatic template controller loading when no specific view controller is present | |
| try { | |
| $controller = $controllerFactory->buildWithResolvedDependencies( | |
| $this->_getTemplateControllerName($controllerName), | |
| $substituteDependencyNames | |
| ); | |
| } | |
| catch (\aae\di\ClassNotDefinedException $e){ | |
| $dynamicresolver = new DynamicResolver(); | |
| $dynamicControllerName = $dynamicresolver->getControllerName($controllerName); | |
| $controller = $controllerFactory->buildWithResolvedDependencies( | |
| $dynamicControllerName, | |
| $substituteDependencyNames | |
| ); | |
| $dynamicresolver->resolve($controller); | |
| } | |
| } | |
| $this->_injectAdditionalDependencies($controller); | |
| $this->_controller = $controller; | |
| return $controller; | |
| } | |
| public function setTemplateDependencyName($dependcyName) { | |
| $this->_templateDependencyName = $dependcyName; | |
| } | |
| protected function _getFullActionName($controller, $action) { | |
| $actionEndings = $controller->getActionEndings(); | |
| if (is_array($actionEndings)) { | |
| foreach ($actionEndings as $ending) { | |
| $fullActionName = $action.$ending; | |
| if (method_exists($controller, $fullActionName)) return $fullActionName; | |
| } | |
| throw new \Exception("The method ".get_class($controller)."->$fullActionName does not exist.", 214141546); | |
| } else { | |
| return $action.$actionEndings; | |
| } | |
| } | |
| protected function _callControllerAction($controller, $action, $args) { | |
| if (is_null($action) || strlen($action) < 1) $action = "default"; | |
| $fullActionName = $this->_getFullActionName($controller, $action); | |
| $actionArgs = $this->_getActionDependencies($controller, $fullActionName); | |
| # arguments in URI part have precedence over query string variables | |
| for ($i=0; $i < count($args); $i++) { | |
| if (!array_key_exists($i, $actionArgs) || | |
| (is_null($actionArgs[$i]) && !is_null($args[$i]))) | |
| { | |
| $actionArgs[$i] = $args[$i]; | |
| } | |
| } | |
| $controllerReturn = (count($actionArgs) > 0) | |
| ? call_user_func_array(array($controller, $action), $actionArgs) | |
| : call_user_func( array($controller, $action)); | |
| if (property_exists($controller, "headers")) { | |
| $this->headers = $controller->headers; | |
| } | |
| return $controllerReturn; | |
| } | |
| } | |
| class DynamicResolutionException extends \Exception {} | |
| class DynamicResolver { | |
| private $_directories = ["anconaesselmann/content", "anconaesselmann/content/projects"]; | |
| private $_extension = ".md"; | |
| private $_validDir = false; | |
| public function getControllerName() { | |
| $args = func_get_args(); | |
| $fileName = \aae\std\std::classFromNSClassName(strtolower($args[0])).$this->_extension; | |
| foreach ($this->_directories as $dir) { | |
| $fullDir = $_SERVER["DOCUMENT_ROOT"].DIRECTORY_SEPARATOR.$dir.DIRECTORY_SEPARATOR.$fileName; | |
| if (file_exists($fullDir)) { | |
| $this->_validDir = $fullDir; | |
| return "aae\ui\MarkdownViewController";; | |
| } | |
| } | |
| throw new DynamicResolutionException("Could not resolve dynamically", 627161632); | |
| } | |
| public function resolve($controller) { | |
| $controller->markdownFileName = $this->_validDir; | |
| $controller->markdownSettings = Markdown::ALLOW_HTML | Markdown::DISPLAY_ATTRIBUTION; | |
| return $controller; | |
| } | |
| } | |
| } |