/** * 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; }