Ejemplo n.º 1
0
 /**
  * Render an action from a controller and render it's associated template
  * @param string $expr
  * @param array $attributes
  * @param array $options
  * @return string
  */
 public function renderAction($expr, $attributes, $options)
 {
     $application = Module::getApplication();
     //parse the name of the controller, action and template directory that should be used
     if (strpos($expr, '/') > 0) {
         $params = explode('/', $expr);
         $controllerName = $params[0];
         $actionName = $params[1];
         $templateDir = $controllerName . '/';
     } else {
         $params = explode(':', $expr);
         $moduleName = $params[0];
         $controllerName = $params[1];
         $actionName = $params[2];
         $actionName = lcfirst($actionName);
         $actionName = strtolower(preg_replace('/([A-Z])/', '-$1', $actionName));
         $templateDir = lcfirst($moduleName) . '-' . lcfirst($controllerName) . '/';
         $controllerName = $moduleName . '\\Controller\\' . $controllerName . 'Controller';
     }
     //instantiate the controller based on the given name
     $controller = $application->getLocator()->get($controllerName);
     //inject the locator
     if ($controller instanceof LocatorAware) {
         $controller->setLocator($application->getLocator());
     }
     //clone the MvcEvent and route and update them with the provided parameters
     $event = $application->getMvcEvent();
     $routeMatch = clone $event->getRouteMatch();
     $event = clone $event;
     foreach ($attributes as $key => $value) {
         $routeMatch->setParam($key, $value);
     }
     $event->setRouteMatch($routeMatch);
     //inject the new event into the controller
     if ($controller instanceof InjectApplicationEventInterface) {
         $controller->setEvent($event);
     }
     //test if the action exists in the controller and change it to not-found if missing
     $method = ActionController::getMethodFromAction($actionName);
     if (!method_exists($controller, $method)) {
         $method = 'notFoundAction';
         $actionName = 'not-found';
     }
     //call the method on the controller
     $response = $controller->{$method}();
     //if the result is an instance of the Response class return it
     if ($response instanceof Response) {
         return $response->getBody();
     }
     //if the response is an instance of ViewModel then render that one
     if ($response instanceof ModelInterface) {
         $viewModel = $response;
     } elseif (is_array($response) || $response instanceof \ArrayAccess || $response instanceof \Traversable) {
         $viewModel = new ViewModel($response);
         $viewModel->setTemplate($templateDir . $actionName);
     } else {
         return '';
     }
     $viewModel->terminate();
     $viewModel->setOption('has_parent', true);
     $view = $application->getLocator()->get('Zend\\View\\View');
     $output = $view->render($viewModel);
     return $output;
 }