diff --git a/CHANGELOG.md b/CHANGELOG.md index 5769cc8..c3ecb14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Removed hard dependency to the form component (it is still required for many features) +### Removed +- Automatic extension of the Symfony DateTimeType. There's a good DateTimeType available, we do not need more. + ## [0.7.3] 2020-12-18 ### Added diff --git a/composer.json b/composer.json index ac14084..9a395e8 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "friendsofphp/php-cs-fixer": "^2.17", "phpspec/prophecy": "^1.8", "twig/twig": "^2.5", - "symfony/symfony": "^4.3 || ^5.0", + "symfony/symfony": "^4.4 || ^5.0", "doctrine/orm": "^v2.6.6", "justinrainbow/json-schema": "^5.2", "doctrine/annotations": "^1.8", diff --git a/couscous.yml b/couscous.yml index 3eac37a..48f2600 100644 --- a/couscous.yml +++ b/couscous.yml @@ -32,3 +32,6 @@ menu: cruds: text: CRUD Reference relativeUrl: docs/crud-controllers.html + forms: + text: Forms Reference + relativeUrl: docs/form-types.html diff --git a/docs/config-reference.md b/docs/config-reference.md index 625d895..b2f856e 100644 --- a/docs/config-reference.md +++ b/docs/config-reference.md @@ -1,6 +1,8 @@ Configuration Reference of Melodiia =================================== +Here is the whole melodiia configuration commented: + ```yaml melodiia: apis: @@ -15,3 +17,4 @@ melodiia: form_extensions: datetime: true ``` + diff --git a/docs/form-types.md b/docs/form-types.md new file mode 100644 index 0000000..e225316 --- /dev/null +++ b/docs/form-types.md @@ -0,0 +1,22 @@ +Using Symfony form types with Melodiia +====================================== + +Melodiia provides an `AbstractType` that you should extends to define you own types. + +In addition, it provides some types that are very specific to API needs: +- BooleanType +- DateTimeType +- CollectionType + +Those types are simple and behave just like you can expect. Excepted for the CollectionType. + +The CollectionType +------------------ + +This type is very similar to the CollectionType of Symfony but regardless the original one, it supports APIs. + +Here is a list of options you can use on it: +- `allow_add` (default to `true`): Allow the user to add items to the collection +- `allow_delete` (default to `true`): Allow the user to remove items from the collection +- `entry_type` (default to `TextType::class`): A form type that represent a collection item +- `entry_options` (default to `[]`): Options of the `entry_type` diff --git a/docs/getting-started.md b/docs/getting-started.md index 8a9b3a9..3489e24 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -87,8 +87,8 @@ class TodoType extends AbstractType You can now use the `Create` controller from the CRUD controllers. -By default Symfony Forms are not well designed for API. That's why we created a new `AbstractType` that you should -extends. Melodiia also provide a set of type for APIs needs: https://github.com/swagindustries/Melodiia/tree/master/src/Form/Type +By default Symfony Forms are not well-designed for API. That's why we created a new `AbstractType` that you should +extend. Melodiia also provide a set of [form types for APIs needs](form-types.md). ```yaml # routing.yaml diff --git a/features/crud.feature b/features/crud.feature index 5a92ada..df65a09 100644 --- a/features/crud.feature +++ b/features/crud.feature @@ -24,15 +24,18 @@ Feature: "data": [ { "id": 1, - "content": "foo" + "content": "foo", + "publishDate":"2050-01-02T00:00:00+00:00" }, { "id": 2, - "content": "bar" + "content": "bar", + "publishDate":"2050-01-02T00:00:00+00:00" }, { "id": 3, - "content": "baz" + "content": "baz", + "publishDate":"2050-01-02T00:00:00+00:00" } ] } @@ -42,7 +45,8 @@ Feature: Given I make a "POST" request on "/todos" with the content: """ { - "content": "hello" + "content": "hello", + "publishDate":"2050-01-02T00:00:00+00:00" } """ And the last response contains: @@ -56,7 +60,8 @@ Feature: """ { "id": 1, - "content": "hello" + "content": "hello", + "publishDate":"2050-01-02T00:00:00+00:00" } """ @@ -81,11 +86,13 @@ Feature: "data": [ { "id": 2, - "content": "bar" + "content": "bar", + "publishDate":"2050-01-02T00:00:00+00:00" }, { "id": 3, - "content": "baz" + "content": "baz", + "publishDate":"2050-01-02T00:00:00+00:00" } ] } diff --git a/features/custom_responses.feature b/features/custom_responses.feature index 1aa3ed0..6068d99 100644 --- a/features/custom_responses.feature +++ b/features/custom_responses.feature @@ -23,7 +23,8 @@ Feature: "data": [ { "id": 1, - "content": "foo" + "content": "foo", + "publishDate":"2050-01-02T00:00:00+00:00" } ] } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 0fa7fd9..784fff8 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -37,12 +37,6 @@ public function getConfigTreeBuilder() ->end() ->end() ->end() - ->arrayNode('form_extensions') - ->addDefaultsIfNotSet() - ->children() - ->booleanNode('datetime')->defaultTrue()->end() - ->end() - ->end() ->end() ; diff --git a/src/DependencyInjection/MelodiiaExtension.php b/src/DependencyInjection/MelodiiaExtension.php index 985b3f5..b7364e3 100644 --- a/src/DependencyInjection/MelodiiaExtension.php +++ b/src/DependencyInjection/MelodiiaExtension.php @@ -33,8 +33,6 @@ public function load(array $configs, ContainerBuilder $container) } if (class_exists(Form::class)) { - $loader->load('form.yaml'); - // The CRUD features requires forms as well as doctrine to be enabled if ($container->hasAlias('melodiia.data_provider')) { $loader->load('crud.yaml'); @@ -49,7 +47,6 @@ public function load(array $configs, ContainerBuilder $container) $config = $this->processConfiguration($configuration, $configs); $container->setParameter('melodiia.config', $config); - $this->disableFormExtensionIfNeeded($container, $config['form_extensions']); // Autoconf $container->registerForAutoconfiguration(FilterInterface::class)->addTag(self::TAG_CRUD_FILTER); diff --git a/src/Form/Extension/DateTimeExtension.php b/src/Form/Extension/DateTimeExtension.php deleted file mode 100644 index 865b256..0000000 --- a/src/Form/Extension/DateTimeExtension.php +++ /dev/null @@ -1,45 +0,0 @@ -setDefaults([ - 'widget' => 'single_text', - 'format' => DateTimeType::HTML5_FORMAT, - ]) - ; - } - - /** - * {@inheritdoc} - * BC Layer: To be remove in Symfony 5.0. - */ - public function getExtendedType() - { - return DateTimeType::class; - } - - /** - * {@inheritdoc} - */ - public static function getExtendedTypes(): iterable - { - return [DateTimeType::class]; - } -} diff --git a/src/Form/Type/MelodiiaCollectionType.php b/src/Form/Type/CollectionType.php similarity index 67% rename from src/Form/Type/MelodiiaCollectionType.php rename to src/Form/Type/CollectionType.php index 38f329d..73592bc 100644 --- a/src/Form/Type/MelodiiaCollectionType.php +++ b/src/Form/Type/CollectionType.php @@ -9,11 +9,9 @@ use Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\OptionsResolver; -class MelodiiaCollectionType extends AbstractType +class CollectionType extends AbstractType { /** * {@inheritdoc} @@ -34,22 +32,6 @@ public function buildForm(FormBuilderInterface $builder, array $options) $builder->addEventSubscriber($reorderInputDataListener); } - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars = array_replace($view->vars, [ - 'allow_add' => $options['allow_add'], - 'allow_delete' => $options['allow_delete'], - ]); - - if ($form->getConfig()->hasAttribute('prototype')) { - $prototype = $form->getConfig()->getAttribute('prototype'); - $view->vars['prototype'] = $prototype->setParent($form)->createView($view); - } - } - /** * {@inheritdoc} */ @@ -58,7 +40,6 @@ public function configureOptions(OptionsResolver $resolver) $resolver->setDefaults([ 'allow_add' => true, 'allow_delete' => true, - 'prototype' => true, 'entry_type' => TextType::class, 'entry_options' => [], 'delete_empty' => false, diff --git a/src/Resources/config/form.yaml b/src/Resources/config/form.yaml deleted file mode 100644 index 2d4ce2c..0000000 --- a/src/Resources/config/form.yaml +++ /dev/null @@ -1,6 +0,0 @@ -services: - melodiia.form.extension.datetime: - class: SwagIndustries\Melodiia\Form\Extension\DateTimeExtension - tags: - - { name: form.type_extension } - diff --git a/tests/Behat/Context/TodoContext.php b/tests/Behat/Context/TodoContext.php index fe5c9f5..e72bcd3 100644 --- a/tests/Behat/Context/TodoContext.php +++ b/tests/Behat/Context/TodoContext.php @@ -18,10 +18,13 @@ public function thereAreSome() $todo1 = new Todo(); $todo1->setContent('foo'); + $todo1->setPublishDate(new \DateTimeImmutable('2050-01-02')); $todo2 = new Todo(); $todo2->setContent('bar'); + $todo2->setPublishDate(new \DateTimeImmutable('2050-01-02')); $todo3 = new Todo(); $todo3->setContent('baz'); + $todo3->setPublishDate(new \DateTimeImmutable('2050-01-02')); $entityManager->persist($todo1); $entityManager->persist($todo2); @@ -39,6 +42,7 @@ public function thereIsOneTodo($content) $todo = new Todo(); $todo->setContent($content); + $todo->setPublishDate(new \DateTimeImmutable('2050-01-02')); $entityManager->persist($todo); $entityManager->flush(); diff --git a/tests/TestApplication/src/Entity/Todo.php b/tests/TestApplication/src/Entity/Todo.php index 7632116..0465efe 100644 --- a/tests/TestApplication/src/Entity/Todo.php +++ b/tests/TestApplication/src/Entity/Todo.php @@ -24,6 +24,11 @@ class Todo implements MelodiiaModel */ private $content; + /** + * @ORM\Column(type="datetime_immutable") + */ + private $publishDate; + public function getId(): ?int { return $this->id; @@ -38,4 +43,14 @@ public function setContent($content): void { $this->content = $content; } + + public function getPublishDate() + { + return $this->publishDate; + } + + public function setPublishDate(?\DateTimeImmutable $publishDate): void + { + $this->publishDate = $publishDate; + } } diff --git a/tests/TestApplication/src/Form/TodoType.php b/tests/TestApplication/src/Form/TodoType.php index e2f9b2a..3575a3e 100644 --- a/tests/TestApplication/src/Form/TodoType.php +++ b/tests/TestApplication/src/Form/TodoType.php @@ -5,9 +5,11 @@ namespace TestApplication\Form; use SwagIndustries\Melodiia\Form\AbstractType; +use SwagIndustries\Melodiia\Form\Type\DateTimeType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraints\GreaterThan; use Symfony\Component\Validator\Constraints\NotBlank; use TestApplication\Entity\Todo; @@ -15,7 +17,12 @@ class TodoType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { - $builder->add('content', TextType::class, ['constraints' => new NotBlank()]); + $builder + ->add('content', TextType::class, ['constraints' => new NotBlank()]) + ->add('publishDate', DateTimeType::class, [ + 'constraints' => [new GreaterThan('today'), new NotBlank()], + ]) + ; } public function configureOptions(OptionsResolver $resolver)