Story #64274

Updated by Mathias Schreiber over 4 years ago

Registering a non-extbase plugin currently needs two things:

* Add the TCA necessary by calling <pre>\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin</pre>
* Add the typoscript by calling <pre>\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPItoST43</pre>

*addPItoST43* adds typoscript in this form: <pre>
plugin.tx_extensionkey_suffix = USER
plugin.tx_extensionkey_suffix.userFunc = tx_extensionkey_suffix->main
</pre>
When you want to use namespaced code (and I say that's what we all want) you need to manually supply a classmap in this form:
<pre>
tx_extensionkey_suffix => '\Vendorname\Extensionname\Controller\Class'
</pre>

I propose a new method to register non-extbase plugins that enforces stronger defaults and reduces the clutter in the Typoscript Obejct Browser.

h3. New method:

<pre>static public function addPluginTyposcript($FQCN, $methodName)</pre>

See the example:
<pre>
static public function addPluginTyposcript(\MyAgency\MyExtension\Cached\Plugin\MyPlugin::class, 'dispatch')
static public function addPluginTyposcript(\MyAgency\MyExtension\UnCached\Plugin\MyPlugin::class, 'dispatch')
static public function addPluginTyposcript(\MyAgency\MyExtension\Cached\Menu\MyMenu::class, 'render')
static public function addPluginTyposcript(\MyAgency\MyExtension\Cached\CType\MyCType::class, 'render')
static public function addPluginTyposcript(\MyAgency\MyExtension\Cached\Header\MyHeader::class, 'render')
</pre>

As you can see the FQCN (Fully qualified class name) holds a strong default for registering a plugin in the frontend.
Let's take the example above apart:
* \MyAgency
** the Vendor name
* \MyExtension
** Your extension key
* \Cached
** defines whether a plugin runs cached or uncached (just for TS registering, you can re-define it via TS, possible values are:
*** Cached
*** Uncached
* \Plugin
** Determines the type, possible values are:
*** -Plugin-
*** Menu
*** CType
*** Header
* \MyPlugin
** Your class name

We will drop support for "just include library", because the design is just broken.
All TS get's added to page.1000, which is problematic if
* you have multiple of these plugins installed
* your root object simply has another name than page

h3. Typoscript result

I propose to add more "dots" to the TS.
Possible result:
<pre>
plugin.MyAgency.MyExtension.Plugin.MyPlugin = USER
plugin.MyAgency.MyExtension.Plugin.MyPlugin.userFunc = \MyAgency\MyExtension\Cached\Plugin\MyPlugin->dispatch
plugin.MyAgency.MyExtension.Menu.MyMenu = USER
plugin.MyAgency.MyExtension.Menu.MyMenu.userFunc = \MyAgency\MyExtension\Cached\Menu\MyMenu->render
</pre>
This will clean up the Typoscript Object browser.

h3. tt_content.CType result

We could also derive the TCA necessary from this classes.
The following fields in tt_content are affected:
* CType
* -list_type-
* menu_type
* header_layout

Storing values in these fields needs to comply to the TS being generated.
So the resulting value from the example would be:
<pre>MyAgency.MyExtension.Plugin.MyPlugin
MyAgency.MyExtension.Menu.MyMenu</pre>

When selecting values in the database this comes in handy because you can now use proper wildcards to isolate specific extensions.

In order to generate the label for the field in the BE we would use a locallang.xlf hit for the same identifier.

h3.
Registering multiple Plugins/CTypes

Currently TYPO3 loops through all registered plugins and adds the TS on demand (in every hit).
Additionally, it's painful if you have an extension that registers, say, 50 CTypes.
The idea would be to look up all CTypes automatically and cache this information.
This way an extension would just need to "configure" something like "I do supply UserFunctions".
If there are cached registrations, use those.
If no cached registrations are in place, try to look them up via the filesystem (using the logic described above) and build up the caches.

Back