Set date (x)days from now in Behat with Symfony2 forms

Using Behat i needed to be able to set a date in a form (x) number of days from the current date. This however is a problem as Behat cannot set a date (x) number of days from now as it does not know the current date. So a simple solution is to create a Behat step definition that takes the field name and a number of days. My step definition looks something like this:

The reason i went with a CSS selector is because Behat supports this anyway, and Symfony2 can create a date form by splitting the field into 3 separate fields, for Month/Day and Year respectively. So we will need to identify 3 fields in our form. Symfony2 will label them with each with the overall field name with an additional underscore and designation. Each field will be a select field.

For example, if my field is called Post_unlockedUntilDate (which was a real field i needed this test case for [the Post_ designation came from symfony based on the entity the form related to), then the 3 fields i would need to find (as created by symfony) would be:

  • Post_unlockedUntilDate_year
  • Post_unlockedUntilDate_month
  • Post_unlockedUntilDate_day

So i created a step definition that takes the CSS and finds the fields by the given selector. Then identifies each field in the results and assigns them to an array with a key for ‘day’, ‘month’ and ‘year’. Then all we need to do is create a new datetime object set (x) number of days from now and then apply that to each field.

So to use it we just call:

Hope this helps. Good luck.

Custom Validators on Validation Groups in Symfony2.

If you are using validation groups and have created a custom validator, you will want to use it in your validation group, however its a bit different from how you would apply validators in the entity, and quite similar in-fact to how you define services.

Its similar to how you define services because you have 2 root nodes, first somewhat like services.yml’s parameters line, in this instance called ‘namespaces’, the second part matches the entities name which the validator will be applied to.

Starting out, your validator.yml file probably looks like this:

This is an example taken from my AttachmentBundle, which you can find here.

Now, when we have a custom validator, in this case, some validators to check a users quota on file uploads etc, we need to set a namespace for our custom validators, with the namespace parameter, and then reference that namespace below followed by our custom validator.

The name of the validator must be wrapped in double quotes so that Symfony2 is aware that this is using a custom validator, inside of which we first start the namespace, and secondly the validator alias.

We define the alias of our validator in our services.yml like so:

Creating embedded forms in Symfony 2.0

If you are looking to create a form from 2 or more entities, like i have been then you probably find the documentation somewhat lacking and confusing. If you follow the guides you can get your form working if you start from the least dependant entity making that the first entity you use to build your form from your controller. I find if you start from the most dependant you usually get all manner of errors.

What i have is a basic forum i am working on, in my current form situation i have 3 entities, Board entity, a Thread entity and a Post entity. If you start by creating your form with Board then chances are it won’t work, i created my forms in separate ‘Type’ classes (PostType.php ThreadType.php and BoardType.php) and then created my PostType form in my controller, which then sorts out its dependencies on its own.

My controller class is very basic and not very polished, but here is what it looks like:

It probably looks somewhat messy as i say, its a rough work in progress, but it works, and here are the FormTypes i used, starting with; PostType.php:

ThreadType.php

And lastly, the BoardType.php

Notice how i added a constructor, this is so we can easily chain feed in from the first object any changes to the form, such as wether we wish to bother including a field or not, we can opt to have any field removed if the form is used under different circumstances such as different access controls for different users with different permissions or if the form is used in another way on the site.

One more thing we need to make sure, is that all the references in our entities make use of the cascade={“persist”} option so that it maintains relations between the relevant forms as new ones get processed, so if say a thread does not exist then when processing the post, it should create one and do the association for us.

Here is an example of a snip from my Post entity class Post.php

Lastly, you will need a formHandler if your not working in your controller, if using my example code then the postFormHandler.php looks like this: