/** * Formats the data of a response * * @param Request $request * @param Response $response * @param ControllerDefinition $controller * @param ActionDefinition $action * @param mixed $result * @param object $obj */ protected function prepareResponseData(Request $request, Response $response, ControllerDefinition $controller, ActionDefinition $action, $result, $obj = null) { $model = $action->getReturnModel(); if ($action->getReturnType() === ActionDefinition::RETURN_BUILDER) { $builderAction = $result; $builderData = array(); $forceInput = false; if (is_array($result)) { $builderAction = $result['action']; $builderController = isset($result['controller']) ? $result['controller'] : $controller; $builderData = isset($result['data']) ? $result['data'] : array(); $forceInput = isset($result['force_input']) ? $result['force_input'] : false; } $schema = array_merge($this->getLimitedActionSchema($builderAction), array('input' => $this->getActionInputSchema($builderController, $builderAction), 'output' => $this->getActionOutputSchema($builderController, $builderAction))); return array('controller' => $builderController->getName(), 'action' => $builderAction->getName(), 'schema' => $schema, 'data' => $builderData, 'force_input' => $forceInput); } if ($action->getReturnType() === ActionDefinition::RETURN_DYNAMIC) { $dynamicAction = $result; $data = null; if (is_array($result)) { list($dynamicAction, $data) = $result; } return array('schema' => $this->getActionOutputSchema($controller, $dynamicAction), 'data' => $this->prepareResponseData($request, $response, $controller, $dynamicAction, $data, $obj)); } if ($action->getReturnType() === ActionDefinition::RETURN_LIST) { $data = array(); if ($result !== null) { foreach ($result as $item) { $data[] = $model->convertObjectToArray($item); } } return $data; } if ($action->getReturnType() === ActionDefinition::RETURN_FILE) { $filename = $action->getName(); $content = $result; if (is_array($result)) { list($filename, $content) = $result; } $response->headers->set('Content-Type', 'application/octet-stream'); $response->headers->set('Content-Disposition', 'attachment; filename=' . $filename); $response->headers->set('Expires', '0'); $response->headers->set('Cache-Control', 'must-revalidate, post-check=0, pre-check=0'); $response->headers->set('Pragma', 'public'); $response->headers->set('Content-Length', strlen($content)); $response->setContent($content); return $response; } if ($action->getReturnType() === ActionDefinition::RETURN_NONE || $result === null) { return null; } if ($model && !is_array($result)) { return $model->convertObjectToArray($result); } return $result; }
/** * Creates an ActionDefinition from a class method * * @param ReflectionMethod $method * @param Annotation $annotation * @param array $additionalAnnotations * @return ActionDefinition */ protected function buildAction(ReflectionMethod $method, $annotation = null, array $additionalAnnotations = array()) { $action = new ActionDefinition(); $action->setName($method->getName()); if ($annotation) { // the annotation is not mandatory but is useful to set some action properties $action->setTitle($annotation->title ?: $method->getName())->setIcon($annotation->icon)->setDefault($annotation->default)->setLoadModel($annotation->load_model); if ($annotation->menu !== null) { $action->setMenu($annotation->menu); } if ($annotation->pipe) { $action->setFlow(ActionDefinition::FLOW_PIPE, $annotation->pipe); } if ($annotation->redirect) { $action->setFlow(ActionDefinition::FLOW_REDIRECT, $annotation->redirect); } if ($annotation->redirect_with_id) { $action->setFlow(ActionDefinition::FLOW_REDIRECT_WITH_ID, $annotation->redirect_with_id); } if ($annotation->redirect_with_data) { $action->setFlow(ActionDefinition::FLOW_REDIRECT_WITH_DATA, $annotation->redirect_with_data); } if ($annotation->delegate) { $action->setFlow(ActionDefinition::FLOW_DELEGATE, $annotation->delegate); } if ($annotation->on_model) { $action->applyToModel($annotation->on_model); } if ($annotation->confirm) { $action->addBehavior(new ConfirmBehavior(array('message' => $annotation->confirm))); } } // some annotations use arguments which could trigger the creation // of an input model if their not ignore $minNbOfParams = 0; $excludeParams = array(); // additional information provided by other annotations $yamlParser = $this->serviceContainer->get('yamlParser'); foreach ($additionalAnnotations as $anno) { if ($anno instanceof \Nucleus\IService\Security\Secure) { $perms = $yamlParser->parse($anno->permissions); $action->setPermissions($perms); } else { if ($anno instanceof \Nucleus\IService\Dashboard\Paginate) { $action->addBehavior(new PaginatedBehavior((array) $anno)); if ($anno->offset_param !== null) { $minNbOfParams++; $excludeParams[] = $anno->offset_param; } } else { if ($anno instanceof \Nucleus\IService\Dashboard\Orderable) { $action->addBehavior(new OrderableBehavior((array) $anno)); $minNbOfParams++; $excludeParams[] = $anno->param; if ($anno->order_param !== null) { $minNbOfParams++; $excludeParams[] = $anno->order_param; } } else { if ($anno instanceof \Nucleus\IService\Dashboard\Filterable) { $action->addBehavior(new FilterableBehavior((array) $anno)); $minNbOfParams++; $excludeParams[] = $anno->param; } else { if ($anno instanceof \Nucleus\IService\Dashboard\ActionBehavior) { $classname = $anno->class; $params = $yamlParser->parse($anno->params) ?: array(); $action->addBehavior(new $classname($params)); } } } } } } // input if (!$annotation || $annotation->in === null) { if ($method->getNumberOfParameters() > $minNbOfParams) { $action->setInputType(ActionDefinition::INPUT_FORM); } } else { $action->setInputType($annotation->in); } if ($action->getInputType() === ActionDefinition::INPUT_FORM || $method->getNumberOfParameters() > $minNbOfParams && $action->getInputType() != ActionDefinition::INPUT_DYNAMIC) { // builds the input model from the method's arguments $inputModel = $this->buildModelFromMethod($method, $additionalAnnotations, $excludeParams); if ($method->getNumberOfParameters() == $minNbOfParams + 1) { $fields = $inputModel->getFields(); if (count($fields) === 1 && $fields[0]->hasRelatedModel()) { $action->setModelOnlyArgument($fields[0]->getName()); $inputModel = $fields[0]->getRelatedModel(); } } $action->setInputModel($inputModel); } // tries to determine the return type if (!preg_match('/@return ([a-zA-Z\\\\]+)(\\[\\])?/', $method->getDocComment(), $returnTag)) { $returnTag = false; } if (!$annotation || !$action->isFlowing() && $annotation->out === null) { if ($returnTag) { $isArray = isset($returnTag[2]); $action->setReturnType($isArray ? ActionDefinition::RETURN_LIST : ActionDefinition::RETURN_OBJECT); } } else { if (!$action->isFlowing()) { $action->setReturnType($annotation->out); } } $modelTypes = array(ActionDefinition::RETURN_LIST, ActionDefinition::RETURN_OBJECT, ActionDefinition::RETURN_FORM); if (in_array($action->getReturnType(), $modelTypes) && (!$returnTag || $returnTag[1] !== 'array')) { if ((!$annotation || $annotation->model === null) && !$returnTag) { throw new DefinitionBuilderException("Action '{$action->getName()}' returns something but has no model attached"); } $action->setReturnModel($this->buildModel($annotation && $annotation->model ? $annotation->model : $returnTag[1])); } return $action; }
public function addAction(ActionDefinition $action) { $this->actions[] = $action; if ($action->getAppliedToModel() !== false) { $action->applyToModel($this->className); } return $this; }