[!!!][FEATURE] Check TCA changes in ext_tables.php 28/50328/7
authorChristian Kuhn <lolli@schwarzbu.ch>
Sun, 23 Oct 2016 11:20:50 +0000 (13:20 +0200)
committerJan Helke <typo3@helke.de>
Mon, 24 Oct 2016 19:21:15 +0000 (21:21 +0200)
TCA changes within ext_tables.php can be moved to
Configuration/TCA since core 6.2. Still having them in
ext_tables.php is highly discouraged since version 7 and
now breaks with version 8.

The patch adds a feature to the Install Tool to find
loaded extensions that still manipulate TCA within
ext_tables.php files.

Additionally, the frontend is changed to no longer load
ext_tables.php files for normal requests and thus actively
ignores TCA changes from those files. This way a frontend
specific cache file is removed and the patch is a preparation
of a possible core cache warmup phase.

Change-Id: Ib639462ec92f4faf788fd20596aa4e7ce311701a
Resolves: #78384
Releases: master
Reviewed-on: https://review.typo3.org/50328
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Jan Helke <typo3@helke.de>
Tested-by: Jan Helke <typo3@helke.de>
14 files changed:
typo3/sysext/core/Classes/Core/Bootstrap.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-78384-FrontendIgnoresTCAInExtTables.rst [new file with mode: 0644]
typo3/sysext/core/Documentation/Changelog/master/Feature-78384-CheckExtTablesTCAChangesInInstallTool.rst [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Core/BootstrapTest.php [deleted file]
typo3/sysext/frontend/Classes/Http/RequestHandler.php
typo3/sysext/frontend/Classes/Utility/EidUtility.php
typo3/sysext/install/Classes/Controller/Action/Ajax/TcaExtTablesCheck.php [new file with mode: 0644]
typo3/sysext/install/Classes/Controller/AjaxController.php
typo3/sysext/install/Classes/Service/LoadTcaService.php
typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaExtTablesCheck.html [new file with mode: 0644]
typo3/sysext/install/Resources/Private/Templates/Action/Tool/ImportantActions.html
typo3/sysext/install/Resources/Public/JavaScript/Install.js
typo3/sysext/rtehtmlarea/Configuration/TCA/Overrides/sys_template.php [new file with mode: 0644]
typo3/sysext/rtehtmlarea/ext_tables.php

index ee721ca..78ec569 100644 (file)
@@ -303,7 +303,6 @@ class Bootstrap
      */
     public function handleRequest($request)
     {
-
         // Resolve request handler that were registered based on the Application
         $requestHandler = $this->resolveRequestHandler($request);
 
@@ -910,34 +909,6 @@ class Bootstrap
     }
 
     /**
-     * Load TCA for frontend
-     *
-     * This method is *only* executed in frontend scope. The idea is to execute the
-     * whole TCA and ext_tables (which manipulate TCA) on first frontend access,
-     * and then cache the full TCA on disk to be used for the next run again.
-     *
-     * This way, ext_tables.php ist not executed every time, but $GLOBALS['TCA']
-     * is still always there.
-     *
-     * @return Bootstrap
-     * @internal This is not a public API method, do not use in own extensions
-     */
-    public function loadCachedTca()
-    {
-        $cacheIdentifier = 'tca_fe_' . sha1((TYPO3_version . PATH_site . 'tca_fe'));
-        /** @var $codeCache \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend */
-        $codeCache = $this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_core');
-        if ($codeCache->has($cacheIdentifier)) {
-            // substr is necessary, because the php frontend wraps php code around the cache value
-            $GLOBALS['TCA'] = unserialize(substr($codeCache->get($cacheIdentifier), 6, -2));
-        } else {
-            $this->loadExtensionTables();
-            $codeCache->set($cacheIdentifier, serialize($GLOBALS['TCA']));
-        }
-        return $this;
-    }
-
-    /**
      * Load ext_tables and friends.
      *
      * This will mainly set up $TCA and several other global arrays
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-78384-FrontendIgnoresTCAInExtTables.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-78384-FrontendIgnoresTCAInExtTables.rst
new file mode 100644 (file)
index 0000000..823ae5f
--- /dev/null
@@ -0,0 +1,55 @@
+.. include:: ../../Includes.txt
+
+=========================================================
+Breaking: #78384 - Frontend ignores TCA in ext_tables.php
+=========================================================
+
+See :issue:`78384`
+
+Description
+===========
+
+Frontend requests no longer load :file:`ext_tables.php` in requests. The only exception is if a backend user is
+logged in to the backend at the same time to initialize the admin panel or frontend editing.
+
+
+Impact
+======
+
+Since especially a not yet cached frontend call relies on initialized `$GLOBALS['TCA']`, changes to `TCA` done
+within :file:`ext_tables.php` are now ignored and may fail.
+
+
+Affected Installations
+======================
+
+Extensions that still set, add or remove settings in `$GLOBALS['TCA']` need to be adapted. The install tool
+provides test "TCA ext_tables check" to find such extensions.
+
+
+Migration
+=========
+
+Neither direct write to `$GLOBALS['TCA']` and `$TCA` is allowed, nor indirect write
+via `ExtensionManagementUtility` methods. An example list of calls and their new positions:
+
+* `$GLOBALS['TCA`]['someTable'] = `: A full table `TCA` is added. This must be moved
+  to `Configuration/TCA/someTable.php`, see `ext:sys_note` as example.
+
+* `ExtensionManagementUtility::addStaticFile()`: A static file is registered
+  in `sys_template`. Add this to `Configuration/TCA/Overrides/sys_template.php`, see `ext:rtehtmlarea` as example.
+
+* `ExtensionManagementUtility::addTCAcolumns()`: Columns are added to a table. Add this
+  to `Configuration/TCA/Overrides/<table>.php`, see `ext:felogin` as example.
+
+* `ExtensionManagementUtility::addToAllTCAtypes()`: Fields are added to types. Add this
+  to `Configuration/TCA/Overrides/<table>.php`, see `ext:felogin` as example.
+
+* `ExtensionManagementUtility::addPiFlexFormValue()`: A new flex from in `tt_content` is registered. Add
+  this to `Configuration/TCA/Overrides/tt_content.php`, see `ext:felogin` as example.
+
+* `ExtensionUtility::registerPlugin()` and `ExtensionManagementUtility::addPlugin`: A new type item
+  is added to the `tt_content` table. Add this to `Configuration/TCA/Overrides/tt_content.php`.
+
+
+.. index:: Frontend, TCA
\ No newline at end of file
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-78384-CheckExtTablesTCAChangesInInstallTool.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-78384-CheckExtTablesTCAChangesInInstallTool.rst
new file mode 100644 (file)
index 0000000..095eddb
--- /dev/null
@@ -0,0 +1,21 @@
+.. include:: ../../Includes.txt
+
+==============================================================
+Feature: #78384 - Check ext tables TCA changes in install tool
+==============================================================
+
+See :issue:`78384`
+
+Description
+===========
+
+The install tool has a new feature to check extensions for :file:`ext_tables.php` files that still change `TCA`.
+
+
+Impact
+======
+
+Changing `TCA` in :file:`ext_tables.php` is not allowed and can lead to failed or incomplete frontend requests.
+The feature helps to find affected, loaded extensions.
+
+.. index:: TCA, ext:install
\ No newline at end of file
diff --git a/typo3/sysext/core/Tests/Unit/Core/BootstrapTest.php b/typo3/sysext/core/Tests/Unit/Core/BootstrapTest.php
deleted file mode 100644 (file)
index fc03de1..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-namespace TYPO3\CMS\Core\Tests\Unit\Core;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-/**
- * Testcase
- */
-class BootstrapTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
-{
-    /////////////////////////////////////////
-    // Tests concerning loadCachedTCA
-    /////////////////////////////////////////
-
-    /**
-     * @test
-     */
-    public function loadCachedTcaRequiresCacheFileIfCacheEntryExists()
-    {
-        /** @var $bootstrapInstance \TYPO3\CMS\Core\Core\Bootstrap|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
-        $bootstrapInstance = $this->getAccessibleMock(
-            \TYPO3\CMS\Core\Core\Bootstrap::class,
-            ['dummy'],
-            [],
-            '',
-            false
-        );
-        $mockCache = $this->getMockBuilder(\TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class)
-            ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $mockCacheManager = $this->getMockBuilder(\TYPO3\CMS\Core\Cache\CacheManager::class)
-            ->setMethods(['getCache'])
-            ->getMock();
-        $mockCacheManager
-            ->expects($this->any())
-            ->method('getCache')
-            ->will($this->returnValue($mockCache));
-        $mockCache
-            ->expects($this->any())
-            ->method('has')
-            ->will($this->returnValue(true));
-        $mockCache
-            ->expects($this->once())
-            ->method('get');
-        $bootstrapInstance->setEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class, $mockCacheManager);
-        $bootstrapInstance->loadCachedTca();
-    }
-
-    /**
-     * @test
-     */
-    public function loadCachedTcaSetsCacheEntryIfNoCacheEntryExists()
-    {
-        /** @var $bootstrapInstance \TYPO3\CMS\Core\Core\Bootstrap|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
-        $bootstrapInstance = $this->getAccessibleMock(
-            \TYPO3\CMS\Core\Core\Bootstrap::class,
-            ['loadExtensionTables'],
-            [],
-            '',
-            false
-        );
-        $mockCache = $this->getMockBuilder(\TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class)
-            ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $mockCacheManager = $this->getMockBuilder(\TYPO3\CMS\Core\Cache\CacheManager::class)
-            ->setMethods(['getCache'])
-            ->getMock();
-        $mockCacheManager
-            ->expects($this->any())
-            ->method('getCache')
-            ->will($this->returnValue($mockCache));
-        $mockCache
-            ->expects($this->any())
-            ->method('has')
-            ->will($this->returnValue(false));
-        $mockCache
-            ->expects($this->once())
-            ->method('set');
-        $bootstrapInstance->setEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class, $mockCacheManager);
-        $bootstrapInstance->loadCachedTca();
-    }
-}
index 51138bc..1a50dea 100644 (file)
@@ -19,6 +19,7 @@ use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\FrontendEditing\FrontendEditingController;
 use TYPO3\CMS\Core\Http\RequestHandlerInterface;
 use TYPO3\CMS\Core\TimeTracker\TimeTracker;
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
 use TYPO3\CMS\Core\Utility\MonitorUtility;
@@ -132,7 +133,7 @@ class RequestHandler implements RequestHandlerInterface
                     ->initializeBackendRouter()
                     ->loadExtensionTables();
         } else {
-            $this->bootstrap->loadCachedTca();
+            ExtensionManagementUtility::loadBaseTca();
         }
         $this->controller->checkAlternativeIdMethods();
         $this->controller->clear_preview();
index e22398d..92cc6c6 100644 (file)
@@ -14,7 +14,6 @@ namespace TYPO3\CMS\Frontend\Utility;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
@@ -76,7 +75,7 @@ class EidUtility
         // but in fact it is not loaded. The check below ensure that
         // TCA is still loaded if such bad extensions are installed
         if (!is_array($GLOBALS['TCA']) || !isset($GLOBALS['TCA']['pages'])) {
-            Bootstrap::getInstance()->loadCachedTca();
+            ExtensionManagementUtility::loadBaseTca();
         }
     }
 
diff --git a/typo3/sysext/install/Classes/Controller/Action/Ajax/TcaExtTablesCheck.php b/typo3/sysext/install/Classes/Controller/Action/Ajax/TcaExtTablesCheck.php
new file mode 100644 (file)
index 0000000..56e01b7
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+namespace TYPO3\CMS\Install\Controller\Action\Ajax;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Install\Service\LoadTcaService;
+
+/**
+ * Check ext_tables.php files of loaded extensions for TCA changes.
+ *
+ * Changing TCA in ext_tables is highly discouraged since core version 7
+ * and can break the frontend since core version 8.
+ *
+ * This test loads all ext_tables.php one-by-one and finds files that
+ * still change TCA.
+ */
+class TcaExtTablesCheck extends AbstractAjaxAction
+{
+    /**
+     * Load base TCA, then load each single ext_tables.php file and see if TCA changed.
+     *
+     * @return string "OK" on success, the error message otherwise
+     */
+    protected function executeAction()
+    {
+        $loadTcaService = GeneralUtility::makeInstance(LoadTcaService::class);
+        $loadTcaService->loadExtensionTablesWithoutMigration();
+        $baseTca = $GLOBALS['TCA'];
+        $messages = [];
+        foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $extensionKey => $extensionInformation) {
+            if ((is_array($extensionInformation) || $extensionInformation instanceof \ArrayAccess)
+                && $extensionInformation['ext_tables.php']
+            ) {
+                $loadTcaService->loadSingleExtTablesFile($extensionKey);
+                $newTca = $GLOBALS['TCA'];
+                if ($newTca !== $baseTca) {
+                    $messages[] = $extensionKey;
+                }
+                $baseTca = $newTca;
+            }
+        }
+        if (empty($messages)) {
+            $messages[] = 'OK';
+        }
+        return implode('<br />', $messages);
+    }
+}
index 187500c..e71e562 100644 (file)
@@ -43,7 +43,8 @@ class AjaxController extends AbstractController
         'coreUpdateMove',
         'coreUpdateActivate',
         'folderStatus',
-        'environmentStatus'
+        'environmentStatus',
+        'tcaExtTablesCheck'
     ];
 
     /**
index c2b3060..6a48115 100644 (file)
@@ -23,28 +23,20 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 class LoadTcaService
 {
-
     /**
      * Load TCA
+     * Mostly a copy of ExtensionManagementUtility to include TCA without migrations.
+     * To be used in install tool only.
      *
      * This will set up $GLOBALS['TCA']
-     */
-    public function loadExtensionTablesWithoutMigration()
-    {
-        $this->loadBaseTca();
-    }
-
-    /**
-     * Copy of ExtensionManagementUtility to include TCA without migrations
      *
      * @see \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::buildBaseTcaFromSingleFiles
      */
-    protected function loadBaseTca()
+    public function loadExtensionTablesWithoutMigration()
     {
         $GLOBALS['TCA'] = [];
 
-        $activePackages = GeneralUtility::makeInstance(PackageManager::class)
-            ->getActivePackages();
+        $activePackages = GeneralUtility::makeInstance(PackageManager::class)->getActivePackages();
 
         // First load "full table" files from Configuration/TCA
         foreach ($activePackages as $package) {
@@ -88,4 +80,37 @@ class LoadTcaService
             }
         }
     }
+
+    /**
+     * Load ext_tables.php of a single extension
+     *
+     * @param string $extensionKey The extension to load a ext_tables.php file from.
+     * @return void
+     */
+    public function loadSingleExtTablesFile(string $extensionKey)
+    {
+        global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
+        global $TBE_MODULES, $TBE_MODULES_EXT, $TCA;
+        global $PAGES_TYPES, $TBE_STYLES;
+        global $_EXTKEY;
+
+        if (!isset($GLOBALS['TYPO3_LOADED_EXT'][$extensionKey])) {
+            throw new \RuntimeException(
+                'Extension ' . $extensionKey . ' does not exist in TYPO3_LOADED_EXT',
+                1477217619
+            );
+        }
+
+        $extensionInformation = $GLOBALS['TYPO3_LOADED_EXT'][$extensionKey];
+        $_EXTKEY = $extensionKey;
+        // Load each ext_tables.php file of loaded extensions
+        if ((is_array($extensionInformation) || $extensionInformation instanceof \ArrayAccess)
+            && $extensionInformation['ext_tables.php']
+        ) {
+            // $_EXTKEY and $_EXTCONF are available in ext_tables.php
+            // and are explicitly set in cached file as well
+            $_EXTCONF = $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$_EXTKEY];
+            require $extensionInformation['ext_tables.php'];
+        }
+    }
 }
diff --git a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaExtTablesCheck.html b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaExtTablesCheck.html
new file mode 100644 (file)
index 0000000..b318b69
--- /dev/null
@@ -0,0 +1,25 @@
+<h3>TCA in ext_tables.php check</h3>
+
+<p>
+       Check if an extension changes $GLOBALS['TCA'] in ext_tables.php.
+</p>
+
+<form method="post">
+       <f:render partial="Action/Common/HiddenFormFields" arguments="{_all}" />
+       <div id="tcaExtTablesCheck">
+               <div id="tcaExtTablesCheck-loading" class="t3js-message typo3-message alert alert-loading" role="alert" style="display: none;">
+                       <h4>Loading...</h4>
+               </div>
+               <div id="tcaExtTablesCheck-ok" class="t3js-message typo3-message alert alert-success" role="alert" style="display: none;">
+                       <h4>No TCA changes in ext_tables.php files. Good job!</h4>
+               </div>
+               <div id="tcaExtTablesCheck-fatal" class="t3js-message typo3-message alert alert-danger" role="alert" style="display: none;">
+                       <h4>Something went wrong checking ext_tables.php, use "Check for broken extensions"!</h4>
+               </div>
+               <div id="tcaExtTablesCheck-broken" class="t3js-message typo3-message alert alert-danger" role="alert" style="display: none;">
+                               <h4>Extensions change TCA in ext_tables.php, check for ExtensionManagementUtility and $GLOBALS['TCA']:</h4>
+                               <p class="messageText"></p>
+               </div>
+               <f:render partial="Action/Common/SubmitButton" arguments="{name:'tceExtTablesCheck', text:'Check loaded extensions'}"/>
+       </div>
+</form>
\ No newline at end of file
index 6d935f0..6a6a8f2 100644 (file)
@@ -38,6 +38,9 @@
        <f:render partial="Action/Tool/ImportantActions/TcaMigrations" arguments="{_all}"/>
        <hr />
 
