Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Form] ResizeListener forces a specific data format requirement on the model #7905

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
searbe opened this issue May 2, 2013 · 4 comments
Closed

Comments

@searbe
Copy link

searbe commented May 2, 2013

This is a follow-up to my comments in issue #7828.

All subscribers listening for a PRE_SET_DATA event will receive model data. This can be problematic since certain field types start to dictate a very specific format for data in the model. even with a data transformer in place.

For example, in my usecase I have model data which could work with the CollectionType, which registers a ResizeListener internally. My data needs transforming before hitting the ResizeListener, as it expects a certain format of data. Since the ResizeListener receives model data on PRE_SET_DATA, there is no mechanism to prepare the data for the listener. The end result is I have to modify the model data itself to get it through the ResizeListener.

Ultimately, a PRE_SET_DATA listener can introduce a specific data format requirement on the model, which can't be solved by simply adding a data transformer.

My thoughts are that if listeners (or at least the ResizeListener specifically) received normalised data, which a transformer can take care of, it wouldn't be possible to impose specific format requirements on the model.

@chrisguitarguy
Copy link
Contributor

I've also run into an issue with this.

Similar scenario to the one @searbe mentioned in #7828: trying to go from an array of key => value pairs to a collection type.

<?php
$input = array(
   'one'    => 'two',
   'three'  => 'four',
);

// transforms to...
$transformed = array(
    array('internal_name' => 'two', 'output_name' => 'one'),
    array('internal_name' => 'four', 'output_name' => 'three'),
);

DataTransformer works great, but because ResizeFormListener uses the keys of the array keys to set property paths and happens before data transformer normalization, the property path's end up being set to one and three in the example and the form fields are empty.

@webmozart
Copy link
Contributor

@searbe Are you aware that you can assign a priority to your listener?

$builder->addEventListener(FormEvents::PRE_SET_DATA, $listener, 100);

@fabpot
Copy link
Member

fabpot commented Feb 21, 2018

Closing as this issue is stalled.

@fabpot fabpot closed this as completed Feb 21, 2018
@ugomeda
Copy link

ugomeda commented Nov 4, 2020

Bumping this issue. I have a model with a field $translations containing a list of translations and the following DataTransformer to transform my ["translationId" => "Translation Value"] array into [["id" => "translationId", "value" => "TranslationValue']] :

<?php

namespace MyNamespaceForm;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

class TranslationTransformer implements DataTransformerInterface
{
    public function transform($translations)
    {
        if ($translations === null) {
            return [];
        }

        $formData = [];
        foreach ($translations as $id => $value) {
          $formData[] = ["id" => $id, "value" => $value];
        }

        return $formData;
    }

    public function reverseTransform($formData)
    {
        $data = [];
        foreach ($formData as $line) {
          if (isset($data[$line['id']])) {
            $failure = new TransformationFailedException("Duplicated key");
            $failure->setInvalidMessage("workspace.translation.duplicate_key");

            throw $failure;
          }
          $data[$line['id']] = $line['value'];
        }

        if (count($data) === 0) {
          return null;
        }

        return $data;
    }
}

I was able to hack my way around the problem, but when I tried to add the key messages.news_label, this happened :

Symfony\Component\Form\Exception\InvalidArgumentException:
The name "messages.news_label" contains illegal characters. Names should start with a letter, digit or underscore and only contain letters, digits, numbers, underscores ("_"), hyphens ("-") and colons (":").

  at vendor/symfony/symfony/src/Symfony/Component/Form/FormConfigBuilder.php:782
  at Symfony\Component\Form\FormConfigBuilder::validateName('messages.news_label')
     (vendor/symfony/symfony/src/Symfony/Component/Form/FormConfigBuilder.php:118)
  at Symfony\Component\Form\FormConfigBuilder->__construct('messages.news_label', null, object(EventDispatcher), 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants