contao/core — pull request #4514 by tristanlins (2012-07-08 20:04:55+00:00)
Title: Echte Namespaces für Contao Extensions

Wie bereits angekündigt, habe ich mich endlich mal mit dem Autoloader auseinander gesetzt und ich muss sagen der Ansatz gefällt mir ;-)
Allerdings finde ich es schade, dass "echte" Namespaces dadurch völlig verloren gehen und selbst Contao Extensions keine Namespaces nutzen können.

Für Extensions habe ich mir jetzt etwas einfallen lassen, wie man Namespaces nach PSR-0 Schema durchsetzen kann.

**Die Idee**

Zu Namespaces brauche ich in dem Fall nichts sagen, aber wie das Namespace Schema aufgebaut ist.
Ich arbeite mit einem ganz normalen Namespace, z.B. `Contao\Extension\Namespaces\NamespaceClass` um die Klasse `NamespaceClass` aus dem Namespace `Contao\Extension\Namespaces` zu benutzen.
Der Namespace `Contao\Extension\Namespaces` existiert allerdings nur Virtuell, die echte Klasse liegt unter `Contao\Extension\Namespaces\_vendor_\NamespaceClass`.
Das Teilstück `_vendor_` ist wie der Name schon vermuten lässt ein Vendor-Identifier. Dieser muss mit einem Unterstrich Anfangen und Enden. Der Teil dazwischen kann beliebig gewählt werden.

Das Mapping sieht dann z.B. so aus: `Contao\Extension\Namespaces\ => Contao\Extension\Namespaces\_vendor\`

Im Endeffekt ist das Mapping nichts anderes, als die bereits vorhandene Namespace Suche, die Contao durchführt, nur dass beim Mapping der Namespace ausgetauscht wird, anstatt ihn einfach voran zu stellen.

Der Entwickler sollte natürlich die Klasse `Contao\Extension\Namespaces\NamespaceClass` anstelle von `Contao\Extension\Namespaces\_vendor_\NamespaceClass` verwenden, der ClassLoader schmeißt eine entsprechende Warnung, sollte er dennoch den vollständigen Pfad benutzen.

Weiterer Vorteil des Mapping: Nach dem Vendor-Part kann die Struktur weiter gehen, bspw. `Contao\Extension\Namespaces\_vendor_\Hook\Page`.

Zu diesem Zweck habe ich eine Beispiel-Extension gebaut, diese ist hier zu finden: https://github.com/InfinitySoft/contao3-poc-namespaces
PS: Das das Content Element eine Warning wirft, ist zu demonstrationszwecken gewollt!

Durch den Vendor-Part ist es weiterhin möglich, Klassen von Erweiterungen zu überschreiben. Eine entsprechende Beispiel-Extension ist hier zu finden: https://github.com/InfinitySoft/contao3-poc-namespaces-extension

**Das Dev-Tool**

Das Dev-Tool kennt jetzt PSR-0. Und zwar unterhalb eines Unterverzeichnisses im Modulverzeichnis. (siehe auch Beispiel-Extension https://github.com/InfinitySoft/contao3-poc-namespaces)
Eine entsprechende Struktur sieht dann z.B. so aus:

```
system/modules/ext/...
.../classes/Contao/Extension/Ext/_vendor_/MyClass.php
.../dca/...
.../templates/...
.../languages/...
.../hooks/Contao/Extension/Ext/_vendor_/Hook/MyHook.php // nur um zu zeigen, dass es auch mit verschiedenen Verzeichnissen geht!
```

Der Namespace für `MyClass` ist `Contao\Extension\Ext\_vendor_` und wird einzig aus dem Verzeichnispfad extrahiert (d.h. nicht aus der Datei gelesen!). Entsprechend muss der Namespace in der Datei exakt dem Namespace im Pfad entsprechen -> PSR-0

Für alle PSR-0 kompatiblen Extensions, baut das Dev-Tool jetzt das entsprechende Namespace Mapping, für das Beispiel wäre das Mapping: `Contao\Extension\Ext => Contao\Extension\Ext\_vendor_`.

**Warum?**

Einige Community-Mitglieder haben ihr missfallen darüber geäußert, dass der ClassLoader nicht mit "echten" Namespaces umgehen kann (ich zähle mich selbst dazu). Wobei er das sogar könnte, vorausgesetzt man lässt die Fähigkeit zum Überschreiben weg.

**Die Lösung beeinträchtigt den bisherigen ClassLoader in seiner Funktion NICHT**, erlaubt aber den Einsatz echter Namespaces mit der Fähigkeit, Klassen zu überschreiben. Und wenn für Contao 3 schon PHP 5.3 vorausgesetzt wird, dann wäre es vermutlich auch eine ziemlich fragwürdige Voraussetzung, wenn man die Namespaces nicht auch nutzen könnte ;-)

Mit der Änderung könnten wir den Weg in Richtung Namespaces zumindest für Erweiterungen ebnen. Mir würde das im Context von Avisota z.B. sehr zu Hilfe kommen, dort habe ich in Version 2 bereits 33 Klassen und es werden noch mehr. Diese alle mit Name-Prefixes zu benennen wird ganz schön unübersichtlich und bei anderen großen Extension sieht das sicher nicht besser aus...