Symfony2: #Assert\MaxLength and input maxlength attribute - forms

I got a Doctrine entity having one field:
/**
* #PHPCRODM\String()
* #Assert\MaxLength(255)
*/
protected $title;
Is it possible to force a maxlength attribute for the input generated from this field, without having to specify it manually?

Apparently, PHPCRODM does not accept such an option. Sad... :(
[Creation Error] The annotation #PHPCRODM\String declared on property [...]\Article::$title does not have a property named "length". Available properties: type, translated, name, property, multivalue, assoc, nullable
Should create a PR when I'll get some free time. :)

Related

Removing ChoiceType transformers during Pre Submit events

I have a form with a collection subform inside. In the subform, there is a choiceType field for the attribute "resourceId". Its data are populated by ajax, with Select2 js plugin (because its data depends on another choice, in which you select the resource type).
In the specific case that i have already a value in resourceId choice, i can't validate my field :
transformationFailure: TransformationFailedException {#4328 ▼
#message: "Unable to reverse value for property path "resourceId": The choice "bd922d35fb828da6e39edf3c7927511c9a6be025" does not exist or is not unique"
This is due because i have to add the default value of the field by javascript (thanks Select2).
I need to cancel the validation on the field, but even if i use the ResetViewTransformers() in the BuildForm method and by rebuilding the field in the PreSubmit event, it still doesn't validate.
TL;DR : How can i cancel validation during PreSubmit event ? (only on my field if possible)
Found the solution. I was going in the wrong direction.
All i had to do was overriding the ChoiceType class and disable the ViewTransformers, then use the new class :
class NonTransformedChoiceType extends ChoiceType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->resetModelTransformers();
$builder->resetViewTransformers();
}
}
add some jquery and add the .ignore class to your specific form field. If you load whole form i suggest loading them seperately so that way you can easily add it.
$("#myform").validate({
ignore: ".ignore, :hidden"
})
Hidden will also make sure that any fields you do hide, for other reason will not be affacted and then give errors, reference: here

Extbase view variable not getting

/**
* New post form
* #param \Vendor\My\Domain\Model\Post|null $newPost New post
* #return void
* #dontvalidate $newPost
*/
public function newAction(\Vendor\My\Domain\Model\Post $newPost = NULL) {
$this->view->assign('test', 'hello');
$this->view->assign('categoryList', $this->categoryRepository->findAllByBlog(0));
$this->view->assign('postObject', $newPost);
}
public function editAction() {
$this->view->assign('categoryList', $this->categoryRepository->findAllByBlog(0));
$postObject = $this->postRepository->findOneByUid($this->request->getArgument('id'));
$this->view->assign('postObject', $postObject);
}
this is my script and my problem is that I have a categoryList array, its is only getting in edit view. I want to use that category list on newaction. When I tried to foreach that array in new action view file it is getting empty. and i can get it after saving the postObject. Any idea about this particular problem? and variable test from newaction also not visible in the newAction Template file.
Am using Typo3 7.6.11
Declare arguments you want to receive, as arguments for your controller action. Reference this argument name correctly in Fluid templates when you build links to your controller action. Do not access arguments from the Request directly. Add correct PDPdoc comments for it, too.
Basically: do the correct thing with your arguments instead of bypassing the framework. This advise applies to anything you do in Extbase.
NB: New and Edit actions should never, ever share the same template (this further indicates you bypass the framework's expected behavior). Create and New, yes. But not New and Edit. If necessary, put the form fields in a partial and the form itself in separate templates so you can control the action building and object/object-name setup correctly.
If a $this->***Repository method returns NULL, it may be that the repository had no StoragePid defined.
Make sure both newAction and editAction have the same storagePid defined in TypoScript or your Backend Plugin Settings (Flexform).
The TypoScript for this would look something like this:
plugin.tx_extension.persistence.storagePid = 100

Symfony + Doctrine + Annotation validation not work in forms

I'm using doctrine annotations in my entities definition to define each variable behavior, i.e.:
#ORM\Column(type="string", length=50, nullable=false)
If I submit the form leaving the field empty, it pass the validation, but (of corse) I receive an error about the INSERT statement, because he cannot insert NULL value.
How this could be possible?
This is because Symfony does not automatically validate your form input based on Doctrine annotations.
Symfony2 ships with a Validator component that makes this task easy and transparent though. This component is based on the JSR303 Bean Validation specification.
Read up on the implementation at http://symfony.com/doc/current/book/validation.html
Here is an example of Validator annotation that might assist you:
// Acme/TaskBundle/Entity/Example.php
use Symfony\Component\Validator\Constraints as Assert;
class Example
{
/**
* #Assert\NotBlank()
* #Assert\MaxLength(50)
* #ORM\Column(type="string", length=50, nullable=false)
*/
public $parameter;
}

Overriding Form Validation messages on symfony2

How to override the form validation messages in symfony2. Though there is a validation.xml file related model classes. I think it validates a form based on html5.
"Please match the requested format", "Please fill out this field". Is there any way to override this validation messages.
Please help me in this regard, i am stuck for more than a day, as i am totally new to symfony
Those messages you see are HTML5 validation messages which are created by the browser. If you want to override them you need to add an oninvalid attribute to the input tag associated with that field. You can do this in two ways:
In your controller or form type, add this attribute to the form field:
$builder->add('email', 'email',array(
'attr'=>array('oninvalid'=>"setCustomValidity('Would you please enter a valid email?')")
));
Or, in your twig template, add this attribute when rendering the form field:
{{ form_row(form.email, { 'attr': {'oninvalid': "setCustomValidity('Please give me a nice email')"} }) }}
You can change the message of each validator thanks to the message option when declaring the assert:
/**
* #ORM\Column(type="string", length=255, unique=true)
* #Assert\NotBlank(
* message="You have to choose a username (this is my custom validation message).",
* groups={"registration", "account", "oauth"}
* )
Also you can apply translation by creating the file MyBundle/Resources/translations/validators.fr.xliff

Parsing comma separated string into multiple database entries (eg. Tags)

I want to create a Symfony 2 Form for a Blog Post. One of the fields that I am wondering how might I implement is the tags field. Post has a many-to-many relationship with Tag. I want my Form to have 1 text box where users enter in a comma separated list of tags. Which will then be converted into multiple Tag's.
How should I implement it? Do I:
Have a tagsInput field (named differently from in the Entity where $tags should be an ArrayCollection)
On POST, I split the tags and create/get multiple tags. Then validate the tags (eg. MaxLength of 32)
I think you are already on the right way since I saw your other question about the form type. I will just comfort you with your choice.
A form type is probably the best way to go. With the form type, you will be able to display a single text field in your form. You will also be able to transform the data into a string for display to the user and to an ArrayCollection to set it in your model. For this, you use a DataTransformer exactly as you are doing in your other question.
With this technique, you don't need an extra field tagsInput in your model, you can have only a single field named tags that will an ArrayCollection. Having one field is possible because the you form type will transform that data from a string to an ArrayCollection.
For the validation, I think you could use the Choice validator. This validator directive seems to be able to validate that an array does not have less than a number of item and not more than another number. You can check the documentation for it here. You would use it like this:
// src/Acme/BlogBundle/Entity/Author.php
use Symfony\Component\Validator\Constraints as Assert;
class Post
{
/**
* #Assert\Choice(min = 1, max = 32)
*/
protected $tags;
}
If it does not work or not as intended, what you could do is to create a custom validator. This validator will then be put in your model for the tags field. This validator would validate the an array have a maximum number of element no greater than a fixed number (32 in your case).
Hope this helps.
Regards,
Matt