*/ namespace oat\tao\model\routing; use oat\oatbox\service\ConfigurableService; use oat\tao\model\http\Controller; use ReflectionClass; use ReflectionMethod; class ControllerService extends ConfigurableService { const SERVICE_ID = 'tao/controllerService'; /** * @param $controllerClass * @param string $action * @throws RouterException */ private function checkAnnotations($controllerClass, $action = '') { /** @var RouteAnnotationService $routeAnnotationService */ $routeAnnotationService = $this->getServiceLocator()->get(RouteAnnotationService::SERVICE_ID); // extra layer of the security - to not launch action if denied if (!$routeAnnotationService->hasAccess($controllerClass, $action)) { $message = $action ? "Unable to run the action '" . $action . "' in '" . $controllerClass . "', blocked by route annotations." : "Class '$controllerClass' blocked by route annotation"; throw new RouterException($message); } } /** * @param $controllerClass * @throws RouterException */ private function checkAbstract($controllerClass) { try { $abstractClass = new ReflectionClass($controllerClass); } catch (\ReflectionException $e) { throw new RouterException($e->getMessage()); } if ($abstractClass->isAbstract()) { throw new RouterException('Attempt to run an action from the Abstract class "' . $controllerClass . '"'); } } /** * @param string $controllerClass * @return mixed * @throws RouterException */ public function checkController($controllerClass) { // abstract class can't be loaded $this->checkAbstract($controllerClass); // check if blocked by annotations $this->checkAnnotations($controllerClass); return $controllerClass; } /** * @param $class * @param $action * @throws RouterException */ private function checkPublic($class, $action) { try { // protected method $reflection = new ReflectionMethod($class, $action); if (!$reflection->isPublic()) { throw new RouterException('The method "' . $action . '" is not public in the class "' . $class . '"'); } } catch (\ReflectionException $e) { throw new RouterException($e->getMessage()); } } /** * @param string $controllerClass * @param string $action * @throws RouterException * @return string */ public function getAction($controllerClass = '', $action = '') { // method needs to be public $this->checkPublic($controllerClass, $action); // check if blocked by annotations $this->checkAnnotations($controllerClass, $action); return $action; } }