during my research on how to reduce the codebase of Extbase to a minimum, I came across the whole Reflection and DependencyInjection parts and I quickly realized that the way Extbase does things is a bit chaotic and hard to solve with 3rd party libraries.
I tried to see if we can use libraries such as
symfony/property-access that rely on great libraries like
nikic/php-parser themselves to have less own code that does magic the Extbase way.
No matter what I tried, I realised that all these libraries are very good and do a brilliant job as long as you stick to the rules, mainly, only using the official annotations for php doc blocks like
@param and such. Unfortunately, Extbase doesn’t comply.
Let’s have an example:
Extbase has a
ReflectionService that analyses all classes for several reasons. There is Dependency Injection, which relies on annotations like
@inject, then there is the validation with
@ignorevalidation and such. There’s also the property mapper part and of course the whole ORM that abuses
@param and introduces annotations like
@lazy and such.
The problem is: If we want to reduce the code of Extbase in current state, we have to teach the 3rd-party-libraries all the dirty ways Extbase does things. That’s when I realized, we need to have a look at the bigger picture here.
My proposal is as follows:
As a first step we could migrate all the custom annotations to doctrine annotations. That way, we define these custom annotations with actual classes. If you played around with flow or symfony, you are used to them. The good thing about these annotations is, that they have a context. Please have a short look at https://review.typo3.org/#/c/54327/ to see a very basic replacement of @inject. When you look at the patch and the use statement in the
QueryFactory you can see, that you get a context from the namespace of the annotation. Using
@Extbase\DependencyInjection\Inject instead of
@inject is a lot more self-explanatory. Also, one can have a look at the class that defines the annotation and sees how it’s to be used.
Like prefixing the Inject with DependencyInjection, we could prefix all custom annotations according to their origin.
Imagine having an
@Extbase\ORM\OneToMany<Foo> instead of
@param ObjectStorage<Foo> or an
@Extbase\Validation\Assert\NotEmpty instead of
@validate NotEmpty. Not only is it a lot clearer what these annotations do and what part of software they are from and for, they bring us also closer to the usage of other frameworks.
Furthermore it’s a small step from
Symfony\Component\Validator\Constraints\Assert\NotEmpty and we are very close to replace all our own logic with the one of a 3rd-party-validation library. Well, that’s just one idea of many. We are also a lot closer to
@Doctrine\ORM\Mapping\ORM\Entity and so on. You get the gist.
How to proceed?
Well, until the release of 9LTS, all annotations need to be reimplemented using doctrine annotations. Then, the usage of all current annotations become deprecated and as of 10LTS people need to have their code ready to use doctrine annotations exclusively. Afterwards, we can start cleaning up Extbase’s code, that deals with doc block analysis.
It’s a job that will last for several LTS version but I think we have a good chance getting things done quickly as soon as we decide to proceed in that direction.
So, what do you think?