diff --git a/Admin/Admin.php b/Admin/Admin.php index 89a8b82576..59dd60c91b 100644 --- a/Admin/Admin.php +++ b/Admin/Admin.php @@ -983,6 +983,8 @@ public function getFormBuilder($object = null, $options = array()) $object = $this->getNewInstance(); } + $this->setSubject($object); + // add the custom inline validation option $metadata = $this->validator->getMetadataFactory()->getClassMetadata($this->class); $metadata->addConstraint(new \Sonata\AdminBundle\Validator\Constraints\InlineConstraint(array( @@ -990,13 +992,14 @@ public function getFormBuilder($object = null, $options = array()) 'method' => 'validate' ))); + $options['data'] = $object; + $options['data_class'] = $this->getClass(); + $formBuilder = $this->getFormContractor()->getFormBuilder( $this->getUniqid(), array_merge($this->formOptions, $options) ); - $formBuilder->setData($object); - $this->defineFormBuilder($formBuilder); return $formBuilder; @@ -1013,15 +1016,6 @@ public function defineFormBuilder(FormBuilder $formBuilder) $this->buildFormFieldDescriptions(); $this->configureFormFields($mapper); - - foreach ($this->getFormFieldDescriptions() as $fieldDescription) { - // do not add field already set in the configureFormField method - if ($mapper->has($fieldDescription->getFieldName())) { - continue; - } - - $mapper->add($fieldDescription); - } } /** diff --git a/Admin/AdminHelper.php b/Admin/AdminHelper.php index bc336c9898..505bb1d1ea 100644 --- a/Admin/AdminHelper.php +++ b/Admin/AdminHelper.php @@ -11,6 +11,8 @@ namespace Sonata\AdminBundle\Admin; use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormView; +use Sonata\AdminBundle\Util\FormViewIterator; use Sonata\AdminBundle\Util\FormBuilderIterator; class AdminHelper @@ -42,6 +44,23 @@ public function getChildFormBuilder(FormBuilder $formBuilder, $elementId) return null; } + /** + * @throws \RuntimeException + * @param \Symfony\Component\Form\FormView $formBuilder + * @param $elementId + * @return \Symfony\Component\Form\FormView + */ + public function getChildFormView(FormView $formView, $elementId) + { + foreach (new \RecursiveIteratorIterator(new FormViewIterator($formView), \RecursiveIteratorIterator::SELF_FIRST) as $name => $formView) { + if ($name == $elementId) { + return $formView; + } + } + + return null; + } + /** * @param string $code * @return \Sonata\AdminBundle\Admin\AdminInterface diff --git a/Admin/BaseFieldDescription.php b/Admin/BaseFieldDescription.php index 380b221ae3..bd4d3709fa 100644 --- a/Admin/BaseFieldDescription.php +++ b/Admin/BaseFieldDescription.php @@ -353,13 +353,14 @@ public function getValue($object) $getters[] = 'get'.$camelizedFieldName; $getters[] = 'is'.$camelizedFieldName; + foreach ($getters as $getter) { if (method_exists($object, $getter)) { return call_user_func(array($object, $getter)); } } - throw new NoValueException(); + throw new NoValueException(sprintf('Unable to retrieve the value of `%s`', $this->getName())); } /** diff --git a/Builder/FormContractorInterface.php b/Builder/FormContractorInterface.php index bd9464df57..345f00fee0 100644 --- a/Builder/FormContractorInterface.php +++ b/Builder/FormContractorInterface.php @@ -27,14 +27,6 @@ interface FormContractorInterface */ function __construct(FormFactoryInterface $formFactory); - /** - * @abstract - * @param \Symfony\Component\Form\FormBuilder $formBuilder - * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription - * @return void - */ - function addField(FormBuilder $formBuilder, FieldDescriptionInterface $fieldDescription); - /** * @abstract * @param \Sonata\AdminBundle\Admin\AdminInterface $admin diff --git a/Builder/ORM/FormContractor.php b/Builder/ORM/FormContractor.php index 0406cc71f0..20daa57119 100644 --- a/Builder/ORM/FormContractor.php +++ b/Builder/ORM/FormContractor.php @@ -30,31 +30,6 @@ class FormContractor implements FormContractorInterface { protected $fieldFactory; - protected $validator; - - /** - * built-in definition - * - * @var array - */ - protected $formTypes = array( - 'string' => array('text', array()), - 'text' => array('textarea', array()), - 'boolean' => array('checkbox', array()), - 'checkbox' => array('checkbox', array()), - 'integer' => array('integer', array()), - 'tinyint' => array('integer', array()), - 'smallint' => array('integer', array()), - 'mediumint' => array('integer', array()), - 'bigint' => array('integer', array()), - 'decimal' => array('number', array()), - 'datetime' => array('datetime', array()), - 'date' => array('date', array()), - 'choice' => array('choice', array()), - 'array' => array('collection', array()), - 'country' => array('country', array()), - ); - public function __construct(FormFactoryInterface $formFactory) { $this->formFactory = $formFactory; @@ -72,73 +47,44 @@ public function __construct(FormFactoryInterface $formFactory) */ protected function defineChildFormBuilder(FormBuilder $formBuilder, FieldDescriptionInterface $fieldDescription, $fieldName = null) { - $fieldName = $fieldName ?: $fieldDescription->getFieldName(); - - $associatedAdmin = $fieldDescription->getAssociationAdmin(); - - if (!$associatedAdmin) { - throw new \RuntimeException(sprintf('inline mode for field `%s` required an Admin definition', $fieldName)); - } - - // retrieve the related object - $childBuilder = $formBuilder->create($fieldName, 'sonata_type_admin', array( - 'field_description' => $fieldDescription - )); - - $formBuilder->add($childBuilder); - - $associatedAdmin->defineFormBuilder($childBuilder); - } - - - /** - * Returns the class associated to a FieldDescriptionInterface if any defined - * - * @throws RuntimeException - * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription - * @return bool|string - */ - public function getFormTypeName(FieldDescriptionInterface $fieldDescription) - { - $typeName = false; - - // the user redefined the mapping type, use the default built in definition - if (!$fieldDescription->getFieldMapping() || $fieldDescription->getType() != $fieldDescription->getMappingType()) { - $typeName = array_key_exists($fieldDescription->getType(), $this->formTypes) ? $this->formTypes[$fieldDescription->getType()] : false; - } else if ($fieldDescription->getOption('form_field_type', false)) { - $typeName = $fieldDescription->getOption('form_field_type', false); - } else if (array_key_exists($fieldDescription->getType(), $this->formTypes)) { - $typeName = $this->formTypes[$fieldDescription->getType()]; - } - - if (!$typeName) { - throw new \RuntimeException(sprintf('No known form type for field `%s` (`%s`) is implemented.', $fieldDescription->getFieldName(), $fieldDescription->getType())); - } - - return $typeName; +// $fieldName = $fieldName ?: $fieldDescription->getFieldName(); +// +// $associatedAdmin = $fieldDescription->getAssociationAdmin(); +// +// if (!$associatedAdmin) { +// throw new \RuntimeException(sprintf('inline mode for field `%s` required an Admin definition', $fieldName)); +// } +// +// // retrieve the related object +// $childBuilder = $formBuilder->create($fieldName, 'sonata_type_admin', array( +// 'field_description' => $fieldDescription +// )); +// +// $formBuilder->add($childBuilder); +// +// $associatedAdmin->defineFormBuilder($childBuilder); } /** * Returns an OneToOne associated field * - * @param \Symfony\Component\Form\FormBuilder $formBuilder * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription - * @return \Symfony\Component\Form\Type\FormTypeInterface + * @param string + * @return array(); */ - protected function defineOneToOneField(FormBuilder $formBuilder, FieldDescriptionInterface $fieldDescription) + protected function getOneToOneFieldOptions($type, FieldDescriptionInterface $fieldDescription) { + $options = array(); + if (!$fieldDescription->hasAssociationAdmin()) { - return; + return $options; } // tweak the widget depend on the edit mode if ($fieldDescription->getOption('edit') == 'inline') { - return $this->defineChildFormBuilder($formBuilder, $fieldDescription); + return $options; } - $type = 'sonata_type_model'; - - $options = $fieldDescription->getOption('form_field_options', array()); $options['class'] = $fieldDescription->getTargetEntity(); $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); @@ -146,7 +92,7 @@ protected function defineOneToOneField(FormBuilder $formBuilder, FieldDescriptio $options['parent'] = 'text'; } - $formBuilder->add($fieldDescription->getFieldName(), $type, $options); + return $options; } /** @@ -154,101 +100,53 @@ protected function defineOneToOneField(FormBuilder $formBuilder, FieldDescriptio * * @param \Symfony\Component\Form\FormBuilder $formBuilder * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription - * @return \Symfony\Component\Form\Type\FormTypeInterface + * @return array */ - protected function getOneToManyField(FormBuilder $formBuilder, FieldDescriptionInterface $fieldDescription) + protected function getOneToManyFieldOptions($type, FieldDescriptionInterface $fieldDescription) { + $options = array(); + if (!$fieldDescription->hasAssociationAdmin()) { - return; + return $options; } if ($fieldDescription->getOption('edit') == 'inline') { // create a collection type with the generated prototype - $options = $fieldDescription->getOption('form_field_options', array()); - $options['type'] = 'sonata_type_admin'; - $options['modifiable'] = true; + $options['type'] = 'sonata_type_admin'; + $options['modifiable'] = true; $options['type_options'] = array( - 'field_description' => $fieldDescription, + 'sonata_field_description' => $fieldDescription, + 'data_class' => $fieldDescription->getAssociationAdmin()->getClass() ); - $formBuilder->add($fieldDescription->getFieldName(), 'sonata_type_collection', $options); - - return; -// $value = $fieldDescription->getValue($formBuilder->getData()); -// -// // add new instances if the min number is not matched -// if ($fieldDescription->getOption('min', 0) > count($value)) { -// -// $diff = $fieldDescription->getOption('min', 0) - count($value); -// foreach (range(1, $diff) as $i) { -// $this->addNewInstance($formBuilder->getData(), $fieldDescription); -// } -// } - - // use custom one to expose the newfield method -// return new \Sonata\AdminBundle\Form\EditableCollectionField($prototype); + return $options; } - return $this->defineManyToManyField($formBuilder, $fieldDescription); + return $this->getManyToManyFieldOptions($type, $fieldDescription); } /** * @param \Symfony\Component\Form\FormBuilder $formBuilder - * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription - * @return \Symfony\Component\Form\Type\FormTypeInterface + * @param string + * @return array */ - protected function defineManyToManyField(FormBuilder $formBuilder, FieldDescriptionInterface $fieldDescription) + protected function getManyToManyFieldOptions($type, FieldDescriptionInterface $fieldDescription) { + $options = array(); + if (!$fieldDescription->hasAssociationAdmin()) { - return; + return array(); } - $type = $fieldDescription->getOption('form_field_type', 'sonata_type_model'); - $options = $fieldDescription->getOption('form_field_options', array()); - if ($type == 'sonata_type_model') { $options['class'] = $fieldDescription->getTargetEntity(); $options['multiple'] = true; - $options['field_description'] = $fieldDescription; $options['parent'] = 'choice'; $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager(); } - $formBuilder->add($fieldDescription->getName(), $type, $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) - { - 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())) - ); - } + return $options; } /** @@ -284,39 +182,9 @@ public function fixFieldDescription(AdminInterface $admin, FieldDescriptionInter $fieldDescription->setAdmin($admin); $fieldDescription->setOption('edit', $fieldDescription->getOption('edit', 'standard')); - // fix template value for doctrine association fields - if (!$fieldDescription->getTemplate()) { - $fieldDescription->setTemplate(sprintf('SonataAdminBundle:CRUD:edit_%s.html.twig', $fieldDescription->getType())); - - if ($fieldDescription->getType() == ClassMetadataInfo::ONE_TO_ONE) { - $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_orm_one_to_one.html.twig'); - } - - if ($fieldDescription->getType() == ClassMetadataInfo::MANY_TO_ONE) { - $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_orm_many_to_one.html.twig'); - } - - if ($fieldDescription->getType() == ClassMetadataInfo::MANY_TO_MANY) { - $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_orm_many_to_many.html.twig'); - } - - if ($fieldDescription->getType() == ClassMetadataInfo::ONE_TO_MANY) { - $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_orm_one_to_many.html.twig'); - } - } - - if (in_array($fieldDescription->getType(), array(ClassMetadataInfo::ONE_TO_MANY, ClassMetadataInfo::MANY_TO_MANY, ClassMetadataInfo::MANY_TO_ONE, ClassMetadataInfo::ONE_TO_ONE ))) { + if (in_array($fieldDescription->getMappingType(), array(ClassMetadataInfo::ONE_TO_MANY, ClassMetadataInfo::MANY_TO_MANY, ClassMetadataInfo::MANY_TO_ONE, ClassMetadataInfo::ONE_TO_ONE ))) { $admin->attachAdminClass($fieldDescription); } - - // set correct default value - if ($fieldDescription->getType() == 'datetime') { - $options = $fieldDescription->getOption('form_field_options', array()); - if (!isset($options['years'])) { - $options['years'] = range(1900, 2100); - } - $fieldDescription->setOption('form_field', $options); - } } public function getFormFactory() @@ -331,6 +199,42 @@ public function getFormFactory() */ public function getFormBuilder($name, array $options = array()) { - return $this->getFormFactory()->createNamedBuilder('form', $name, $options); + return $this->getFormFactory()->createNamedBuilder('form', $name, null, $options); + } + + public function getDefaultOptions($type, FieldDescriptionInterface $fieldDescription, array $options = array()) + { + $options['sonata_field_description'] = $fieldDescription; + + if (!is_string($type)) { + return $options; + } + + // only add default options to Admin Bundle widget ... + $types = array('sonata_type_model', 'sonata_type_admin', 'sonata_type_collection'); + + if (!in_array($type, $types)) { + return $options; + } + + $fieldOptions = array(); + + switch ($fieldDescription->getMappingType()) { + case ClassMetadataInfo::ONE_TO_MANY: + + $fieldOptions = $this->getOneToManyFieldOptions($type, $fieldDescription); + break; + + case ClassMetadataInfo::MANY_TO_MANY: + $fieldOptions = $this->getManyToManyFieldOptions($type, $fieldDescription); + break; + + case ClassMetadataInfo::MANY_TO_ONE: + case ClassMetadataInfo::ONE_TO_ONE: + $fieldOptions = $this->getOneToOneFieldOptions($type, $fieldDescription); + break; + } + + return array_merge($fieldOptions, $options); } } \ No newline at end of file diff --git a/Controller/HelperController.php b/Controller/HelperController.php index 1c42a349ce..14efa25272 100644 --- a/Controller/HelperController.php +++ b/Controller/HelperController.php @@ -68,10 +68,15 @@ public function retrieveFormFieldElementAction() $admin = $helper->getAdmin($code); $uniqid = $this->get('request')->query->get('uniqid'); - $subject = $admin->getModelManager()->findOne($admin->getClass(), $objectId); - if (!$subject) { - throw new NotFoundHttpException(sprintf('Unable to find the object id: %s, class: %s', $objectId, $admin->getClass())); + if ($objectId) { + $subject = $admin->getModelManager()->findOne($admin->getClass(), $objectId); + if (!$subject) { + throw new NotFoundHttpException(sprintf('Unable to find the object id: %s, class: %s', $objectId, $admin->getClass())); + } + } else { + $subject = $admin->getNewInstance(); } + if ($uniqid) { $admin->setUniqid($uniqid); } @@ -81,7 +86,7 @@ public function retrieveFormFieldElementAction() $form = $formBuilder->getForm(); $form->bindRequest($this->get('request')); - $childFormBuilder = $helper->getChildFormBuilder($formBuilder, $elementId); + $view = $helper->getChildFormView($form->createView(), $elementId); // render the widget // todo : fix this, the twig environment variable is not set inside the extension ... @@ -89,7 +94,7 @@ public function retrieveFormFieldElementAction() $extension = $twig->getExtension('form'); $extension->initRuntime($this->get('twig')); - return new Response($extension->renderWidget($childFormBuilder->getForm()->createView())); + return new Response($extension->renderWidget($view)); } public function getShortObjectDescriptionAction() diff --git a/DependencyInjection/Compiler/AddDependencyCallsPass.php b/DependencyInjection/AddDependencyCallsCompilerPass.php similarity index 97% rename from DependencyInjection/Compiler/AddDependencyCallsPass.php rename to DependencyInjection/AddDependencyCallsCompilerPass.php index de754c524b..8bacd6b678 100755 --- a/DependencyInjection/Compiler/AddDependencyCallsPass.php +++ b/DependencyInjection/AddDependencyCallsCompilerPass.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Sonata\AdminBundle\DependencyInjection\Compiler; +namespace Sonata\AdminBundle\DependencyInjection; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -23,7 +23,7 @@ * * @author Thomas Rabaix */ -class AddDependencyCallsPass implements CompilerPassInterface +class AddDependencyCallsCompilerPass implements CompilerPassInterface { /** * {@inheritDoc} diff --git a/DependencyInjection/AddFormExtensionCompilerPass.php b/DependencyInjection/AddFormExtensionCompilerPass.php new file mode 100644 index 0000000000..3017753394 --- /dev/null +++ b/DependencyInjection/AddFormExtensionCompilerPass.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\AdminBundle\DependencyInjection; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Add all dependencies to the Admin class, this avoid to write to many lines + * in the configuration files. + * + * @author Thomas Rabaix + */ +class AddFormExtensionCompilerPass implements CompilerPassInterface +{ + /** + * {@inheritDoc} + */ + public function process(ContainerBuilder $container) + { + $ignores = array('form', 'csrf'); + + foreach ($container->findTaggedServiceIds('form.type') as $id => $attributes) { + $name = isset($attributes[0]['alias']) ? $attributes[0]['alias'] : false; + + if (!$name || in_array($name, $ignores)) { + continue; + } + + $definition = new Definition('Sonata\AdminBundle\Form\Extension\Field\Type\FormTypeFieldExtension', array($name)); + $definition->addTag('form.type_extension', array('alias' => $name)); + + $container->setDefinition(sprintf('sonata.admin.form.extension.%s', $name), $definition); + } + + // append the extension + $typeExtensions = array(); + + foreach ($container->findTaggedServiceIds('form.type_extension') as $serviceId => $tag) { + $alias = isset($tag[0]['alias']) + ? $tag[0]['alias'] + : $serviceId; + + $typeExtensions[$alias][] = $serviceId; + } + + $container->getDefinition('form.extension')->replaceArgument(2, $typeExtensions); + } +} diff --git a/Form/EventListener/ResizeFormListener.php b/Form/EventListener/ResizeFormListener.php index aa1bc6dcc0..010427deff 100644 --- a/Form/EventListener/ResizeFormListener.php +++ b/Form/EventListener/ResizeFormListener.php @@ -46,18 +46,18 @@ class ResizeFormListener implements EventSubscriberInterface public function __construct(FormFactoryInterface $factory, $type, array $typeOptions = array(), $resizeOnBind = false) { - $this->factory = $factory; - $this->type = $type; + $this->factory = $factory; + $this->type = $type; $this->resizeOnBind = $resizeOnBind; - $this->typeOptions = $typeOptions; + $this->typeOptions = $typeOptions; } public static function getSubscribedEvents() { return array( - FormEvents::PRE_SET_DATA => 'preSetData', - FormEvents::PRE_BIND => 'preBind', - FormEvents::BIND_NORM_DATA => 'onBindNormData', + FormEvents::PRE_SET_DATA => 'preSetData', + FormEvents::PRE_BIND => 'preBind', + FormEvents::BIND_NORM_DATA => 'onBindNormData', ); } @@ -84,7 +84,8 @@ public function preSetData(DataEvent $event) $options = array_merge($this->typeOptions, array( 'property_path' => '['.$name.']', )); - $form->add($this->factory->createNamed($this->type, $name, null, $options)); + + $form->add($this->factory->createNamed($this->type, $name, $value, $options)); } } diff --git a/Form/Extension/Field/Type/FormTypeFieldExtension.php b/Form/Extension/Field/Type/FormTypeFieldExtension.php new file mode 100644 index 0000000000..b265be276b --- /dev/null +++ b/Form/Extension/Field/Type/FormTypeFieldExtension.php @@ -0,0 +1,137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\AdminBundle\Form\Extension\Field\Type; + +use Symfony\Component\Form\AbstractTypeExtension; +use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormView; + +use Sonata\AdminBundle\Admin\NoValueException; +use Sonata\AdminBundle\Admin\FieldDescriptionInterface; + +class FormTypeFieldExtension extends AbstractTypeExtension +{ + protected $type; + + /** + * @param srting $type + */ + public function __construct($type) + { + $this->type = $type; + } + + public function buildForm(FormBuilder $builder, array $options) + { + $sonataAdmin = array( + 'admin' => null, + 'object' => null, + 'value' => null, + 'edit' => 'standard', + 'inline' => 'natual', + 'field_description' => null, + ); + + if ($options['sonata_field_description'] instanceof FieldDescriptionInterface) { + $fieldDescription = $options['sonata_field_description']; + + $sonataAdmin['object'] = $fieldDescription->getAdmin()->getSubject(); + $sonataAdmin['value'] = $this->getValueFromFieldDescription($sonataAdmin['object'], $fieldDescription); + $sonataAdmin['admin'] = $fieldDescription->getAdmin(); + $sonataAdmin['field_description'] = $fieldDescription; + + $parentFieldDescription = $fieldDescription->getAdmin()->getParentFieldDescription(); + + if ($parentFieldDescription) { + $sonataAdmin['edit'] = $parentFieldDescription->getOption('edit', 'standard'); + $sonataAdmin['inline'] = $parentFieldDescription->getOption('inline', 'natural'); + } else { + $sonataAdmin['edit'] = $fieldDescription->getOption('edit', 'standard'); + $sonataAdmin['inline'] = $fieldDescription->getOption('inline', 'natural'); + } + } + + $builder->setAttribute('sonata_admin', $sonataAdmin); + } + + public function buildView(FormView $view, FormInterface $form) + { + $view->set('sonata_admin', $form->getAttribute('sonata_admin')); + } + + /** + * Returns the name of the type being extended + * + * @return string The name of the type being extended + */ + function getExtendedType() + { + return $this->type; + } + + /** + * Overrides the default options form the extended type. + * + * @param array $options + * + * @return array + */ + public function getDefaultOptions(array $options) + { + return array( + 'sonata_admin' => null, + 'sonata_object' => null, + 'sonata_value' => null, + 'sonata_field_description' => null, + ); + } + + /** + * Returns the allowed option values for each option (if any). + * + * @param array $options + * + * @return array The allowed option values + */ + public function getAllowedOptionValues(array $options) + { + return array(); + } + + /** + * return the value related to FieldDescription, if the associated object does no + * exists => a temporary one is created + * + * @param object $object + * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription + * @return mixed + */ + public function getValueFromFieldDescription($object, FieldDescriptionInterface $fieldDescription) + { + if (!$object) { + return null; + throw new \RunTimeException(sprintf('Object cannot be null - id: %s, field: %s ', $fieldDescription->getAdmin()->getCode(), $fieldDescription->getName())); + } + + $value = null; + try { + $value = $fieldDescription->getValue($object); + } catch (NoValueException $e) { + if ($fieldDescription->getAssociationAdmin()) { + $value = $fieldDescription->getAssociationAdmin()->getNewInstance(); + } + } + + return $value; + } +} \ No newline at end of file diff --git a/Form/FormMapper.php b/Form/FormMapper.php index 8a586ce763..16dc038844 100644 --- a/Form/FormMapper.php +++ b/Form/FormMapper.php @@ -34,86 +34,86 @@ public function __construct(FormContractorInterface $formContractor, FormBuilder $this->admin = $admin; } - /** - * The method add a new field to the provided FormBuilder, there are 4 ways to add new field : - * - * - if $name is a string with no related FieldDescription, then the form will use the FormFactory - * to instantiate a new Field - * - if $name is a FormDescription, the method uses information defined in the FormDescription to - * instantiate a new Field - * - if $name is a FormBuilder, then a FieldDescriptionInterface is created, the FormBuilder is added to - * the form - * - if $name is a string with a related FieldDescription, then the method uses information defined in the - * FormDescription to instantiate a new Field - * - * @throws \RuntimeException - * @param string $name - * @param array $fieldOptions - * @param array $fieldDescriptionOptions - * @return \Symfony\Component\Form\FieldInterface|void - */ - public function add($name, array $fieldOptions = array(), array $fieldDescriptionOptions = array()) - { - $fieldType = false; - if ($name instanceof FieldDescriptionInterface) { - - $fieldDescription = $name; - $fieldDescription->mergeOptions($fieldDescriptionOptions); - - } else if ($name instanceof FormBuilder) { - - $fieldType = $name; - - $fieldDescription = $this->admin->getModelManager()->getNewFieldDescriptionInstance( - $this->admin->getClass(), - $fieldType->getName(), - $fieldDescriptionOptions - ); - - $this->formContractor->fixFieldDescription($this->admin, $fieldDescription, $fieldDescriptionOptions); - - $this->admin->addFormFieldDescription($fieldType->getName(), $fieldDescription); - - } else if (is_string($name) && !$this->admin->hasFormFieldDescription($name)) { - - $fieldDescription = $this->admin->getModelManager()->getNewFieldDescriptionInstance( - $this->admin->getClass(), - $name, - $fieldDescriptionOptions - ); - - // set default configuration - $this->formContractor->fixFieldDescription($this->admin, $fieldDescription, $fieldDescriptionOptions); - - // add the FieldDescription - $this->admin->addFormFieldDescription($name, $fieldDescription); - - } else if (is_string($name) && $this->admin->hasFormFieldDescription($name)) { - $fieldDescription = $this->admin->getFormFieldDescription($name); - - // update configuration - $this->formContractor->fixFieldDescription($this->admin, $fieldDescription, $fieldDescriptionOptions); - - } else { - - throw new \RuntimeException('invalid state'); - } - - $fieldDescription->mergeOption('form_field_options', $fieldOptions); - - // nothing to build as a Field is provided - if ($fieldType) { - $this->formBuilder->add($fieldType); - } - - // add the field with the FormBuilder - $this->formContractor->addField( - $this->formBuilder, - $fieldDescription - ); - - return $this; - } +// /** +// * The method add a new field to the provided FormBuilder, there are 4 ways to add new field : +// * +// * - if $name is a string with no related FieldDescription, then the form will use the FormFactory +// * to instantiate a new Field +// * - if $name is a FormDescription, the method uses information defined in the FormDescription to +// * instantiate a new Field +// * - if $name is a FormBuilder, then a FieldDescriptionInterface is created, the FormBuilder is added to +// * the form +// * - if $name is a string with a related FieldDescription, then the method uses information defined in the +// * FormDescription to instantiate a new Field +// * +// * @throws \RuntimeException +// * @param string $name +// * @param array $fieldOptions +// * @param array $fieldDescriptionOptions +// * @return \Symfony\Component\Form\FieldInterface|void +// */ +// public function add($name, array $fieldOptions = array(), array $fieldDescriptionOptions = array()) +// { +// $fieldType = false; +// if ($name instanceof FieldDescriptionInterface) { +// +// $fieldDescription = $name; +// $fieldDescription->mergeOptions($fieldDescriptionOptions); +// +// } else if ($name instanceof FormBuilder) { +// +// $fieldType = $name; +// +// $fieldDescription = $this->admin->getModelManager()->getNewFieldDescriptionInstance( +// $this->admin->getClass(), +// $fieldType->getName(), +// $fieldDescriptionOptions +// ); +// +// $this->formContractor->fixFieldDescription($this->admin, $fieldDescription, $fieldDescriptionOptions); +// +// $this->admin->addFormFieldDescription($fieldType->getName(), $fieldDescription); +// +// } else if (is_string($name) && !$this->admin->hasFormFieldDescription($name)) { +// +// $fieldDescription = $this->admin->getModelManager()->getNewFieldDescriptionInstance( +// $this->admin->getClass(), +// $name, +// $fieldDescriptionOptions +// ); +// +// // set default configuration +// $this->formContractor->fixFieldDescription($this->admin, $fieldDescription, $fieldDescriptionOptions); +// +// // add the FieldDescription +// $this->admin->addFormFieldDescription($name, $fieldDescription); +// +// } else if (is_string($name) && $this->admin->hasFormFieldDescription($name)) { +// $fieldDescription = $this->admin->getFormFieldDescription($name); +// +// // update configuration +// $this->formContractor->fixFieldDescription($this->admin, $fieldDescription, $fieldDescriptionOptions); +// +// } else { +// +// throw new \RuntimeException('invalid state'); +// } +// +// $fieldDescription->mergeOption('form_field_options', $fieldOptions); +// +// // nothing to build as a Field is provided +// if ($fieldType) { +// $this->formBuilder->add($fieldType); +// } +// +// // add the field with the FormBuilder +// $this->formContractor->addField( +// $this->formBuilder, +// $fieldDescription +// ); +// +// return $this; +// } /** * @param string $name @@ -122,7 +122,7 @@ public function add($name, array $fieldOptions = array(), array $fieldDescriptio * @param array $fieldDescriptionOptions * @return \Symfony\Component\Form\FormInterface */ - public function addType($name, $type = null, array $options = array(), array $fieldDescriptionOptions = array()) + public function add($name, $type = null, array $options = array(), array $fieldDescriptionOptions = array()) { if (!isset($fieldDescriptionOptions['type']) && is_string($type)) { $fieldDescriptionOptions['type'] = $type; @@ -136,6 +136,8 @@ public function addType($name, $type = null, array $options = array(), array $fi $this->formContractor->fixFieldDescription($this->admin, $fieldDescription, $fieldDescriptionOptions); + $options = $this->formContractor->getDefaultOptions($type, $fieldDescription, $options); + $this->admin->addFormFieldDescription($name instanceof FormBuilder ? $name->getName() : $name, $fieldDescription); if ($name instanceof FormBuilder) { diff --git a/Form/Type/AdminType.php b/Form/Type/AdminType.php index 022cfd67cc..f5c4c48cf3 100644 --- a/Form/Type/AdminType.php +++ b/Form/Type/AdminType.php @@ -43,7 +43,6 @@ public function buildForm(FormBuilder $builder, array $options) public function getDefaultOptions(array $options) { return array( - 'field_description' => null, 'delete' => true, ); } @@ -54,11 +53,11 @@ public function getDefaultOptions(array $options) */ public function getFieldDescription(array $options) { - if (!$options['field_description']) { - throw new \RuntimeException('Please provide a valid `field_description` option'); + if (!isset($options['sonata_field_description'])) { + throw new \RuntimeException('Please provide a valid `sonata_field_description` option'); } - return $options['field_description']; + return $options['sonata_field_description']; } /** @@ -72,6 +71,6 @@ public function getAdmin(array $options) public function getName() { - return 'sonata_model_admin'; + return 'sonata_type_admin'; } } \ No newline at end of file diff --git a/Form/Type/CollectionType.php b/Form/Type/CollectionType.php index 8c36aa2df9..d8cd12e629 100644 --- a/Form/Type/CollectionType.php +++ b/Form/Type/CollectionType.php @@ -42,6 +42,6 @@ public function getDefaultOptions(array $options) public function getName() { - return 'sonata_admin_collection'; + return 'sonata_type_collection'; } } \ No newline at end of file diff --git a/Form/Type/ModelType.php b/Form/Type/ModelType.php index 9193a39450..7f1bccf20a 100644 --- a/Form/Type/ModelType.php +++ b/Form/Type/ModelType.php @@ -15,6 +15,8 @@ use Symfony\Component\Form\FormBuilder; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormView; use Sonata\AdminBundle\Form\EventListener\MergeCollectionListener; use Sonata\AdminBundle\Form\ChoiceList\ModelChoiceList; @@ -48,7 +50,6 @@ public function getDefaultOptions(array $options) 'choices' => null, 'parent' => 'choice', 'preferred_choices' => array(), - 'field_description' => false, ); $options = array_replace($defaultOptions, $options); @@ -73,6 +74,6 @@ public function getParent(array $options) public function getName() { - return 'sonata_model'; + return 'sonata_type_model'; } } \ No newline at end of file diff --git a/Model/ORM/ModelManager.php b/Model/ORM/ModelManager.php index f037855318..c5b537bac6 100644 --- a/Model/ORM/ModelManager.php +++ b/Model/ORM/ModelManager.php @@ -64,6 +64,10 @@ public function hasMetadata($class) */ public function getNewFieldDescriptionInstance($class, $name, array $options = array()) { + if (!is_string($name)) { + throw new \RunTimeException('The name argument must be a string'); + } + $metadata = $this->getMetadata($class); $fieldDescription = new FieldDescription; @@ -298,7 +302,7 @@ public function getDefaultSortValues($class) * @param object $instance * @return void */ - function modelTransform($class, $instance) + public function modelTransform($class, $instance) { return $instance; } @@ -308,7 +312,7 @@ function modelTransform($class, $instance) * @param array $array * @return object */ - function modelReverseTransform($class, array $array = array()) + public function modelReverseTransform($class, array $array = array()) { $instance = $this->getModelInstance($class); $metadata = $this->getMetadata($class); @@ -374,22 +378,22 @@ public function getModelCollectionInstance($class) return new \Doctrine\Common\Collections\ArrayCollection(); } - function collectionClear(&$collection) + public function collectionClear(&$collection) { return $collection->clear(); } - function collectionHasElement(&$collection, &$element) + public function collectionHasElement(&$collection, &$element) { return $collection->contains($element); } - function collectionAddElement(&$collection, &$element) + public function collectionAddElement(&$collection, &$element) { return $collection->add($element); } - function collectionRemoveElement(&$collection, &$element) + public function collectionRemoveElement(&$collection, &$element) { return $collection->removeElement($element); } diff --git a/Resources/views/CRUD/base_edit.html.twig b/Resources/views/CRUD/base_edit.html.twig index d762fabd3a..143c8a4df8 100644 --- a/Resources/views/CRUD/base_edit.html.twig +++ b/Resources/views/CRUD/base_edit.html.twig @@ -61,7 +61,10 @@ file that was distributed with this source code. {% for field_name in form_group.fields %} {% if admin.formfielddescriptions[field_name] is defined %} - {{ admin.formfielddescriptions[field_name]|render_form_element(form, object) }} + {#{{ admin.formfielddescriptions[field_name]|render_form_element(form, object) }}#} + + {{ form_row(form[field_name])}} + {% endif %} {% endfor %} diff --git a/Resources/views/CRUD/edit_bigint.html.twig b/Resources/views/CRUD/edit_bigint.html.twig deleted file mode 100644 index 5d4a6e83c3..0000000000 --- a/Resources/views/CRUD/edit_bigint.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{# - -This file is part of the Sonata package. - -(c) Thomas Rabaix - -For the full copyright and license information, please view the LICENSE -file that was distributed with this source code. - -#} - -{% extends 'SonataAdminBundle:CRUD:edit_integer.html.twig' %} \ No newline at end of file diff --git a/Resources/views/CRUD/edit_choice.html.twig b/Resources/views/CRUD/edit_choice.html.twig deleted file mode 100644 index 5df635a7a8..0000000000 --- a/Resources/views/CRUD/edit_choice.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{# - -This file is part of the Sonata package. - -(c) Thomas Rabaix - -For the full copyright and license information, please view the LICENSE -file that was distributed with this source code. - -#} - -{% extends base_template %} diff --git a/Resources/views/CRUD/edit_country.html.twig b/Resources/views/CRUD/edit_country.html.twig deleted file mode 100644 index cac78eb2ae..0000000000 --- a/Resources/views/CRUD/edit_country.html.twig +++ /dev/null @@ -1,13 +0,0 @@ -{# - -This file is part of the Sonata package. - -(c) Thomas Rabaix - -For the full copyright and license information, please view the LICENSE -file that was distributed with this source code. - -#} - -{% extends base_template %} - diff --git a/Resources/views/CRUD/edit_date.html.twig b/Resources/views/CRUD/edit_date.html.twig deleted file mode 100644 index 5df635a7a8..0000000000 --- a/Resources/views/CRUD/edit_date.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{# - -This file is part of the Sonata package. - -(c) Thomas Rabaix - -For the full copyright and license information, please view the LICENSE -file that was distributed with this source code. - -#} - -{% extends base_template %} diff --git a/Resources/views/CRUD/edit_datetime.html.twig b/Resources/views/CRUD/edit_datetime.html.twig deleted file mode 100644 index 5df635a7a8..0000000000 --- a/Resources/views/CRUD/edit_datetime.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{# - -This file is part of the Sonata package. - -(c) Thomas Rabaix - -For the full copyright and license information, please view the LICENSE -file that was distributed with this source code. - -#} - -{% extends base_template %} diff --git a/Resources/views/CRUD/edit_decimal.html.twig b/Resources/views/CRUD/edit_decimal.html.twig deleted file mode 100644 index 0604864210..0000000000 --- a/Resources/views/CRUD/edit_decimal.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -{# - -This file is part of the Sonata package. - -(c) Thomas Rabaix - -For the full copyright and license information, please view the LICENSE -file that was distributed with this source code. - -#} - -{% extends base_template %} - -{% block field %}{{ form_widget(field_element, {'attr': {'class' : 'title'}}) }}{% endblock %} diff --git a/Resources/views/CRUD/edit_orm_many_association_script.html.twig b/Resources/views/CRUD/edit_orm_many_association_script.html.twig index aff6052ea8..a0bfc2520f 100644 --- a/Resources/views/CRUD/edit_orm_many_association_script.html.twig +++ b/Resources/views/CRUD/edit_orm_many_association_script.html.twig @@ -26,13 +26,13 @@ This code manage the many-to-[one|many] association field popup - if the parent has an objectId defined then the related input get updated - if the parent has NO object then an ajax request is made to refresh the popup #} - var field_dialog_form_list_link_{{ field_element.vars.id }} = function(event) { - initialize_popup_{{ field_element.vars.id }}(); + var field_dialog_form_list_link_{{ form.vars.id }} = function(event) { + initialize_popup_{{ form.vars.id }}(); event.preventDefault(); event.stopPropagation(); - var element = jQuery(this).parents('#field_dialog_{{ field_element.vars.id }} td.sonata-ba-list-field'); + var element = jQuery(this).parents('#field_dialog_{{ form.vars.id }} td.sonata-ba-list-field'); // the user does does click on a row column if (element.length == 0) { @@ -41,31 +41,31 @@ This code manage the many-to-[one|many] association field popup type: 'GET', url: jQuery(this).attr('href'), success: function(html) { - field_dialog_{{ field_element.vars.id }}.html(html); + field_dialog_{{ form.vars.id }}.html(html); } }); return; } - jQuery('#{{ field_element.vars.id }}').val(element.attr('objectId')); - jQuery('#{{ field_element.vars.id }}').trigger('change'); + jQuery('#{{ form.vars.id }}').val(element.attr('objectId')); + jQuery('#{{ form.vars.id }}').trigger('change'); - field_dialog_{{ field_element.vars.id }}.dialog('close'); + field_dialog_{{ form.vars.id }}.dialog('close'); } // handle the add link - var field_dialog_form_list_{{ field_element.vars.id }} = function(event) { + var field_dialog_form_list_{{ form.vars.id }} = function(event) { - initialize_popup_{{ field_element.vars.id }}(); + initialize_popup_{{ form.vars.id }}(); event.preventDefault(); event.stopPropagation(); var a = jQuery(this); - field_dialog_{{ field_element.vars.id }}.html(''); + field_dialog_{{ form.vars.id }}.html(''); // retrieve the form element from the related admin generator jQuery.ajax({ @@ -73,12 +73,12 @@ This code manage the many-to-[one|many] association field popup success: function(html) { // populate the popup container - field_dialog_{{ field_element.vars.id }}.html(html); + field_dialog_{{ form.vars.id }}.html(html); // capture the submit event to make an ajax call, ie : POST data to the // related create admin - jQuery('a', field_dialog_{{ field_element.vars.id }}).live('click', field_dialog_form_list_link_{{ field_element.vars.id }}); - jQuery('form', field_dialog_{{ field_element.vars.id }}).live('submit', function(event) { + jQuery('a', field_dialog_{{ form.vars.id }}).live('click', field_dialog_form_list_link_{{ form.vars.id }}); + jQuery('form', field_dialog_{{ form.vars.id }}).live('submit', function(event) { event.preventDefault(); var form = jQuery(this); @@ -88,22 +88,22 @@ This code manage the many-to-[one|many] association field popup url: form.attr('action'), data: {_xml_http_request: true}, success: function(html) { - field_dialog_{{ field_element.vars.id }}.html(html); + field_dialog_{{ form.vars.id }}.html(html); } }); }); // open the dialog in modal mode - field_dialog_{{ field_element.vars.id }}.dialog({ + field_dialog_{{ form.vars.id }}.dialog({ height: 'auto', width: 980, modal: true, resizable: false, - title: '{{ field_description.associationadmin.label }}', + title: '{{ sonata_admin.field_description.associationadmin.label }}', close: function(event, ui) { // make sure we have a clean state - jQuery('a', field_dialog_{{ field_element.vars.id }}).die('click'); - jQuery('form', field_dialog_{{ field_element.vars.id }}).die('submit'); + jQuery('a', field_dialog_{{ form.vars.id }}).die('click'); + jQuery('form', field_dialog_{{ form.vars.id }}).die('submit'); } }); } @@ -111,44 +111,44 @@ This code manage the many-to-[one|many] association field popup }; // handle the add link - var field_dialog_form_add_{{ field_element.vars.id }} = function(event) { - initialize_popup_{{ field_element.vars.id }}(); + var field_dialog_form_add_{{ form.vars.id }} = function(event) { + initialize_popup_{{ form.vars.id }}(); event.preventDefault(); event.stopPropagation(); var a = jQuery(this); - field_dialog_{{ field_element.vars.id }}.html(''); + field_dialog_{{ form.vars.id }}.html(''); - Admin.log('[{{ field_element.vars.id }}|field_dialog_form_add] add link action'); + Admin.log('[{{ form.vars.id }}|field_dialog_form_add] add link action'); // retrieve the form element from the related admin generator jQuery.ajax({ url: a.attr('href'), success: function(html) { - Admin.log('[{{ field_element.vars.id }}|field_dialog_form_add] ajax success', field_dialog_{{ field_element.vars.id }}); + Admin.log('[{{ form.vars.id }}|field_dialog_form_add] ajax success', field_dialog_{{ form.vars.id }}); // populate the popup container - field_dialog_{{ field_element.vars.id }}.html(html); + field_dialog_{{ form.vars.id }}.html(html); // capture the submit event to make an ajax call, ie : POST data to the // related create admin - jQuery('a', field_dialog_{{ field_element.vars.id }}).live('click', field_dialog_form_action_{{ field_element.vars.id }}); - jQuery('form', field_dialog_{{ field_element.vars.id }}).live('submit', field_dialog_form_action_{{ field_element.vars.id }}); + jQuery('a', field_dialog_{{ form.vars.id }}).live('click', field_dialog_form_action_{{ form.vars.id }}); + jQuery('form', field_dialog_{{ form.vars.id }}).live('submit', field_dialog_form_action_{{ form.vars.id }}); // open the dialog in modal mode - field_dialog_{{ field_element.vars.id }}.dialog({ + field_dialog_{{ form.vars.id }}.dialog({ height: 'auto', width: 650, modal: true, resizable: false, - title: '{{ field_description.associationadmin.label }}', + title: '{{ sonata_admin.field_description.associationadmin.label }}', close: function(event, ui) { - Admin.log('[{{ field_element.vars.id }}|field_dialog_form_add] dialog closed - removing `live` events'); + Admin.log('[{{ form.vars.id }}|field_dialog_form_add] dialog closed - removing `live` events'); // make sure we have a clean state - jQuery('a', field_dialog_{{ field_element.vars.id }}).die('click'); - jQuery('form', field_dialog_{{ field_element.vars.id }}).die('submit'); + jQuery('a', field_dialog_{{ form.vars.id }}).die('click'); + jQuery('form', field_dialog_{{ form.vars.id }}).die('submit'); } }); } @@ -156,13 +156,13 @@ This code manage the many-to-[one|many] association field popup }; // handle the post data - var field_dialog_form_action_{{ field_element.vars.id }} = function(event) { + var field_dialog_form_action_{{ form.vars.id }} = function(event) { event.preventDefault(); event.stopPropagation(); - Admin.log('[{{ field_element.vars.id }}|field_dialog_form_action] action catch', this); - initialize_popup_{{ field_element.vars.id }}(); + Admin.log('[{{ form.vars.id }}|field_dialog_form_action] action catch', this); + initialize_popup_{{ form.vars.id }}(); var element = jQuery(this); @@ -178,7 +178,7 @@ This code manage the many-to-[one|many] association field popup } if (element.hasClass('sonata-ba-action')) { - Admin.log('[{{ field_element.vars.id }}|field_dialog_form_action] reserved action stop catch all events'); + Admin.log('[{{ form.vars.id }}|field_dialog_form_action] reserved action stop catch all events'); return; } @@ -188,7 +188,7 @@ This code manage the many-to-[one|many] association field popup var form = jQuery(this); - Admin.log('[{{ field_element.vars.id }}|field_dialog_form_action] execute ajax call'); + Admin.log('[{{ form.vars.id }}|field_dialog_form_action] execute ajax call'); // the ajax post jQuery(form).ajaxSubmit({ @@ -197,39 +197,39 @@ This code manage the many-to-[one|many] association field popup data: data, success: function(data) { - Admin.log('[{{ field_element.vars.id }}|field_dialog_form_action] ajax success'); + Admin.log('[{{ form.vars.id }}|field_dialog_form_action] ajax success'); if (typeof data == 'string') { - field_dialog_{{ field_element.vars.id }}.html(data); + field_dialog_{{ form.vars.id }}.html(data); return; }; // if the crud action return ok, then the element has been added // so the widget container must be refresh with the last option available if (data.result == 'ok') { - field_dialog_{{ field_element.vars.id }}.dialog('close'); + field_dialog_{{ form.vars.id }}.dialog('close'); - {% if field_description.options.edit == 'list' %} + {% if sonata_admin.field_description.options.edit == 'list' %} {# in this case we update the hidden input, and call the change event to retrieve the post information #} - jQuery('#{{ field_element.vars.id }}').val(data.objectId); - jQuery('#{{ field_element.vars.id }}').change(); + jQuery('#{{ form.vars.id }}').val(data.objectId); + jQuery('#{{ form.vars.id }}').change(); {% else %} // reload the form element - jQuery('#field_widget_{{ field_element.vars.id }}').closest('form').ajaxSubmit({ + jQuery('#field_widget_{{ form.vars.id }}').closest('form').ajaxSubmit({ url: '{{ url('sonata_admin_retrieve_form_element', { - 'elementId': field_element.vars.id, - 'objectId': admin.root.id(admin.root.subject), - 'uniqid': admin.root.uniqid, - 'code': admin.root.code + 'elementId': form.vars.id, + 'objectId': sonata_admin.admin.root.id(sonata_admin.admin.root.subject), + 'uniqid': sonata_admin.admin.root.uniqid, + 'code': sonata_admin.admin.root.code }) }}', data: {_xml_http_request: true }, type: 'POST', success: function(html) { - jQuery('#field_widget_{{ field_element.vars.id }}').html(html); + jQuery('#field_container_{{ form.vars.id }}').replaceWith(html); } }); @@ -239,29 +239,29 @@ This code manage the many-to-[one|many] association field popup } // otherwise, display form error - field_dialog_{{ field_element.vars.id }}.html(html); + field_dialog_{{ form.vars.id }}.html(html); - Admin.add_pretty_errors(field_dialog_{{ field_element.vars.id }}); + Admin.add_pretty_errors(field_dialog_{{ form.vars.id }}); // reattach the event - jQuery('form', field_dialog_{{ field_element.vars.id }}).submit(field_dialog_form_action_{{ field_element.vars.id }}); + jQuery('form', field_dialog_{{ form.vars.id }}).submit(field_dialog_form_action_{{ form.vars.id }}); } }); return false; } - var field_dialog_{{ field_element.vars.id }} = false; + var field_dialog_{{ form.vars.id }} = false; - function initialize_popup_{{ field_element.vars.id }}() { + function initialize_popup_{{ form.vars.id }}() { // initialize component - if (!field_dialog_{{ field_element.vars.id }}) { - field_dialog_{{ field_element.vars.id }} = jQuery("#field_dialog_{{ field_element.vars.id }}"); + if (!field_dialog_{{ form.vars.id }}) { + field_dialog_{{ form.vars.id }} = jQuery("#field_dialog_{{ form.vars.id }}"); // move the dialog as a child of the root element, nested form breaks html ... - jQuery(document).append(field_dialog_{{ field_element.vars.id }}); + jQuery(document).append(field_dialog_{{ form.vars.id }}); - Admin.log('[{{ field_element.vars.id }}|field_dialog] move dialog container as a document child'); + Admin.log('[{{ form.vars.id }}|field_dialog] move dialog container as a document child'); } } @@ -270,17 +270,17 @@ This code manage the many-to-[one|many] association field popup #} // this function initialize the popup // this can be only done this way has popup can be cascaded - function start_field_dialog_form_add_{{ field_element.vars.id }}(event) { + function start_field_dialog_form_add_{{ form.vars.id }}(event) { event.preventDefault(); // remove the html event a var a = jQuery(event.target).closest('a'); a.attr('onclick', ''); - initialize_popup_{{ field_element.vars.id }}(); + initialize_popup_{{ form.vars.id }}(); // add the jQuery event to the a element - a.click(field_dialog_form_add_{{ field_element.vars.id }}); + a.click(field_dialog_form_add_{{ form.vars.id }}); // trigger the event a.trigger('click'); @@ -288,26 +288,26 @@ This code manage the many-to-[one|many] association field popup return false; } - Admin.add_pretty_errors(field_dialog_{{ field_element.vars.id }}); + Admin.add_pretty_errors(field_dialog_{{ form.vars.id }}); - {% if field_description.options.edit == 'list' %} + {% if sonata_admin.field_description.options.edit == 'list' %} {# This code is used to defined the "list" popup #} // this function initialize the popup // this can be only done this way has popup can be cascaded - function start_field_dialog_form_list_{{ field_element.vars.id }}(event) { + function start_field_dialog_form_list_{{ form.vars.id }}(event) { event.preventDefault(); // remove the html event a var a = jQuery(event.target).closest('a'); a.attr('onclick', ''); - initialize_popup_{{ field_element.vars.id }}(); + initialize_popup_{{ form.vars.id }}(); // add the jQuery event to the a element - a.click(field_dialog_form_list_{{ field_element.vars.id }}); + a.click(field_dialog_form_list_{{ form.vars.id }}); // trigger the event a.trigger('click'); @@ -320,16 +320,16 @@ This code manage the many-to-[one|many] association field popup #} // update the - jQuery('#{{ field_element.vars.id }}').live('change', function(event) { + jQuery('#{{ form.vars.id }}').live('change', function(event) { jQuery.ajax({ type: 'GET', url: '{{ url('sonata_admin_short_object_information', { 'objectId': 'OBJECT_ID', - 'uniqid': field_description.associationadmin.uniqid, - 'code': field_description.associationadmin.code + 'uniqid': sonata_admin.field_description.associationadmin.uniqid, + 'code': sonata_admin.field_description.associationadmin.code })}}'.replace('OBJECT_ID', jQuery(this).val()), success: function(html) { - jQuery('#field_widget_{{ field_element.vars.id }}').html(html); + jQuery('#field_widget_{{ form.vars.id }}').html(html); } }); }); diff --git a/Resources/views/CRUD/edit_orm_many_to_many.html.twig b/Resources/views/CRUD/edit_orm_many_to_many.html.twig index 4935a982ce..eb74dd5e27 100644 --- a/Resources/views/CRUD/edit_orm_many_to_many.html.twig +++ b/Resources/views/CRUD/edit_orm_many_to_many.html.twig @@ -9,33 +9,29 @@ file that was distributed with this source code. #} -{% extends base_template %} - -{% block field %} - {% if field_description.associationadmin %} -
- - {{ form_widget(field_element) }} - - - - - {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} - - - - +{% if sonata_admin.field_description.associationadmin %} +
+ + {{ form_widget(form) }} + + + + + {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} + + + + +
- {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %} - {% endif %} -{% endblock %} \ No newline at end of file + {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %} +{% endif %} diff --git a/Resources/views/CRUD/edit_orm_many_to_one.html.twig b/Resources/views/CRUD/edit_orm_many_to_one.html.twig index b63c124a50..603524333e 100644 --- a/Resources/views/CRUD/edit_orm_many_to_one.html.twig +++ b/Resources/views/CRUD/edit_orm_many_to_one.html.twig @@ -9,72 +9,67 @@ file that was distributed with this source code. #} -{% extends base_template %} - -{% block field %} - - {% if not field_description.hasassociationadmin%} - {{ value|render_relation_element(field_description) }} - {% elseif field_description.options.edit == 'inline' %} - {% for nested_field_description in field_description.associationadmin.formfielddescriptions %} - {{ nested_field_description|render_form_element(field_element, value) }} - {% endfor %} - - {% else %} - -
- - {% if field_description.options.edit == 'list' %} - - {% if admin.id(value) %} - {% render 'SonataAdminBundle:Helper:getShortObjectDescription' with {}, { - 'query': { - 'code': field_description.associationadmin.code, - 'objectId': admin.id(value), - 'uniqid': field_description.associationadmin.uniqid - } - }%} - {% endif %} - - - {{ form_widget(field_element) }} - - {% else %} - - {{ form_widget(field_element) }} - - {% endif %} - - - - {% if field_description.options.edit == 'list' %} - - {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} - +{% if not sonata_admin.field_description.hasassociationadmin%} + {{ value|render_relation_element(sonata_admin.field_description) }} +{% elseif sonata_admin.field_description.options.edit == 'inline' %} + {% for field_description in sonata_admin.field_description.associationadmin.formfielddescriptions %} + {{ form_row(form.getChild(field_description.name))}} + {% endfor %} + +{% else %} + +
+ + {% if sonata_admin.field_description.options.edit == 'list' %} + + {% if admin.id(value) %} + {% render 'SonataAdminBundle:Helper:getShortObjectDescription' with {}, { + 'query': { + 'code': sonata_admin.field_description.associationadmin.code, + 'objectId': sonata_admin.admin.id(value), + 'uniqid': sonata_admin.field_description.associationadmin.uniqid + } + }%} {% endif %} + + + {{ form_widget(form) }} + + {% else %} + + {{ form_widget(form) }} + + {% endif %} + + - - {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} + {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} - + {% endif %} + + + {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} + + - +
- {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %} - {% endif %} -{% endblock %} \ No newline at end of file + {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %} +{% endif %} diff --git a/Resources/views/CRUD/edit_orm_one_association_script.html.twig b/Resources/views/CRUD/edit_orm_one_association_script.html.twig index 494cdf9345..99057389bf 100644 --- a/Resources/views/CRUD/edit_orm_one_association_script.html.twig +++ b/Resources/views/CRUD/edit_orm_one_association_script.html.twig @@ -23,7 +23,7 @@ This code manage the one-to-many association field popup // handle the add link - var field_add_{{ field_element.vars.id }} = function(event) { + var field_add_{{ form.vars.id }} = function(event) { event.preventDefault(); event.stopPropagation(); @@ -33,15 +33,15 @@ This code manage the one-to-many association field popup // the ajax post jQuery(form).ajaxSubmit({ url: '{{ url('sonata_admin_append_form_element', { - 'code': admin.root.code, - 'elementId': field_element.vars.id, - 'objectId': admin.root.subject.id, - 'uniqid': admin.root.uniqid + 'code': sonata_admin.admin.root.code, + 'elementId': form.vars.id, + 'objectId': sonata_admin.admin.root.subject.id, + 'uniqid': sonata_admin.admin.root.uniqid }) }}', type: "POST", data: { _xml_http_request: true }, success: function(html) { - jQuery('#sonata-ba-field-container-{{ field_element.vars.id }}') + jQuery('#sonata-ba-field-container-{{ form.vars.id }}') .replaceWith(html) // replace the html .trigger('sonata.add_element'); } @@ -50,11 +50,11 @@ This code manage the one-to-many association field popup return false; }; - var field_widget_{{ field_element.vars.id }} = false; + var field_widget_{{ form.vars.id }} = false; // this function initialize the popup // this can be only done this way has popup can be cascaded - function start_field_retrieve_{{ field_element.vars.id }}(event) { + function start_field_retrieve_{{ form.vars.id }}(event) { event.preventDefault(); // remove the html event a @@ -62,10 +62,10 @@ This code manage the one-to-many association field popup a.attr('onclick', ''); // initialize component - field_widget_{{ field_element.vars.id }} = jQuery("#field_widget_{{ field_element.vars.id }}"); + field_widget_{{ form.vars.id }} = jQuery("#field_widget_{{ form.vars.id }}"); // add the jQuery event to the a element - a.click(field_add_{{ field_element.vars.id }}); + a.click(field_add_{{ form.vars.id }}); // trigger the event a.trigger('click'); @@ -77,5 +77,4 @@ This code manage the one-to-many association field popup - {% endautoescape %} \ No newline at end of file diff --git a/Resources/views/CRUD/edit_orm_one_to_many.html.twig b/Resources/views/CRUD/edit_orm_one_to_many.html.twig index 8a34d3759f..31a1ea2701 100644 --- a/Resources/views/CRUD/edit_orm_one_to_many.html.twig +++ b/Resources/views/CRUD/edit_orm_one_to_many.html.twig @@ -9,141 +9,143 @@ file that was distributed with this source code. #} -{% extends base_template %} - -{% block field %} - {% if not field_description.hasassociationadmin%} - {% for element in value%} - {{ element|render_relation_element(field_description) }} - {% endfor %} - {% else %} -
- - {% if field_description.options.edit == 'inline' %} - {% if inline == 'table' %} - - - {% for nested_group_field_name, nested_group_field in field_element.children %} - - {% for field_name, nested_field in nested_group_field.children %} - - {% endfor %} - - {% endfor %} - -
- {% if field_description.associationadmin.formfielddescriptions[field_name] is defined %} - {{ field_description.associationadmin.formfielddescriptions[field_name]|render_form_element( - nested_group_field, - value[nested_group_field_name] - ) }} - - {% set dummy = nested_group_field.setrendered %} - {% else %} - {{ form_widget(nested_field) }} - {% endif %} -
- {% else %} -
- {% for nested_group_field_name, nested_group_field in field_element.children %} - {% for field_name, nested_field in nested_group_field.children %} - {% if field_description.associationadmin.formfielddescriptions[field_name] is defined %} - {{ field_description.associationadmin.formfielddescriptions[field_name]|render_form_element( - nested_group_field, - value, { - 'inline': 'natural', - 'edit' : 'inline' - } - ) }} - - {% set dummy = nested_group_field.setrendered %} - {% else %} - {{ form_widget(nested_field) }} - {% endif %} - {% endfor %} +{% if not sonata_admin.field_description.hasassociationadmin%} + {% for element in value%} + {{ element|render_relation_element(sonata_admin.field_description) }} + {% endfor %} +{% else %} +
+ + {% if sonata_admin.field_description.options.edit == 'inline' %} + {% if sonata_admin.field_description.options.inline == 'table' %} + + + {% for nested_group_field_name, nested_group_field in form.children %} + + {% for field_name, nested_field in nested_group_field.children %} + + {% endfor %} + {% endfor %} - - {% endif %} + +
+ {% if sonata_admin.field_description.associationadmin.formfielddescriptions[field_name] is defined %} + {#{{ sonata_admin.field_description.associationadmin.formfielddescriptions[field_name]|render_form_element(#} + {#nested_group_field,#} + {#value[nested_group_field_name]#} + {#) }}#} + + {{ form_widget(nested_field) }} + + {% set dummy = nested_group_field.setrendered %} + {% else %} + {{ form_widget(nested_field) }} + {% endif %} +
{% else %} - {{ form_widget(field_element) }} +
+ {% for nested_group_field_name, nested_group_field in form.children %} + {% for field_name, nested_field in nested_group_field.children %} + {% if sonata_admin.field_description.associationadmin.formfielddescriptions[field_name] is defined %} + {{ form_widget(nested_field, { + 'inline': 'natural', + 'edit' : 'inline' + }) }} + {#{{ sonata_admin.field_description.associationadmin.formfielddescriptions[field_name]|render_form_element(#} + {#nested_group_field,#} + {#value, {#} + {#'inline': 'natural',#} + {#'edit' : 'inline'#} + {#}#} + {#) }}#} + + {% set dummy = nested_group_field.setrendered %} + {% else %} + {{ form_widget(nested_field) }} + {% endif %} + {% endfor %} + {% endfor %} +
{% endif %} + {% else %} + {{ form_widget(form) }} + {% endif %} +
+ + {% if sonata_admin.field_description.options.edit == 'inline' %} + + + {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} + - {% if field_description.options.edit == 'inline' %} - - - {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} - - - - {# add code for the sortable options #} - {% if field_description.options.sortable is defined %} - - {% endif %} - - {# include association code #} - {% include 'SonataAdminBundle:CRUD:edit_orm_one_association_script.html.twig' %} + apply_position_value_{{ form.vars.id }}(); - {% else %} - - - {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} - - - - - - {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %} + {% endif %} -
- {% endif %} -{% endblock %} \ No newline at end of file + + {# include association code #} + {% include 'SonataAdminBundle:CRUD:edit_orm_one_association_script.html.twig' %} + + {% else %} + + + {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} + + + + + + {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %} + {% endif %} +
+{% endif %} \ No newline at end of file diff --git a/Resources/views/CRUD/edit_orm_one_to_one.html.twig b/Resources/views/CRUD/edit_orm_one_to_one.html.twig index 9c2b987fdd..c10afd3b65 100644 --- a/Resources/views/CRUD/edit_orm_one_to_one.html.twig +++ b/Resources/views/CRUD/edit_orm_one_to_one.html.twig @@ -9,70 +9,65 @@ file that was distributed with this source code. #} -{% extends base_template %} - -{% block field %} - {% if not field_description.hasassociationadmin%} - {{ value|render_relation_element(field_description) }} - {% elseif field_description.options.edit == 'inline' %} - {% for nested_field_description in field_description.associationadmin.formfielddescriptions %} - {{ nested_field_description|render_form_element(field_element, value) }} - {% endfor %} - {% else %} -
- - {% if field_description.options.edit == 'list' %} - - {% if admin.id(value) %} - {% render 'SonataAdminBundle:Helper:getShortObjectDescription' with {}, { - 'query': { - 'code': field_description.associationadmin.code, - 'objectId': admin.id(value), - 'uniqid': field_description.associationadmin.uniqid - } - }%} - {% endif %} - - - {{ form_widget(field_element) }} - - {% else %} - - {{ form_widget(field_element) }} - - {% endif %} - - - {% if field_description.options.edit == 'list' %} - - {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} - +{% if not sonata_admin.field_description.hasassociationadmin%} + {{ value|render_relation_element(sonata_admin.field_description) }} +{% elseif sonata_admin.field_description.options.edit == 'inline' %} + {% for field_description in sonata_admin.field_description.associationadmin.formfielddescriptions %} + {{ form_row(form.getChild(field_description.name)) }} + {% endfor %} +{% else %} +
+ {% if sonata_admin.field_description.options.edit == 'list' %} + + {% if sonata_admin.field_description.associationadmin.id(sonata_admin.value) %} + {% render 'SonataAdminBundle:Helper:getShortObjectDescription' with {}, { + 'query': { + 'code': sonata_admin.field_description.associationadmin.code, + 'objectId': sonata_admin.admin.id(sonata_admin.value), + 'uniqid': sonata_admin.field_description.associationadmin.uniqid + } + }%} {% endif %} + + + {{ form_widget(form) }} + + {% else %} + + {{ form_widget(form) }} + + {% endif %} + - {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} - + {% endif %} + + + {% trans from 'SonataAdminBundle' %}btn_add{% endtrans %} + + - +
- {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %} - {% endif %} -{% endblock %} \ No newline at end of file + {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %} +{% endif %} diff --git a/Resources/views/CRUD/edit_smallint.html.twig b/Resources/views/CRUD/edit_smallint.html.twig deleted file mode 100644 index 5d4a6e83c3..0000000000 --- a/Resources/views/CRUD/edit_smallint.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{# - -This file is part of the Sonata package. - -(c) Thomas Rabaix - -For the full copyright and license information, please view the LICENSE -file that was distributed with this source code. - -#} - -{% extends 'SonataAdminBundle:CRUD:edit_integer.html.twig' %} \ No newline at end of file diff --git a/Resources/views/Form/admin_fields.html.twig b/Resources/views/Form/admin_fields.html.twig new file mode 100644 index 0000000000..643fbdb2af --- /dev/null +++ b/Resources/views/Form/admin_fields.html.twig @@ -0,0 +1,97 @@ +{# + +This file is part of the Sonata package. + +(c) Thomas Rabaix + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. + +#} + +{% extends 'form_div_layout.html.twig' %} + +{# Rows #} + +{% block field_row %} + {% if not sonata_admin.field_description %} + {{ parent() }} + {% else %} +
+ {% block label %} + {% if sonata_admin.field_description.options.name is defined %} + {{ form_label(form, sonata_admin.field_description.options.name) }} + {% else %} + {{ form_label(form) }} + {% endif %} +
+ {% endblock %} + +
+ + {{ form_widget(form) }} + + {% if sonata_admin.field_description.help %} + {{ sonata_admin.field_description.help }} + {% endif %} + + {% if form.vars.errors|length > 0 %} +
+ {{ form_errors(form) }} +
+ {% endif %} +
+
+ {% endif %} +{% endblock field_row %} + +{# Custom Sonata Admin Extension #} +{% block sonata_admin_orm_one_to_one_widget %} + {% include 'SonataAdminBundle:CRUD:edit_orm_one_to_one.html.twig' %} +{% endblock %} + +{% block sonata_admin_orm_many_to_many_widget %} + {% include 'SonataAdminBundle:CRUD:edit_orm_many_to_many.html.twig' %} +{% endblock %} + +{% block sonata_admin_orm_many_to_one_widget %} + {% include 'SonataAdminBundle:CRUD:edit_orm_many_to_one.html.twig' %} +{% endblock %} + +{% block sonata_admin_orm_one_to_many_widget %} + {% include 'SonataAdminBundle:CRUD:edit_orm_one_to_many.html.twig' %} +{% endblock %} + +{% block sonata_type_model_widget %} + {# + This is not the best way to do if + TODO : improve this part + #} + {% if sonata_admin.field_description.mappingtype == 2 %} + {{ block('sonata_admin_orm_one_to_one_widget') }} + {% elseif sonata_admin.field_description.mappingtype == 8 %} + {{ block('sonata_admin_orm_many_to_many_widget') }} + {% elseif sonata_admin.field_description.mappingtype == 4 %} + {{ block('sonata_admin_orm_one_to_many_widget') }} + {% endif %} + +{% endblock %} + +{% block sonata_type_admin_widget %} + {% if sonata_admin.field_description.mappingtype == 2 %} + {{ block('sonata_admin_orm_one_to_one_widget') }} + {% elseif sonata_admin.field_description.mappingtype == 8 %} + {{ block('sonata_admin_orm_many_to_many_widget') }} + {% elseif sonata_admin.field_description.mappingtype == 4 %} + sonata_type_admin_widget + + {{ block('sonata_admin_orm_one_to_many_widget') }} + {% endif %} +{% endblock %} + +{% block sonata_type_admin_collection_widget %} + sonata_type_admin_collection_widget + {% if sonata_admin.field_description.mappingtype == 4 %} + {{ block('sonata_admin_orm_one_to_many_widget') }} + {% endif %} +{% endblock %} diff --git a/SonataAdminBundle.php b/SonataAdminBundle.php index e8c5260748..32284bdb61 100644 --- a/SonataAdminBundle.php +++ b/SonataAdminBundle.php @@ -12,7 +12,8 @@ use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Sonata\AdminBundle\DependencyInjection\Compiler\AddDependencyCallsPass; +use Sonata\AdminBundle\DependencyInjection\AddDependencyCallsCompilerPass; +use Sonata\AdminBundle\DependencyInjection\AddFormExtensionCompilerPass; class SonataAdminBundle extends Bundle { @@ -20,6 +21,7 @@ public function build(ContainerBuilder $container) { parent::build($container); - $container->addCompilerPass(new AddDependencyCallsPass()); + $container->addCompilerPass(new AddDependencyCallsCompilerPass()); + $container->addCompilerPass(new AddFormExtensionCompilerPass()); } } diff --git a/Twig/Extension/SonataAdminExtension.php b/Twig/Extension/SonataAdminExtension.php index deac952f59..6a68f05546 100644 --- a/Twig/Extension/SonataAdminExtension.php +++ b/Twig/Extension/SonataAdminExtension.php @@ -41,7 +41,7 @@ public function getFilters() { return array( 'render_list_element' => new \Twig_Filter_Method($this, 'renderListElement', array('is_safe' => array('html'))), - 'render_form_element' => new \Twig_Filter_Method($this, 'renderFormElement', array('is_safe' => array('html'))), +// 'render_form_element' => new \Twig_Filter_Method($this, 'renderFormElement', array('is_safe' => array('html'))), 'render_filter_element' => new \Twig_Filter_Method($this, 'renderFilterElement', array('is_safe' => array('html'))), 'render_view_element' => new \Twig_Filter_Method($this, 'renderViewElement', array('is_safe' => array('html'))), 'render_relation_element' => new \Twig_Filter_Method($this, 'renderRelationElement', array('is_safe' => array('html'))), @@ -192,60 +192,60 @@ public function renderViewElement(FieldDescriptionInterface $fieldDescription, $ )); } - /** - * 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())) { - return; - } - - $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->getTemplate($fieldDescription, 'SonataAdminBundle:CRUD:base_standard_edit_field.html.twig'); - - return $this->output($fieldDescription, $template, 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) - ))); - } +// /** +// * 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())) { +// return; +// } +// +// $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->getTemplate($fieldDescription, 'SonataAdminBundle:CRUD:base_standard_edit_field.html.twig'); +// +// return $this->output($fieldDescription, $template, 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) +// ))); +// } /** * @throws \RunTimeException diff --git a/Util/FormViewIterator.php b/Util/FormViewIterator.php new file mode 100644 index 0000000000..2203da2488 --- /dev/null +++ b/Util/FormViewIterator.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\AdminBundle\Util; + +use Symfony\Component\Form\FormView; + +class FormViewIterator implements \RecursiveIterator +{ + protected $formView; + + public function __construct(FormView $formView) + { + $this->iterator = $formView->getIterator(); + } + + public function getChildren() + { + return new FormViewIterator($this->current()); + } + + public function hasChildren() + { + return $this->current()->hasChildren(); + } + + public function current() + { + return $this->iterator->current(); + } + + public function next() + { + return $this->iterator->next(); + } + + public function key() + { + return $this->current()->get('id'); + } + + public function valid() + { + return $this->iterator->valid(); + } + + public function rewind() + { + return $this->iterator->rewind(); + } +} \ No newline at end of file