суббота, 12 февраля 2022 г.

[SyliusResourceBundle] how to pass model into controller?

 Sometimes you don't need to use model instead of entity, and then save some data into entity and persist it. It means you cannot use it in Sylius ResourceControllers, because your model must implement ResourceInterface, create dedicated ResourceController, Repository, Manager, and model cannot do it.

If you want it, this means you doing it wrong, because it violated CRUD principles. The best solution is to use Symfony Data Transformers https://symfony.com/doc/current/form/data_transformers.html , add it to your form, implement transform() method, where it will create your model/DTO object from entity, and reverseTransform(), where DTO will be converted into Entity object.

вторник, 1 февраля 2022 г.

[Doctrine] how to replace Many-To-Many to three entities

When you need to put new field/database columns into Many-To-Many, relationship, you will need to switch to intermediate entity. In my case it is StudentKlass.

Imagine three entities: Team - StudentTeam - Student

use Doctrine\ORM\Mapping as ORM;

class Team {
/**
* @ORM\OneToMany(targetEntity=StudentTeam::class, mappedBy="team", cascade={"persist"})
*/
private $studentTeams;

public function __construct() {
$this->studentTeams = new ArrayCollection();
}
...
}

class StudentTeam {
/**
* @ORM\ManyToOne(targetEntity=Student::class, inversedBy="teams")
* @ORM\JoinColumn(name="student_id", referencedColumnName="id")
*/
private $student;

/**
* @ORM\ManyToOne(targetEntity=Team::class, inversedBy="studentTeams")
*/
private $team;
...
}

class Student {
/**
* @ORM\OneToMany(targetEntity=StudentTeam::class, mappedBy="student")
*/
private $teams;
private $name;
private $email;
...

} 

Also don't forget to create getters, adders & removers!

You can use example how to use it in Symfony forms, which has example how to use nested forms:

class TeamType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('studentTeams', CollectionType::class, [
'entry_type' => TeamStudentType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
]);
...
}

class TeamStudentType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add(
$builder
->create('student', FormType::class, [
'data_class' => Student::class,
])
->add('email', TextType::class)
->add('name', TextType::class)
)
;
}
}
}