0

Working with Symfony 5.3 I would like to find all classes within the project which use a custom annotation @MyAnnotation.

While I have found countless tutorials and a lot of information about annotations, they all only show how to check if a given object or method uses some annotation. For example it is no problem to use a kernel event subscriber to test if the current controller uses a annotation or not.

But I was not able to find a way, to automatically find / discover all classes which use a given annotation. I assume that Doctrine itself does the same to find all entities which use its @Entity annotation. But how is this done?

I tried to check the Doctrine code to see how hit works, but I did not found out.

Is there some build in features? Or is there some giveMeAllClassesInProject() method I could use to test each class manually?

Traversing all classes within the project would not be practical. I do not have to actively tell Doctrine that MyBundle is installed in the project and that it can find its entities at /vendor/me/my-bundle/src/Entity but Doctrine does find these entities.

Of course the src/Entity/ part is standard and pretty sure belongs to the Doctrines default configuration, but Doctrine still need to know which bundles are installed, where to find them, where to find the project src/ dir, etc. So there needs to be be some giveMeAlleSrcDirsInProject() method or something in this direction, doesn't it?

Additionally even if Symfony would deliver all src/ dirs, traversing them and checking all entity classes for some annotation on every request would be pretty inefficient. So this information is surely cached somehow. But when is this information gathered, etc.

In short: Is there any standard procedure on how to implement annotations like @Entity?

yivi
  • 42,438
  • 18
  • 116
  • 138
FLichter
  • 169
  • 9
  • *"But how is this done?"* Doctrine knows where to search for entities, defined in configuration file – Cid Aug 26 '21 at 10:55
  • What you want doesn't exist. You need to traverse the directories. You could try relying on other system that did the something similar, but since they would be looking in different places with different configurations, they might not find all that you want. – yivi Aug 26 '21 at 12:37
  • There is not, and there can't be, any kind of `giveMeAlleSrcDirsInProject()`. – yivi Aug 26 '21 at 12:37

1 Answers1

2

You would need to traverse all classes that exist in a project, and check each one if they are annotated one way or another.

Usually that's not practical, so you would have (like Doctrine or Symfony do) configuration settings telling your code WHERE to look for those classes.

Then you scan only those files, and that's that.

Doctrine knows which bundles are installed and where to look thanks to the Doctrine Symfony Bundle, and by default looks always in the same places for defined mappings. But even the, it only look in specific directories within those bundles (scanning those directories), it doesn't "know about all defined classes".

Using something like get_declared_classes() wouldn't work, since not all classes are necessarily read at a given time for a given request. And some/many classes will be loaded that are irrelevant for your use case. Same with trying to rely on other system that did something similar and left some kind of cache behind: since those libraries/packages are looking for different things than you, their results might not be relevant.

Even with configuration telling the application where to look, this is typically not done at runtime on each request, since it would be too expensive. Packages/Frameworks as Doctrine or Symfony do this once and "cache" the results in different kinds of configuration files and proxy classes.

For traversing directories and checking files therein, maybe you can use Symfony Finder. You are bound to find many examples online. The exact implementation would depend on different assumptions made by your application.

yivi
  • 42,438
  • 18
  • 116
  • 138
  • It seems that your answer was added while I edited my question. I answer most of the questions I added. Thanks! I will have a closer look at the link. – FLichter Aug 26 '21 at 12:24
  • Your edit didn't change my answer, sorry. I don't understand the bit about "I answer most of the questions I added". You are answering this question? How? In any case, the answer is the same: you need to scan the directories you are interested, and define that somehow. – yivi Aug 26 '21 at 12:42
  • Sorry, it should be "**It** answers most of the questions I added..." (not I). The main question is this "Is there any standard procedure on how to implement annotations like `@Entity?`" Using some kind of "magic "getAllClasses()" method was just an assumption. I assume that the answer is simply "No there is no standard procedure / best practice how to implement this type of annotations". – FLichter Aug 26 '21 at 12:46
  • The answer, as stated, is "no", you need to implement your own by scanning the files and checking the classes. – yivi Aug 26 '21 at 12:47