From 1ab0b95e7447f7fd6cf0c3953272e962f1c788eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 9 Mar 2016 20:54:38 +0100 Subject: [PATCH] order the type alphabetically Improve also the form "TranslatableActivityType" to use the TranslatableStringHelper. --- .../ChillActivityExtension.php | 1 + Form/Type/TranslatableActivityType.php | 48 ++++++-- Resources/config/services.yml | 3 +- Resources/config/services/repositories.yml | 6 + .../Type/TranslatableActivityTypeTest.php | 115 ++++++++++++++++++ 5 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 Resources/config/services/repositories.yml create mode 100644 Tests/Form/Type/TranslatableActivityTypeTest.php diff --git a/DependencyInjection/ChillActivityExtension.php b/DependencyInjection/ChillActivityExtension.php index b66544a65..4a2f5795b 100644 --- a/DependencyInjection/ChillActivityExtension.php +++ b/DependencyInjection/ChillActivityExtension.php @@ -47,6 +47,7 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.yml'); + $loader->load('services/repositories.yml'); } public function prepend(ContainerBuilder $container) diff --git a/Form/Type/TranslatableActivityType.php b/Form/Type/TranslatableActivityType.php index 4ce59ae82..6e4865bb7 100644 --- a/Form/Type/TranslatableActivityType.php +++ b/Form/Type/TranslatableActivityType.php @@ -25,6 +25,10 @@ namespace Chill\ActivityBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Chill\MainBundle\Templating\TranslatableStringHelper; +use Doctrine\ORM\EntityRepository; +use Chill\ActivityBundle\Entity\ActivityType; /** * Description of TranslatableActivityType @@ -33,14 +37,22 @@ use Symfony\Component\HttpFoundation\RequestStack; */ class TranslatableActivityType extends AbstractType { - /** - * @var RequestStack - */ - private $requestStack; - public function __construct(RequestStack $requestStack) + /** + * + * @var TranslatableStringHelper + */ + protected $translatableStringHelper; + + protected $activityTypeRepository; + + public function __construct( + TranslatableStringHelper $helper, + EntityRepository $activityTypeRepository + ) { - $this->requestStack = $requestStack; + $this->translatableStringHelper = $helper; + $this->activityTypeRepository = $activityTypeRepository; } public function getName() @@ -50,16 +62,34 @@ class TranslatableActivityType extends AbstractType public function getParent() { - return 'entity'; + return EntityType::class; } public function configureOptions(OptionsResolver $resolver) { - $locale = $this->requestStack->getCurrentRequest()->getLocale(); + // create a local copy for use in closures + $translatableStringHelper = $this->translatableStringHelper; + $types = $this->activityTypeRepository->findAll(); + + // sort by alphabetical order + usort($types, function(ActivityType $typeA, ActivityType $typeB) use ($translatableStringHelper) { + $strA = $translatableStringHelper->localize($typeA->getName()); + $strB = $translatableStringHelper->localize($typeB->getName()); + + if ($strA === $strB) { + return 0; + } + + return $strA < $strB ? -1 : 1; + }); + $resolver->setDefaults( array( 'class' => 'ChillActivityBundle:ActivityType', - 'property' => 'name['.$locale.']' + 'choices' => $types, + 'choice_label' => function (ActivityType $type) use ($translatableStringHelper) { + return $translatableStringHelper->localize($type->getName()); + } ) ); } diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 751bf979d..4be25af03 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -16,7 +16,8 @@ services: chill.activity.form.type.translatableactivitytype: class: Chill\ActivityBundle\Form\Type\TranslatableActivityType arguments: - - "@request_stack" + - "@chill.main.helper.translatable_string" + - "@chill_activity.repository.activity_type" tags: - { name: form.type, alias: translatable_activity_type } diff --git a/Resources/config/services/repositories.yml b/Resources/config/services/repositories.yml new file mode 100644 index 000000000..967c67bc3 --- /dev/null +++ b/Resources/config/services/repositories.yml @@ -0,0 +1,6 @@ +services: + chill_activity.repository.activity_type: + class: Doctrine\ORM\EntityRepository + factory: ['@doctrine.orm.entity_manager', getRepository] + arguments: + - 'Chill\ActivityBundle\Entity\ActivityType' diff --git a/Tests/Form/Type/TranslatableActivityTypeTest.php b/Tests/Form/Type/TranslatableActivityTypeTest.php new file mode 100644 index 000000000..89007d4d0 --- /dev/null +++ b/Tests/Form/Type/TranslatableActivityTypeTest.php @@ -0,0 +1,115 @@ + + * + * 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\ActivityBundle\Tests\Form\Type; + +use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use Chill\ActivityBundle\Form\Type\TranslatableActivityType; +use Symfony\Component\Form\Extension\Core\Type\FormType; + +/** + * + * + * @author Julien Fastré + */ +class TranslatableActivityTypeTest extends KernelTestCase +{ + + /** + * + * @var \Symfony\Component\Form\FormBuilderInterface + */ + protected $builder; + + /** + * + * @var \Symfony\Component\DependencyInjection\ContainerInterface + */ + protected $container; + + public function setUp() + { + self::bootKernel(); + + $this->container = self::$kernel->getContainer(); + + $this->builder = $this->container + ->get('form.factory') + ->createBuilder(FormType::class, null, array( + 'csrf_protection' => false, + 'csrf_field_name' => '_token' + )); + + $request = new \Symfony\Component\HttpFoundation\Request(); + $request->setLocale('fr'); + + $this->container->get('request_stack') + ->push($request); + } + + /** + * + * @return \Chill\ActivityBundle\Entity\ActivityType + */ + protected function getRandomType() + { + $types = $this->container->get('doctrine.orm.entity_manager') + ->getRepository('ChillActivityBundle:ActivityType') + ->findAll(); + + return $types[array_rand($types)]; + } + + public function testForm() + { + $type = $this->getRandomType(); + $form = $this->builder->add('type', TranslatableActivityType::class) + ->getForm(); + + $form->submit(array( + 'type' => $type->getId() + )); + + $this->assertTrue($form->isSynchronized()); + $this->assertInstanceOf(\Chill\ActivityBundle\Entity\ActivityType::class, + $form->getData()['type'], + "The data is an instance of Chill\ActivityBundle\Entity\ActivityType"); + $this->assertEquals($type->getId(), $form->getData()['type']->getId()); + + // test the ordering of the types in the form + $view = $form->createView(); + + $this->assertGreaterThan(0, count($view['type']->vars['choices']), + "test that there are at least one choice"); + + foreach($view['type']->vars['choices'] as $choice) { + // initialize the previous value is not set (this is the first) + if (!isset($previous)) { + $previous = $choice->label; + } else { + $this->assertTrue($previous < $choice->label); + $previous = $choice->label; + } + } + + } + + + +}