[TASK] Backport Fluid from FLOW3 1.0.5
authorTymoteusz Motylewski <t.motylewski@gmail.com>
Fri, 20 Jul 2012 21:29:17 +0000 (23:29 +0200)
committerFelix Oertel <mehl@foertel.com>
Sat, 21 Jul 2012 11:24:40 +0000 (13:24 +0200)
Make Extbase Fluid in sync with FLOW3 1.0.5 (Fluid rev 152ae289)

Change-Id: I0c043b6cc7bc7e3dac0145d83a2ff885a34b5cfc
Resolves: #39149
Releases: 6.0
Reviewed-on: http://review.typo3.org/12952
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
Tested-by: Oliver Klee
Reviewed-by: Daniel Lorenz
Tested-by: Daniel Lorenz
Reviewed-by: Felix Oertel
Tested-by: Felix Oertel
typo3/sysext/fluid/Classes/Core/Compiler/AbstractCompiledTemplate.php
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ViewHelperNode.php
typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/AliasViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/CommentViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/SelectViewHelper.php
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/AbstractViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/SelectViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/HtmlentitiesViewHelperTest.php

index cc7cde5..af68983 100644 (file)
@@ -50,15 +50,23 @@ abstract class Tx_Fluid_Core_Compiler_AbstractCompiledTemplate implements Tx_Flu
                }
                if (isset($this->viewHelpersByPositionAndContext[$uniqueCounter])) {
                        if ($this->viewHelpersByPositionAndContext[$uniqueCounter]->contains($renderingContext)) {
-                               return $this->viewHelpersByPositionAndContext[$uniqueCounter][$renderingContext];
+                               $viewHelper = $this->viewHelpersByPositionAndContext[$uniqueCounter][$renderingContext];
+                               $viewHelper->resetState();
+                               return $viewHelper;
                        } else {
                                $viewHelperInstance = self::$objectContainer->getInstance($viewHelperName);
+                               if ($viewHelperInstance instanceof t3lib_Singleton) {
+                                       $viewHelperInstance->resetState();
+                               }
                                $this->viewHelpersByPositionAndContext[$uniqueCounter]->attach($renderingContext, $viewHelperInstance);
                                return $viewHelperInstance;
                        }
                } else {
                        $this->viewHelpersByPositionAndContext[$uniqueCounter] = t3lib_div::makeInstance('Tx_Extbase_Persistence_ObjectStorage');
                        $viewHelperInstance = self::$objectContainer->getInstance($viewHelperName);
+                       if ($viewHelperInstance instanceof t3lib_Singleton) {
+                               $viewHelperInstance->resetState();
+                       }
                        $this->viewHelpersByPositionAndContext[$uniqueCounter]->attach($renderingContext, $viewHelperInstance);
                        return $viewHelperInstance;
                }
