Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony 4 - how to use service tags when autowiring an entire path

I'm working on a bundle for Symfony 4 that is structured like this:

\Acme
  \FooBundle
    \Article
      \Entity
        - Article.php
        - Comment.php
      \Form
        - ArticleType.php
      \Repository
        - ArticleRepository.php
        - CommentRepository.php
      - ArticleManager.php
    \User
      \Entity
        - User.php
      \Repository
        - UserRepository.php
      - UserManager.php
    \SomethingElse
      \Entity
        - SomethingElse.php
      \Repository
        - SomethingElseRepository.php
      - SomethingElseManager.php

There are many more folders and entities, but is irrelevant for the question.

Autowiring all the classes in that folder can be created with a config like this one:

Acme\FooBundle\:
    resource: '../../*/{*Manager.php,Repository/*Repository.php}'
    exclude: '../../{Manager/BaseManager.php,Repository/BaseRepository.php}'
    autowire: true

But when you need to add service tags like doctrine.repository_service, this kind of configuration won't help no more. Without the tag, when using in controller like:

$this->getDoctrine()->getRepository(Bar::class)

or

$this->getDoctrine()->getManager()->getRepository(Bar::class)

it throws an error:

The "Acme\FooBundle\SomethingElse\Repository\SomethingElseRepository" entity repository implements "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface", but its service could not be found. Make sure the service exists and is tagged with "doctrine.repository_service".

The thing is that, since they all reside in the same root folder I'm not allowed to use a config like the following one, because it would have duplicated Acme\FooBundle\ keys:

Acme\FooBundle\:
    resource: '../../*/{*Manager.php}'
    exclude: '../../{Manager/BaseManager.php}'
    autowire: true

Acme\FooBundle\:
    resource: '../../*/{Repository/*Repository.php}'
    exclude: '../../{Repository/BaseRepository.php}'
    autowire: true
    tags: ['doctrine.repository_service']

So, I was wondering if there's a workaround that I couldn't find or I should just manually add each and every service?

Edit: It would have been a nice feature to be able to use an annotation in the class so when it's loaded it "knows" it's tag, but I'm thinking it works the other way around, loading a class because is was tagged with a certain tag.

like image 230
VMC Avatar asked Mar 31 '18 08:03

VMC


1 Answers

I encountered the same error message after refactoring (renaming) some entities and the related repositories using PhpStorm 2019.2 The refactor did not update the repository class name in the doc block for the entity:

* @ORM\Entity(repositoryClass="App\Repository\OldRepository")

So I used right-click > Copy Reference to get the fully qualified name of NewRepository and pasted it in to the doc block reference:

* @ORM\Entity(repositoryClass="\App\Repository\NewRepository")

PhpStorm prefixed the class with a backslash and I didn't notice until after trying many combinations of suggested solutions for this error. I only needed to remove the backslash and the error is gone:

* @ORM\Entity(repositoryClass="App\Repository\NewRepository")
like image 59
Arleigh Hix Avatar answered Oct 06 '22 00:10

Arleigh Hix