Revert "[!!!][TASK] Refactor property access in compiled fluid templates" 82/39282/3
authorChristian Kuhn <lolli@schwarzbu.ch>
Tue, 5 May 2015 16:17:39 +0000 (18:17 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 5 May 2015 16:27:39 +0000 (18:27 +0200)
This reverts commit 3bebd954624564ea64ee5e49bbbadf0a407947eb.

The patch to optimize compiled fluid templates breaks too heavily
and is not stable enough. A different solution is on the horizon
and may be picked up later again.

Change-Id: I2d7b0a42f8e1aa4750893f041aa5e617c82eb127
Resolves: #66808
Reverts: #66758
Releases: master
Reviewed-on: http://review.typo3.org/39282
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/core/Documentation/Changelog/master/Breaking-66758-FluidRefactorPropertyAccess.rst [deleted file]
typo3/sysext/fluid/Classes/Core/Compiler/AbstractCompiledTemplate.php
typo3/sysext/fluid/Classes/Core/Compiler/TemplateCompiler.php
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ObjectAccessorNode.php

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-66758-FluidRefactorPropertyAccess.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-66758-FluidRefactorPropertyAccess.rst
deleted file mode 100644 (file)
index 2e1bde7..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-=======================================================================
-Breaking: #66758 - Refactor property access in compiled fluid templates
-=======================================================================
-
-Description
-===========
-
-Refactors property access in Fluid templates to use a closure that calculates the getters and/or array
-access keys to resolve the property path and self replaces this after the first rendering in the compiled
-template. This improves property access dramatically after the first request.
-
-Impact
-======
-
-This breaks if you access different types of data with the same path. For example if you have an array in
-which arrays and objects are nested on the same level.
-
-Example::
-
-  Array (available in Fluid as {data})
-    Object (getFoo())
-    Array['foo']
-
-  <f:for each="data" as="element">
-       {element.foo}
-  </f:for>
-
-This code would break with the change as the closure would determine that accessing {element.foo} needs to
-use the getter method `getFoo()` so accessing the second element which is an array would break as fluid would
-try to access `foo` as well with `getFoo()`.
\ No newline at end of file
index e363739..efcb4b3 100644 (file)
@@ -95,17 +95,4 @@ abstract class AbstractCompiledTemplate implements \TYPO3\CMS\Fluid\Core\Parser\
                return static::$defaultEncoding;
        }
 
-       /**
-        * @param array $replacements
-        */
-       public function replacePropertyAccessors($replacements, $file) {
-               $code = file_get_contents($file);
-
-               foreach ($replacements as $pattern => $replacementCode) {
-                       $code = preg_replace($pattern, $replacementCode, $code);
-               }
-
-               file_put_contents($file, $code);
-       }
-
 }
