[TASK] Sync CMS Fluid with Flow Fluid 1.1 (part2)
authorTymoteusz Motylewski <t.motylewski@gmail.com>
Sun, 3 Mar 2013 17:53:42 +0000 (18:53 +0100)
committerMarc Bastian Heinrichs <typo3@mbh-software.de>
Sun, 3 Mar 2013 21:08:21 +0000 (22:08 +0100)
This is the second part of a backport fluid from Flow.

Change-Id: I96e47131414c50801ff7628508dc05d7d7b5e106
Releases: 6.1
Resolves: #44819
Fixes: #45985
Reviewed-on: https://review.typo3.org/18163
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Marc Bastian Heinrichs
Tested-by: Marc Bastian Heinrichs
36 files changed:
typo3/sysext/fluid/Classes/Compatibility/DocbookGeneratorService.php
typo3/sysext/fluid/Classes/Core/Compiler/TemplateCompiler.php
typo3/sysext/fluid/Classes/Core/Parser/InterceptorInterface.php
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ArrayNode.php
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ViewHelperNode.php
typo3/sysext/fluid/Classes/Core/Parser/TemplateParser.php
typo3/sysext/fluid/Classes/Core/Rendering/RenderingContextInterface.php
typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractViewHelper.php
typo3/sysext/fluid/Classes/Core/ViewHelper/ArgumentDefinition.php
typo3/sysext/fluid/Classes/Core/ViewHelper/TagBuilder.php
typo3/sysext/fluid/Classes/Core/ViewHelper/ViewHelperVariableContainer.php
typo3/sysext/fluid/Classes/Core/Widget/AbstractWidgetViewHelper.php
typo3/sysext/fluid/Classes/Service/AbstractGenerator.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Service/DocbookGenerator.php
typo3/sysext/fluid/Classes/View/AbstractTemplateView.php
typo3/sysext/fluid/Classes/View/TemplateView.php
typo3/sysext/fluid/Classes/ViewHelpers/AliasViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/ForViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/AbstractFormViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/HiddenViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/PasswordViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/RadioViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/SubmitViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/TextareaViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/TextfieldViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Format/HtmlentitiesDecodeViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Format/HtmlentitiesViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Format/HtmlspecialcharsViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Format/PrintfViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/GroupedForViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/IfViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/LayoutViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/RenderViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/SectionViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/ThenViewHelper.php

index 014b13a..15f37b3 100644 (file)
@@ -29,21 +29,25 @@ namespace TYPO3\CMS\Fluid\Compatibility;
  */
 class DocbookGeneratorService extends \TYPO3\CMS\Fluid\Service\DocbookGenerator {
 
+       /**
+        *
+        * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
+        */
+       protected $objectManager;
+
        public function userFunc() {
-               if (!class_exists('TYPO3\\CMS\\Extbase\\Utility\\ClassLoaderUtility')) {
-                       require \t3lib_extmgm::extPath('extbase') . 'Classes/Utility/ClassLoader.php';
-               }
-               $classLoader = new \TYPO3\CMS\Extbase\Utility\ClassLoaderUtility();
-               spl_autoload_register(array($classLoader, 'loadClass'));
-               return $this->generateDocbook('Tx_Fluid_ViewHelpers');
+               $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
+               $this->injectDocCommentParser($this->objectManager->get('TYPO3\\CMS\\Extbase\\Reflection\\DocCommentParser'));
+               $this->injectReflectionService($this->objectManager->get('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService'));
+               return $this->generateDocbook('TYPO3\CMS\Fluid\ViewHelpers');
        }
 
        protected function getClassNamesInNamespace($namespace) {
-               $namespaceParts = explode('_', $namespace);
+               $namespaceParts = explode('\\', $namespace);
                if ($namespaceParts[count($namespaceParts) - 1] == '') {
                }
-               $classFilePathAndName = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath(\TYPO3\CMS\Core\Utility\GeneralUtility::camelCaseToLowerCaseUnderscored($namespaceParts[1])) . 'Classes/';
-               $classFilePathAndName .= implode(array_slice($namespaceParts, 2, -1), '/') . '/';
+               $classFilePathAndName = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath(\TYPO3\CMS\Core\Utility\GeneralUtility::camelCaseToLowerCaseUnderscored($namespaceParts[2])) . 'Classes/';
+               $classFilePathAndName .= implode(array_slice($namespaceParts, 3, -1), '/') . '/';
                $classNames = array();
                $this->recursiveClassNameSearch($namespace, $classFilePathAndName, $classNames);
                sort($classNames);
@@ -51,7 +55,9 @@ class DocbookGeneratorService extends \TYPO3\CMS\Fluid\Service\DocbookGenerator
        }
 
        private function recursiveClassNameSearch($namespace, $directory, &$classNames) {
+
                $dh = opendir($directory);
+               $counter = 0;
                while (($file = readdir($dh)) !== FALSE) {
                        if ($file == '.' || $file == '..' || $file == '.svn') {
                                continue;
@@ -62,16 +68,12 @@ class DocbookGeneratorService extends \TYPO3\CMS\Fluid\Service\DocbookGenerator
                                }
                                $classNames[] = $namespace . substr($file, 0, -4);
                        } elseif (is_dir($directory . $file)) {
-                               $this->recursiveClassNameSearch($namespace . $file . '_', $directory . $file . '/', $classNames);
+                               $this->recursiveClassNameSearch($namespace . $file . '\\', $directory . $file . '/', $classNames);
                        }
                }
                closedir($dh);
        }
 
-       protected function instanciateViewHelper($className) {
-               $objectFactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
-               return $objectFactory->get($className);
-       }
 }
 
 ?>
\ No newline at end of file
index 25038b4..aebd6f3 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\Core\Compiler;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 class TemplateCompiler implements \TYPO3\CMS\Core\SingletonInterface {
 
        const SHOULD_GENERATE_VIEWHELPER_INVOCATION = '##should_gen_viewhelper##';
@@ -69,6 +70,7 @@ class TemplateCompiler implements \TYPO3\CMS\Core\SingletonInterface {
                $identifier = $this->sanitizeIdentifier($identifier);
                $this->variableCounter = 0;
                $generatedRenderFunctions = '';
+
                if ($parsingState->getVariableContainer()->exists('sections')) {
                        $sections = $parsingState->getVariableContainer()->get('sections');
                        // TODO: refactor to $parsedTemplate->getSections()
@@ -78,14 +80,17 @@ class TemplateCompiler implements \TYPO3\CMS\Core\SingletonInterface {
                }
                $generatedRenderFunctions .= $this->generateCodeForSection($this->convertListOfSubNodes($parsingState->getRootNode()), 'render', 'Main Render function');
                $convertedLayoutNameNode = $parsingState->hasLayout() ? $this->convert($parsingState->getLayoutNameNode()) : array('initialization' => '', 'execution' => 'NULL');
-               $classDefinition = 'class FluidCache_' . $identifier . ' extends TYPO3\\CMS\\Fluid\\Core\\Compiler\\AbstractCompiledTemplate';
-               $templateCode = '%s {
+
+               $classDefinition = 'class FluidCache_' . $identifier . ' extends \\TYPO3\\CMS\\Fluid\\Core\\Compiler\\AbstractCompiledTemplate';
+
+               $templateCode = <<<EOD
+%s {
 
 public function getVariableContainer() {
        // TODO
-       return new TYPO3\\CMS\\Fluid\\Core\\ViewHelper\\TemplateVariableContainer();
+       return new \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer();
 }
-public function getLayoutName(TYPO3\\CMS\\Fluid\\Core\\Rendering\\RenderingContextInterface $renderingContext) {
+public function getLayoutName(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface \$renderingContext) {
 %s
 return %s;
 }
@@ -95,8 +100,14 @@ return %s;
 
 %s
 
-}';
-               $templateCode = sprintf($templateCode, $classDefinition, $convertedLayoutNameNode['initialization'], $convertedLayoutNameNode['execution'], $parsingState->hasLayout() ? 'TRUE' : 'FALSE', $generatedRenderFunctions);
+}
+EOD;
+               $templateCode = sprintf($templateCode,
+                               $classDefinition,
+                               $convertedLayoutNameNode['initialization'],
+                               $convertedLayoutNameNode['execution'],
+                               ($parsingState->hasLayout() ? 'TRUE' : 'FALSE'),
+                               $generatedRenderFunctions);
                $this->templateCache->set($identifier, $templateCode);
        }
 
@@ -111,15 +122,24 @@ return %s;
                return preg_replace('([^a-zA-Z0-9_\\x7f-\\xff])', '_', $identifier);
        }
 
-       protected function generateCodeForSection($converted, $expectedFunctionName, $comment) {
-               $templateCode = '/**
+       /**
+        * @param array $converted
+        * @param string $expectedFunctionName
+        * @param string $comment
+        * @return string
+        */
+       protected function generateCodeForSection(array $converted, $expectedFunctionName, $comment) {
+               $templateCode = <<<EOD
+/**
  * %s
  */
-public function %s(TYPO3\\CMS\\Fluid\\Core\\Rendering\\RenderingContextInterface $renderingContext) {
-$self = $this;
+public function %s(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface \$renderingContext) {
+\$self = \$this;
 %s
 return %s;
-}';
+}
+
+EOD;
                return sprintf($templateCode, $comment, $expectedFunctionName, $converted['initialization'], $converted['execution']);
        }
 
@@ -130,6 +150,7 @@ return %s;
         *
         * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $node
         * @return array two-element array, see above
+        * @throws \TYPO3\CMS\Fluid\Exception
         */
        protected function convert(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $node) {
                if ($node instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode) {
@@ -147,7 +168,7 @@ return %s;
                } elseif ($node instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\BooleanNode) {
                        return $this->convertBooleanNode($node);
                } else {
-                       throw new \Exception('TODO: TYPE XY NOT FOUND');
+                       throw new \TYPO3\CMS\Fluid\Exception('Syntax tree node type "' . get_class($node) . '" is not supported.');
                }
        }
 
@@ -185,9 +206,11 @@ return %s;
         */
        protected function convertViewHelperNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode $node) {
                $initializationPhpCode = '// Rendering ViewHelper ' . $node->getViewHelperClassName() . chr(10);
+
                // Build up $arguments array
                $argumentsVariableName = $this->variableName('arguments');
                $initializationPhpCode .= sprintf('%s = array();', $argumentsVariableName) . chr(10);
+
                $alreadyBuiltArguments = array();
                foreach ($node->getArguments() as $argumentName => $argumentValue) {
                        $converted = $this->convert($argumentValue);
@@ -195,14 +218,17 @@ return %s;
                        $initializationPhpCode .= sprintf('%s[\'%s\'] = %s;', $argumentsVariableName, $argumentName, $converted['execution']) . chr(10);
                        $alreadyBuiltArguments[$argumentName] = TRUE;
                }
+
                foreach ($node->getUninitializedViewHelper()->prepareArguments() as $argumentName => $argumentDefinition) {
                        if (!isset($alreadyBuiltArguments[$argumentName])) {
                                $initializationPhpCode .= sprintf('%s[\'%s\'] = %s;', $argumentsVariableName, $argumentName, var_export($argumentDefinition->getDefaultValue(), TRUE)) . chr(10);
                        }
                }
+
                // Build up closure which renders the child nodes
                $renderChildrenClosureVariableName = $this->variableName('renderChildrenClosure');
                $initializationPhpCode .= sprintf('%s = %s;', $renderChildrenClosureVariableName, $this->wrapChildNodesInClosure($node)) . chr(10);
+
                if ($node->getUninitializedViewHelper() instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface) {
                        // ViewHelper is compilable
                        $viewHelperInitializationPhpCode = '';
@@ -215,13 +241,18 @@ return %s;
                                );
                        }
                }
