/** * @param string $type * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription * * @return array */ public function getDefaultOptions($type, FieldDescriptionInterface $fieldDescription) { $options = array('sonata_field_description' => $fieldDescription); if ($type == 'sonata_type_model' || $type == 'sonata_type_model_list') { if ($fieldDescription->getOption('edit') == 'list') { throw new \LogicException('The ``sonata_type_model`` type does not accept an ``edit`` option anymore, please review the UPGRADE-2.1.md file from the SonataAdminBundle'); } $options['class'] = $fieldDescription->getTargetEntity(); $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); } elseif ($type == 'sonata_type_admin') { if (!$fieldDescription->getAssociationAdmin()) { throw new \RuntimeException(sprintf('The current field `%s` is not linked to an admin. Please create one for the target entity : `%s`', $fieldDescription->getName(), $fieldDescription->getTargetEntity())); } $options['data_class'] = $fieldDescription->getAssociationAdmin()->getClass(); $fieldDescription->setOption('edit', $fieldDescription->getOption('edit', 'admin')); } elseif ($type == 'sonata_type_collection') { if (!$fieldDescription->getAssociationAdmin()) { throw new \RuntimeException(sprintf('The current field `%s` is not linked to an admin. Please create one for the target entity : `%s`', $fieldDescription->getName(), $fieldDescription->getTargetEntity())); } $options['type'] = 'sonata_type_admin'; $options['modifiable'] = true; $options['type_options'] = array('sonata_field_description' => $fieldDescription, 'data_class' => $fieldDescription->getAssociationAdmin()->getClass()); } return $options; }
/** * {@inheritdoc} */ public function getDefaultOptions($type, FieldDescriptionInterface $fieldDescription) { $options = array(); $options['sonata_field_description'] = $fieldDescription; if ($type == 'sonata_type_model' || $type == 'sonata_type_model_list' || $type == 'sonata_type_model_hidden') { if ($fieldDescription->getOption('edit') == 'list') { throw new \LogicException('The ``sonata_type_model`` type does not accept an ``edit`` option anymore, please review the UPGRADE-2.1.md file from the SonataAdminBundle'); } $options['class'] = $fieldDescription->getTargetEntity(); $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); } elseif ($type == 'sonata_type_admin') { if (!$fieldDescription->getAssociationAdmin()) { throw new \RuntimeException(sprintf('The current field `%s` is not linked to an admin. Please create one for the target entity : `%s`', $fieldDescription->getName(), $fieldDescription->getTargetEntity())); } if (!in_array($fieldDescription->getMappingType(), array(ClassMetadataInfo::ONE_TO_ONE, ClassMetadataInfo::MANY_TO_ONE))) { throw new \RuntimeException(sprintf('You are trying to add `sonata_type_admin` field `%s` which is not One-To-One or Many-To-One. Maybe you want `sonata_model_list` instead?', $fieldDescription->getName())); } $options['data_class'] = $fieldDescription->getAssociationAdmin()->getClass(); $fieldDescription->setOption('edit', $fieldDescription->getOption('edit', 'admin')); } elseif ($type == 'sonata_type_collection') { if (!$fieldDescription->getAssociationAdmin()) { throw new \RuntimeException(sprintf('The current field `%s` is not linked to an admin. Please create one for the target entity : `%s`', $fieldDescription->getName(), $fieldDescription->getTargetEntity())); } $options['type'] = 'sonata_type_admin'; $options['modifiable'] = true; $options['type_options'] = array('sonata_field_description' => $fieldDescription, 'data_class' => $fieldDescription->getAssociationAdmin()->getClass()); } return $options; }
/** * @param $type * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription * @return array */ public function getDefaultOptions($type, FieldDescriptionInterface $fieldDescription) { $options = array(); $options['sonata_field_description'] = $fieldDescription; if ($type == 'doctrine_phpcr_type_tree_model') { $options['class'] = $fieldDescription->getTargetEntity(); $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); } if ($type == 'sonata_type_model') { $options['class'] = $fieldDescription->getTargetEntity(); $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); switch ($fieldDescription->getMappingType()) { case ClassMetadata::ONE_TO_MANY: case ClassMetadata::MANY_TO_MANY: $options['multiple'] = true; $options['parent'] = 'choice'; break; case ClassMetadata::MANY_TO_ONE: case ClassMetadata::ONE_TO_ONE: break; } if ($fieldDescription->getOption('edit') == 'list') { $options['parent'] = 'text'; if (!array_key_exists('required', $options)) { $options['required'] = false; } } } else { if ($type == 'sonata_type_admin') { // nothing here ... $options['edit'] = 'inline'; } else { if ($type == 'sonata_type_collection') { $options['type'] = 'sonata_type_admin'; $options['modifiable'] = true; $options['type_options'] = array('sonata_field_description' => $fieldDescription, 'data_class' => $fieldDescription->getAssociationAdmin()->getClass()); } } } return $options; }
/** * Return xEditable choices based on the field description choices options & catalogue options. * With the following choice options: * ['Status1' => 'Alias1', 'Status2' => 'Alias2'] * The method will return: * [['value' => 'Status1', 'text' => 'Alias1'], ['value' => 'Status2', 'text' => 'Alias2']]. * * @param FieldDescriptionInterface $fieldDescription * * @return array */ public function getXEditableChoices(FieldDescriptionInterface $fieldDescription) { $choices = $fieldDescription->getOption('choices', array()); $catalogue = $fieldDescription->getOption('catalogue'); $xEditableChoices = array(); if (!empty($choices)) { reset($choices); $first = current($choices); // the choices are already in the right format if (is_array($first) && array_key_exists('value', $first) && array_key_exists('text', $first)) { $xEditableChoices = $choices; } else { foreach ($choices as $value => $text) { $text = $catalogue ? $fieldDescription->getAdmin()->trans($text, array(), $catalogue) : $text; $xEditableChoices[] = array('value' => $value, 'text' => $text); } } } return $xEditableChoices; }
/** * @throws \RunTimeException * * @param mixed $element * @param FieldDescriptionInterface $fieldDescription * * @return mixed */ public function renderRelationElement($element, FieldDescriptionInterface $fieldDescription) { if (!is_object($element)) { return $element; } $propertyPath = $fieldDescription->getOption('associated_property'); if (null === $propertyPath) { // For BC kept associated_tostring option behavior $method = $fieldDescription->getOption('associated_tostring', '__toString'); if (!method_exists($element, $method)) { throw new \RuntimeException(sprintf('You must define an `associated_property` option or create a `%s::__toString` method to the field option %s from service %s is ', get_class($element), $fieldDescription->getName(), $fieldDescription->getAdmin()->getCode())); } return call_user_func(array($element, $method)); } return PropertyAccess::createPropertyAccessor()->getValue($element, $propertyPath); }
/** * @throws \RunTimeException * * @param mixed $element * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription * * @return mixed */ public function renderRelationElement($element, FieldDescriptionInterface $fieldDescription) { $method = $fieldDescription->getOption('associated_tostring', '__toString'); if (!is_object($element)) { return $element; } if (!method_exists($element, $method)) { throw new \RunTimeException(sprintf('You must define an `associated_tostring` option or create a `%s::__toString` method to the field option %s from service %s is ', get_class($element), $fieldDescription->getName(), $fieldDescription->getAdmin()->getCode())); } return call_user_func(array($element, $method)); }
/** * @throws \RunTimeException * * @param mixed $element * @param FieldDescriptionInterface $fieldDescription * * @return mixed */ public function renderRelationElement($element, FieldDescriptionInterface $fieldDescription) { if (!is_object($element)) { return $element; } $propertyPath = $fieldDescription->getOption('associated_property'); if (null === $propertyPath) { // For BC kept associated_tostring option behavior $method = $fieldDescription->getOption('associated_tostring'); if ($method) { @trigger_error('Option "associated_tostring" is deprecated since version 2.3. Use "associated_property" instead.', E_USER_DEPRECATED); } else { $method = '__toString'; } if (!method_exists($element, $method)) { throw new \RuntimeException(sprintf('You must define an `associated_property` option or create a `%s::__toString` method to the field option %s from service %s is ', get_class($element), $fieldDescription->getName(), $fieldDescription->getAdmin()->getCode())); } return call_user_func(array($element, $method)); } if (is_callable($propertyPath)) { return $propertyPath($element); } return $this->pool->getPropertyAccessor()->getValue($element, $propertyPath); }
/** * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription * @return array */ public function getChoices(FieldDescriptionInterface $fieldDescription) { $modelManager = $fieldDescription->getAdmin()->getModelManager(); $targets = $modelManager->getEntityManager() ->createQueryBuilder() ->select('t') ->from($fieldDescription->getTargetEntity(), 't') ->getQuery() ->execute(); $choices = array(); foreach ($targets as $target) { // todo : puts this into a configuration option and use reflection foreach (array('getTitle', 'getName', '__toString') as $getter) { if (method_exists($target, $getter)) { $choices[$modelManager->getNormalizedIdentifier($target)] = $target->$getter(); break; } } } return $choices; }
/** * render a field element from the FieldDescription * * * @throws InvalidArgumentException * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription * @param \Sumfony\Component\Form\FormView $formView * @param mixed $object * @param array $params * @return string */ public function renderFormElement(FieldDescriptionInterface $fieldDescription, FormView $formView, $object, $params = array()) { if (!$fieldDescription->getFieldName()) { return ''; } if (!$formView->offsetExists($fieldDescription->getFieldName())) { throw new \RuntimeException(sprintf('No child named %s', $fieldDescription->getFieldName())); } $children = $formView->offsetGet($fieldDescription->getFieldName()); if (in_array('hidden', $children->get('types'))) { return ''; } // find the correct edit parameter // edit : standard | inline // inline : natural | table $parentFieldDescription = $fieldDescription->getAdmin()->getParentFieldDescription(); if (!$parentFieldDescription) { $params['edit'] = $fieldDescription->getOption('edit', 'standard'); $params['inline'] = $fieldDescription->getOption('inline', 'natural'); $base_template = sprintf('SonataAdminBundle:CRUD:base_%s_edit_field.html.twig', 'standard'); } else { $params['edit'] = $parentFieldDescription->getOption('edit', 'standard'); $params['inline'] = $parentFieldDescription->getOption('inline', 'natural'); $base_template = sprintf('SonataAdminBundle:CRUD:base_%s_edit_field.html.twig', $params['edit']); } $template = $this->environment->loadTemplate($fieldDescription->getTemplate()); return $this->output($fieldDescription, $template->render(array_merge($params, array('admin' => $fieldDescription->getAdmin(), 'object' => $object, 'field_description' => $fieldDescription, 'value' => $this->getValueFromFieldDescription($object, $fieldDescription, $params), 'field_element' => $children, 'base_template' => $fieldDescription->getOption('base_template', $base_template))))); }
/** * {@inheritdoc} * * @throws \LogicException if a sonata_type_model field does not have a * target model configured. */ public function getDefaultOptions($type, FieldDescriptionInterface $fieldDescription) { $options = array(); $options['sonata_field_description'] = $fieldDescription; if ($type == 'doctrine_phpcr_odm_tree') { $options['class'] = $fieldDescription->getTargetEntity(); $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); } if ($type == 'sonata_type_model' || $type == 'sonata_type_model_list') { if (!$fieldDescription->getTargetEntity()) { throw new \LogicException(sprintf('The field "%s" in class "%s" does not have a target model defined. ' . 'Please specify the "targetDocument" attribute in the mapping for this class.', $fieldDescription->getName(), $fieldDescription->getAdmin()->getClass())); } $options['class'] = $fieldDescription->getTargetEntity(); $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); } elseif ($type == 'sonata_type_admin') { if (!$fieldDescription->getAssociationAdmin()) { throw $this->getAssociationAdminException($fieldDescription); } $options['data_class'] = $fieldDescription->getAssociationAdmin()->getClass(); $fieldDescription->setOption('edit', $fieldDescription->getOption('edit', 'admin')); } elseif ($type == 'sonata_type_collection') { if (!$fieldDescription->getAssociationAdmin()) { throw $this->getAssociationAdminException($fieldDescription); } $options['type'] = 'sonata_type_admin'; $options['modifiable'] = true; $options['type_options'] = array('sonata_field_description' => $fieldDescription, 'data_class' => $fieldDescription->getAssociationAdmin()->getClass()); } return $options; }
/** * Add a new field type into the provided FormBuilder * * @param \Symfony\Component\Form\FormBuilder $formBuilder * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription * @return void */ public function addField(FormBuilder $formBuilder, FieldDescriptionInterface $fieldDescription) { // There is a bug in the GraphWalker, so for now we always load related associations // for more information : https://github.com/symfony/symfony/pull/1056 if ($formBuilder->getData() && in_array($fieldDescription->getType(), array(ClassMetadataInfo::ONE_TO_MANY, ClassMetadataInfo::MANY_TO_MANY, ClassMetadataInfo::MANY_TO_ONE, ClassMetadataInfo::ONE_TO_ONE))) { $value = $fieldDescription->getValue($formBuilder->getData()); $infos = $fieldDescription->getAssociationMapping(); if ($value instanceof $infos['targetEntity'] && $value instanceof \Doctrine\ORM\Proxy\Proxy) { $relatedId = 'get' . current($fieldDescription->getAdmin()->getModelManager()->getIdentifierFieldNames($infos['targetEntity'])); $value->{$relatedId}(); // force to load the lazy loading method __load in the proxy methode } } switch ($fieldDescription->getType()) { case ClassMetadataInfo::ONE_TO_MANY: $this->getOneToManyField($formBuilder, $fieldDescription); break; case ClassMetadataInfo::MANY_TO_MANY: $this->defineManyToManyField($formBuilder, $fieldDescription); break; case ClassMetadataInfo::MANY_TO_ONE: case ClassMetadataInfo::ONE_TO_ONE: $this->defineOneToOneField($formBuilder, $fieldDescription); break; default: list($type, $default_options) = $this->getFormTypeName($fieldDescription); $formBuilder->add($fieldDescription->getFieldName(), $type, array_merge($default_options, $fieldDescription->getOption('form_field_options', array()))); } }
/** * @param $type * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription * @param array $options * @return array */ public function getDefaultOptions($type, FieldDescriptionInterface $fieldDescription) { $options = array(); $options['sonata_field_description'] = $fieldDescription; if ($type == 'sonata_type_model') { $options['class'] = $fieldDescription->getTargetEntity(); $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); switch ($fieldDescription->getMappingType()) { case ClassMetadataInfo::ONE_TO_MANY: case ClassMetadataInfo::MANY_TO_MANY: $options['multiple'] = true; $options['parent'] = 'choice'; break; case ClassMetadataInfo::MANY_TO_ONE: case ClassMetadataInfo::ONE_TO_ONE: break; } } else if ($type == 'sonata_type_admin') { // nothing here ... $options['edit'] = 'inline'; } else if ($type == 'sonata_type_collection') { $options['type'] = 'sonata_type_admin'; $options['modifiable'] = true; $options['type_options'] = array( 'sonata_field_description' => $fieldDescription, 'data_class' => $fieldDescription->getAssociationAdmin()->getClass() ); } return $options; }
/** * {@inheritdoc} * * @throws \LogicException if a sonata_type_model field does not have a * target model configured. */ public function getDefaultOptions($type, FieldDescriptionInterface $fieldDescription) { $options = array(); $options['sonata_field_description'] = $fieldDescription; switch ($type) { case 'Sonata\\DoctrinePHPCRAdminBundle\\Form\\Type\\TreeModelType': case 'doctrine_phpcr_odm_tree': $options['class'] = $fieldDescription->getTargetEntity(); $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); break; case 'Sonata\\AdminBundle\\Form\\Type\\Modeltype': case 'sonata_type_model': case 'Sonata\\AdminBundle\\Form\\Type\\ModelTypeList': case 'sonata_type_model_list': if (!$fieldDescription->getTargetEntity()) { throw new \LogicException(sprintf('The field "%s" in class "%s" does not have a target model defined. Please specify the "targetDocument" attribute in the mapping for this class.', $fieldDescription->getName(), $fieldDescription->getAdmin()->getClass())); } $options['class'] = $fieldDescription->getTargetEntity(); $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); break; case 'Sonata\\AdminBundle\\Form\\Type\\AdminType': case 'sonata_type_admin': if (!$fieldDescription->getAssociationAdmin()) { throw $this->getAssociationAdminException($fieldDescription); } $options['data_class'] = $fieldDescription->getAssociationAdmin()->getClass(); $fieldDescription->setOption('edit', $fieldDescription->getOption('edit', 'admin')); break; case 'Sonata\\AdminBundle\\Form\\Type\\CollectionType': case 'sonata_type_collection': if (!$fieldDescription->getAssociationAdmin()) { throw $this->getAssociationAdminException($fieldDescription); } $options['type'] = 'sonata_type_admin'; $options['modifiable'] = true; $options['type_options'] = array('sonata_field_description' => $fieldDescription, 'data_class' => $fieldDescription->getAssociationAdmin()->getClass()); break; } return $options; }