index 8cb0fdd..c4ebb66 100644 (file)
@@ -86,8 +86,6 @@ class TemplateCompiler implements \TYPO3\CMS\Core\SingletonInterface {
                $templateCode = <<<EOD
 %s {
 
-public \$propertyAccessorReplacements = array();
-
 public function getVariableContainer() {
        // @todo
        return new \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer();
@@ -141,11 +139,6 @@ public function %s(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface \$r
 
 %s
 
-       if (\$this->propertyAccessorReplacements !== array()) {
-               \$this->replacePropertyAccessors(\$this->propertyAccessorReplacements, __FILE__);
-               \$this->propertyAccessorReplacements = array();
-       }
-
 return %s;
 }
 
@@ -277,32 +270,16 @@ EOD;
        protected function convertObjectAccessorNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode $node) {
                $objectPathSegments = explode('.', $node->getObjectPath());
                $firstPathElement = array_shift($objectPathSegments);
-               $nodeIdentifier = md5(spl_object_hash($node) . $node->getObjectPath() . uniqid());
                if ($objectPathSegments === array()) {
                        return array(
                                'initialization' => '',
                                'execution' => sprintf('$currentVariableContainer->getOrNull(\'%s\')', $firstPathElement)
                        );
                } else {
-                       $executionCode = <<<EOD
-/** ###%s### */ call_user_func(function(\$self) use (\$currentVariableContainer, \$renderingContext) {
-       \$subject = \$currentVariableContainer->getOrNull('%s');
-
-       \$accessors = \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode::getPropertyAccessors(\$subject, %s);
-
-       if (\$accessors !== NULL) {
-               \$self->propertyAccessorReplacements['~/\*\* ###%s### \*/ .* /\*\* ###%s### \*/~s'] = '\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode::resolvePropertyAccessors(\$currentVariableContainer->getOrNull(\'%s\'), ' . var_export(\$accessors, TRUE) . ')';
-               return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode::resolvePropertyAccessors(\$subject, \$accessors);
-       } else {
-               \$self->propertyAccessorReplacements['~/\*\* ###%s### \*/ .* /\*\* ###%s### \*/~s'] = '\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode::getPropertyPath(\$currentVariableContainer->getOrNull(\'%s\'), \'%s\', \$renderingContext)';
-               return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode::getPropertyPath(\$subject, '%s', \$renderingContext);
-       }
-}, \$self) /** ###%s### */
-
-EOD;
+                       $executionCode = '\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode::getPropertyPath($currentVariableContainer->getOrNull(\'%s\'), \'%s\', $renderingContext)';
                        return array(
                                'initialization' => '',
-                               'execution' => sprintf($executionCode, $nodeIdentifier, $firstPathElement, var_export($objectPathSegments, TRUE), $nodeIdentifier, $nodeIdentifier, $firstPathElement, $nodeIdentifier, $nodeIdentifier, $firstPathElement, implode('.', $objectPathSegments), implode('.', $objectPathSegments), $nodeIdentifier)
+                               'execution' => sprintf($executionCode, $firstPathElement, implode('.', $objectPathSegments))
                        );
                }
        }
index 0ff518c..a4ba127 100644 (file)
@@ -92,68 +92,4 @@ class ObjectAccessorNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\Abstrac
                }
                return $subject;
        }
-
-       /**
-        * get property accessors for a given property path.
-        *
-        * @param mixed $subject
-        * @param array $propertyPathSegments
-        * @return null|string
-        */
-       static public function getPropertyAccessors($subject, $propertyPathSegments) {
-               $accessors = array();
-               foreach ($propertyPathSegments as $pathSegment) {
-                       if ($subject === NULL || is_scalar($subject)) {
-                               return NULL;
-                       }
-
-                       if (is_array($subject)) {
-                               $accessors[] = array('t' => 'a', 'c' => $pathSegment);
-                       }
-
-                       if (is_object($subject)) {
-                               $getterMethodName = 'get' . ucfirst($pathSegment);
-                               if (!is_callable(array($subject, $getterMethodName))) {
-                                       $getterMethodName = 'is' . ucfirst($pathSegment);
-                               }
-                               if (!is_callable(array($subject, $getterMethodName))) {
-                                       $getterMethodName = 'has' . ucfirst($pathSegment);
-                               }
-                               if (!is_callable(array($subject, $getterMethodName))) {
-                                       return NULL;
-                               }
-
-                               $accessors[] = array('t' => 'o', 'c' => $getterMethodName);
-                       }
-
-                       $subject = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getPropertyInternal($subject, $pathSegment, FALSE, $exists);
-               }
-
-               return $accessors;
-       }
-
-       /**
-        * Resolves property accessors from compiled templates.
-        *
-        * @param mixed $subject
-        * @param array $accessors
-        * @return mixed
-        */
-       static public function resolvePropertyAccessors($subject, array $accessors) {
-               foreach ($accessors as $accessor) {
-                       if ($subject === NULL) {
-                               return NULL;
-                       }
-
-                       if ($accessor['t'] === 'a') {
-                               $subject = $subject[$accessor['c']];
-                       }
-
-                       if ($accessor['t'] === 'o') {
-                               $subject = $subject->{$accessor['c']}();
-                       }
-               }
-
-               return $subject;
-       }
 }