injectableFactory = $injectableFactory; $this->classFinder = $classFinder; $this->metadata = $metadata; $this->controllersHash = (object) []; } public function process(string $controllerName, string $actionName, $params, $data, $request, $response = null) { $controller = $this->getController($controllerName); return $this->processRequest($controller, $controllerName, $actionName, $params, $data, $request, $response); } protected function getControllerClassName(string $name) : string { $className = $this->classFinder->find('Controllers', $name); if (!$className) { throw new NotFound("Controller '{$name}' does not exist."); } if (!class_exists($className)) { throw new NotFound("Class not found for controller '{$name}'."); } return $className; } protected function createController(string $name) : object { $className = $this->getControllerClassName($name); $controller = $this->injectableFactory->createWith($className, [ 'name' => $name, ]); return $controller; } protected function getController(string $name) : object { if (!property_exists($this->controllersHash, $name)) { $this->controllersHash->$name = $this->createController($name); } return $this->controllersHash->$name; } protected function processRequest( object $controller, string $controllerName, string $actionName, $params, $data, $request, $response = null ) { if ($data && stristr($request->getContentType(), 'application/json')) { $data = json_decode($data); } if ($actionName == 'index') { $actionName = $controller::$defaultAction ?? 'index'; } $requestMethod = $request->getMethod(); $actionNameUcfirst = ucfirst($actionName); $beforeMethodName = 'before' . $actionNameUcfirst; $actionMethodName = 'action' . $actionNameUcfirst; $afterMethodName = 'after' . $actionNameUcfirst; $fullActionMethodName = strtolower($requestMethod) . ucfirst($actionMethodName); if (method_exists($controller, $fullActionMethodName)) { $primaryActionMethodName = $fullActionMethodName; } else { $primaryActionMethodName = $actionMethodName; } if (!method_exists($controller, $primaryActionMethodName)) { throw new NotFound( "Action {$requestMethod} '{$actionName}' does not exist in controller '{$controllerName}'." ); } // TODO Remove in 6.0.0 if ($data instanceof \StdClass) { if ( $this->metadata->get( ['app', 'deprecatedControllerActions', $controllerName, $primaryActionMethodName]) ) { $data = get_object_vars($data); } } if (method_exists($controller, $beforeMethodName)) { $controller->$beforeMethodName($params, $data, $request, $response); } $result = $controller->$primaryActionMethodName($params, $data, $request, $response); if (method_exists($controller, $afterMethodName)) { $controller->$afterMethodName($params, $data, $request, $response); } if (is_array($result) || is_bool($result) || $result instanceof \StdClass) { return Json::encode($result); } return $result; } }