Symfony: Form Issue Using Return Type Hinting in Doctrine Entity Methods

Symfony: Form issue using Return type hinting in Doctrine Entity methods

If an Entity Property cannot be null (and you use PHP 7.1+), then applying the nullable return type declaration sounds more like a dirty and fast workaround to maintain a direct data binding between Entities and Forms (using the Symfony Form Component).

A better global approach (in my opinion) is to decouple the Form data binding from your Doctrine Entities using a DTO (Data Transfer Object), that is a simple POPO (Plain Old PHP Object) to contain your form data.

Using a DTO will allow you to maintain a strict type hinting in your Doctrine Entities (no loss of data consistency) and will decouple Form data binding (but also data validation) from your Entities.

DTO's allows reusability and have many other advantages.

Some useful references about the use of DTO's with Symfony Forms:

  • Avoiding Entities in Forms (by Iltar van der Berg)
  • Rethinking Form Development (by Iltar van der Berg)
  • Symfony Forms 101 (by Bernhard Schussek the creator of the Form component)
  • Don't Use Entities in Symfony Forms. Use Custom Data Objects Instead
  • Entities should always be valid

Symfony forms php7 type hints

With php 7.1 you can specify it in this way:

public function getName() : ?string {

In this way you specify that return values is string or null but only from php 7.1

Can I not define the argument type in the setters of an entity due to form validation?

If you want your entity to be at a valid state you shouldn't link them with your form, you will have to use a DTO object representing your form then update your entity with the values when your form is valid.

The easiest way is to change your setter / getter to be able to return/set null values

public function setLabel(string $label = null): void
{
$this->label = $label;
}
public function getLabel(): ?string
{
return $this->label;
}

Symfony forms (as standalone component with Doctrine) EntityType not working

Believe me, you're asking for trouble!

EntityType::class works when it is seamsly integrated to "Symfony" framework (there's magic under the hoods - via DoctrineBundle). Otherwise, you need to write a lot of code for it to work properly.

Not worth the effort!

It's a lot easier if you to create an entity repository and inject it in form constructor, then use in a ChoiceType::class field. Somethink like this:

<?php
# you form class
namespace Application\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class InvoiceItemtType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('product', ChoiceType::class, [
'choices' => $this->loadProducts($options['products'])
]);
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(['products' => [],]); # custom form option
}

private function loadProducts($productsCollection)
{
# custom logic here (if any)
}
}

And somewhere in application:

$repo = $entityManager->getRepository(Product::class);
$formOptions = ['products' => $repo->findAll()];
$formFactory = Forms::createFormFactory();
$formFactory->create(InvoiceItemtType::class, new InvoiceItem, $formOptions);

That's the point!

Symfony - Return type for Doctrine entity

I've just now read an article about this and it's not supported to have a return type-hinting as object

You can however in PHP 7.2:
http://php.net/manual/en/migration72.new-features.php

Validation annotations in doctrine entities

Entities shouldn't know anything about input validation. It is not their job. I personally never do that. There are other options as well - first two depend on FormTypes if they are used.

  1. Defining form validation constraints in formtypes in symfony - This is ok but if you take out your FormType class your validation rules go as well so it is highly coupled approach. Not suggestion this!
  2. Defining form validation annotations in models in symfony - This is ok because there is a validation dedicated separate model class now. Neither Entity nor FormType know about validation. Only the validation model is aware of it so all decoupled from each other. Even if you take out FormType, you can still use the validation model class with Symfony Serializer and Validator. Example below does it.
  3. Validating, serialising and mapping json request to model classes - This is the final and preferred approach. As I mentioned above, whether you are using FormTypes or not, I would go with this option. You can use native Symfony Serializer instead of JMS if you wish. There are more examples on this in the same blog.


Related Topics



Leave a reply



Submit