+       <f:render partial="Action/Tool/ImportantActions/TcaExtTablesCheck" arguments="{_all}"/>
+       <hr />
+
        <f:render partial="Action/Tool/ImportantActions/CoreUpdateButton" arguments="{_all}"/>
        <hr />
 
index 36d2aa3..2a651ab 100644 (file)
@@ -215,6 +215,38 @@ TYPO3.Install.ExtensionChecker = {
        }
 };
 
+TYPO3.Install.TcaExtTablesChecker = {
+       checkTcaExtTables: function() {
+               var self = this;
+               var url = location.href + '&install[controller]=ajax&install[action]=tcaExtTablesCheck';
+
+               $('button', '#tcaExtTablesCheck').hide();
+               $('#tcaExtTablesCheck-loading').show();
+
+               $.ajax({
+                       url: url,
+                       cache: false,
+                       success: function(data) {
+                               if (data === 'OK') {
+                                       $('#tcaExtTablesCheck-loading').hide();
+                                       $('#tcaExtTablesCheck-ok').show();
+                               } else {
+                                       if (data === 'unauthorized') {
+                                               location.reload();
+                                       }
+                                       $('#tcaExtTablesCheck-loading').hide();
+                                       // secure me!
+                                       $('#tcaExtTablesCheck-broken').show().find('.messageText').html(data);
+                               }
+                       },
+                       error: function() {
+                               $('#tcaExtTablesCheck-loading').hide();
+                               $('#tcaExtTablesCheck-fatal').show();
+                       }
+               });
+       }
+};
+
 TYPO3.Install.Status = {
        getFolderStatus: function() {
                var url = location.href + '&install[controller]=ajax&install[action]=folderStatus';
@@ -618,6 +650,16 @@ $(function() {
                }));
        }
 