index 9e26245..4c9440d 100644 (file)
@@ -100,11 +100,9 @@ class Tx_Fluid_Core_Parser_SyntaxTree_ViewHelperNode extends Tx_Fluid_Core_Parse
         * @return object evaluated node after the view helper has been called.
         */
        public function evaluate(Tx_Fluid_Core_Rendering_RenderingContextInterface $renderingContext) {
-               $objectManager = $renderingContext->getObjectManager();
-               $contextVariables = $renderingContext->getTemplateVariableContainer()->getAllIdentifiers();
-
                if ($this->viewHelpersByContext->contains($renderingContext)) {
                        $viewHelper = $this->viewHelpersByContext[$renderingContext];
+                       $viewHelper->resetState();
                } else {
                        $viewHelper = clone $this->uninitializedViewHelper;
                        $this->viewHelpersByContext->attach($renderingContext, $viewHelper);
index 17ab0fa..d7bb36b 100644 (file)
@@ -458,6 +458,16 @@ abstract class Tx_Fluid_Core_ViewHelper_AbstractViewHelper {
        static public function renderStatic(array $arguments, Closure $renderChildrenClosure, Tx_Fluid_Core_Rendering_RenderingContextInterface $renderingContext) {
                return NULL;
        }
+
+       /**
+        * Resets the ViewHelper state.
+        *
+        * Overwrite this method if you need to get a clean state of your ViewHelper.
+        *
+        * @return void
+        */
+       public function resetState() {
+       }
 }
 
 ?>
\ No newline at end of file
index 7d02a21..b7c34d7 100644 (file)
@@ -42,8 +42,9 @@
 class Tx_Fluid_ViewHelpers_AliasViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper {
 
        /**
+        * Render alias
         *
-        * @param array $map array that specifies which variables should be mapped to which alias
+        * @param array $map Array that specifies which variables should be mapped to which alias
         * @return string Rendered string
         * @api
         */
index e15e296..8554cf8 100644 (file)
@@ -12,7 +12,7 @@
 
 /**
  * This ViewHelper prevents rendering of any content inside the tag
- * Note: Contents of the comment will still be **parsed** thus throwing an
+ * Note: Contents of the comment will still be *parsed* thus throwing an
  * Exception if it contains syntax errors. You can put child nodes in
  * CDATA tags to avoid this.
  *
@@ -58,4 +58,4 @@ class Tx_Fluid_ViewHelpers_CommentViewHelper extends Tx_Fluid_Core_ViewHelper_Ab
        }
 }
 
-?>
\ No newline at end of file
+?>
index eaa8cef..b8b4499 100644 (file)
@@ -223,25 +223,34 @@ class Tx_Fluid_ViewHelpers_Form_SelectViewHelper extends Tx_Fluid_ViewHelpers_Fo
         */
        protected function getSelectedValue() {
                $value = $this->getValue();
-               if (!$this->hasArgument('optionValueField')) {
-                       return $value;
-               }
-               if (!is_array($value) && !($value instanceof Iterator)) {
-                       if (is_object($value)) {
-                               return Tx_Extbase_Reflection_ObjectAccess::getPropertyPath($value, $this->arguments['optionValueField']);
-                       } else {
-                               return $value;
-                       }
+               if (!is_array($value) && !($value instanceof  Traversable)) {
+                       return $this->getOptionValueScalar($value);
                }
                $selectedValues = array();
                foreach($value as $selectedValueElement) {
-                       if (is_object($selectedValueElement)) {
-                               $selectedValues[] = Tx_Extbase_Reflection_ObjectAccess::getPropertyPath($selectedValueElement, $this->arguments['optionValueField']);
+                       $selectedValues[] = $this->getOptionValueScalar($selectedValueElement);
+               }
+               return $selectedValues;
+       }
+
+       /**
+        * Get the option value for an object
+        *
+        * @param mixed $valueElement
+        * @return string
+        */
+       protected function getOptionValueScalar($valueElement) {
+               if (is_object($valueElement)) {
+                       if ($this->hasArgument('optionValueField')) {
+                               return Tx_Extbase_Reflection_ObjectAccess::getPropertyPath($valueElement, $this->arguments['optionValueField']);
+                       } else if ($this->persistenceManager->getBackend()->getIdentifierByObject($valueElement) !== NULL){
+                               return $this->persistenceManager->getBackend()->getIdentifierByObject($valueElement);
                        } else {
-                               $selectedValues[] = $selectedValueElement;
+                               return (string)$valueElement;
                        }
+               } else {
+                       return $valueElement;
                }
-               return $selectedValues;
        }
 
        /**
index 470f0f1..d00f4a1 100644 (file)
@@ -18,6 +18,7 @@ require_once(dirname(__FILE__) . '/../Fixtures/TestViewHelper2.php');
  *
  */
 class Tx_Fluid_Tests_Unit_Core_ViewHelper_AbstractViewHelperTest extends Tx_Extbase_Tests_Unit_BaseTestCase {
+
        /**
         * @test
         */
@@ -33,8 +34,8 @@ class Tx_Fluid_Tests_Unit_Core_ViewHelper_AbstractViewHelperTest extends Tx_Extb
                $isRequired = TRUE;
                $expected = new Tx_Fluid_Core_ViewHelper_ArgumentDefinition($name, $type, $description, $isRequired);
 
-               $viewHelper->_call('registerArgument', $name, $type, $isRequired, $description);
-               $this->assertEquals($viewHelper->prepareArguments(), array($name => $expected), 'Argument definitions not returned correctly.');
+               $viewHelper->_call('registerArgument', $name, $type, $description, $isRequired);
+               $this->assertEquals(array($name => $expected), $viewHelper->prepareArguments(), 'Argument definitions not returned correctly.');
        }
 
        /**
@@ -49,8 +50,8 @@ class Tx_Fluid_Tests_Unit_Core_ViewHelper_AbstractViewHelperTest extends Tx_Extb
                $type = "string";
                $isRequired = TRUE;
 
-               $viewHelper->_call('registerArgument', $name, $type, $isRequired, $description);
-               $viewHelper->_call('registerArgument', $name, "integer", $isRequired, $description);
+               $viewHelper->_call('registerArgument', $name, $type, $description, $isRequired);
+               $viewHelper->_call('registerArgument', $name, "integer", $description, $isRequired);
        }
 
        /**
@@ -70,8 +71,8 @@ class Tx_Fluid_Tests_Unit_Core_ViewHelper_AbstractViewHelperTest extends Tx_Extb
                $isRequired = TRUE;
                $expected = new Tx_Fluid_Core_ViewHelper_ArgumentDefinition($name, $overriddenType, $overriddenDescription, $isRequired);
 
-               $viewHelper->_call('registerArgument', $name, $type, $isRequired, $description);
-               $viewHelper->_call('overrideArgument', $name, $overriddenType, $isRequired, $overriddenDescription);
+               $viewHelper->_call('registerArgument', $name, $type, $description, $isRequired);
+               $viewHelper->_call('overrideArgument', $name, $overriddenType, $overriddenDescription, $isRequired);
                $this->assertEquals($viewHelper->prepareArguments(), array($name => $expected), 'Argument definitions not returned correctly. The original ArgumentDefinition could not be overridden.');
        }
 
@@ -85,7 +86,7 @@ class Tx_Fluid_Tests_Unit_Core_ViewHelper_AbstractViewHelperTest extends Tx_Extb
                $viewHelper = $this->getAccessibleMock('Tx_Fluid_Core_ViewHelper_AbstractViewHelper', array('render'), array(), '', FALSE);
                $viewHelper->injectReflectionService($mockReflectionService);
 
-               $viewHelper->_call('overrideArgument', 'argumentName', 'string', TRUE, 'description');
+               $viewHelper->_call('overrideArgument', 'argumentName', 'string', 'description', TRUE);
        }
 
        /**
@@ -112,13 +113,13 @@ class Tx_Fluid_Tests_Unit_Core_ViewHelper_AbstractViewHelperTest extends Tx_Extb
                $availableClassNames = array(
                        array('Tx_Fluid_Core_Fixtures_TestViewHelper'),
                );
-               $reflectionService = new Tx_Extbase_Reflection_Service();
-               // $reflectionService->setStatusCache($this->getMock('Tx_Fluid_Cache_Frontend_StringFrontend', array(), array(), '', FALSE));
                $dataCacheMock = $this->getMock('t3lib_cache_frontend_VariableFrontend', array(), array(), '', FALSE);
                $dataCacheMock->expects($this->any())->method('has')->will($this->returnValue(TRUE));
                $dataCacheMock->expects($this->any())->method('get')->will($this->returnValue(array()));
+
+               $reflectionService = new Tx_Extbase_Reflection_Service();
                $reflectionService->setDataCache($dataCacheMock);
-               // $reflectionService->buildReflectionData($availableClassNames);
+
 
                $viewHelper = new Tx_Fluid_Core_Fixtures_TestViewHelper();
                $viewHelper->injectReflectionService($reflectionService);
@@ -144,13 +145,13 @@ class Tx_Fluid_Tests_Unit_Core_ViewHelper_AbstractViewHelperTest extends Tx_Extb
                $availableClassNames = array(
                        array('Tx_Fluid_Core_Fixtures_TestViewHelper2'),
                );
-               $reflectionService = new Tx_Extbase_Reflection_Service();
-               // $reflectionService->setStatusCache($this->getMock('Tx_Fluid_Cache_Frontend_StringFrontend', array(), array(), '', FALSE));
                $dataCacheMock = $this->getMock('t3lib_cache_frontend_VariableFrontend', array(), array(), '', FALSE);
                $dataCacheMock->expects($this->any())->method('has')->will($this->returnValue(TRUE));
                $dataCacheMock->expects($this->any())->method('get')->will($this->returnValue(array()));
+
+               $reflectionService = new Tx_Extbase_Reflection_Service();
                $reflectionService->setDataCache($dataCacheMock);
-               // $reflectionService->buildReflectionData($availableClassNames);
+
 
                $viewHelper = new Tx_Fluid_Core_Fixtures_TestViewHelper2();
                $viewHelper->injectReflectionService($reflectionService);
index 6c4f399..54489a2 100644 (file)
@@ -21,7 +21,7 @@ require_once(dirname(__FILE__) . '/FormFieldViewHelperBaseTestcase.php');
 class Tx_Fluid_Tests_Unit_ViewHelpers_Form_SelectViewHelperTest extends Tx_Fluid_Tests_Unit_ViewHelpers_Form_FormFieldViewHelperBaseTestcase {
 
        /**
-        * var Tx_Fluid_ViewHelpers_Form_SelectViewHelper
+        * @var Tx_Fluid_ViewHelpers_Form_SelectViewHelper
         */
        protected $viewHelper;
 
@@ -231,6 +231,51 @@ class Tx_Fluid_Tests_Unit_ViewHelpers_Form_SelectViewHelperTest extends Tx_Fluid
 
        /**
         * @test
+        * @author Johannes K√ľnsebeck <jk@hdnet.de>
+        */
+       public function multipleSelectOnDomainObjectsCreatesExpectedOptionsWithoutOptionValueField() {
+               $mockPersistenceManager = $this->getMock('Tx_Extbase_Persistence_ManagerInterface');
+
+               $mockBackend = $this->getMock('Tx_Extbase_Persistence_Backend',array('getIdentifierByObject'),array(),'',false);
+               $mockBackend->expects($this->any())->method('getIdentifierByObject')->will($this->returnCallback(
+                       function ($object) {
+                               return $object->getId();
+                       }
+               ));
+               $mockPersistenceManager->expects($this->any())->method('getBackend')->will($this->returnValue($mockBackend));
+               $this->viewHelper->injectPersistenceManager($mockPersistenceManager);
+
+               $this->tagBuilder = new Tx_Fluid_Core_ViewHelper_TagBuilder();
+               $this->viewHelper->expects($this->exactly(3))->method('registerFieldNameForFormTokenGeneration')->with('myName[]');
+
+               $user_is = new Tx_Fluid_ViewHelpers_Fixtures_UserDomainClass(1, 'Ingmar', 'Schlecht');
+               $user_sk = new Tx_Fluid_ViewHelpers_Fixtures_UserDomainClass(2, 'Sebastian', 'Kurfuerst');
+               $user_rl = new Tx_Fluid_ViewHelpers_Fixtures_UserDomainClass(3, 'Robert', 'Lemke');
+
+               $this->arguments['options'] = array($user_is,$user_sk,$user_rl);
+               $this->arguments['value'] = array($user_rl, $user_is);
+               $this->arguments['optionLabelField'] = 'lastName';
+               $this->arguments['name'] = 'myName';
+               $this->arguments['multiple'] = 'multiple';
+
+               $this->injectDependenciesIntoViewHelper($this->viewHelper);
+
+               $this->viewHelper->initializeArguments();
+               $this->viewHelper->initialize();
+               $actual = $this->viewHelper->render();
+
+               $expected = '<input type="hidden" name="myName" value="" />'.
+                       '<select multiple="multiple" name="myName[]">' .
+                       '<option value="1" selected="selected">Schlecht</option>' . chr(10) .
+                       '<option value="2">Kurfuerst</option>' . chr(10) .
+                       '<option value="3" selected="selected">Lemke</option>' . chr(10) .
+                       '</select>';
+               $this->assertSame($expected, $actual);
+       }
+
+
+       /**
+        * @test
         */
        public function selectWithoutFurtherConfigurationOnDomainObjectsUsesUuidForValueAndLabel() { $this->markTestIncomplete("TODO - fix test in backporter");
                $mockPersistenceManager = $this->getMock('Tx_Extbase_Persistence_ManagerInterface');
index 9efd29b..ec76c81 100644 (file)
@@ -61,8 +61,7 @@ class Tx_Fluid_Tests_Unit_ViewHelpers_Format_HtmlentitiesViewHelperTest extends
         * @test
         */
        public function renderDecodesSimpleString() {
-               $copyrightSymbol = chr(169);
-               $source = 'Some special characters: &' . $copyrightSymbol . '"\'';
+               $source = 'Some special characters: &'.chr(169).'"\'';
                $expectedResult = 'Some special characters: &amp;&copy;&quot;\'';
                $actualResult = $this->viewHelper->render($source);
                $this->assertEquals($expectedResult, $actualResult);
@@ -72,8 +71,7 @@ class Tx_Fluid_Tests_Unit_ViewHelpers_Format_HtmlentitiesViewHelperTest extends
         * @test
         */
        public function renderRespectsKeepQuoteArgument() {
-               $copyrightSymbol = chr(169);
-               $source = 'Some special characters: &' . $copyrightSymbol . '"\'';
+               $source = 'Some special characters: &'.chr(169).'"\'';
                $expectedResult = 'Some special characters: &amp;&copy;"\'';
                $actualResult = $this->viewHelper->render($source, TRUE);
                $this->assertEquals($expectedResult, $actualResult);
@@ -83,9 +81,8 @@ class Tx_Fluid_Tests_Unit_ViewHelpers_Format_HtmlentitiesViewHelperTest extends
         * @test
         */
        public function renderRespectsEncodingArgument() {
-               $copyrightSymbol = chr(169);
-               $source = utf8_decode('Some special characters: &' . $copyrightSymbol . '"\'');
-               $expectedResult = 'Some special characters: &amp;?&quot;\'';
+               $source = utf8_decode('Some special characters: &¬©"\'');
+               $expectedResult = 'Some special characters: &amp;&copy;&quot;\'';
                $actualResult = $this->viewHelper->render($source, FALSE, 'ISO-8859-1');
                $this->assertEquals($expectedResult, $actualResult);
        }