+
                // ViewHelper is not compilable, so we need to instanciate it directly and render it.
                $viewHelperVariableName = $this->variableName('viewHelper');
+
                $initializationPhpCode .= sprintf('%s = $self->getViewHelper(\'%s\', $renderingContext, \'%s\');', $viewHelperVariableName, $viewHelperVariableName, $node->getViewHelperClassName()) . chr(10);
                $initializationPhpCode .= sprintf('%s->setArguments(%s);', $viewHelperVariableName, $argumentsVariableName) . chr(10);
                $initializationPhpCode .= sprintf('%s->setRenderingContext($renderingContext);', $viewHelperVariableName) . chr(10);
+
                $initializationPhpCode .= sprintf('%s->setRenderChildrenClosure(%s);', $viewHelperVariableName, $renderChildrenClosureVariableName) . chr(10);
+
                $initializationPhpCode .= '// End of ViewHelper ' . $node->getViewHelperClassName() . chr(10);
+
                return array(
                        'initialization' => $initializationPhpCode,
                        'execution' => sprintf('%s->initializeArgumentsAndRender()', $viewHelperVariableName)
@@ -248,7 +279,9 @@ return %s;
        protected function convertArrayNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ArrayNode $node) {
                $initializationPhpCode = '// Rendering Array' . chr(10);
                $arrayVariableName = $this->variableName('array');
+
                $initializationPhpCode .= sprintf('%s = array();', $arrayVariableName) . chr(10);
+
                foreach ($node->getInternalArray() as $key => $value) {
                        if ($value instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode) {
                                $converted = $this->convert($value);
@@ -282,15 +315,19 @@ return %s;
                                );
                        case 1:
                                $converted = $this->convert(current($node->getChildNodes()));
+
                                return $converted;
                        default:
                                $outputVariableName = $this->variableName('output');
                                $initializationPhpCode = sprintf('%s = \'\';', $outputVariableName) . chr(10);
+
                                foreach ($node->getChildNodes() as $childNode) {
                                        $converted = $this->convert($childNode);
+
                                        $initializationPhpCode .= $converted['initialization'] . chr(10);
                                        $initializationPhpCode .= sprintf('%s .= %s;', $outputVariableName, $converted['execution']) . chr(10);
                                }
+
                                return array(
                                        'initialization' => $initializationPhpCode,
                                        'execution' => $outputVariableName
@@ -308,6 +345,7 @@ return %s;
                if ($node->getComparator() !== NULL) {
                        $convertedLeftSide = $this->convert($node->getLeftSide());
                        $convertedRightSide = $this->convert($node->getRightSide());
+
                        return array(
                                'initialization' => $initializationPhpCode . $convertedLeftSide['initialization'] . $convertedRightSide['initialization'],
                                'execution' => sprintf('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\BooleanNode::evaluateComparator(\'%s\', %s, %s)', $node->getComparator(), $convertedLeftSide['execution'], $convertedRightSide['execution'])
index 81d095b..17b35ed 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\Core\Parser;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * An interceptor interface. Interceptors are used in the parsing stage to change
  * the syntax tree of a template, e.g. by adding viewhelper nodes.
index f2ae28f..ac15627 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Array Syntax Tree Node. Handles JSON-like arrays.
  */
index 57def6c..0af2121 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Node which will call a ViewHelper associated with this node.
  */
@@ -91,7 +92,7 @@ class ViewHelperNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNod
         *
         * First, it evaluates the arguments of the view helper.
         *
-        * If the view helper implements Tx_Fluid_Core_ViewHelper_Facets_ChildNodeAccessInterface,
+        * If the view helper implements \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface,
         * it calls setChildNodes(array childNodes) on the view helper.
         *
         * Afterwards, checks that the view helper did not leave a variable lying around.
@@ -107,6 +108,7 @@ class ViewHelperNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNod
                        $viewHelper = clone $this->uninitializedViewHelper;
                        $this->viewHelpersByContext->attach($renderingContext, $viewHelper);
                }
+
                $evaluatedArguments = array();
                if (count($viewHelper->prepareArguments())) {
                        foreach ($viewHelper->prepareArguments() as $argumentName => $argumentDefinition) {
@@ -118,13 +120,17 @@ class ViewHelperNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNod
                                }
                        }
                }
+
                $viewHelper->setArguments($evaluatedArguments);
                $viewHelper->setViewHelperNode($this);
                $viewHelper->setRenderingContext($renderingContext);
+
                if ($viewHelper instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface) {
                        $viewHelper->setChildNodes($this->childNodes);
                }
+
                $output = $viewHelper->initializeArgumentsAndRender();
+
                return $output;
        }
 
index 9ea620f..cb4a121 100644 (file)
@@ -10,12 +10,14 @@ namespace TYPO3\CMS\Fluid\Core\Parser;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Template parser building up an object syntax tree
  */
 class TemplateParser {
 
-       static public $SCAN_PATTERN_NAMESPACEDECLARATION = '/(?<!\\\\){namespace\\s*([a-zA-Z]+[a-zA-Z0-9]*)\\s*=\\s*((?:[A-Za-z0-9\.]+|Tx)(?:LEGACY_NAMESPACE_SEPARATOR\\w+|FLUID_NAMESPACE_SEPARATOR\\w+)+)\\s*}/m';
+       static public $SCAN_PATTERN_NAMESPACEDECLARATION = '/(?<!\\\\){namespace\\s*(?P<identifier>[a-zA-Z]+[a-zA-Z0-9]*)\\s*=\\s*(?P<phpNamespace>(?:[A-Za-z0-9\.]+|Tx)(?:LEGACY_NAMESPACE_SEPARATOR\\w+|FLUID_NAMESPACE_SEPARATOR\\w+)+)\\s*}/m';
+       static public $SCAN_PATTERN_XMLNSDECLARATION = '/\sxmlns:(?P<identifier>.*?)="(?P<xmlNamespace>.*?)"/m';
 
        /**
         * This regular expression splits the input string at all dynamic tags, AND
@@ -26,7 +28,7 @@ class TemplateParser {
                        (?: <\\/?                                      # Start dynamic tags
                                        (?:(?:NAMESPACE):[a-zA-Z0-9\\.]+)     # A tag consists of the namespace prefix and word characters
                                        (?:                                   # Begin tag arguments
-                                               \\s*[a-zA-Z0-9:]+                  # Argument Keys
+                                               \\s*[a-zA-Z0-9:-]+                  # Argument Keys
                                                =                                 # =
                                                (?>                               # either... If we have found an argument, we will not back-track (That does the Atomic Bracket)
                                                        "(?:\\\\"|[^"])*"              # a double-quoted string
@@ -53,7 +55,7 @@ class TemplateParser {
                (?P<Attributes>                                   # Begin Tag Attributes
                        (?:                                           # A tag might have multiple attributes
                                \\s*
-                               [a-zA-Z0-9:]+                             # The attribute name
+                               [a-zA-Z0-9:-]+                             # The attribute name
                                =                                         # =
                                (?>                                       # either... # If we have found an argument, we will not back-track (That does the Atomic Bracket)
                                        "(?:\\\\"|[^"])*"                      # a double-quoted string
@@ -79,7 +81,7 @@ class TemplateParser {
                (?:                                              #
                        \\s*                                          #
                        (?P<Argument>                                # The attribute name
-                               [a-zA-Z0-9:]+                            #
+                               [a-zA-Z0-9:-]+                            #
                        )                                            #
                        =                                            # =
                        (?>                                          # If we have found an argument, we will not back-track (That does the Atomic Bracket)
@@ -228,8 +230,13 @@ class TemplateParser {
        /x';
 
        /**
-        * Namespace identifiers and their component name prefix (Associative array).
+        * This pattern detects the default xml namespace
         *
+        */
+       static public $SCAN_PATTERN_DEFAULT_XML_NAMESPACE = '/^http\:\/\/typo3\.org\/ns\/(?P<PhpNamespace>.+)$/s';
+
+       /**
+        * Namespace identifiers and their component name prefix (Associative array).
         * @var array
         */
        protected $namespaces = array(
@@ -247,6 +254,11 @@ class TemplateParser {
        protected $configuration;
 
        /**
+        * @var array
+        */
+       protected $settings;
+
+       /**
         * Constructor. Preprocesses the $SCAN_PATTERN_NAMESPACEDECLARATION by
         * inserting the correct namespace separator.
         */
@@ -256,6 +268,15 @@ class TemplateParser {
        }
 
        /**
+        * Injects Fluid settings
+        *
+        * @param array $settings
+        */
+       public function injectSettings(array $settings) {
+               $this->settings = $settings;
+       }
+
+       /**
         * Inject object factory
         *
         * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
@@ -284,21 +305,24 @@ class TemplateParser {
         * TemplateParser directly.
         *
         * @param string $templateString The template to parse as a string
-        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
         * @return \TYPO3\CMS\Fluid\Core\Parser\ParsedTemplateInterface Parsed template
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
         */
        public function parse($templateString) {
                if (!is_string($templateString)) {
                        throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Parse requires a template string as argument, ' . gettype($templateString) . ' given.', 1224237899);
                }
                $this->reset();
+
                $templateString = $this->extractNamespaceDefinitions($templateString);
                $splitTemplate = $this->splitTemplateAtDynamicTags($templateString);
                $parsingState = $this->buildObjectTree($splitTemplate);
+
                $variableContainer = $parsingState->getVariableContainer();
                if ($variableContainer !== NULL && $variableContainer->exists('layoutName')) {
                        $parsingState->setLayoutNameNode($variableContainer->get('layoutName'));
                }
+
                return $parsingState;
        }
 
@@ -327,22 +351,43 @@ class TemplateParser {
         * $this->namespaces.
         *
         * @param string $templateString Template string to extract the namespaces from
-        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
         * @return string The updated template string without namespace declarations inside
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception if a namespace can't be resolved or has been declared already
         */
        protected function extractNamespaceDefinitions($templateString) {
-               $matchedVariables = array();
-               if (preg_match_all(self::$SCAN_PATTERN_NAMESPACEDECLARATION, $templateString, $matchedVariables) > 0) {
-                       foreach (array_keys($matchedVariables[0]) as $index) {
-                               $namespaceIdentifier = $matchedVariables[1][$index];
-                               $fullyQualifiedNamespace = $matchedVariables[2][$index];
-                               if (key_exists($namespaceIdentifier, $this->namespaces)) {
-                                       throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Namespace identifier "' . $namespaceIdentifier . '" is already registered. Do not redeclare namespaces!', 1224241246);
+               $matches = array();
+               preg_match_all(self::$SCAN_PATTERN_XMLNSDECLARATION, $templateString, $matches, PREG_SET_ORDER);
+               foreach ($matches as $match) {
+                               // skip reserved "f" namespace identifier
+                       if ($match['identifier'] === 'f') {
+                               continue;
+                       }
+                       if (array_key_exists($match['identifier'], $this->namespaces)) {
+                               throw new \TYPO3\CMS\Fluid\Core\Parser\Exception(sprintf('Namespace identifier "%s" is already registered. Do not re-declare namespaces!', $match['identifier']), 1331135889);
+                       }
+                       if (isset($this->settings['namespaces'][$match['xmlNamespace']])) {
+                               $phpNamespace = $this->settings['namespaces'][$match['xmlNamespace']];
+                       } else {
+                               $matchedPhpNamespace = array();
+                               if (preg_match(self::$SCAN_PATTERN_DEFAULT_XML_NAMESPACE, $match['xmlNamespace'], $matchedPhpNamespace) === 0) {
+                                       continue;
                                }
-                               $this->namespaces[$namespaceIdentifier] = $fullyQualifiedNamespace;
+                               $phpNamespace = str_replace('/', '\\', $matchedPhpNamespace['PhpNamespace']);
+                       }
+                       $this->namespaces[$match['identifier']] = $phpNamespace;
+               }
+               $matches = array();
+               preg_match_all(self::$SCAN_PATTERN_NAMESPACEDECLARATION, $templateString, $matches, PREG_SET_ORDER);
+               foreach ($matches as $match) {
+                       if (array_key_exists($match['identifier'], $this->namespaces)) {
+                               throw new \TYPO3\CMS\Fluid\Core\Parser\Exception(sprintf('Namespace identifier "%s" is already registered. Do not re-declare namespaces!', $match['identifier']), 1224241246);
                        }
+                       $this->namespaces[$match['identifier']] = $match['phpNamespace'];
+               }
+               if ($matches !== array()) {
                        $templateString = preg_replace(self::$SCAN_PATTERN_NAMESPACEDECLARATION, '', $templateString);
                }
+
                return $templateString;
        }
 
@@ -360,29 +405,32 @@ class TemplateParser {
        /**
         * Build object tree from the split template
         *
-        * @param array $splitTemplate The split template, so that every tag with a namespace declaration is already a separate array element.
-        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
+        * @param array $splitTemplate The split template, so that every tag with a namespace declaration is already a seperate array element.
         * @return \TYPO3\CMS\Fluid\Core\Parser\ParsingState
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
         */
        protected function buildObjectTree($splitTemplate) {
                $regularExpression_openingViewHelperTag = $this->prepareTemplateRegularExpression(self::$SCAN_PATTERN_TEMPLATE_VIEWHELPERTAG);
                $regularExpression_closingViewHelperTag = $this->prepareTemplateRegularExpression(self::$SCAN_PATTERN_TEMPLATE_CLOSINGVIEWHELPERTAG);
+
                $state = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\ParsingState');
                $rootNode = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\RootNode');
                $state->setRootNode($rootNode);
                $state->pushNodeToStack($rootNode);
+
                foreach ($splitTemplate as $templateElement) {
                        $matchedVariables = array();
                        if (preg_match(self::$SCAN_PATTERN_CDATA, $templateElement, $matchedVariables) > 0) {
                                $this->textHandler($state, $matchedVariables[1]);
                        } elseif (preg_match($regularExpression_openingViewHelperTag, $templateElement, $matchedVariables) > 0) {
-                               $this->openingViewHelperTagHandler($state, $matchedVariables['NamespaceIdentifier'], $matchedVariables['MethodIdentifier'], $matchedVariables['Attributes'], $matchedVariables['Selfclosing'] === '' ? FALSE : TRUE);
+                               $this->openingViewHelperTagHandler($state, $matchedVariables['NamespaceIdentifier'], $matchedVariables['MethodIdentifier'], $matchedVariables['Attributes'], ($matchedVariables['Selfclosing'] === '' ? FALSE : TRUE));
                        } elseif (preg_match($regularExpression_closingViewHelperTag, $templateElement, $matchedVariables) > 0) {
                                $this->closingViewHelperTagHandler($state, $matchedVariables['NamespaceIdentifier'], $matchedVariables['MethodIdentifier']);
                        } else {
                                $this->textAndShorthandSyntaxHandler($state, $templateElement);
                        }
                }
+
                if ($state->countNodeStack() !== 1) {
                        throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Not all tags were closed!', 1238169398);
                }
@@ -402,6 +450,7 @@ class TemplateParser {
        protected function openingViewHelperTagHandler(\TYPO3\CMS\Fluid\Core\Parser\ParsingState $state, $namespaceIdentifier, $methodIdentifier, $arguments, $selfclosing) {
                $argumentsObjectTree = $this->parseArguments($arguments);
                $this->initializeViewHelperAndAddItToStack($state, $namespaceIdentifier, $methodIdentifier, $argumentsObjectTree);
+
                if ($selfclosing) {
                        $node = $state->popNodeFromStack();
                        $this->callInterceptor($node, \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_CLOSING_VIEWHELPER, $state);
@@ -416,31 +465,38 @@ class TemplateParser {
         * @param string $namespaceIdentifier Namespace identifier - being looked up in $this->namespaces
         * @param string $methodIdentifier Method identifier
         * @param array $argumentsObjectTree Arguments object tree
-        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
         * @return void
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
         */
        protected function initializeViewHelperAndAddItToStack(\TYPO3\CMS\Fluid\Core\Parser\ParsingState $state, $namespaceIdentifier, $methodIdentifier, $argumentsObjectTree) {
                if (!array_key_exists($namespaceIdentifier, $this->namespaces)) {
                        throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Namespace could not be resolved. This exception should never be thrown!', 1224254792);
                }
                $viewHelper = $this->objectManager->get($this->resolveViewHelperName($namespaceIdentifier, $methodIdentifier));
+
                // The following three checks are only done *in an uncached template*, and not needed anymore in the cached version
                $expectedViewHelperArguments = $viewHelper->prepareArguments();
                $this->abortIfUnregisteredArgumentsExist($expectedViewHelperArguments, $argumentsObjectTree);
                $this->abortIfRequiredArgumentsAreMissing($expectedViewHelperArguments, $argumentsObjectTree);
                $this->rewriteBooleanNodesInArgumentsObjectTree($expectedViewHelperArguments, $argumentsObjectTree);
+
                $currentViewHelperNode = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\ViewHelperNode', $viewHelper, $argumentsObjectTree);
+
                $state->getNodeFromStack()->addChildNode($currentViewHelperNode);
-               if ($viewHelper instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface && !$viewHelper instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface) {
+
+               if ($viewHelper instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface && !($viewHelper instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface)) {
                        $state->setCompilable(FALSE);
                }
+
                // PostParse Facet
                if ($viewHelper instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\PostParseInterface) {
                        // Don't just use $viewHelper::postParseEvent(...),
                        // as this will break with PHP < 5.3.
                        call_user_func(array($viewHelper, 'postParseEvent'), $currentViewHelperNode, $argumentsObjectTree, $state->getVariableContainer());
                }
+
                $this->callInterceptor($currentViewHelperNode, \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_OPENING_VIEWHELPER, $state);
+
                $state->pushNodeToStack($currentViewHelperNode);
        }
 
@@ -448,7 +504,7 @@ class TemplateParser {
         * Throw an exception if there are arguments which were not registered
         * before.
         *
-        * @param array $expectedArguments Array of Tx_Fluid_Core_ViewHelper_ArgumentDefinition of all expected arguments
+        * @param array $expectedArguments Array of \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition of all expected arguments
         * @param array $actualArguments Actual arguments
         * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
         */
@@ -457,6 +513,7 @@ class TemplateParser {
                foreach ($expectedArguments as $expectedArgument) {
                        $expectedArgumentNames[] = $expectedArgument->getName();
                }
+
                foreach (array_keys($actualArguments) as $argumentName) {
                        if (!in_array($argumentName, $expectedArgumentNames)) {
                                throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Argument "' . $argumentName . '" was not registered.', 1237823695);
@@ -467,7 +524,7 @@ class TemplateParser {
        /**
         * Throw an exception if required arguments are missing
         *
-        * @param array $expectedArguments Array of Tx_Fluid_Core_ViewHelper_ArgumentDefinition of all expected arguments
+        * @param array $expectedArguments Array of \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition of all expected arguments
         * @param array $actualArguments Actual arguments
         * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
         */
@@ -499,7 +556,7 @@ class TemplateParser {
         * Resolve a viewhelper name.
         *
         * @param string $namespaceIdentifier Namespace identifier for the view helper.
-        * @param string $methodIdentifier Method identifier, might be hierarchical like "link.url
+        * @param string $methodIdentifier Method identifier, might be hierarchical like "link.url"
         * @return string The fully qualified class name of the viewhelper
         */
        protected function resolveViewHelperName($namespaceIdentifier, $methodIdentifier) {
@@ -529,7 +586,7 @@ class TemplateParser {
                        throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Namespace could not be resolved. This exception should never be thrown!', 1224256186);
                }
                $lastStackElement = $state->popNodeFromStack();
-               if (!$lastStackElement instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode) {
+               if (!($lastStackElement instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode)) {
                        throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('You closed a templating tag which you never opened!', 1224485838);
                }
                if ($lastStackElement->getViewHelperClassName() != $this->resolveViewHelperName($namespaceIdentifier, $methodIdentifier)) {
@@ -540,7 +597,7 @@ class TemplateParser {
 
        /**
         * Handles the appearance of an object accessor (like {posts.author.email}).
-        * Creates a new instance of Tx_Fluid_ObjectAccessorNode.
+        * Creates a new instance of \TYPO3\CMS\Fluid\ObjectAccessorNode.
         *
         * Handles ViewHelpers as well which are in the shorthand syntax.
         *
@@ -554,19 +611,23 @@ class TemplateParser {
        protected function objectAccessorHandler(\TYPO3\CMS\Fluid\Core\Parser\ParsingState $state, $objectAccessorString, $delimiter, $viewHelperString, $additionalViewHelpersString) {
                $viewHelperString .= $additionalViewHelpersString;
                $numberOfViewHelpers = 0;
+
                // The following post-processing handles a case when there is only a ViewHelper, and no Object Accessor.
                // Resolves bug #5107.
                if (strlen($delimiter) === 0 && strlen($viewHelperString) > 0) {
                        $viewHelperString = $objectAccessorString . $viewHelperString;
                        $objectAccessorString = '';
                }
+
                // ViewHelpers
                $matches = array();
                if (strlen($viewHelperString) > 0 && preg_match_all(self::$SPLIT_PATTERN_SHORTHANDSYNTAX_VIEWHELPER, $viewHelperString, $matches, PREG_SET_ORDER) > 0) {
                        // The last ViewHelper has to be added first for correct chaining.
                        foreach (array_reverse($matches) as $singleMatch) {
                                if (strlen($singleMatch['ViewHelperArguments']) > 0) {
-                                       $arguments = $this->postProcessArgumentsForObjectAccessor($this->recursiveArrayHandler($singleMatch['ViewHelperArguments']));
+                                       $arguments = $this->postProcessArgumentsForObjectAccessor(
+                                               $this->recursiveArrayHandler($singleMatch['ViewHelperArguments'])
+                                       );
                                } else {
                                        $arguments = array();
                                }
@@ -574,14 +635,18 @@ class TemplateParser {
                                $numberOfViewHelpers++;
                        }
                }
+
                // Object Accessor
                if (strlen($objectAccessorString) > 0) {
+
                        $node = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\ObjectAccessorNode', $objectAccessorString);
                        $this->callInterceptor($node, \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_OBJECTACCESSOR, $state);
+
                        $state->getNodeFromStack()->addChildNode($node);
                }
+
                // Close ViewHelper Tags if needed.
-               for ($i = 0; $i < $numberOfViewHelpers; $i++) {
+               for ($i=0; $i<$numberOfViewHelpers; $i++) {
                        $node = $state->popNodeFromStack();
                        $this->callInterceptor($node, \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_CLOSING_VIEWHELPER, $state);
                }
@@ -591,8 +656,8 @@ class TemplateParser {
         * Call all interceptors registered for a given interception point.
         *
         * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $node The syntax tree node which can be modified by the interceptors.
-        * @param integer $interceptionPoint the interception point. One of the Tx_Fluid_Core_Parser_InterceptorInterface::INTERCEPT_* constants.
-        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState the parsing state
+        * @param integer $interceptionPoint the interception point. One of the \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_* constants.
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $state the parsing state
         * @return void
         */
        protected function callInterceptor(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface &$node, $interceptionPoint, \TYPO3\CMS\Fluid\Core\Parser\ParsingState $state) {
@@ -613,14 +678,14 @@ class TemplateParser {
        /**
         * Post process the arguments for the ViewHelpers in the object accessor
         * syntax. We need to convert an array into an array of (only) nodes
-        * TODO: This method should become superflous once the rest has been refactored, so that this code is not needed.
         *
         * @param array $arguments The arguments to be processed
         * @return array the processed array
+        * @todo This method should become superflous once the rest has been refactored, so that this code is not needed.
         */
        protected function postProcessArgumentsForObjectAccessor(array $arguments) {
                foreach ($arguments as $argumentName => $argumentValue) {
-                       if (!$argumentValue instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode) {
+                       if (!($argumentValue instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode)) {
                                $arguments[$argumentName] = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\TextNode', (string) $argumentValue);
                        }
                }
@@ -660,7 +725,7 @@ class TemplateParser {
         * no { or < is found, then we just return a TextNode.
         *
         * @param string $argumentString
-        * @return mixed ArgumentObject the corresponding argument object tree.
+        * @return SyntaxTree\AbstractNode the corresponding argument object tree.
         */
        protected function buildArgumentObjectTree($argumentString) {
                if (strpos($argumentString, '{') === FALSE && strpos($argumentString, '<') === FALSE) {
@@ -683,11 +748,13 @@ class TemplateParser {
        protected function unquoteString($quotedValue) {
                switch ($quotedValue[0]) {
                        case '"':
-                               $value = str_replace('\\"', '"', trim($quotedValue, '"'));
-                               break;
-                       case '\'':
-                               $value = str_replace('\\\'', '\'', trim($quotedValue, '\''));
-                               break;
+                               $value = str_replace('\\"', '"', preg_replace('/(^"|"$)/', '', $quotedValue));
+                       break;
+                       case "'":
+                               $value = str_replace("\\'", "'", preg_replace('/(^\'|\'$)/', '', $quotedValue));
+                       break;
+                       default:
+                               $value = $quotedValue;
                }
                return str_replace('\\\\', '\\', $value);
        }
@@ -715,10 +782,11 @@ class TemplateParser {
         */
        protected function textAndShorthandSyntaxHandler(\TYPO3\CMS\Fluid\Core\Parser\ParsingState $state, $text) {
                $sections = preg_split($this->prepareTemplateRegularExpression(self::$SPLIT_PATTERN_SHORTHANDSYNTAX), $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+
                foreach ($sections as $section) {
                        $matchedVariables = array();
                        if (preg_match(self::$SCAN_PATTERN_SHORTHANDSYNTAX_OBJECTACCESSORS, $section, $matchedVariables) > 0) {
-                               $this->objectAccessorHandler($state, $matchedVariables['Object'], $matchedVariables['Delimiter'], isset($matchedVariables['ViewHelper']) ? $matchedVariables['ViewHelper'] : '', isset($matchedVariables['AdditionalViewHelpers']) ? $matchedVariables['AdditionalViewHelpers'] : '');
+                               $this->objectAccessorHandler($state, $matchedVariables['Object'], $matchedVariables['Delimiter'], (isset($matchedVariables['ViewHelper']) ? $matchedVariables['ViewHelper'] : ''), (isset($matchedVariables['AdditionalViewHelpers']) ? $matchedVariables['AdditionalViewHelpers'] : ''));
                        } elseif (preg_match(self::$SCAN_PATTERN_SHORTHANDSYNTAX_ARRAYS, $section, $matchedVariables) > 0) {
                                $this->arrayHandler($state, $matchedVariables['Array']);
                        } else {
@@ -736,7 +804,9 @@ class TemplateParser {
         * @return void
         */
        protected function arrayHandler(\TYPO3\CMS\Fluid\Core\Parser\ParsingState $state, $arrayText) {
-               $state->getNodeFromStack()->addChildNode($this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\ArrayNode', $this->recursiveArrayHandler($arrayText)));
+               $state->getNodeFromStack()->addChildNode(
+                       $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\ArrayNode', $this->recursiveArrayHandler($arrayText))
+               );
        }
 
        /**
@@ -750,8 +820,8 @@ class TemplateParser {
         * - sub-arrays
         *
         * @param string $arrayText Array text
+        * @return SyntaxTree\ArrayNode the array node built up
         * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
-        * @return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface the array node built up
         */
        protected function recursiveArrayHandler($arrayText) {
                $matches = array();
@@ -763,7 +833,7 @@ class TemplateParser {
                                        $arrayToBuild[$arrayKey] = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\ObjectAccessorNode', $singleMatch['VariableIdentifier']);
                                } elseif (array_key_exists('Number', $singleMatch) && (!empty($singleMatch['Number']) || $singleMatch['Number'] === '0')) {
                                        $arrayToBuild[$arrayKey] = floatval($singleMatch['Number']);
-                               } elseif (array_key_exists('QuotedString', $singleMatch) && !empty($singleMatch['QuotedString'])) {
+                               } elseif ((array_key_exists('QuotedString', $singleMatch) && !empty($singleMatch['QuotedString']))) {
                                        $argumentString = $this->unquoteString($singleMatch['QuotedString']);
                                        $arrayToBuild[$arrayKey] = $this->buildArgumentObjectTree($argumentString);
                                } elseif (array_key_exists('Subarray', $singleMatch) && !empty($singleMatch['Subarray'])) {
@@ -788,6 +858,7 @@ class TemplateParser {
        protected function textHandler(\TYPO3\CMS\Fluid\Core\Parser\ParsingState $state, $text) {
                $node = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\TextNode', $text);
                $this->callInterceptor($node, \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_TEXT, $state);
+
                $state->getNodeFromStack()->addChildNode($node);
        }
 }
index 60b6aa2..e146172 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\Core\Rendering;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 interface RenderingContextInterface {
 
        /**
index 7e0a78b..f795093 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\Core\ViewHelper;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * The abstract base class for all view helpers.
  *
@@ -25,7 +26,7 @@ abstract class AbstractViewHelper {
        private $argumentsInitialized = FALSE;
 
        /**
-        * Stores all Tx_Fluid_ArgumentDefinition instances
+        * Stores all \TYPO3\CMS\Fluid\ArgumentDefinition instances
         *
         * @var array
         */
@@ -80,7 +81,6 @@ abstract class AbstractViewHelper {
 
        /**
         * @var \Closure
-        * @internal
         */
        protected $renderChildrenClosure = NULL;
 
@@ -100,15 +100,26 @@ abstract class AbstractViewHelper {
        private $reflectionService;
 
        /**
+        * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
         * With this flag, you can disable the escaping interceptor inside this ViewHelper.
         * THIS MIGHT CHANGE WITHOUT NOTICE, NO PUBLIC API!
-        *
         * @var boolean
-        * @internal
         */
        protected $escapingInterceptorEnabled = TRUE;
 
        /**
+        * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
+        * @return void
+        */
+       public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
         * @param array $arguments
         * @return void
         */
@@ -143,7 +154,6 @@ abstract class AbstractViewHelper {
         *
         * THIS METHOD MIGHT CHANGE WITHOUT NOTICE; NO PUBLIC API!
         *
-        * @internal
         * @return boolean
         */
        public function isEscapingInterceptorEnabled() {
@@ -160,6 +170,7 @@ abstract class AbstractViewHelper {
         * @param boolean $required If TRUE, argument is required. Defaults to FALSE.
         * @param mixed $defaultValue Default value of argument
         * @return \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper $this, to allow chaining.
+        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         * @api
         */
        protected function registerArgument($name, $type, $description, $required = FALSE, $defaultValue = NULL) {
@@ -181,6 +192,7 @@ abstract class AbstractViewHelper {
         * @param boolean $required If TRUE, argument is required. Defaults to FALSE.
         * @param mixed $defaultValue Default value of argument
         * @return \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper $this, to allow chaining.
+        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         * @api
         */
        protected function overrideArgument($name, $type, $description, $required = FALSE, $defaultValue = NULL) {
@@ -208,7 +220,6 @@ abstract class AbstractViewHelper {
         *
         * @param \Closure $renderChildrenClosure
         * @return void
-        * @internal
         */
        public function setRenderChildrenClosure(\Closure $renderChildrenClosure) {
                $this->renderChildrenClosure = $renderChildrenClosure;
@@ -222,6 +233,7 @@ abstract class AbstractViewHelper {
        public function initializeArgumentsAndRender() {
                $this->validateArguments();
                $this->initialize();
+
                return $this->callRenderMethod();
        }
 
@@ -229,6 +241,7 @@ abstract class AbstractViewHelper {
         * Call the render() method and handle errors.
         *
         * @return string the rendered ViewHelper
+        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         */
        protected function callRenderMethod() {
                $renderMethodParameters = array();
@@ -237,6 +250,7 @@ abstract class AbstractViewHelper {
                                $renderMethodParameters[$argumentName] = $this->arguments[$argumentName];
                        }
                }
+
                try {
                        return call_user_func_array(array($this, 'render'), $renderMethodParameters);
                } catch (\TYPO3\CMS\Fluid\Core\ViewHelper\Exception $exception) {
@@ -278,7 +292,6 @@ abstract class AbstractViewHelper {
         * No public API yet.
         *
         * @return \Closure
-        * @internal
         */
        protected function buildRenderChildrenClosure() {
                $self = $this;
@@ -290,7 +303,7 @@ abstract class AbstractViewHelper {
        /**
         * Initialize all arguments and return them
         *
-        * @return array Array of Tx_Fluid_Core_ViewHelper_ArgumentDefinition instances.
+        * @return array Array of \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition instances.
         */
        public function prepareArguments() {
                if (!$this->argumentsInitialized) {
@@ -311,19 +324,23 @@ abstract class AbstractViewHelper {
         * Register method arguments for "render" by analysing the doc comment above.
         *
         * @return void
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
         */
        private function registerRenderMethodArguments() {
                $methodParameters = $this->reflectionService->getMethodParameters(get_class($this), 'render');
                if (count($methodParameters) === 0) {
                        return;
                }
+
                if (\TYPO3\CMS\Fluid\Fluid::$debugMode) {
                        $methodTags = $this->reflectionService->getMethodTagsValues(get_class($this), 'render');
+
                        $paramAnnotations = array();
                        if (isset($methodTags['param'])) {
                                $paramAnnotations = $methodTags['param'];
                        }
                }
+
                $i = 0;
                foreach ($methodParameters as $parameterName => $parameterInfo) {
                        $dataType = NULL;
@@ -335,6 +352,7 @@ abstract class AbstractViewHelper {
                        if ($dataType === NULL) {
                                throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('could not determine type of argument "' . $parameterName . '" of the render-method in ViewHelper "' . get_class($this) . '". Either the methods docComment is invalid or some PHP optimizer strips off comments.', 1242292003);
                        }
+
                        $description = '';
                        if (\TYPO3\CMS\Fluid\Fluid::$debugMode && isset($paramAnnotations[$i])) {
                                $explodedAnnotation = explode(' ', $paramAnnotations[$i]);
@@ -346,7 +364,7 @@ abstract class AbstractViewHelper {
                        if (isset($parameterInfo['defaultValue'])) {
                                $defaultValue = $parameterInfo['defaultValue'];
                        }
-                       $this->argumentDefinitions[$parameterName] = new \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition($parameterName, $dataType, $description, $parameterInfo['optional'] === FALSE, $defaultValue, TRUE);
+                       $this->argumentDefinitions[$parameterName] = new \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition($parameterName, $dataType, $description, ($parameterInfo['optional'] === FALSE), $defaultValue, TRUE);
                        $i++;
                }
        }
@@ -355,6 +373,7 @@ abstract class AbstractViewHelper {
         * Validate arguments, and throw exception if arguments do not validate.
         *
         * @return void
+        * @throws \InvalidArgumentException
         */
        public function validateArguments() {
                $argumentDefinitions = $this->prepareArguments();
@@ -376,7 +395,7 @@ abstract class AbstractViewHelper {
                                                throw new \InvalidArgumentException('The argument "' . $argumentName . '" was registered with type "boolean", but is of type "' . gettype($this->arguments[$argumentName]) . '" in view helper "' . get_class($this) . '".', 1240227732);
                                        }
                                } elseif (class_exists($type, FALSE)) {
-                                       if (!$this->arguments[$argumentName] instanceof $type) {
+                                       if (!($this->arguments[$argumentName] instanceof $type)) {
                                                if (is_object($this->arguments[$argumentName])) {
                                                        throw new \InvalidArgumentException('The argument "' . $argumentName . '" was registered with type "' . $type . '", but is of type "' . get_class($this->arguments[$argumentName]) . '" in view helper "' . get_class($this) . '".', 1256475114);
                                                } else {
@@ -434,11 +453,11 @@ abstract class AbstractViewHelper {
         * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode
         * @param \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler
         * @return string
-        * @internal
-        * @see Tx_Fluid_Core_ViewHelper_Facets_CompilableInterface
+        * @see \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface
         */
        public function compile($argumentsVariableName, $renderChildrenClosureVariableName, &$initializationPhpCode, \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode, \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler) {
-               return sprintf('%s::renderStatic(%s, %s, $renderingContext)', get_class($this), $argumentsVariableName, $renderChildrenClosureVariableName);
+               return sprintf('%s::renderStatic(%s, %s, $renderingContext)',
+                               get_class($this), $argumentsVariableName, $renderChildrenClosureVariableName);
        }
 
        /**
@@ -449,8 +468,7 @@ abstract class AbstractViewHelper {
         * @param \Closure $renderChildrenClosure
         * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
         * @return mixed
-        * @internal
-        * @see Tx_Fluid_Core_ViewHelper_Facets_CompilableInterface
+        * @see \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface
         */
        static public function renderStatic(array $arguments, \Closure $renderChildrenClosure, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
                return NULL;
index 0d03da7..909df9a 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\Core\ViewHelper;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Argument definition of each view helper argument
  */
index 653b9c1..3113ae4 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\Core\ViewHelper;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Tag builder. Can be easily accessed in AbstractTagBasedViewHelper
  *
@@ -125,6 +126,41 @@ class TagBuilder {
        }
 
        /**
+        * Returns TRUE if the tag has an attribute with the given name
+        *
+        * @param string $attributeName name of the attribute
+        * @return boolean TRUE if the tag has an attribute with the given name, otherwise FALSE
+        * @api
+        */
+       public function hasAttribute($attributeName) {
+               return array_key_exists($attributeName, $this->attributes);
+       }
+
+       /**
+        * Get an attribute from the $attributes-collection
+        *
+        * @param string $attributeName name of the attribute
+        * @return string The attribute value or NULL if the attribute is not registered
+        * @api
+        */
+       public function getAttribute($attributeName) {
+               if (!$this->hasAttribute($attributeName)) {
+                       return NULL;
+               }
+               return $this->attributes[$attributeName];
+       }
+
+       /**
+        * Get all attribute from the $attributes-collection
+        *
+        * @return array Attributes indexed by attribute name
+        * @api
+        */
+       public function getAttributes() {
+               return $this->attributes;
+       }
+
+       /**
         * Adds an attribute to the $attributes-collection
         *
         * @param string $attributeName name of the attribute to be added to the tag
index a96f954..b60bed1 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\Core\ViewHelper;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * @api
  */
@@ -34,9 +35,9 @@ class ViewHelperVariableContainer {
         *
         * In case the value is already inside, an exception is thrown.
         *
-        * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like Tx_Fluid_ViewHelpers_ForViewHelper)
+        * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper)
         * @param string $key Key of the data
-        * @param object $value The value to store
+        * @param mixed $value The value to store
         * @return void
         * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception\InvalidVariableException if there was no key with the specified name
         * @api
@@ -53,9 +54,9 @@ class ViewHelperVariableContainer {
         * to your fully qualified ViewHelper Class Name.
         * In case the value is already inside, it is silently overridden.
         *
-        * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like Tx_Fluid_ViewHelpers_ForViewHelper)
+        * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper)
         * @param string $key Key of the data
-        * @param object $value The value to store
+        * @param mixed $value The value to store
         * @return void
         */
        public function addOrUpdate($viewHelperName, $key, $value) {
@@ -68,9 +69,9 @@ class ViewHelperVariableContainer {
        /**
         * Gets a variable which is stored
         *
-        * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like Tx_Fluid_ViewHelpers_ForViewHelper)
+        * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper)
         * @param string $key Key of the data
-        * @return object The object stored
+        * @return mixed The object stored
         * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception\InvalidVariableException if there was no key with the specified name
         * @api
         */
@@ -84,7 +85,7 @@ class ViewHelperVariableContainer {
        /**
         * Determine whether there is a variable stored for the given key
         *
-        * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like Tx_Fluid_ViewHelpers_ForViewHelper)
+        * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper)
         * @param string $key Key of the data
         * @return boolean TRUE if a value for the given ViewHelperName / Key is stored, FALSE otherwise.
         * @api
@@ -96,7 +97,7 @@ class ViewHelperVariableContainer {
        /**
         * Remove a value from the variable container
         *
-        * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like Tx_Fluid_ViewHelpers_ForViewHelper)
+        * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper)
         * @param string $key Key of the data to remove
         * @return void
         * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception\InvalidVariableException if there was no key with the specified name
index 2531557..9b42974 100644 (file)
@@ -51,7 +51,7 @@ abstract class AbstractWidgetViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper
        /**
         * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
         */
-       private $objectManager;
+       protected $objectManager;
 
        /**
         * @var \TYPO3\CMS\Extbase\Service\ExtensionService
diff --git a/typo3/sysext/fluid/Classes/Service/AbstractGenerator.php b/typo3/sysext/fluid/Classes/Service/AbstractGenerator.php
new file mode 100644 (file)
index 0000000..45de645
--- /dev/null
@@ -0,0 +1,127 @@
+<?php
+namespace TYPO3\CMS\Fluid\Service;
+
+/*                                                                        *
+ * This script is backported from the TYPO3 Flow package "TYPO3.Fluid".   *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License, either version 3   *
+ *  of the License, or (at your option) any later version.                *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * Common base class for XML generators.
+ */
+abstract class AbstractGenerator {
+
+       /**
+        * The reflection class for AbstractViewHelper. Is needed quite often, that's why we use a pre-initialized one.
+        *
+        * @var \TYPO3\CMS\Extbase\Reflection\ClassReflection
+        */
+       protected $abstractViewHelperReflectionClass;
+
+       /**
+        * The doc comment parser.
+        *
+        * @var \TYPO3\CMS\Extbase\Reflection\DocCommentParser
+        */
+       protected $docCommentParser;
+
+       /**
+        * @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
+        */
+       protected $reflectionService;
+
+       /**
+        * Constructor. Sets $this->abstractViewHelperReflectionClass
+        *
+        */
+       public function __construct() {
+               \TYPO3\CMS\Fluid\Fluid::$debugMode = TRUE; // We want ViewHelper argument documentation
+               $this->abstractViewHelperReflectionClass = new \TYPO3\CMS\Extbase\Reflection\ClassReflection('TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper');
+       }
+
+       /**
+        *
+        * @param \TYPO3\CMS\Extbase\Reflection\DocCommentParser $docCommentParser
+        */
+       public function injectDocCommentParser(\TYPO3\CMS\Extbase\Reflection\DocCommentParser $docCommentParser) {
+               $this->docCommentParser = $docCommentParser;
+       }
+
+       /**
+        *
+        * @param \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService
+        */
+       public function injectReflectionService(\TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService) {
+               $this->reflectionService = $reflectionService;
+       }
+
+
+       /**
+        * Get all class names inside this namespace and return them as array.
+        *
+        * @param string $namespace
+        * @return array Array of all class names inside a given namespace.
+        */
+       protected function getClassNamesInNamespace($namespace) {
+               $affectedViewHelperClassNames = array();
+
+               $allViewHelperClassNames = $this->reflectionService->getAllSubClassNamesForClass('TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper');
+               foreach ($allViewHelperClassNames as $viewHelperClassName) {
+                       if ($this->reflectionService->isClassAbstract($viewHelperClassName)) {
+                               continue;
+                       }
+                       if (strncmp($namespace, $viewHelperClassName, strlen($namespace)) === 0) {
+                               $affectedViewHelperClassNames[] = $viewHelperClassName;
+                       }
+               }
+               sort($affectedViewHelperClassNames);
+               return $affectedViewHelperClassNames;
+       }
+
+       /**
+        * Get a tag name for a given ViewHelper class.
+        * Example: For the View Helper TYPO3\CMS\Fluid\ViewHelpers\Form\SelectViewHelper, and the
+        * namespace prefix TYPO3\CMS\Fluid\ViewHelpers\, this method returns "form.select".
+        *
+        * @param string $className Class name
+        * @param string $namespace Base namespace to use
+        * @return string Tag name
+        */
+       protected function getTagNameForClass($className, $namespace) {
+               $strippedClassName = substr($className, strlen($namespace));
+               $classNameParts = explode(\TYPO3\CMS\Fluid\Fluid::NAMESPACE_SEPARATOR, $strippedClassName);
+
+               if (count($classNameParts) == 1) {
+                       $tagName = lcfirst(substr($classNameParts[0], 0, -10)); // strip the "ViewHelper" ending
+               } else {
+                       $tagName = lcfirst($classNameParts[0]) . '.' . lcfirst(substr($classNameParts[1], 0, -10));
+               }
+               return $tagName;
+       }
+
+       /**
+        * Add a child node to $parentXmlNode, and wrap the contents inside a CDATA section.
+        *
+        * @param \SimpleXMLElement $parentXmlNode Parent XML Node to add the child to
+        * @param string $childNodeName Name of the child node
+        * @param string $childNodeValue Value of the child node. Will be placed inside CDATA.
+        * @return \SimpleXMLElement the new element
+        */
+       protected function addChildWithCData(\SimpleXMLElement $parentXmlNode, $childNodeName, $childNodeValue) {
+               $parentDomNode = dom_import_simplexml($parentXmlNode);
+               $domDocument = new \DOMDocument();
+
+               $childNode = $domDocument->appendChild($domDocument->createElement($childNodeName));
+               $childNode->appendChild($domDocument->createCDATASection($childNodeValue));
+               $childNodeTarget = $parentDomNode->ownerDocument->importNode($childNode, true);
+               $parentDomNode->appendChild($childNodeTarget);
+               return simplexml_import_dom($childNodeTarget);
+       }
+
+}
+?>
\ No newline at end of file
index f27d86c..54313d8 100644 (file)
@@ -10,11 +10,12 @@ namespace TYPO3\CMS\Fluid\Service;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * XML Schema (XSD) Generator. Will generate an XML schema which can be used for autocompletion
  * in schema-aware editors like Eclipse XML editor.
  */
-class DocbookGenerator extends \TYPO3\CMS\Fluid\Compatibility\DocbookGeneratorService {
+class DocbookGenerator extends \TYPO3\CMS\Fluid\Service\AbstractGenerator {
 
        /**
         * Generate the XML Schema definition for a given namespace.
@@ -176,8 +177,7 @@ class DocbookGenerator extends \TYPO3\CMS\Fluid\Compatibility\DocbookGeneratorSe
                                }
                                $this->addChildWithCData($example, 'programlisting', trim($tmp[2]));
                        } else {
-                               $textParts = explode('
-', $singleMatch);
+                               $textParts = explode("\n", $singleMatch);
                                foreach ($textParts as $text) {
                                        if (trim($text) === '') {
                                                continue;
index 734f80c..a155d2a 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\View;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Abstract Fluid Template View.
  *
@@ -124,8 +125,8 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
 
        public function initializeView() {
        }
-
        // Here, the backporter can insert the initializeView method, which is needed for Fluid v4.
+
        /**
         * Assign a value to the variable container.
         *
@@ -173,6 +174,7 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
        public function render($actionName = NULL) {
                $this->baseRenderingContext->setControllerContext($this->controllerContext);
                $this->templateParser->setConfiguration($this->buildParserConfiguration());
+
                $templateIdentifier = $this->getTemplateIdentifier($actionName);
                if ($this->templateCompiler->has($templateIdentifier)) {
                        $parsedTemplate = $this->templateCompiler->get($templateIdentifier);
@@ -182,6 +184,7 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
                                $this->templateCompiler->store($templateIdentifier, $parsedTemplate);
                        }
                }
+
                if ($parsedTemplate->hasLayout()) {
                        $layoutName = $parsedTemplate->getLayoutName($this->baseRenderingContext);
                        $layoutIdentifier = $this->getLayoutIdentifier($layoutName);
@@ -201,6 +204,7 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
                        $output = $parsedTemplate->render($this->baseRenderingContext);
                        $this->stopRendering();
                }
+
                return $output;
        }
 
@@ -224,7 +228,9 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
                        $renderingContext->injectTemplateVariableContainer($variableContainer);
                        $renderingTypeOnNextLevel = $this->getCurrentRenderingType();
                }
+
                $parsedTemplate = $this->getCurrentParsedTemplate();
+
                if ($parsedTemplate->isCompiled()) {
                        $methodNameOfSection = 'section_' . sha1($sectionName);
                        if ($ignoreUnknown && !method_exists($parsedTemplate, $methodNameOfSection)) {
@@ -244,11 +250,14 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
                                }
                        }
                        $section = $sections[$sectionName];
+
                        $renderingContext->getViewHelperVariableContainer()->add('TYPO3\\CMS\\Fluid\\ViewHelpers\\SectionViewHelper', 'isCurrentlyRenderingSection', 'TRUE');
+
                        $this->startRendering($renderingTypeOnNextLevel, $parsedTemplate, $renderingContext);
                        $output = $section->evaluate($renderingContext);
                        $this->stopRendering();
                }
+
                return $output;
        }
 
@@ -266,6 +275,7 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
                        $this->partialIdentifierCache[$partialName] = $this->getPartialIdentifier($partialName);
                }
                $partialIdentifier = $this->partialIdentifierCache[$partialName];
+
                if ($this->templateCompiler->has($partialIdentifier)) {
                        $parsedPartial = $this->templateCompiler->get($partialIdentifier);
                } else {
@@ -274,9 +284,11 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
                                $this->templateCompiler->store($partialIdentifier, $parsedPartial);
                        }
                }
+
                $variableContainer = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\ViewHelper\\TemplateVariableContainer', $variables);
                $renderingContext = clone $this->getCurrentRenderingContext();
                $renderingContext->injectTemplateVariableContainer($variableContainer);
+
                $this->startRendering(self::RENDERING_PARTIAL, $parsedPartial, $renderingContext);
                if ($sectionName !== NULL) {
                        $output = $this->renderSection($sectionName, $variables);
@@ -284,6 +296,7 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
                        $output = $parsedPartial->render($renderingContext);
                }
                $this->stopRendering();
+
                return $output;
        }
 
@@ -323,7 +336,7 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
         * this method returns that path, otherwise a path and filename will be
         * resolved using the layoutPathAndFilenamePattern.
         *
-        * @param string $layoutName Name of the layout to use. If none given, use "Default
+        * @param string $layoutName Name of the layout to use. If none given, use "Default"
         * @return string Path and filename of layout file
         * @throws \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
         */
@@ -385,7 +398,7 @@ abstract class AbstractTemplateView implements \TYPO3\CMS\Extbase\Mvc\View\ViewI
        /**
         * Get the current rendering type.
         *
-        * @return one of RENDERING_* constants
+        * @return integer one of RENDERING_* constants
         */
        protected function getCurrentRenderingType() {
                $currentRendering = end($this->renderingStack);
index 1433eec..20b9135 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\View;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * The main template view. Should be used as view if you want Fluid Templating
  *
@@ -104,6 +105,7 @@ class TemplateView extends \TYPO3\CMS\Fluid\View\AbstractTemplateView {
        }
 
        // Here, the backporter can insert a constructor method, which is needed for Fluid v4.
+
        /**
         * Sets the path and name of of the template file. Effectively overrides the
         * dynamic resolving of a template file.
@@ -236,7 +238,7 @@ class TemplateView extends \TYPO3\CMS\Fluid\View\AbstractTemplateView {
         * this method returns that path, otherwise a path and filename will be
         * resolved using the layoutPathAndFilenamePattern.
         *
-        * @param string $layoutName Name of the layout to use. If none given, use "Default
+        * @param string $layoutName Name of the layout to use. If none given, use "Default"
         * @return string contents of the layout template
         * @throws \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
         */
@@ -257,7 +259,7 @@ class TemplateView extends \TYPO3\CMS\Fluid\View\AbstractTemplateView {
         * this method returns that path, otherwise a path and filename will be
         * resolved using the layoutPathAndFilenamePattern.
         *
-        * @param string $layoutName Name of the layout to use. If none given, use "Default
+        * @param string $layoutName Name of the layout to use. If none given, use "Default"
         * @return string Path and filename of layout files
         * @throws \TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException
         */
@@ -402,9 +404,9 @@ class TemplateView extends \TYPO3\CMS\Fluid\View\AbstractTemplateView {
         * as Controller Object Name and the current format is "html"
         *
         * If pattern is "@templateRoot/@subpackage/@controller/@action.@format", then the resulting array is:
-        * - "Resources/Private/Templates/MySubPackage/My/@action.html"
-        * - "Resources/Private/Templates/MySubPackage/@action.html"
-        * - "Resources/Private/Templates/@action.html"
+        *  - "Resources/Private/Templates/MySubPackage/My/@action.html"
+        *  - "Resources/Private/Templates/MySubPackage/@action.html"
+        *  - "Resources/Private/Templates/@action.html"
         *
         * If you set $formatIsOptional to TRUE, then for any of the above arrays, every element will be duplicated  - once with "@format"
         * replaced by the current request format, and once with ."@format" stripped off.
@@ -418,6 +420,7 @@ class TemplateView extends \TYPO3\CMS\Fluid\View\AbstractTemplateView {
                $pattern = str_replace('@templateRoot', $this->getTemplateRootPath(), $pattern);
                $pattern = str_replace('@partialRoot', $this->getPartialRootPath(), $pattern);
                $pattern = str_replace('@layoutRoot', $this->getLayoutRootPath(), $pattern);
+
                $subpackageKey = $this->controllerContext->getRequest()->getControllerSubpackageKey();
                $controllerName = $this->controllerContext->getRequest()->getControllerName();
                if ($subpackageKey !== NULL) {
@@ -431,7 +434,8 @@ class TemplateView extends \TYPO3\CMS\Fluid\View\AbstractTemplateView {
                        $subpackageParts = array();
                }
                $results = array();
-               $i = $controllerName === NULL ? 0 : -1;
+
+               $i = ($controllerName === NULL) ? 0 : -1;
                do {
                        $temporaryPattern = $pattern;
                        if ($i < 0) {
@@ -439,12 +443,14 @@ class TemplateView extends \TYPO3\CMS\Fluid\View\AbstractTemplateView {
                        } else {
                                $temporaryPattern = str_replace('//', '/', str_replace('@controller', '', $temporaryPattern));
                        }
-                       $temporaryPattern = str_replace('@subpackage', implode('/', $i < 0 ? $subpackageParts : array_slice($subpackageParts, $i)), $temporaryPattern);
+                       $temporaryPattern = str_replace('@subpackage', implode('/', ($i < 0 ? $subpackageParts : array_slice($subpackageParts, $i))), $temporaryPattern);
+
                        $results[] = \TYPO3\CMS\Core\Utility\GeneralUtility::fixWindowsFilePath(str_replace('@format', $this->controllerContext->getRequest()->getFormat(), $temporaryPattern));
                        if ($formatIsOptional) {
                                $results[] = \TYPO3\CMS\Core\Utility\GeneralUtility::fixWindowsFilePath(str_replace('.@format', '', $temporaryPattern));
                        }
                } while ($i++ < count($subpackageParts) && $bubbleControllerAndSubpackage);
+
                return $results;
        }
 
index c648e05..8cff37d 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Declares new variables which are aliases of other variables.
  * Takes a "map"-Parameter which is an associative array which defines the shorthand mapping.
@@ -28,7 +29,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *
  * <code title="Multiple mappings">
  * <f:alias map="{x: foo.bar.baz, y: foo.bar.baz.name}">
- * {x.name} or {y}
+ *   {x.name} or {y}
  * </f:alias>
  * </code>
  * <output>
@@ -41,9 +42,8 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
 class AliasViewHelper extends \TYPO3\CMS\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 9cefda6..76d28f3 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Loop view helper which can be used to interate over array.
  * Implements what a basic foreach()-PHP-method does.
@@ -25,33 +26,33 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *
  * <code title="Output array key">
  * <ul>
- * <f:for each="{fruit1: 'apple', fruit2: 'pear', fruit3: 'banana', fruit4: 'cherry'}" as="fruit" key="label">
- * <li>{label}: {fruit}</li>
- * </f:for>
+ *   <f:for each="{fruit1: 'apple', fruit2: 'pear', fruit3: 'banana', fruit4: 'cherry'}" as="fruit" key="label">
+ *     <li>{label}: {fruit}</li>
+ *   </f:for>
  * </ul>
  * </code>
  * <output>
  * <ul>
- * <li>fruit1: apple</li>
- * <li>fruit2: pear</li>
- * <li>fruit3: banana</li>
- * <li>fruit4: cherry</li>
+ *   <li>fruit1: apple</li>
+ *   <li>fruit2: pear</li>
+ *   <li>fruit3: banana</li>
+ *   <li>fruit4: cherry</li>
  * </ul>
  * </output>
  *
  * <code title="Iteration information">
  * <ul>
- * <f:for each="{0:1, 1:2, 2:3, 3:4}" as="foo" iteration="fooIterator">
- * <li>Index: {fooIterator.index} Cycle: {fooIterator.cycle} Total: {fooIterator.total}{f:if(condition: fooIterator.isEven, then: ' Even')}{f:if(condition: fooIterator.isOdd, then: ' Odd')}{f:if(condition: fooIterator.isFirst, then: ' First')}{f:if(condition: fooIterator.isLast, then: ' Last')}</li>
- * </f:for>
+ *   <f:for each="{0:1, 1:2, 2:3, 3:4}" as="foo" iteration="fooIterator">
+ *     <li>Index: {fooIterator.index} Cycle: {fooIterator.cycle} Total: {fooIterator.total}{f:if(condition: fooIterator.isEven, then: ' Even')}{f:if(condition: fooIterator.isOdd, then: ' Odd')}{f:if(condition: fooIterator.isFirst, then: ' First')}{f:if(condition: fooIterator.isLast, then: ' Last')}</li>
+ *   </f:for>
  * </ul>
  * </code>
  * <output>
  * <ul>
- * <li>Index: 0 Cycle: 1 Total: 4 Odd First</li>
- * <li>Index: 1 Cycle: 2 Total: 4 Even</li>
- * <li>Index: 2 Cycle: 3 Total: 4 Odd</li>
- * <li>Index: 3 Cycle: 4 Total: 4 Even Last</li>
+ *   <li>Index: 0 Cycle: 1 Total: 4 Odd First</li>
+ *   <li>Index: 1 Cycle: 2 Total: 4 Even</li>
+ *   <li>Index: 2 Cycle: 3 Total: 4 Odd</li>
+ *   <li>Index: 3 Cycle: 4 Total: 4 Even Last</li>
  * </ul>
  * </output>
  *
@@ -79,6 +80,7 @@ class ForViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
         * @param \Closure $renderChildrenClosure
         * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
         * @return string
+        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         */
        static public function renderStatic(array $arguments, \Closure $renderChildrenClosure, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
                $templateVariableContainer = $renderingContext->getTemplateVariableContainer();
@@ -86,8 +88,9 @@ class ForViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
                        return '';
                }
                if (is_object($arguments['each']) && !$arguments['each'] instanceof \Traversable) {
-                       throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('ForViewHelper only supports arrays and objects implementing Traversable interface', 1248728393);
+                       throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('ForViewHelper only supports arrays and objects implementing \Traversable interface', 1248728393);
                }
+
                if ($arguments['reverse'] === TRUE) {
                        // array_reverse only supports arrays
                        if (is_object($arguments['each'])) {
@@ -100,6 +103,7 @@ class ForViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
                        'cycle' => 1,
                        'total' => count($arguments['each'])
                );
+
                $output = '';
                foreach ($arguments['each'] as $keyValue => $singleElement) {
                        $templateVariableContainer->add($arguments['as'], $singleElement);
index ef8ce2b..8150460 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Form;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Abstract Form View Helper. Bundles functionality related to direct property access of objects in other Form ViewHelpers.
  *
@@ -64,10 +65,12 @@ abstract class AbstractFormViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\A
         * @param object $object Object to create the identity field for
         * @param string $name Name
         * @return string A hidden field containing the Identity (UID in TYPO3 Flow, uid in Extbase) of the given object or NULL if the object is unknown to the persistence framework
-        * @see Tx_Fluid_MVC_Controller_Argument::setValue()
+        * @see \TYPO3\CMS\Extbase\Mvc\Controller\Argument::setValue()
         */
        protected function renderHiddenIdentityField($object, $name) {
-               if (!is_object($object) || !$object instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject || $object->_isNew() && !$object->_isClone()) {
+               if (!is_object($object)
+                       || !($object instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject)
+                       || ($object->_isNew() && !$object->_isClone())) {
                        return '';
                }
                // Intentionally NOT using PersistenceManager::getIdentifierByObject here!!
@@ -78,7 +81,8 @@ abstract class AbstractFormViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\A
                }
                $name = $this->prefixFieldName($name) . '[__identity]';
                $this->registerFieldNameForFormTokenGeneration($name);
-               return chr(10) . '<input type="hidden" name="' . $name . '" value="' . $identifier . '" />' . chr(10);
+
+               return chr(10) . '<input type="hidden" name="'. $name . '" value="' . $identifier .'" />' . chr(10);
        }
 
        /**
index 74d2c5e..07b6f6a 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Form;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Renders an <input type="hidden" ...> tag.
  *
@@ -54,9 +55,11 @@ class HiddenViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFie
        public function render() {
                $name = $this->getName();
                $this->registerFieldNameForFormTokenGeneration($name);
+
                $this->tag->addAttribute('type', 'hidden');
                $this->tag->addAttribute('name', $name);
                $this->tag->addAttribute('value', $this->getValue());
+
                return $this->tag->render();
        }
 }
index 2daf233..990295a 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Form;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * View Helper which creates a simple Password Text Box (<input type="password">).
  *
@@ -48,7 +49,7 @@ class PasswordViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormF
        }
 
        /**
-        * Renders the textbox.
+        * Renders the password input field.
         *
         * @return string
         * @api
@@ -56,10 +57,13 @@ class PasswordViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormF
        public function render() {
                $name = $this->getName();
                $this->registerFieldNameForFormTokenGeneration($name);
+
                $this->tag->addAttribute('type', 'password');
                $this->tag->addAttribute('name', $name);
                $this->tag->addAttribute('value', $this->getValue());
+
                $this->setErrorClassAttribute();
+
                return $this->tag->render();
        }
 }
index 417a484..e708d1f 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Form;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * View Helper which creates a simple radio button (<input type="radio">).
  *
@@ -72,20 +73,29 @@ class RadioViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFiel
         */
        public function render($checked = NULL) {
                $this->tag->addAttribute('type', 'radio');
+
                $nameAttribute = $this->getName();
                $valueAttribute = $this->getValue();
                if ($checked === NULL && $this->isObjectAccessorMode()) {
-                       $propertyValue = $this->getPropertyValue();
-                       // no type-safe comparisation by intention
+                       if ($this->hasMappingErrorOccured()) {
+                               $propertyValue = $this->getLastSubmittedFormData();
+                       } else {
+                               $propertyValue = $this->getPropertyValue();
+                       }
+
+                       // no type-safe comparison by intention
                        $checked = $propertyValue == $valueAttribute;
                }
+
                $this->registerFieldNameForFormTokenGeneration($nameAttribute);
                $this->tag->addAttribute('name', $nameAttribute);
                $this->tag->addAttribute('value', $valueAttribute);
                if ($checked) {
                        $this->tag->addAttribute('checked', 'checked');
                }
+
                $this->setErrorClassAttribute();
+
                return $this->tag->render();
        }
 }
index 7591a7f..6e6ddce 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Form;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Creates a submit button.
  *
@@ -59,9 +60,11 @@ class SubmitViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFie
        public function render() {
                $name = $this->getName();
                $this->registerFieldNameForFormTokenGeneration($name);
+
                $this->tag->addAttribute('type', 'submit');
                $this->tag->addAttribute('name', $name);
                $this->tag->addAttribute('value', $this->getValue());
+
                return $this->tag->render();
        }
 }
index 4824cf6..1d9d069 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Form;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Textarea view helper.
  * The value of the text area needs to be set via the "value" attribute, as with all other form ViewHelpers.
@@ -56,10 +57,13 @@ class TextareaViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormF
        public function render() {
                $name = $this->getName();
                $this->registerFieldNameForFormTokenGeneration($name);
+
                $this->tag->forceClosingTag(TRUE);
                $this->tag->addAttribute('name', $name);
                $this->tag->setContent(htmlspecialchars($this->getValue()));
+
                $this->setErrorClassAttribute();
+
                return $this->tag->render();
        }
 }
index d5c0c3a..9771a14 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Form;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * View Helper which creates a text field (<input type="text">).
  *
@@ -59,19 +60,26 @@ class TextfieldViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractForm
        public function render($required = NULL, $type = 'text', $placeholder = NULL) {
                $name = $this->getName();
                $this->registerFieldNameForFormTokenGeneration($name);
+
                $this->tag->addAttribute('type', $type);
                $this->tag->addAttribute('name', $name);
+
                $value = $this->getValue();
+
                if ($placeholder !== NULL) {
                        $this->tag->addAttribute('placeholder', $placeholder);
                }
+
                if ($value !== NULL) {
                        $this->tag->addAttribute('value', $value);
                }
+
                if ($required !== NULL) {
                        $this->tag->addAttribute('required', 'required');
                }
+
                $this->setErrorClassAttribute();
+
                return $this->tag->render();
        }
 }
index 1b5b099..724b6e4 100644 (file)
@@ -10,8 +10,9 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
- * Formats a DateTime object.
+ * Formats a \DateTime object.
  *
  * = Examples =
  *
@@ -85,8 +86,8 @@ class DateViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
         *
         * @param mixed $date either a DateTime object or a string that is accepted by DateTime constructor
         * @param string $format Format String which is taken to format the Date/Time
-        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         * @return string Formatted date
+        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         * @api
         */
        public function render($date = NULL, $format = 'Y-m-d') {
@@ -105,7 +106,7 @@ class DateViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
                                }
                                $date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
                        } catch (\Exception $exception) {
-                               throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('"' . $date . '" could not be parsed by DateTime constructor.', 1241722579);
+                               throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('"' . $date . '" could not be parsed by \DateTime constructor.', 1241722579);
                        }
                }
 
index 7d56c55..fb52a4f 100644 (file)
@@ -10,10 +10,27 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Applies html_entity_decode() to a value
- *
  * @see http://www.php.net/html_entity_decode
+ *
+ * = Examples =
+ *
+ * <code title="default notation">
+ * <f:format.htmlentitiesDecode>{text}</f:format.htmlentitiesDecode>
+ * </code>
+ * <output>
+ * Text with &amp; &quot; &lt; &gt; replaced by unescaped entities (html_entity_decode applied).
+ * </output>
+ *
+ * <code title="inline notation">
+ * {text -> f:format.htmlentitiesDecode(encoding: 'ISO-8859-1')}
+ * </code>
+ * <output>
+ * Text with &amp; &quot; &lt; &gt; replaced by unescaped entities (html_entity_decode applied).
+ * </output>
+ *
  * @api
  */
 class HtmlentitiesDecodeViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Format\AbstractEncodingViewHelper {
index 8a0a2c3..a6c799c 100644 (file)
@@ -10,10 +10,27 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Applies htmlentities() escaping to a value
- *
  * @see http://www.php.net/manual/function.htmlentities.php
+ *
+ * = Examples =
+ *
+ * <code title="default notation">
+ * <f:format.htmlentities>{text}</f:format.htmlentities>
+ * </code>
+ * <output>
+ * Text with & " ' < > * replaced by HTML entities (htmlentities applied).
+ * </output>
+ *
+ * <code title="inline notation">
+ * {text -> f:format.htmlentities(encoding: 'ISO-8859-1')}
+ * </code>
+ * <output>
+ * Text with & " ' < > * replaced by HTML entities (htmlentities applied).
+ * </output>
+ *
  * @api
  */
 class HtmlentitiesViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Format\AbstractEncodingViewHelper implements \TYPO3\CMS\Core\SingletonInterface {
index 9dbf15b..18ba0f4 100644 (file)
@@ -10,10 +10,27 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Applies htmlspecialchars() escaping to a value
- *
  * @see http://www.php.net/manual/function.htmlspecialchars.php
+ *
+ * = Examples =
+ *
+ * <code title="default notation">
+ * <f:format.htmlspecialchars>{text}</f:format.htmlspecialchars>
+ * </code>
+ * <output>
+ * Text with & " ' < > * replaced by HTML entities (htmlspecialchars applied).
+ * </output>
+ *
+ * <code title="inline notation">
+ * {text -> f:format.htmlspecialchars(encoding: 'ISO-8859-1')}
+ * </code>
+ * <output>
+ * Text with & " ' < > * replaced by HTML entities (htmlspecialchars applied).
+ * </output>
+ *
  * @api
  */
 class HtmlspecialcharsViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Format\AbstractEncodingViewHelper implements \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface {
@@ -51,10 +68,20 @@ class HtmlspecialcharsViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Format\Abs
                return htmlspecialchars($value, $flags, $encoding, $doubleEncode);
        }
 
+       /**
+        * @param string $argumentsVariableName
+        * @param string $renderChildrenClosureVariableName
+        * @param string $initializationPhpCode
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode
+        * @param \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler
+        * @return string
+        */
        public function compile($argumentsVariableName, $renderChildrenClosureVariableName, &$initializationPhpCode, \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode, \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler) {
                $valueVariableName = $templateCompiler->variableName('value');
                $initializationPhpCode .= sprintf('%s = (%s[\'value\'] !== NULL ? %s[\'value\'] : %s());', $valueVariableName, $argumentsVariableName, $argumentsVariableName, $renderChildrenClosureVariableName) . chr(10);
-               return sprintf('(!is_string(%s) ? %s : htmlspecialchars(%s, (%s[\'keepQuotes\'] ? ENT_NOQUOTES : ENT_COMPAT), (%s[\'encoding\'] !== NULL ? %s[\'encoding\'] : TYPO3\\CMS\\Fluid\\Core\\Compiler\\AbstractCompiledTemplate::resolveDefaultEncoding()), %s[\'doubleEncode\']))', $valueVariableName, $valueVariableName, $valueVariableName, $argumentsVariableName, $argumentsVariableName, $argumentsVariableName, $argumentsVariableName);
+
+               return sprintf('(!is_string(%s) ? %s : htmlspecialchars(%s, (%s[\'keepQuotes\'] ? ENT_NOQUOTES : ENT_COMPAT), (%s[\'encoding\'] !== NULL ? %s[\'encoding\'] : \\TYPO3\\CMS\\Fluid\\Core\\Compiler\\AbstractCompiledTemplate::resolveDefaultEncoding()), %s[\'doubleEncode\']))',
+                               $valueVariableName, $valueVariableName, $valueVariableName, $argumentsVariableName, $argumentsVariableName, $argumentsVariableName, $argumentsVariableName);
        }
 }
 
index 6f76b1f..10f9942 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * A view helper for formatting values with printf. Either supply an array for
  * the arguments or a single value.
index a664a61..fd78d5f 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * Grouped loop view helper.
  * Loops through the specified values.
@@ -20,9 +21,9 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *
  * <code title="Simple">
  * <f:groupedFor each="{0: {name: 'apple', color: 'green'}, 1: {name: 'cherry', color: 'red'}, 2: {name: 'banana', color: 'yellow'}, 3: {name: 'strawberry', color: 'red'}}" as="fruitsOfThisColor" groupBy="color">
- * <f:for each="{fruitsOfThisColor}" as="fruit">
- * {fruit.name}
- * </f:for>
+ *   <f:for each="{fruitsOfThisColor}" as="fruit">
+ *     {fruit.name}
+ *   </f:for>
  * </f:groupedFor>
  * </code>
  * <output>
@@ -31,38 +32,38 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *
  * <code title="Two dimensional list">
  * <ul>
- * <f:groupedFor each="{0: {name: 'apple', color: 'green'}, 1: {name: 'cherry', color: 'red'}, 2: {name: 'banana', color: 'yellow'}, 3: {name: 'strawberry', color: 'red'}}" as="fruitsOfThisColor" groupBy="color" groupKey="color">
- * <li>
- * {color} fruits:
- * <ul>
- * <f:for each="{fruitsOfThisColor}" as="fruit" key="label">
- * <li>{label}: {fruit.name}</li>
- * </f:for>
- * </ul>
- * </li>
- * </f:groupedFor>
+ *   <f:groupedFor each="{0: {name: 'apple', color: 'green'}, 1: {name: 'cherry', color: 'red'}, 2: {name: 'banana', color: 'yellow'}, 3: {name: 'strawberry', color: 'red'}}" as="fruitsOfThisColor" groupBy="color" groupKey="color">
+ *     <li>
+ *       {color} fruits:
+ *       <ul>
+ *         <f:for each="{fruitsOfThisColor}" as="fruit" key="label">
+ *           <li>{label}: {fruit.name}</li>
+ *         </f:for>
+ *       </ul>
+ *     </li>
+ *   </f:groupedFor>
  * </ul>
  * </code>
  * <output>
  * <ul>
- * <li>green fruits
- * <ul>
- * <li>0: apple</li>
- * </ul>
- * </li>
- * <li>red fruits
- * <ul>
- * <li>1: cherry</li>
- * </ul>
- * <ul>
- * <li>3: strawberry</li>
- * </ul>
- * </li>
- * <li>yellow fruits
- * <ul>
- * <li>2: banana</li>
- * </ul>
- * </li>
+ *   <li>green fruits
+ *     <ul>
+ *       <li>0: apple</li>
+ *     </ul>
+ *   </li>
+ *   <li>red fruits
+ *     <ul>
+ *       <li>1: cherry</li>
+ *     </ul>
+ *     <ul>
+ *       <li>3: strawberry</li>
+ *     </ul>
+ *   </li>
+ *   <li>yellow fruits
+ *     <ul>
+ *       <li>2: banana</li>
+ *     </ul>
+ *   </li>
  * </ul>
  * </output>
  *
@@ -77,8 +78,8 @@ class GroupedForViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractView
         * @param string $as The name of the iteration variable
         * @param string $groupBy Group by this property
         * @param string $groupKey The name of the variable to store the current group
-        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         * @return string Rendered string
+        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         * @api
         */
        public function render($each, $as, $groupBy, $groupKey = 'groupKey') {
@@ -88,11 +89,13 @@ class GroupedForViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractView
                }
                if (is_object($each)) {
                        if (!$each instanceof \Traversable) {
-                               throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('GroupedForViewHelper only supports arrays and objects implementing Traversable interface', 1253108907);
+                               throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('GroupedForViewHelper only supports arrays and objects implementing \Traversable interface', 1253108907);
                        }
                        $each = iterator_to_array($each);
                }
+
                $groups = $this->groupElements($each, $groupBy);
+
                foreach ($groups['values'] as $currentGroupIndex => $group) {
                        $this->templateVariableContainer->add($groupKey, $groups['keys'][$currentGroupIndex]);
                        $this->templateVariableContainer->add($as, $group);
@@ -108,8 +111,8 @@ class GroupedForViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractView
         *
         * @param array $elements The array / traversable object to be grouped
         * @param string $groupBy Group by this property
-        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         * @return array The grouped array in the form array('keys' => array('key1' => [key1value], 'key2' => [key2value], ...), 'values' => array('key1' => array([key1value] => [element1]), ...), ...)
+        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
         */
        protected function groupElements(array $elements, $groupBy) {
                $groups = array('keys' => array(), 'values' => array());
index 65d3531..c8114a0 100644 (file)
@@ -10,11 +10,12 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * This view helper implements an if/else condition.
- * Check Tx_Fluid_Core_Parser_SyntaxTree_ViewHelperNode::convertArgumentValue() to see how boolean arguments are evaluated
+ * Check \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode::convertArgumentValue() to see how boolean arguments are evaluated
  *
- * Conditions:**
+ * **Conditions:**
  *
  * As a condition is a boolean value, you can just use a boolean argument.
  * Alternatively, you can write a boolean expression there.
@@ -33,24 +34,24 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  * below).
  * ::
  *
- * <f:if condition="{rank} > 100">
- * Will be shown if rank is > 100
- * </f:if>
- * <f:if condition="{rank} % 2">
- * Will be shown if rank % 2 != 0.
- * </f:if>
- * <f:if condition="{rank} == {k:bar()}">
- * Checks if rank is equal to the result of the ViewHelper "k:bar"
- * </f:if>
- * <f:if condition="{0: foo.bar} == {0: 'stringToCompare'}">
- * Will result true if {foo.bar}'s represented value equals 'stringToCompare'.
- * </f:if>
+ *   <f:if condition="{rank} > 100">
+ *     Will be shown if rank is > 100
+ *   </f:if>
+ *   <f:if condition="{rank} % 2">
+ *     Will be shown if rank % 2 != 0.
+ *   </f:if>
+ *   <f:if condition="{rank} == {k:bar()}">
+ *     Checks if rank is equal to the result of the ViewHelper "k:bar"
+ *   </f:if>
+ *   <f:if condition="{0: foo.bar} == {0: 'stringToCompare'}">
+ *     Will result true if {foo.bar}'s represented value equals 'stringToCompare'.
+ *   </f:if>
  *
  * = Examples =
  *
  * <code title="Basic usage">
  * <f:if condition="somecondition">
- * This is being shown in case the condition matches
+ *   This is being shown in case the condition matches
  * </f:if>
  * </code>
  * <output>
@@ -59,12 +60,12 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *
  * <code title="If / then / else">
  * <f:if condition="somecondition">
- * <f:then>
- * This is being shown in case the condition matches.
- * </f:then>
- * <f:else>
- * This is being displayed in case the condition evaluates to FALSE.
- * </f:else>
+ *   <f:then>
+ *     This is being shown in case the condition matches.
+ *   </f:then>
+ *   <f:else>
+ *     This is being displayed in case the condition evaluates to FALSE.
+ *   </f:else>
  * </f:if>
  * </code>
  * <output>
@@ -80,7 +81,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  * Otherwise, everything the value of the "else"-attribute is displayed.
  * </output>
  *
- * @see Tx_Fluid_Core_Parser_SyntaxTree_ViewHelperNode::convertArgumentValue()
+ * @see \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode::convertArgumentValue()
  * @api
  */
 class IfViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper {
index 691869b..8c8c29e 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * With this tag, you can select a layout to be used for the current template.
  *
@@ -50,6 +51,7 @@ class LayoutViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelp
                } else {
                        $layoutNameNode = new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode('Default');
                }
+
                $variableContainer->add('layoutName', $layoutNameNode);
        }
 
index 806073b..e154e2c 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * ViewHelper that renders a section or a specified partial
  *
@@ -32,27 +33,27 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *
  * <code title="Rendering recursive sections">
  * <f:section name="mySection">
- * <ul>
- * <f:for each="{myMenu}" as="menuItem">
- * <li>
- * {menuItem.text}
- * <f:if condition="{menuItem.subItems}">
- * <f:render section="mySection" arguments="{myMenu: menuItem.subItems}" />
- * </f:if>
- * </li>
- * </f:for>
- * </ul>
+ *  <ul>
+ *    <f:for each="{myMenu}" as="menuItem">
+ *      <li>
+ *        {menuItem.text}
+ *        <f:if condition="{menuItem.subItems}">
+ *          <f:render section="mySection" arguments="{myMenu: menuItem.subItems}" />
+ *        </f:if>
+ *      </li>
+ *    </f:for>
+ *  </ul>
  * </f:section>
  * <f:render section="mySection" arguments="{myMenu: menu}" />
  * </code>
  * <output>
  * <ul>
- * <li>menu1
- * <ul>
- * <li>menu1a</li>
- * <li>menu1b</li>
- * </ul>
- * </li>
+ *   <li>menu1
+ *     <ul>
+ *       <li>menu1a</li>
+ *       <li>menu1b</li>
+ *     </ul>
+ *   </li>
  * [...]
  * (depending on the value of {menu})
  * </output>
@@ -82,6 +83,7 @@ class RenderViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelp
         */
        public function render($section = NULL, $partial = NULL, $arguments = array(), $optional = FALSE) {
                $arguments = $this->loadSettingsIntoArguments($arguments);
+
                if ($partial !== NULL) {
                        return $this->viewHelperVariableContainer->getView()->renderPartial($partial, $section, $arguments);
                } elseif ($section !== NULL) {
index 66a2372..81a9488 100644 (file)
@@ -10,6 +10,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * A Section view helper
  *
@@ -25,27 +26,27 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *
  * <code title="Rendering recursive sections">
  * <f:section name="mySection">
- * <ul>
- * <f:for each="{myMenu}" as="menuItem">
- * <li>
- * {menuItem.text}
- * <f:if condition="{menuItem.subItems}">
- * <f:render section="mySection" arguments="{myMenu: menuItem.subItems}" />
- * </f:if>
- * </li>
- * </f:for>
- * </ul>
+ *  <ul>
+ *    <f:for each="{myMenu}" as="menuItem">
+ *      <li>
+ *        {menuItem.text}
+ *        <f:if condition="{menuItem.subItems}">
+ *          <f:render section="mySection" arguments="{myMenu: menuItem.subItems}" />
+ *        </f:if>
+ *      </li>
+ *    </f:for>
+ *  </ul>
  * </f:section>
  * <f:render section="mySection" arguments="{myMenu: menu}" />
  * </code>
  * <output>
  * <ul>
- * <li>menu1
- * <ul>
- * <li>menu1a</li>
- * <li>menu1b</li>
- * </ul>
- * </li>
+ *   <li>menu1
+ *     <ul>
+ *       <li>menu1a</li>
+ *       <li>menu1b</li>
+ *     </ul>
+ *   </li>
  * [...]
  * (depending on the value of {menu})
  * </output>
index 6ec91ab..3875ece 100644 (file)
@@ -10,10 +10,11 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
  * "THEN" -> only has an effect inside of "IF". See If-ViewHelper for documentation.
  *
- * @see Tx_Fluid_ViewHelpers_IfViewHelper
+ * @see \TYPO3\CMS\Fluid\ViewHelpers\IfViewHelper
  * @api
  */
 class ThenViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {