Y
Y
You Care2017-03-14 17:00:53
symfony
You Care, 2017-03-14 17:00:53

Where to place logic in Symfony 3 application (+ Doctrine 2)?

Hello everyone, can anyone advise where it is more correct / better to place the logic when there are several entities (Doctrine entity) that implement a common interface?
The situation is this, there is a Request interface:

<?php

namespace AppBundle\Entity;

interface Request
    public function approve();
    public function reject();
}

and several entities: Invite and JoinRequest in the first, the company invites a person to the company, in the second, vice versa.
Invite example:
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/** @ORM\Entity */
class Invite implements Request
{

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

    /**
     * @ORM\ManyToOne(targetEntity="Company")
     * @ORM\JoinColumn(nullable=false)
     * @var Company
     */
    private $company;

    /**
     * @ORM\ManyToOne(targetEntity="User")
     * @ORM\JoinColumn(nullable=false)
     * @var User
     */
    private $user;

    public function approve()
    {
        // Some logic here. Add user to company, send mail, add flash message etc...
    }

    public function reject()
    {
        // Same
    }

    // Getters/Setters.
}

there will also be other types of entities (request to exchange contacts, etc.)
As far as I understand, placing any business logic in Doctrine Entities themselves is considered bad practice, and passing dependencies to Entity (mailer, twig templating, flash messages) does not look very good beautiful, in the controller too, so the only thing that comes to my mind is to allocate a separate service for all these Request Entities, or even one for each, but doesn’t this kill the whole point of polymorphism?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
voronkovich, 2017-03-15
@voronkovich

I would choose the 2nd option - for each entity its own service that implements logic. Could you clarify what you mean by "kills the meaning of polymorphism"? Polymorphism should not be an end in itself. Preferring decoration over inheritance doesn't kill the point of inheritance, does it?

D
Denis, 2017-03-15
@prototype_denis

Take a look at how FOSUserBundle is invited symfony.com/doc/current/bundles/FOSUserBundle/addi... The
logic itself can be placed anywhere, from controllers to Doctrine listeners and specific managers. Based on your specific case.
In my opinion, parent models (user, company) should manage invites, and not vice versa. It is better that more models will know about one small one than one small one about everyone with whom it is associated.
Throw out somewhere in UserManager'e, CompanyManager'e event and hang up the listener on it. After all, on the invite (I mean) the end-to-end logic hangs (send something to the soap, write it to the log, update a couple of your properties).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question