Symfony 4 - How to add business logic to an Entity Symfony 4 - How to add business logic to an Entity symfony symfony

Symfony 4 - How to add business logic to an Entity


What you are looking for is a wrong way of achieving the desired effect. For this to work you will have to inject the router into the entity which essentially turns it into "business logic" (e.g. controller) rather than "persistence" and breaks the single responsibility principle. Besides it's hard to achieve technically as you'll have to modify Doctrine's internals

There are two ways to handle this properly and both of them involve custom Twig extension:

The simplest one is to define a custom Twig filter which takes care of generating the correct URL:

<?phpnamespace App\Twig\Extension;use App\Entity\Article;use Symfony\Component\Routing\RouterInterface;use Twig\Extension\AbstractExtension;use Twig\TwigFilter;class ArticleExtension extends AbstractExtension{    private $router;    public function __construct(RouterInterface $router)    {        $this->router = $router;    }    public function getFilters()    {        return [            new TwigFilter('article_url', [$this, 'getArticleUrl']),        ];    }    public function getArticleUrl(Article $article): string    {        return $this->router->generate('article_show', ['slug' => $article->getSlug()]);    }}

Then in twig you just use the filter like this:

{% for article in articles %}    ...    <a href="{{ article|article_url }}">        {{ article.title }}    </a>    ...{% endfor %}

If you are using Symfony 3.4+ with awtowiring/autoconfigure just creating the class will be enough otherwise you need to register it as twig extension in the container.Please refer to Symfony's documentation for more details

The second option mentioned is only necessary if you want to reuse the route generation outside of the view/templating. In this case the necessary logic (which is now in the Twig extension) must be moved to a separate standalone service. Then you'd have to inject this service into the extension and use it instead of directly invoking the router. Check the relevant documentation entry for a verbose walk-trough on creating/registering a service


I can't understand why a business entity should be aware of the routing system.

If you want its url know by the entity, just add a setUrl() and getUrl() method in your entity and store it the already generated url