+       // Handle TCA ext_tables check
+       var $tcaExtTablesCheckSection = $('#tcaExtTablesCheck');
+       if ($tcaExtTablesCheckSection) {
+               $tcaExtTablesCheckSection.on('click', 'button', (function(e) {
+                       TYPO3.Install.TcaExtTablesChecker.checkTcaExtTables();
+                       e.preventDefault();
+                       return false;
+               }));
+       }
+
        var $installLeft = $('.t3js-list-group-wrapper');
        if ($installLeft.length > 0) {
                TYPO3.Install.Status.getFolderStatus();
diff --git a/typo3/sysext/rtehtmlarea/Configuration/TCA/Overrides/sys_template.php b/typo3/sysext/rtehtmlarea/Configuration/TCA/Overrides/sys_template.php
new file mode 100644 (file)
index 0000000..248d30d
--- /dev/null
@@ -0,0 +1,5 @@
+<?php
+defined('TYPO3_MODE') or die();
+
+// Add static template for Click-enlarge rendering
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('rtehtmlarea', 'static/clickenlarge/', 'Clickenlarge Rendering');
index aa84db9..6796d25 100644 (file)
@@ -1,9 +1,6 @@
 <?php
 defined('TYPO3_MODE') or die();
 
-// Add static template for Click-enlarge rendering
-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('rtehtmlarea', 'static/clickenlarge/', 'Clickenlarge Rendering');
-
 // Add Abbreviation records
 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_rtehtmlarea_acronym');
 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('tx_rtehtmlarea_acronym', 'EXT:rtehtmlarea/Resources/Private/Language/locallang_csh_abbreviation.xlf');