[FEATURE] Add Fluid interceptor registration 55/48055/13
authorNicole Cordes <typo3@cordes.co>
Tue, 10 May 2016 08:24:15 +0000 (10:24 +0200)
committerBenni Mack <benni@typo3.org>
Tue, 19 Jul 2016 20:22:37 +0000 (22:22 +0200)
In Fluid Standalone it is possible to register interceptors to manipulate
the template output on different events. The core should offer a way to
register own interceptor classes. This patch introduces a way to register
classes in TYPO3_CONF_VARS[fluid] which are added to the Fluid Parser
Configuration.

Resolves: #76107
Releases: master
Change-Id: Ib46ed602166161c6d625dcd8419954ae68bff0de
Reviewed-on: https://review.typo3.org/48055
Tested-by: Bamboo TYPO3com <info@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Benni Mack <benni@typo3.org>
Reviewed-by: Peter Foerger <pfoerger@mac.com>
Tested-by: Benni Mack <benni@typo3.org>
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Documentation/Changelog/master/Feature-76107-AddFluidInterceptorRegistration.rst [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Rendering/RenderingContext.php

index 3107b6a..c3c932c 100644 (file)
@@ -282,6 +282,9 @@ return array(
                 'vimeo' => 'video/vimeo',
             )
         ),
+        'fluid' => array(
+            'interceptors' => array(),
+        ),
         'livesearch' => array(),    // Array: keywords used for commands to search for specific tables
         'isInitialInstallationInProgress' => false,        // Boolean: If TRUE, the installation is 'in progress'. This value is handled within the install tool step installer internally.
         'isInitialDatabaseImportDone' => true,        // Boolean: If TRUE, the database import is finished. This value is handled within the install tool step installer internally.
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-76107-AddFluidInterceptorRegistration.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-76107-AddFluidInterceptorRegistration.rst
new file mode 100644 (file)
index 0000000..35c23ca
--- /dev/null
@@ -0,0 +1,57 @@
+====================================================
+Feature: #76107 - Add fluid interceptor registration
+====================================================
+
+Description
+===========
+
+Interceptors in Fluid Standalone were introduced to be able to change the template output.
+The Fluid API already allows for registration of custom interceptors. Now it is possible to define
+custom interceptors via the following option:
+
+.. code-block:: php
+
+   $GLOBALS['TYPO3_CONF_VARS']['fluid']['interceptors']
+
+Interceptors registered here are added to the Fluid parser configuration.
+
+Impact
+======
+
+Extensions are able to register custom interceptors using the mentioned configuration sections.
+
+Registered interceptor classes have to implement the
+``\TYPO3Fluid\Fluid\Core\Parser\InterceptorInterface``.
+
+Impact
+======
+
+Extensions are able to register custom interceptors using the available configuration in
+``$TYPO3_CONF_VARS[fluid][interceptors]``.
+
+Registered classes have to implement the \TYPO3Fluid\Fluid\Core\Parser\InterceptorInterface.
+
+.. code-block:: php
+
+   // Register own interceptor to fluid parser configuration
+   $GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'][\TYPO3\CMS\Fluid\Core\Parser\Interceptor\DebugInterceptor::class] =
+      \TYPO3\CMS\Fluid\Core\Parser\Interceptor\DebugInterceptor::class;
+
+.. code-block:: php
+
+   use TYPO3Fluid\Fluid\Core\Parser\InterceptorInterface;
+   use TYPO3Fluid\Fluid\Core\Parser\ParsingState;
+   use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\NodeInterface;
+
+   class DebugInterceptor implements InterceptorInterface
+   {
+      public function process(NodeInterface $node, $interceptorPosition, ParsingState $parsingState)
+      {
+         return $node;
+      }
+
+      public function getInterceptionPoints()
+      {
+         return [];
+      }
+   }
index e1316aa..d52e980 100644 (file)
@@ -18,12 +18,14 @@ use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Object\ObjectManager;
 use TYPO3\CMS\Fluid\Core\Cache\FluidTemplateCache;
+use TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface;
 use TYPO3\CMS\Fluid\Core\Parser\PreProcessor\XmlnsNamespaceTemplatePreProcessor;
 use TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\Expression\LegacyNamespaceExpressionNode;
 use TYPO3\CMS\Fluid\Core\Variables\CmsVariableProvider;
 use TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperResolver;
 use TYPO3\CMS\Fluid\View\TemplatePaths;
 use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler;
+use TYPO3Fluid\Fluid\Core\Parser\Configuration;
 use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\Expression\CastingExpressionNode;
 use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\Expression\MathExpressionNode;
 use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\Expression\TernaryExpressionNode;
@@ -140,6 +142,28 @@ class RenderingContext extends \TYPO3Fluid\Fluid\Core\Rendering\RenderingContext
     }
 
     /**
+     * Build parser configuration
+     *
+     * @return Configuration
+     * @throws \InvalidArgumentException if a class not implementing InterceptorInterface was registered
+     */
+    public function buildParserConfiguration()
+    {
+        $parserConfiguration = parent::buildParserConfiguration();
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'])) {
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'] as $className) {
+                $interceptor = GeneralUtility::makeInstance($className);
+                if (!$interceptor instanceof InterceptorInterface) {
+                    throw new \InvalidArgumentException('Interceptor "' . $className . '" needs to implement ' . InterceptorInterface::class . '.', 1462869795);
+                }
+                $parserConfiguration->addInterceptor($interceptor);
+            }
+        }
+
+        return $parserConfiguration;
+    }
+
+    /**
      * Set legacy compatibility mode on/off by boolean.
      * If set to FALSE, the ViewHelperResolver will only load a limited sub-set of ExpressionNodes,
      * making Fluid behave like the legacy version of the CMS core extension.