Search code examples
symfonyvalidationdoctrine-ormformbuilder

Load specific doctrine entity through symfony form request result


Firstly, I hope you will forgive me for my bad English. Secondly, I know, everything is on the internet! But this time, I didn't find what I wanted.

Here is a little bit of context:

I'm currently working with the symfony framework (v3).

I got two entity:

  • error

  • errorCode

Their relation is one to many, one errorCode can be linked to many errors but one error can only have one errorCode.

The errorCode table is feeded manually by a database administrator.

I have the folowing structure of nested formTypes:

errorType
    ->errorCodeType

The errorCodeType contain 3 different subcodes fields (integerType) which aren't the table primary keys but are what I will type during error reporting.


My problem:

How to load and link the correct errorCode after submitting the form and throw an error on the fields if no corresponding errorCode instance was found in the database.


My constraints:

  • Database structure (I know that's dumb but I've got to work with an existing database and I can't really create any views due to an intolerant database manager).
  • PHP - 5.6.30 ( you know servers and things... ;) ).

Solutions envisaged:

  • Data Transformer (I don't really think I can use them with multiple inputs).
  • Custom validator (well I think this might be the solution but I don't really know how to use it and I haven't found any doc explaining how to set an entity field neither how to use multiple inputs).
  • Event listeners (same, don't really know to use it and don't really know how to show the validation error to the correct fields).

Well, I know the solution might be in one of them but I couldn't think a way to properly use them.


Anyway, thank you for your help, sorry again for my poor English and have a nice day/evening.



EDIT:

My errorType form:

$builder->add('code', CollectionType::class, array(
    'entry_type' => ErrorCodeType::class,
    'allow_add' => false,
    'allow_delete' => false,
    'required'=>true,
));

$builder->add('operatorAnnotation', TextType::class, array('label'=>'compléments','required'=>true));

My errorCodeType form:

$builder->add('aSubcode1', IntegerType::class, array('label'=>'Code de catégorie','required'=>true));
$builder->add('aSubcode2', IntegerType::class, array('label'=>'Code de classe','required'=>true));
$builder->add('aSubcode3', IntegerType::class, array('label'=>'Code de détail','required'=>true));

My errorCode Entity:

/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\Column(type="integer")
 */
private $aSubcode1;

/**
 * @ORM\Column(type="integer")
 */
private $aSubCode2;

/**
 * @ORM\Column(type="integer")
 */
private $aSubCode3;

/**
 * @ORM\OneToMany(targetEntity="Error", mappedBy="code", cascade={"persist"})
 */
private $errors;

/*.........More things.......*/

My error Entity:

/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 */
private $operatorAnnotation;

/**
 * @ORM\ManyToOne(targetEntity="ErrorCode", inversedBy="errors", cascade={"persist"})
 */
private $code;

/*.........More things.......*/

Solution

  • Ok so, thank you @Neok for trying helping me!

    I found a "Ghetto" way to get what I wanted:

    First of all, I unlinked my forms and my entities.

    Then, I've made a custom form for my errors (still not linked) which include all three sub-codes fields of the ErrorCode entity and some other fields relatives to the Error entity (this is the first thing that is from my taste "Ghetto").

    After that, I've catched the form in my controller and executed multiples queries to load the ErrorCode entity or, if not possible, find which field in giving me trouble (which one isn't valid)

    Then, the process take two distinct paths:

    • If everything is valid, I link my found ErrorCode to my error (which id is sent through the url (second "ghetto" part)) and cascade persist my error.

    • if something is wrong, i send back the form after using ( $myForm->get([MyField])->addError([MyError]) ) (which is the third thing i think is "ghetto")

    If someone find a better solution, I'd like to hear it but i thought it would be a good thing to present the one I've found.

    Last but not least, if my English grammar, syntax, vocabulary... makes your eyes bleed, you're welcome to ask edition on my post.