Details
-
Improvement
-
Resolution: Fixed
-
High
-
None
Description
The feature in the tutorial that adds the possibility to validate user that created the input Tweet isn't finished. To complete it, I needed to implement few more things:
Firstly, I needed to create a FormMapper, that allows me to add an input field to form with content field definition. To achieve this, I created file TweetFieldTypeBundle/eZ/Publish/FieldType/Tweet/FormMapper.php:
namespace EzSystems\TweetFieldTypeBundle\eZ\Publish\FieldType\Tweet; use EzSystems\RepositoryForms\Data\FieldDefinitionData; use EzSystems\RepositoryForms\FieldType\FieldDefinitionFormMapperInterface; use EzSystems\TweetFieldTypeBundle\Form\StringToArrayTransformer; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormInterface; class FormMapper implements FieldDefinitionFormMapperInterface { public function mapFieldDefinitionForm(FormInterface $fieldDefinitionForm, FieldDefinitionData $data) { $fieldDefinitionForm ->add( // Creating from FormBuilder as we need to add a DataTransformer. $fieldDefinitionForm->getConfig()->getFormFactory()->createBuilder() ->create('authorList', TextType::class, [ 'required' => false, 'property_path' => 'validatorConfiguration[TweetValueValidator][authorList]', 'label' => 'field_definition.eztweet.authorList' ]) ->addModelTransformer(new StringToArrayTransformer()) // Deactivate auto-initialize as we're not on the root form. ->setAutoInitialize(false)->getForm() ); } }
Because the input type is Text and the validator can have multiple entries (multiple users), the FormMapper uses a DataTransformer that divides input by comma. It looks like this (TweetFieldTypeBundle\Form\StringToArrayTransformer.php):
namespace EzSystems\TweetFieldTypeBundle\Form; use Symfony\Component\Form\DataTransformerInterface; class StringToArrayTransformer implements DataTransformerInterface { public function transform($array) { if ($array !== null) { return implode(',', $array); } return ''; } public function reverseTransform($string) { if (!empty($string)) { $array = explode(',', $string); return array_map('trim', $array); } return array(); } }
Next thing is to register the FormMapper as a service, so the system would know to use it. To achieve this, I added the following lines to TweetFieldTypeBundle/Resources/config/fieldtypes.yml:
ezsystems.tweetbundle.fieldtype.eztweet.form_mapper:
class: 'EzSystems\TweetFieldTypeBundle\eZ\Publish\FieldType\Tweet\FormMapper'
tags:
- {name: ez.fieldFormMapper.definition, fieldType: eztweet}
After that, I needed to add the template to show the new part of the form to the user. To do that, I created file TweetFieldTypeBundle/Resources/views/platformui/content_type/edit/eztweet.html.twig:
{% block eztweet_field_definition_edit %}
<div class="eztweet-validator author_list{% if group_class is not empty %} {{ group_class }}{% endif %}">
{{- form_label(form.authorList) -}}
{{- form_errors(form.authorList) -}}
{{- form_widget(form.authorList) -}}
</div>
{% endblock %}
And I registered it by editing file TweetFieldTypeBundle/Resources/config/ez_field_templates.yml:
fielddefinition_edit_templates:
- {template: "EzSystemsTweetFieldTypeBundle:platformui/content_type/edit:eztweet.html.twig", priority: 0}
The last thing to do was to make sure that validation data is properly saved into the database. To achieve this, I had to implement two functions in LegacyConverter file (TweetFieldTypeBundle/eZ/Publish/FieldType/Tweet/LegacyConverter.php):
public function toStorageFieldDefinition(FieldDefinition $fieldDef, StorageFieldDefinition $storageDef) { $storageDef->dataText1 = json_encode($fieldDef->fieldTypeConstraints->validators['TweetValueValidator']['authorList']); } public function toFieldDefinition(StorageFieldDefinition $storageDef, FieldDefinition $fieldDef) { $authorList = json_decode($storageDef->dataText1); if (!empty($authorList)) { $fieldDef->fieldTypeConstraints->validators = array( 'TweetValueValidator' => array( 'authorList' => $authorList ), ); } }