diff --git a/Controller/CustomFieldController.php b/Controller/CustomFieldController.php index 8c775af1e..9cbea02b6 100644 --- a/Controller/CustomFieldController.php +++ b/Controller/CustomFieldController.php @@ -244,4 +244,5 @@ class CustomFieldController extends Controller ->getForm() ; } + } diff --git a/Controller/CustomFieldsGroupController.php b/Controller/CustomFieldsGroupController.php index bd8ff2b0f..b4bb9dabb 100644 --- a/Controller/CustomFieldsGroupController.php +++ b/Controller/CustomFieldsGroupController.php @@ -146,7 +146,6 @@ class CustomFieldsGroupController extends Controller 'action' => $this->generateUrl('customfieldsgroup_update', array('id' => $entity->getId())), 'method' => 'PUT', )); - $form->add('submit', 'submit', array('label' => 'Update')); return $form; @@ -221,4 +220,44 @@ class CustomFieldsGroupController extends Controller ->getForm() ; } + + /** + * This function render the customFieldsGroup as a form. + * + * This function is for testing purpose ! + * + * The route which call this action is not in Resources/config/routing.yml, + * but in Tests/Fixtures/App/app/config.yml + * + * @param int $id + */ + public function renderFormAction($id, Request $request) + { + $em = $this->getDoctrine()->getManager(); + + $entity = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')->find($id); + + if (!$entity) { + throw $this->createNotFoundException('Unable to find CustomFieldsGroups entity.'); + } + + $form = $this->createForm('custom_field', null, array('group' => $entity)); + $form->add('submit', 'submit', array('label' => 'POST')); + $form->handleRequest($request); + + if ($form->isSubmitted()) { + var_dump($form->getData()); + var_dump(json_encode($form->getData())); + } + + $this->get('twig.loader') + ->addPath(__DIR__.'/../Tests/Fixtures/App/app/Resources/views/', + $namespace = 'test'); + + return $this + ->render('@test/CustomField/simple_form_render.html.twig', array( + 'form' => $form->createView() + )); + + } } diff --git a/CustomFields/CustomFieldChoice.php b/CustomFields/CustomFieldChoice.php new file mode 100644 index 000000000..6b45db9b0 --- /dev/null +++ b/CustomFields/CustomFieldChoice.php @@ -0,0 +1,156 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace Chill\CustomFieldsBundle\CustomFields; + +use Chill\CustomFieldsBundle\CustomFields\CustomFieldInterface; +use Symfony\Component\Form\FormBuilderInterface; +use Chill\CustomFieldsBundle\Entity\CustomField; +use Chill\CustomFieldsBundle\Form\Type\ChoicesType; +use Symfony\Component\HttpFoundation\RequestStack; +use Chill\CustomFieldsBundle\Form\Type\ChoicesListType; +use Chill\CustomFieldsBundle\Form\DataTransformer\CustomFieldDataTransformer; +use Chill\CustomFieldsBundle\Form\Type\ChoiceWithOtherType; + +/** + * + * + * @author Julien Fastré + */ +class CustomFieldChoice implements CustomFieldInterface +{ + const ALLOW_OTHER = 'other'; + const MULTIPLE = 'multiple'; + const EXPANDED = 'expanded'; + const CHOICES = 'choices'; + + /** + * + * @var RequestStack + */ + private $requestStack; + + private $defaultLocale; + + public function __construct(RequestStack $requestStack, $defaultLocale) + { + $this->requestStack = $requestStack; + $this->defaultLocale = $defaultLocale; + } + + + + public function buildForm(FormBuilderInterface $builder, CustomField $customField) + { + //prepare choices + $locale = $this->requestStack->getCurrentRequest()->getLocale(); + $choices = array(); + foreach($customField->getOptions()[self::CHOICES] as $persistedChoices) { + if ($persistedChoices['active']){ + $choices[$persistedChoices['slug']] = $persistedChoices['name'][$locale]; + } + } + + //prepare $options + $options = array( + 'multiple' => $customField->getOptions()[self::MULTIPLE], + 'choices' => $choices, + 'required' => (count($choices) > 1) ? true : false //not required if only one + ); + + //if allow_other = true + if ($customField->getOptions()[self::ALLOW_OTHER] === 1) { + + $builder->add( + $builder->create($customField->getSlug(), new ChoiceWithOtherType(), $options) + ->addModelTransformer(new CustomFieldDataTransformer($this, $customField))); + + } else { //if allow_other = false + + //we add the 'expanded' to options + $options['expanded'] = $customField->getOptions()[self::EXPANDED]; + + $builder->add( + $builder->create($customField->getSlug(), 'choice', $options) + ->addModelTransformer(new CustomFieldDataTransformer($this, $customField)) + ); + + } + + } + + public function buildOptionsForm(FormBuilderInterface $builder) + { + $builder->add(self::MULTIPLE, 'choice', array( + 'expanded' => true, + 'multiple' => false, + 'choices' => array( + 1 => 'Multiple', + 0 => 'Unique' + ), + 'empty_data' => 0 + )) + ->add(self::EXPANDED, 'choice', array( + 'expanded' => true, + 'multiple' => false, + 'choices' => array( + 1 => 'Expanded', + 0 => 'Non expanded' + ), + 'empty_data' => 0 + )) + ->add(self::ALLOW_OTHER, 'choice', array( + 'label' => 'Allow other', + 'choices' => array( + 0 => 'No', + 1 => 'Yes' + ), + 'empty_data' => 0, + 'expanded' => true, + 'multiple' => false + )) + ->add(self::CHOICES, new ChoicesType(), array( + 'type' => new ChoicesListType($this->defaultLocale), + 'allow_add' => true + )); + + return $builder; + } + + public function deserialize($serialized, CustomField $customField) + { + return $serialized; + } + + public function getName() + { + return 'Choices'; + } + + public function render($value, CustomField $customField) + { + + } + + public function serialize($value, CustomField $customField) + { + return $value; + } +} diff --git a/CustomFields/CustomFieldInterface.php b/CustomFields/CustomFieldInterface.php index 5d1e1b978..952d6af56 100644 --- a/CustomFields/CustomFieldInterface.php +++ b/CustomFields/CustomFieldInterface.php @@ -39,8 +39,9 @@ interface CustomFieldInterface /** * - * @param type $value + * @param mixed $value the raw value, **not deserialized** (= as stored in the db) * @param \Chill\CustomFieldsBundle\CustomField\CustomField $customField + * @return string an html representation of the value */ public function render($value, CustomField $customField); diff --git a/DependencyInjection/ChillCustomFieldsExtension.php b/DependencyInjection/ChillCustomFieldsExtension.php index 5d5eb4de5..6b14df6ad 100644 --- a/DependencyInjection/ChillCustomFieldsExtension.php +++ b/DependencyInjection/ChillCustomFieldsExtension.php @@ -6,13 +6,14 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader; +use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; /** * This is the class that loads and manages your bundle configuration * * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html} */ -class ChillCustomFieldsExtension extends Extension +class ChillCustomFieldsExtension extends Extension implements PrependExtensionInterface { /** * {@inheritDoc} @@ -33,4 +34,17 @@ class ChillCustomFieldsExtension extends Extension $container->setParameter('chill_custom_fields.customizables_entities', $config['customizables_entities']); } + + + /* (non-PHPdoc) + * @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend() + */ + public function prepend(ContainerBuilder $container) + { + // add form layout to twig resources + $twigConfig['form']['resources'][] = 'ChillCustomFieldsBundle:Form:form_div_layout.html.twig'; + $container->prependExtensionConfig('twig', $twigConfig); + + } + } diff --git a/DependencyInjection/CustomFieldCompilerPass.php b/DependencyInjection/CustomFieldCompilerPass.php index d1a2b8a14..8ea599a4f 100644 --- a/DependencyInjection/CustomFieldCompilerPass.php +++ b/DependencyInjection/CustomFieldCompilerPass.php @@ -28,7 +28,7 @@ class CustomFieldCompilerPass implements CompilerPassInterface $taggedServices = $container->findTaggedServiceIds( 'chill.custom_field' - ); + ); foreach ($taggedServices as $id => $tagAttributes) { foreach ($tagAttributes as $attributes) { diff --git a/Form/Type/ChoiceWithOtherType.php b/Form/Type/ChoiceWithOtherType.php new file mode 100644 index 000000000..65e048129 --- /dev/null +++ b/Form/Type/ChoiceWithOtherType.php @@ -0,0 +1,53 @@ + + * + */ +class ChoiceWithOtherType extends AbstractType +{ + + + /* (non-PHPdoc) + * @see \Symfony\Component\Form\AbstractType::buildForm() + */ + public function buildForm(FormBuilderInterface $builder, array $options) + { + //add an 'other' entry in choices array + $options['choices']['_other'] = '__other__'; + //ChoiceWithOther must always be expanded + $options['expanded'] = true; + + $builder + ->add('_other', 'text', array('required' => false)) + ->add('_choices', 'choice', $options) + ; + + } + + /* (non-PHPdoc) + * @see \Symfony\Component\Form\AbstractType::setDefaultOptions() + */ + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver + ->setRequired(array('choices')) + ->setAllowedTypes(array('choices' => array('array'))) + ->setDefaults(array('multiple' => false)) + ; + + } + + + public function getName() + { + return 'choice_with_other'; + } +} \ No newline at end of file diff --git a/Form/Type/ChoicesListType.php b/Form/Type/ChoicesListType.php new file mode 100644 index 000000000..246f14c45 --- /dev/null +++ b/Form/Type/ChoicesListType.php @@ -0,0 +1,66 @@ +defaultLocale = $defaultLocale; + } + + /* (non-PHPdoc) + * @see \Symfony\Component\Form\AbstractType::buildForm() + */ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $locale = $this->defaultLocale; + + $builder->add('name', 'translatable_string') + ->add('active', 'checkbox', array( + 'required' => false, + 'empty_data' => true + )) + ->add('slug', 'hidden', array( + + )) + ->addEventListener(FormEvents::SUBMIT, function(FormEvent $event) use ($locale){ + $form = $event->getForm(); + $data = $event->getData(); + + $formData = $form->getData(); + + if (NULL === $formData['slug']) { + $slug = $form['name'][$locale]->getData(); + $slug= strtolower($slug); + $slug= preg_replace('/[^a-zA-Z0-9 -]/','', $slug); // only take alphanumerical characters, but keep the spaces and dashes too... + $slug= str_replace(' ','-', $slug); // replace spaces by dashes + + $data['slug'] = $slug; + $event->setData($data); + } else { + $data['slug'] = $formData['slug']; + $event->setData($data); + } + }) + ; + } + + + /* + * + * @see \Symfony\Component\Form\FormTypeInterface::getName() + */ + public function getName() + { + return 'cf_choices_list'; + } + +} \ No newline at end of file diff --git a/Form/Type/ChoicesType.php b/Form/Type/ChoicesType.php new file mode 100644 index 000000000..75d409bfc --- /dev/null +++ b/Form/Type/ChoicesType.php @@ -0,0 +1,26 @@ + + * + */ +class ChoicesType extends AbstractType +{ + public function getName() + { + return 'cf_choices'; + } + + public function getParent() + { + return 'collection'; + } + + +} \ No newline at end of file diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 2e4588728..295667a09 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -41,6 +41,14 @@ services: - "@request_stack" tags: - { name: 'chill.custom_field', type: 'text' } + + chill.custom_field.choice: + class: Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice + arguments: + - "@request_stack" + - %locale% + tags: + - { name: 'chill.custom_field', type: 'choice' } chill.custom_field.address: class: Chill\CustomFieldsBundle\CustomFields\CustomFieldAddress diff --git a/Resources/views/CustomField/form.html.twig b/Resources/views/CustomField/form.html.twig index efa52428d..524517ec7 100644 --- a/Resources/views/CustomField/form.html.twig +++ b/Resources/views/CustomField/form.html.twig @@ -1,5 +1,7 @@ {% extends '::base.html.twig' %} +{% block javascripts_head %}{% endblock %} + {% block body -%} {{ form(form) }} {% endblock %} diff --git a/Resources/views/CustomField/new.html.twig b/Resources/views/CustomField/new.html.twig index 2661a94cd..108602ea0 100644 --- a/Resources/views/CustomField/new.html.twig +++ b/Resources/views/CustomField/new.html.twig @@ -4,7 +4,6 @@

CustomField creation

{{ form(form) }} -