[TASK] Merge submodule fluid into core
authorThomas Maroschik <tmaroschik@dfau.de>
Mon, 27 May 2013 17:05:51 +0000 (19:05 +0200)
committerThomas Maroschik <tmaroschik@dfau.de>
Mon, 27 May 2013 17:05:51 +0000 (19:05 +0200)
257 files changed:
.gitmodules
typo3/sysext/fluid [deleted submodule]
typo3/sysext/fluid/ChangeLog.txt [new file with mode: 0644]
typo3/sysext/fluid/Classes/Compatibility/DocbookGeneratorService.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Compatibility/TemplateParserBuilder.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Compiler/AbstractCompiledTemplate.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Compiler/TemplateCompiler.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Exception.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/Configuration.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/Exception.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/Interceptor/Escape.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/InterceptorInterface.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/ParsedTemplateInterface.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/ParsingState.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/AbstractNode.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ArrayNode.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/BooleanNode.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/NodeInterface.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/NumericNode.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ObjectAccessorNode.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/RenderingContextAwareInterface.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/RootNode.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/TextNode.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ViewHelperNode.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Parser/TemplateParser.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Rendering/RenderingContext.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Rendering/RenderingContextInterface.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractConditionViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractTagBasedViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/ArgumentDefinition.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/Arguments.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/Exception.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/Exception/InvalidVariableException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/Exception/RenderingContextNotAccessibleException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/Facets/ChildNodeAccessInterface.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/Facets/CompilableInterface.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/Facets/PostParseInterface.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/TagBuilder.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/TemplateVariableContainer.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/ViewHelperInterface.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/ViewHelperVariableContainer.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/AbstractWidgetController.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/AbstractWidgetViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/AjaxWidgetContextHolder.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Bootstrap.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Exception.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Exception/MissingControllerException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Exception/RenderingContextNotFoundException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Exception/WidgetContextNotFoundException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Exception/WidgetRequestNotFoundException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/WidgetContext.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/WidgetRequest.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/WidgetRequestBuilder.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/WidgetRequestHandler.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Exception.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Fluid.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Service/AbstractGenerator.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Service/DocbookGenerator.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/View/AbstractTemplateView.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/View/Exception.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/View/Exception/InvalidSectionException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/View/Exception/InvalidTemplateResourceException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/View/StandaloneView.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/View/TemplateView.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/AliasViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/BaseViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/AbstractBackendViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/Buttons/CshViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/Buttons/IconViewHelper.php [new file with mode: 0755]
typo3/sysext/fluid/Classes/ViewHelpers/Be/Buttons/ShortcutViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/ContainerViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/Menus/ActionMenuItemViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/Menus/ActionMenuViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/PageInfoViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/PagePathViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/Security/IfAuthenticatedViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/Security/IfHasRoleViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/TableListViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/Widget/Controller/PaginateController.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/Widget/PaginateViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/CObjectViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/CommentViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/CountViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/CycleViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/DebugViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/ElseViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/FlashMessagesViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/ForViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/AbstractFormFieldViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/AbstractFormViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/ButtonViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/CheckboxViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/ErrorsViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/HiddenViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/PasswordViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/RadioViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/SelectViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/SubmitViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/TextareaViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/TextfieldViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/UploadViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/ValidationResultsViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/FormViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/AbstractEncodingViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/CdataViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/CropViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/CurrencyViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/HtmlViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/HtmlentitiesDecodeViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/HtmlentitiesViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/HtmlspecialcharsViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/Nl2brViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/NumberViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/PaddingViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/PrintfViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/RawViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/StripTagsViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/UrlencodeViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/GroupedForViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/IfViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/ImageViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/LayoutViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Link/ActionViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Link/EmailViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Link/ExternalViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Link/PageViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/RenderChildrenViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/RenderViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/SectionViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Security/IfAuthenticatedViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Security/IfHasRoleViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/ThenViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/TranslateViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Uri/ActionViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Uri/EmailViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Uri/ExternalViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Uri/ImageViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Uri/PageViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Uri/ResourceViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/AutocompleteViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/Controller/AutocompleteController.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/Controller/PaginateController.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/LinkViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/PaginateViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/UriViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Configuration/TypoScript/setup.txt [new file with mode: 0644]
typo3/sysext/fluid/Migrations/Code/ClassAliasMap.php [new file with mode: 0644]
typo3/sysext/fluid/Resources/Private/Language/locallang.xlf [new file with mode: 0644]
typo3/sysext/fluid/Resources/Private/Templates/ViewHelpers/Be/Widget/Paginate/Index.html [new file with mode: 0644]
typo3/sysext/fluid/Resources/Private/Templates/ViewHelpers/Widget/Autocomplete/Index.html [new file with mode: 0644]
typo3/sysext/fluid/Resources/Private/Templates/ViewHelpers/Widget/Paginate/Index.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Compiler/AbstractCompilerTemplateTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Fixtures/TestViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Fixtures/TestViewHelper2.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/Fixtures/ChildNodeAccessFacetViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/Fixtures/PostParseFacetViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/Fixtures/TemplateParserTestFixture01-shorthand-split.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/Fixtures/TemplateParserTestFixture01-shorthand.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/Fixtures/TemplateParserTestFixture06-split.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/Fixtures/TemplateParserTestFixture06.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/Fixtures/TemplateParserTestFixture14-split.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/Fixtures/TemplateParserTestFixture14.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/Interceptor/EscapeTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/ParsingStateTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/SyntaxTree/AbstractNodeTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/SyntaxTree/BooleanNodeTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/SyntaxTree/NumericNodeTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/SyntaxTree/TextNodeTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/SyntaxTree/ViewHelperNodeTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/TemplateParserPatternTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/TemplateParserTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Rendering/RenderingContextTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/AbstractConditionViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/AbstractTagBasedViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/AbstractViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/ArgumentDefinitionTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/TagBuilderTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/TemplateVariableContainerTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/ViewHelperVariableContainerTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetControllerTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/AjaxWidgetContextHolderTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/WidgetContextTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/WidgetRequestBuilderTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/WidgetRequestHandlerTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/WidgetRequestTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/AbstractTemplateViewTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/Fixtures/LayoutFixture [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/Fixtures/LayoutFixture.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/Fixtures/LayoutFixture.xml [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/Fixtures/StandaloneViewFixture.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/Fixtures/TemplateViewFixture.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/Fixtures/TemplateViewSectionFixture.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/Fixtures/TransparentSyntaxTreeNode.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/Fixtures/UnparsedTemplateFixture.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/StandaloneViewTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/TemplateViewTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/AliasViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/BaseViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Be/IfAuthenticatedViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Be/IfHasRoleViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/CountViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/CycleViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/ElseViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Fixtures/ConstraintSyntaxTreeNode.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Fixtures/IfFixture.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Fixtures/IfThenElseFixture.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/FlashMessagesViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/ForViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/AbstractFormFieldViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/AbstractFormViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/ButtonViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/CheckboxViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/Fixtures/EmptySyntaxTreeNode.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/Fixtures/Fixture_UserDomainClass.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/FormFieldViewHelperBaseTestcase.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/HiddenViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/PasswordViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/RadioViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/SelectViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/SubmitViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/TextareaViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/TextfieldViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/UploadViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/FormViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/CropViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/CurrencyViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/DateViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/HtmlentitiesDecodeViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/HtmlentitiesViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/HtmlspecialcharsViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/Nl2brViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/NumberViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/PaddingViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/PrintfViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/RawViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/StripTagsViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/UrlencodeViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/GroupedForViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/IfViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Link/EmailViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Link/ExternalViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/RenderChildrenViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/RenderViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Security/IfAuthenticatedViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Security/IfHasRoleViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/ThenViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Uri/EmailViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Uri/ExternalViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/ViewHelperBaseTestcase.php [new file with mode: 0644]
typo3/sysext/fluid/ext_emconf.php [new file with mode: 0755]
typo3/sysext/fluid/ext_icon.gif [new file with mode: 0644]
typo3/sysext/fluid/ext_localconf.php [new file with mode: 0644]
typo3/sysext/fluid/ext_tables.php [new file with mode: 0644]
typo3/sysext/fluid/ext_typoscript_setup.txt [new file with mode: 0644]

index 0dddbd7..79f1e7c 100644 (file)
@@ -4,9 +4,6 @@
 [submodule "typo3/sysext/workspaces"]
        path = typo3/sysext/workspaces
        url = git://git.typo3.org/TYPO3v4/CoreProjects/workspaces/workspaces.git
-[submodule "typo3/sysext/fluid"]
-       path = typo3/sysext/fluid
-       url = git://git.typo3.org/TYPO3v4/CoreProjects/MVC/fluid.git
 [submodule "typo3/sysext/linkvalidator"]
        path = typo3/sysext/linkvalidator
        url = git://git.typo3.org/TYPO3v4/Extensions/linkvalidator.git
diff --git a/typo3/sysext/fluid b/typo3/sysext/fluid
deleted file mode 160000 (submodule)
index 518e1aa..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 518e1aa86b56d7032b983cfc1234baeae2c4df8b
diff --git a/typo3/sysext/fluid/ChangeLog.txt b/typo3/sysext/fluid/ChangeLog.txt
new file mode 100644 (file)
index 0000000..0554653
--- /dev/null
@@ -0,0 +1,548 @@
+ChangeLog for Fluid
+===================
+
+Changes for 6.1.0
+=================
+
+[!!!][FEATURE] Allow Fluid arrays only in ViewHelper arguments
+--------------------------------------------------------------
+
+This change greatly enhances the JavaScript compatibility of Fluid.
+
+Fluid Arrays are a subset of the JavaScript object syntax, making it
+hard to work with them in mixed HTML/JavaScript documents. For example
+before this change, the following JavaScript Object was parsed by Fluid::
+
+       var uris = {
+         endPoint1: '{f:uri.action(.)}',
+         endPoint2: '{f:uri.action(.)}',
+       };
+
+Before this change, the above snippet resulted in the following template,
+as the generated array was casted to a string:
+
+       var uris = Array
+
+With this change, Fluid only parses arrays which are used inside
+ViewHelper arguments, such that an array inside normal text is not
+converted anymore.
+
+Breaking Change
+===============
+
+This change is only breaking in very rare cases where one relied on
+the inner contents of the ViewHelper being an array, f.e. if one used
+the debug ViewHelper as follows::
+
+       <f:debug>{key1: 'value1', key2: 'value2'}</f:debug>
+
+. or if anybody wrote custom ViewHelpers which use this convention.
+
+Relying on that would be very fragile anyways, as the insertion of a
+single space character before the opening curly bracket or after the
+closing one would cast the array back to a string.
+
+ViewHelpers which were written like this should be re-written to take
+the array as ViewHelper argument::
+
+       <f:debug value="{key1: 'value1', key2: 'value2'}" />
+
+Full Changes for 6.1.0
+======================
+
+[BUGFIX] Fluid must not use legacy flash message handling
+[BUGFIX] Don't use folders as templates, partials and layouts
+[TASK] Use __DIR__ instead of dirname(__FILE__)
+[TASK] Add namespaing to ConfigurationManagerInterface
+[TASK] Remove further t3lib mentions
+[TASK] Update t3lib mentions
+[TASK] Adjust Comments to describe string comparison
+[CLEANUP] Drop incomplete tests
+[BUGFIX] Add needed setting to handle file_references correctly
+[BUGFIX] Add needed setting to handle file_references correctly
+[TASK] Remove not maintained md5 in ext_emconf
+[BUGFIX] Incomplete mock reset in StandaloneViewTest
+[BUGFIX] FormViewHelper creates inline styling
+[BUGFIX] PHP 5.4 E_STRICT warning in HtmlViewHelper
+[TASK] Cleanup fluid
+[FEATURE] Adjustable decimals for view helper format.currency
+[TASK] Update examples in ValidationResults ViewHelper
+[TASK] Sync TYPO3 CMS Fluid with Flow Fluid 1.1 (part3)
+[TASK] Sync CMS Fluid with Flow Fluid 1.1 (part2)
+[TASK] Add test for GroupedForViewHelper to support DateTime Objects
+[TASK] Replace ObjectManager create with get
+[BUGFIX] Apply arguments to the default string
+[TASK] Clean up Unit tests in fluid
+[FEATURE] Complete the Property Mapper whitelist change for fluid
+[BUGFIX] Follow-up typo to #45316
+[TASK] Sync CMS Fluid with Flow Fluid 1.1 (part1)
+[FEATURE] Support literal strings in boolean arguments
+[TASK] Add dataproviders for 2 tests in DateViewHelperTest
+[BUGFIX] Skip a SelectViewHelperTest on Mac
+[BUGFIX] Unit test fails with broken timezone
+[BUGFIX] Wrong numbers in BE paginage widget
+[BUGFIX] Remove superfluous newline
+[BUGFIX] Date ViewHelper not using configured Timezones
+[BUGFIX] Fix typo and improve backup of system settings
+[FEATURE] Introduce prepend option for Select ViewHelper
+[BUGFIX] Remove PHP Error caused by setlocale call
+[BUGFIX] Incomplete locale backup in unit test
+[BUGFIX] selectViewHelper sorting should respect locales
+Revert "[TASK] Adjust failing test"
+[TASK] Adjust failing test
+[BUGFIX] Image viewhelper clears $GLOBALS['TSFE'] in backend context
+[TASK] Update version to 6.1.0-dev
+
+Changes for 1.4.0:
+==================
+included in TYPO3 4.6.0
+
+This change features numerous cleanups, and the following new features:
+
+Compilation of Fluid Templates to PHP files
+-------------------------------------------
+
+This adds a compile step to the parsing process of templates, layouts and
+partials.
+If no compiled cache file exists, Fluid will create it while parsing the
+respective Fluid template.
+The cache file is invalidated as soon as the template/layout/partial
+has been modified (or if caches are flushed).
+This speeds up the rendering process by factor 2-5, and reduces memory
+consumption drastically.
+
+!!! $this->arguments->hasArgument() removed
+-------------------------------------------
+
+AbstractViewHelper::$arguments are no longer an object but an array.
+
+If you used $this->arguments->hasArgument() in your custom ViewHelpers,
+you'll have to replace this with $this->hasArgument().
+
+THIS IS A BREAKING CHANGE.
+
+!!! Introduction of {_all} Variable
+-----------------------------------
+
+You can now use {_all} inside your template to access all variables available
+right now. This is especially helpful for debugging:
+
+    {_all -> f:debug()}
+
+or for passing all currently available variables to a partial:
+
+    <f:render partial="..." arguments="{_all}" />
+
+This is only a breaking change if you used a variable _all inside your own
+templates.
+
+Widgets: Allow overriding templateRootPath
+------------------------------------------
+It is now possible to override the widget template root path via the framework
+configuration, for example:
+
+    plugin.tx_extension.view {
+      widget.<WidgetViewHelperClassName>.templateRootPath=...
+    }
+
+Full Changes from 1.4.0 beta1 to 1.4.0:
+=======================================
+[TASK] Update version to 1.4.0-rc1
+[TASK] Increase version number
+[BUGFIX] Create new CObject in CObject ViewHelper
+[BUGFIX] Fix Doc comment in format.padding ViewHelper
+[BUGFIX] ViewHelper: Make SelectViewHelper use property paths as arguments
+[FEATURE] Add parameter to RenderViewHelper for optional sections
+[BUGFIX] Sanitize identifier when compiling templates
+[BUGFIX] use $for only when not empty and not NULL
+[+BUGFIX] disable cache when displaying FlashMessages in frontend
+[+FEATURE] Comment ViewHelper
+[TASK] Remove fluid autoloader
+[+TASK] Marking Fluid as "stable" instead of "beta"
+[+BUGFIX] Incorrect type of Error thrown (FLOW3 Error)
+[BUGFIX] Make textfield view helper handle zero (not empty) values
+
+Full Changes for 1.4.0 beta1:
+=============================
+
+[!!!][FEATURE] Compilation of Fluid templates to PHP files. Resolves: #28545
+[TASK] Minor cleanups
+[TASK] Tweak inline comment in TemplateView
+[!!!][+FEATURE] Add a reserved variable {_all} returning all template variables
+[BUGFIX] Deactivate EscapeInterceptor for certain ViewHelpers. Related: #27678
+[TASK] Split escape ViewHelper into dedicated format ViewHelpers. Related: #27628
+[BUGFIX] Whitespace fixes
+[FEATURE] IconViewHelper (BE) should support CSS-sprites. Resolves: #9957
+[TASK] Code Cleanup in TemplateView
+[+BUGFIX] Use of depreciated function debug in debugViewHelper. Fixes: #27970
+[BUGFIX] Fix Widget support. Resolves: #27783
+[TASK] Recreate ext_autoload.php. Related: #27680
+[+FEATURE] (ViewHelpers): Adjust Fluid to new Property Mapper. Related: #27656
+[+TASK] Fluid: Make use of newly introduced Extension Service. Related: #13864
+[+BUGFIX] Fix unit tests
+[TASK] Fluid: Use strpos() instead of strstr() where possible
+[TASK] Make TextboxViewHelper a subclass of TextFieldViewHelper
+[TASK] (ViewHelper): Code Cleanup to AbstractFormField ViewHelper
+[TASK] (Core): Code Cleanup in AbstractTagBasedViewHelper
+[+BUGFIX] (Core): Condition improvements. Resolves: #27557
+[TASK] Cleanup and small improvements to Interceptors
+[TASK] Comment and non-functional changes
+[+BUGFIX] Empty a tag ends with /> instead of </a>. Resolves: #27556
+[BUGFIX] Better error message for "unknown section" exception
+[+BUGFIX] Fluid (Core): Simplify debugging of exceptions thrown during render
+[+BUGFIX] Fluid: Fix CObjViewHelper. Fixes: #26138
+[+FEATURE] Widgets: Allow overriding templateRootPath. Thanks to Peter B├╝cker. Resolves: #10823
+[FEATURE] PaddingViewHelper: allow padding-type right/left/both. Resolves: #9283
+[BUGFIX] Fix documentation for BE-ViewHelpers. Resolves: #9942
+[~TASK] Update jQuery versions
+[+BUGFIX] CObjViewHelper: fixed using numeric values as data argument. Fixes: #12891
+[+BUGFIX] ActionMenuItemViewHelper: XHTML compliance in "selected" attribute value. Fixes: #8744
+[+BUGFIX] Fluid: CObjViewHelper fix deprecated call "getAccessibleProperties". Fixes: #26138
+[!!!][+TASK] Fluid v4 (Core): Make layout UpperCamelCase (with fallback)
+[~TASK] Fluid: Raising version from 1.3.0 to 1.4.0-devel
+[+FEATURE] Fluid (ViewHelpers): Add RawViewHelper
+[+FEATURE] Fluid v4 (Core): Set layoutName by variable
+
+
+
+Changes for 1.3.0:
+==================
+included in TYPO3 4.5.0 LTS.
+
+Here, only smaller bugs and inconsistencies have been fixed. For a description of bigger features, see below to the versions where they were introduced.
+
+Full Changes for 1.3.0:
+=======================
+
+[+TASK] Fluid (ViewHelpers): fixed typo in doc comment examples of emailViewhelper
+[+BUGFIX] Fluid (Tests): Fixed CropViewHelper unit test
+[+BUGFIX] Fixed comparison of Objects
+       Objects in comparison expressions were compared lazily
+       with == before this change. Now, they are compared with
+       ===, which is the expected behavior on objects.
+[+TASK] Fluid (ViewHelpers): Extended inline documentation of FlashMessages ViewHelper
+[+BUGFIX] Fluid (Tests): Fixed Fluid unit tests!
+
+Changes for 1.3.0 RC1:
+======================
+included in TYPO3 4.5.0 RC1.
+
+This change contains numerous bugfixes, most notably fixes the Widget
+Bootstrap and the Standalone View (which is used in "FLUIDTEMPLATE").
+
+Full Changes for 1.3.0 RC1:
+===========================
+
+[+BUGFIX] Fluid (View): Fix StandaloneView
+       Since implementation of Dependency Injection the Fluid
+       Standalone view was broken in some cases, cause it did not
+       properly initialize all needed objects.
+       Fixes: #11520
+[+BUGFIX] Fluid (Core): Allow ViewHelpers to be placed in t3lib and tslib
+       The Fluid template parser does now recognize ViewHelpers inside t3lib/
+       or sysext/cms/tslib/, so Fluid can now be used inside the TYPO3 core.
+       Thanks to Andreas Wolf for the patch!
+       Resolves: #12061
+[+BUGFIX] Fluid (Widget): Adopt Widget Bootstrap to Extbase Bootstrap changes
+       Problem: The configureObjectManager method in Tx_Fluid_Core_Widget_Bootstrap
+       uses a call on a static method Tx_Extbase_Object_Container_Container::getContainer()
+       which doesn't exist anymore. The Container has become a t3lib_Singleton.
+       This patch changes the behavior, and makes it work again.
+       Thanks to Thomas Maroschik for the patch!
+       Resolves: #11991
+
+Changes for 1.3.0 Beta 4:
+=========================
+included in TYPO3 4.5.0 Beta 4.
+
+This change contains numerous bugfixes.
+
+Full Changes for 1.3.0 Beta 4:
+==============================
+
+[~TASK] Fluid (Tests): Fixed some testcase class names
+[+FEATURE] Fluid (ViewHelpers): prepend URIs with scheme if it's not specified in link.external / uri.external ViewHelpers. Resolves #10401
+[+TASK] Fluid (ViewHelpers): Fix, cleanup and extend inline documentation of ViewHelpers
+[+BUGFIX] Fluid (View): Fixed deprecation message about lowercase template files names
+
+Changes for 1.3.0 Beta 2:
+=========================
+included in TYPO3 4.5.0 Beta 2.
+
+The main change is the updating of the FlashMessage ViewHelper and concept:
+
+Since r3062 Extbase uses the t3lib_FlashMessageQueue to store flashmessages.
+Now you can output them including title and severity, making it possible
+to render flashmessages just like the ones from the core in BE mode.
+To keep backwards compatibility, the default rendering still outputs
+only the message bodies in an unordered list. Set the renderMode argument
+to "div" in order to display the new style:
+<f:flashMessages renderMode="div" />
+
+**********************************************************************************************
+*Extbase / Fluid 1.3.0 can now ONLY BE USED WITH TYPO3 4.5, as the older versions do not have*
+*the FlashMessageQueue available!                                                            *
+**********************************************************************************************
+
+Full Changes for 1.3.0 Beta 2:
+==============================
+[+BUGFIX] Fluid (ViewHelpers/Widget): widget.link and widget.uri no create relative URLs
+[+FEATURE] Fluid (ViewHelpers): Add render mode to FlashMessage ViewHelper
+[-TASK] Fluid: Removed all @scope annotations as they are not used in v4
+[+TASK] Fluid (View): Added additional check for deprecated lower case template filenames that works on case insensitive file systems (Windows) too. Watch your deprecation log in typo3conf and fix your template filenames if they're still lower case.
+[+BUGFIX]: explicitly cast offset to integer to avoid exceptions in paginate view helper
+
+
+Changes for 1.3.0 Beta 1a:
+==========================
+included in TYPO3 4.5.0 Beta 1.
+
+This Fluid Release contains the following main features, along with the usual bunch of bugfixes:
+
+* Fluid Widgets (see below)
+* Fluid Standalone View (in Fluid 1.3.0 Alpha 3, but has not been inside a TYPO3 Release yet)
+       In order to be able to use Fluid templates beyond the Extbase plugin context
+       (e.g. to render E-Mail templates or to use the new FLUIDTEMPLATE content object)
+       we created a new template view, that encapsulates inner workings and provides
+       an easy-to-use API:
+
+       $view = t3lib_div::makeInstance('Tx_Fluid_View_StandaloneView');
+       $view->setTemplatePathAndFilename('foo/Bar.html');
+       print $view->render();
+
+Fluid Widgets
+-------------
+
+Widgets are special ViewHelpers which encapsulate complex functionality. It can be best understood
+what widgets are by giving some examples:
+* <f:widget.paginate> renders a Paginator, i.e. can be used to display large amounts of objects. This
+  is best known from search engines.
+* <f:widget.autocomplete> adds autocompletion functionality to a text field.
+* More widgets could include a Google Maps widget, a sortable grid, ...
+
+Internally, widgets consist of an own Controller and View part.
+
+Using widgets inside your templates is really simple: Just use them like standard ViewHelpers,
+and consult their documentation for usage examples. An example for the <f:widget.paginate> follows below:
+
+<f:widget.paginate itemsPerPage="10" objects="{blogs}" as="paginatedBlogs">
+       // use {paginatedBlogs} as you used {blogs} before, most certainly inside
+       // a <f:for> loop.
+</f:widget.paginate>
+
+In the above example, it looks like {blogs} contains all Blog objects, thus you might wonder if all
+objects were fetched from the database. However, the blogs are NOT fetched from the database until
+you actually use them, so the paginate ViewHelper will adjust the query sent to the database and
+receive only the small subset of objects. So, there is no negative performance overhead in using
+the Paginate Widget.
+
+For more details on how to write widgets, consult the Fluid manual, section "Fluid Widgets".
+
+Full Changes for 1.3.0 Beta 1a:
+===============================
+[+FEATURE] Fluid (ViewHelpers): the subject argument of the count ViewHelper is now optional so you can use it like {objects -> f:count()}
+[+BUGFIX] Fluid (ViewHelpers): Fixed inline documentation of widget.autocomplete ViewHelper. This fixes #10882
+[+TASK] Fluid (ViewHelpers): Added some more inline documentation for cObject, widget.paginate, widget.autocomplete & count ViewHelpers
+[+BUGFIX] Fluid (ViewHelpers): replaced two occurrences of Tx_Extbase_Dispatcher::*() by using the injected ConfigurationManager
+[+TASK] Fluid (ViewHelpers): uri.image now works in BE mode too
+[+BUGFIX] Fluid (ViewHelpers): Adjustment to skinning api change
+[+FEATURE] Fluid (ViewHelpers/Widget): Slightly improved paginate widget: The link to the first page now skips the currentPage argument resulting in nicer URLs and less cHashes
+[+FEATURE] Fluid (ViewHelpers): excluding obsolete widget arguments & cHash from widget links if they're not explicitly set
+[+BUGFIX] Fluid (Core/Widget): AjaxWidgetContextHolder now uses a unique id for the Ajax WidgetContext. This makes sure, that the ajax response gets the right context, even if you open multiple browser windows in the same session
+[+BUGFIX] Fluid (Core): The Fluid Widget Bootstrap now initializes the object manager in order to respect "config.tx_extbase.object" configuration.. TODO: this should be somehow refactored to avoid code duplication
+[+BUGFIX] Fluid: Reduced the typeNum for the fluidAjaxWidgetResponse page. Apparently 7076857368 was too large ;) TODO: the typeNum should be somehow configurable
+[~TASK] Fluid (ViewHelpers/Widget): removed $GLOBALS['TSFE']->additionalHeaderData call from AutocompleteViewHelper as this is not configurable like this. Moved the jQuery includes to Configuration/TypoScript/setup.txt which can be included in your main TS template
+[+BUGFIX] Fluid (ViewHelpers): Fixed Widget URI generation in widget.link/widget.uri ViewHelpers/Link/WidgetViewHelpers
+[~TASK] Fluid (ViewHelpers/Widget): Tweaked PaginateViewHelper: Minor refactoring of controller & template
+[-TASK] Fluid (Compatibility): Forgot to remove obsolete Tx_Fluid_Compatibility_ObjectManager in previous commit
+[+FEATURE] Fluid (Core/Widget): Added Tx_Fluid_Core_Widget_Bootstrap that is used to dispatch Ajax requests (see ext_typoscript_setup.txt).
+[~TASK] Fluid (Compatibility): Removed Tx_Fluid_Compatibility_ObjectManager and replaced instances by Tx_Extbase_Object_ObjectManagerInterface instances
+[~TASK] Fluid (Core/Widget): AbstractWidgetController has to be a singleton so it can be injected in the WidgetViewHelper.. To be discussed!
+[+TASK] Fluid (Core/Widget): AjaxWidgetContextHolder is now correctly stored in the BE/FE Users session if the ajaxWidget of the corresponding Widget is TRUE.
+[+TASK] Fluid (Core/Widget): The WidgetContext now contains a reference to the parent extension & plugin name. That's needed for the widgetAjaxResponse.
+[+BUGFIX] Fluid (Core/Widget): WidgetRequestBuilder now correctly interprets GET parameters and dispatches Ajax requests
+[+BUGFIX] Fluid (ViewHelpers): Modified ViewHelpers cObject, format.crop, format.html, image, uri.image so that they use dependency injection in order to retrieve the current cObject instance from the configurationManager
+[+BUGFIX] Fluid (ViewHelpers): Fixed form ViewHelper to respect configured pluginNamespace in field name prefixes
+[+BUGFIX] Fluid (ViewHelpers): link.widget/uri.widget ViewHelpers now create correct URIs
+[+BUGFIX] Fluid (ViewHelpers): replaced @inject annotation by injectController method in AutocompleteViewHelper.
+[+FEATURE] First step of "Fluid widget" backport
+       This is the first step of the Widget backport (#8773). This contains all the core classes that are required for the widget implementation and two exemplary Widget ViewHelpers "widget.paginate" and "widget.autocomplete".
+       Note: Ajax widgets are not yet working!!
+       Relates to: #8773
+       Relates to: #10568
+[!!!][+BUGFIX] Fluid (View): Adjust fluid to recent resolveView() backport
+       Tx_Fluid_View_AbstractTemplateView now implements the Tx_Extbase_MVC_View_ViewInterface that was changed in r2675.
+       NOTE: This is a breaking change because the API method Tx_Fluid_View_TemplateView::hasTemplate was renamed to canRender(). Besides I deleted the TemplateViewInterface that is no longer needed. Implement Tx_Extbase_MVC_View_ViewInterface or simply extend Tx_Fluid_View_AbstractTemplateView if you want to write your own view implementation
+       Relates to: #8990
+[+BUGFIX] Fluid: Adjust Fluid to Dependency Injection changes. Relates to: #9062
+
+Changes for 1.3.0 Alpha 3:
+==========================
+[+BUGFIX] Fluid (ViewHelpers): ImageViewHelper supports additionalAttributes argument
+       The image view helper did not call the parent constructor, which registeres the "additionalAttributes" argument. Thanks to Michael Knoll.
+[+FEATURE] Fluid (View): Fluid Standalone view (#10473)
+[+TASK] Fluid (ViewHelpers): Minor tweak in CObject ViewHelper
+       Make sure, that the configurationManager is initialized.
+       This is just a preliminary solution that will be replaced as soon
+       as the Extbase dispatcher refactoring (#7153) is done.
+
+Changes for 1.3.0 Alpha 2:
+==========================
+included in TYPO3 4.5.0 Alpha 2.
+
+In this release, mostly small bugfixes have been made in Fluid. Highlights are:
+
+ * {settings} is now automatically in partials. (#6289)
+
+ * You can now use <f:security.ifAuthenticated> and <f:security.ifHasRole role="foo"> (#9143)
+   in your Fluid templates to check whether an FE user is currently logged in / belongs to the
+   specified usergroup.
+   Note: if "role" is a numeric value the uid of the usergroup is compared, otherwise the title
+   of the usergroup.
+   To deal with BE users you can use the respective be.security.* view helpers
+
+ * Boolean expressions can now contain negative numbers. Resolves #9434.
+
+Full Changes:
+-------------
+
+[+FEATURE] Fluid (Core): {settings} is available in Partials
+Now, the {settings} are automatically available in partials and sections.
+Before, they had to be passed explicitely, i.e. by calling
+<f:render section="..." arguments="{settings: settings}" />.
+If somebody defined his own "settings"-argument, this still takes precedence:
+<f:render section="..." arguments="{settings: some.different.settings}" />
+This means that this change is completely backwards compatible.
+NOTE: The settings are NOT merged together, like it has been suggested in #6289,
+as this will lead to un-obvious behavior for the user.
+
+[-API] Fluid (Core): Remove getTemplateParser() method.
+This method has accidentally gotten an @api annotation,
+and was only needed for the Viewhelpertest package.
+Now, this package is cleaned up, and this method can be
+completely thrown away.
+
+[+BUGFIX] Fluid (ViewHelpers): Fix bug in Form ViewHelper
+Since #6521 you can use the "objectName" argument to specify the name of a bound object rather then using the "name" attribute.
+But if you do so, the rendered hidden identity field is not correct anymore. This behavior is fixed with this commit.
+Resolves: #9515
+
+* Documentation Cleanup
+
+[+FEATURE] Fluid (ViewHelpers): Backported ifAuthenticated & ifHasRole security ViewHelpers
+you can now use <f:security.ifAuthenticated> and <f:security.ifHasRole role="foo">
+in your Fluid templates to check whether an FE user is currently logged in / belongs to the
+specified usergroup.
+Note: if role is a numeric value the uid of the usergroup is compared, otherwise the title
+of the usergroup.
+to deal with BE users you can use the respective be.security.* view helpers
+Resolves #9143
+
+[TASK] Fluid (Core): Regular Expression performance improvements
+In rare cases, on some systems (like mine), the
+PCRE parser reproducably crashes if one passes very
+long argument strings into it, or very complex ones.
+With this patch, the parser is slightly modified
+to decrease the use of backtracking; which then avoids
+the crashes mostly.
+
+[TASK] Fluid (Core): Formatted Regular Expressions more nicely
+There were some undocumented regular expressions
+in the parser, which needed to be formatted nicely.
+
+[+BUGFIX] Fluid (Core): Boolean expressions can now contain negative numbers. Resolves #9434.
+Boolean expressions with negative numbers did not work so far.
+Now, they work as expected. Example from Viewhelpertest which displayed
+a wrong result before, and now displays the correct result:
+<f:if condition="{testVariables.number.minusOne} < -1.1">
+       <f:then>Then part!</f:then>
+       <f:else>Else part!</f:else>
+</f:if>
+Issue: #9434
+
+
+
+Changes for 1.3.0 Alpha 1
+=========================
+included in TYPO3 4.5.0 Alpha 1.
+
+In this release, numerous bugs have been fixed, making Fluid more stable than ever. Below are some nice features which have been introduced:
+
+* Instead of <f:form name="...">, you should now write write <f:form objectName="...">, to create an XHTML compliant form (#6521)
+
+* The <f:for>-ViewHelper has now Iteration Information available, if you want that:
+  <f:for each="{objects}" as="object" iteration="iteration">
+     {iteration.index} is a counter which starts at 0
+     {iteration.cycle} is a counter which starts at 1
+     {iteration.isEven} / {iteration.isOdd} is a boolean variable which is true if the index is even/odd
+     {iteration.isFirst} / {iteration.isLast} is a boolean variable which is true if it is the first or last element in the list.
+  </f:for>
+
+!!! Refactored all Condition-ViewHelpers like f:if, f:security.if* to use a newly created base class F3\Fluid\Core\ViewHelper\ConditionViewHelper. This greatly simplifies the implementation of custom conditions.
+  THIS IS A BREAKING CHANGE in case you copied the f:if ViewHelper to create a custom condition ViewHelper, as the internal workings changed. Please check the new f:if ViewHelper to see how to adjust your ViewHelper -- you basically just have to throw away a lot of code. Resolves #8824.
+
+* Fixed section, partial and layout rendering to function in all cases as expected now, and tested this behavior also.
+  !!! Removed renderSection() and renderWithLayout() from public API in Tx_Fluid_View_TemplateView, as this should only be called from inside Fluid.
+
+* Fixing checkbox, radio and select-ViewHelpers, but this task is not finished yet.
+  !!! The value argument is required again in form.checkbox and form.radio ViewHelpers. This is a breaking change, as the value argument has not been mandatory for a while. But it probably won't break existing templates as omitting the value makes no sense at all.
+
+* Fixed BE support of ViewHelpers (cObject, format.crop, uri.resource, format.html, image)
+
+* Negative numeric values are now properly converted to FALSE when used in boolean ViewHelper arguments.
+
+* added f:uri.image ViewHelper, working just like f:image, but returning the URL and not the full image tag.
+
+Full Changes:
+-------------
+[~TASK] Fluid: Changed version of Extbase dependency from '1.2.0-1.2.999' to '1.3.0.devel' to reflect the version scheme defined in the wiki. Relates to #9152.
+[+BUGFIX] Fluid (View): AbstractTemplateView now correctly implements F3\FLOW3\MVC\View\ViewInterface and assign() and assignMultiple() will return an instance of $this to allow chaining again like $this->view->assign()->assign()... This fixes #9090 (backported from Fluid package r4931)
+[~TASK] Fluid (Tests): committing modified AbstractFormFieldViewHelperTest that I forgot to add in previous commit
+[+TASK] Fluid (ViewHelpers): Small performance improvement in ForViewHelper: Objects will only be converted to arrays if reverse is TRUE. Relates to #8732 (backported from Fluid package r4907)
+[+TASK] Fluid (View): Added getter for template parser to AbstractTemplateView. This is useful if you want to use the parser from within your custom ViewHelper (creating a new instance would skip interceptor registration) (backported from Fluid package r4907)
+[~TASK] Fluid (ViewHelpers): Added argument "objectName" to form ViewHelper. This is now the recommended way to specify the name of the object that is bound to a form! If objectName is not specified, the name attribute will be used as object name for backwards-compatibility reasons. This resolves #6521 (backported from Fluid package r4905)
+* Raised Fluid version in trunk to 1.3.0-devel
+[+BUGFIX] Fluid (ViewHelpers): Fixed a possible security issue where the content inside the Fluid a is not properly HTML escaped.
+[+FEATURE] Fluid (ViewHelpers): Added iteration information to for ViewHelper. Thanks to all the contributors for your input and patches! This resolves #6149 (backported from Fluid package r4904)
+[~TASK] Fluid (ViewHelpers): Fresh backport from Fluid package r4899 (Mostly fixed typos. slightly improved count ViewHelper)
+[~TASK] Fluid (ViewHelpers): Replaced custom convertToArray() method by PHPs iterator_to_array() function in cycle, for and groupedFor ViewHelpers. This resolves #8732. (backport from Fluid package r4898)
+[+BUGFIX] Fluid (ViewHelpers): Now, it is possible to "unselect" checkboxes and multiselect fields in editing forms. This fixes #5638. This fixes #8535. This fixes #6897 (improved forward-backport from Fluid package r4874)
+[+TASK] Fluid (Tests): Backported FormViewHelperTest from Fluid package
+[+BUGFIX] Fluid (ViewHelpers): FormViewHelper wraps hidden fields with a div tag to create XHTML valid output. This fixes #5512 (backported from Fluid package)
+[~TASK] Fluid (ViewHelpers): Fixed BE support of the ViewHelpers cObject, format.crop, uri.resource. Relates to #8947
+[~TASK] Fluid (ViewHelpers): Added BE support in the ViewHelpers format.html and image. Relates to #8947
+[!!!][+TASK] Fluid (ViewHelpers): The value argument is required again in form.checkbox and form.radio ViewHelpers. This is a breaking change, as the value argument has not been mandatory for a while. But it probably won't break existing templates as omitting the value makes no sense at all. Relates to #8852 (backported from Fluid package r4864)
+[+FEATURE] Fluid (Core): implemented overrideArgument() method in AbstractViewHelper to be able to override previously registered arguments in subclasses. This resolves #8852 (backported from Fluid package r4864)
+[+BUGFIX] Fluid (Core): Negative numeric values are properly converted to FALSE when used in boolean ViewHelper arguments. This resolves #8893 (backported from Fluid package r4864)
+[+BUGFIX] Fluid (ViewHelpers): Reversed the rendering order of header and childNodes in be.container ViewHelper to enable child nodes to modify the pageRenderer. This resolves #8880 (thanks to Andreas Wolf)
+[+BUGFIX] Fluid: Removed leading slash from @var annotations that were backported by mistake
+[+BUGFIX] Fluid: Replaced SplObjectStorage by Tx_Extbase_Persistence_ObjectStorage to be PHP 5.2-compatible (which ships with a broken implementation of SplObjectStorage)
+[!!!][~TASK] Fluid (Core): Renamed ConditionViewHelper and TagBasedViewHelper to Abstract*ViewHelper as per CGL. (backported from Fluid package r4840). To be backwards-compatible, TagBasedViewHelper.php still exists and will write an entry to TYPO3s deprecation log if used. Please adapt your custom ViewHelpers and inherit from AbstractTagBasedViewHelper instead of TagBasedViewHelper. This resolves #8834
+[~TASK] Fluid: Marked vfs unit tests to be skipped, as vfs is not part of v4 (yet)
+[-TASK] Fluid: Removed @package/@subpackage annotations from all Fluid classes. They have already been removed in FLOW3 packages in r2813.
+[-TASK] Fluid: Removed @version annotation from all Fluid classes to ease the backporting process. Relates to #8835 (backported from Fluid package)
+[+BUGFIX] Fluid (View): fixed method signature of AbstractTemplateView:getTemplateSource() that was different from the concrete implementation (backported from Fluid package)
+Fluid in v5 and v4 are now synchronized again!
+[+FEATURE] Fluid: The TemplateVariableContainer now provides a method to retrieve all variables.
+[~TASK] Fluid (Core): Introduced a RenderingContextInterface to more cleanly decouple Fluid's rendering context from the TypoScript rendering context. Note that view helpers (and other code) should now refer to that interface instead of the concrete Fluid implementation!
+[!!!][+BUGFIX] Fluid (Core): Refactored all Condition-ViewHelpers like f:if, f:security.if* to use a newly created base class F3\Fluid\Core\ViewHelper\ConditionViewHelper. This greatly simplifies the implementation of custom conditions. However, THIS IS A BREAKING CHANGE in case you copied the f:if ViewHelper to create a custom condition ViewHelper, as the internal workings changed. Please check the new f:if ViewHelper to see how to adjust your ViewHelper -- you basically just have to throw away a lot of code. Resolves #8824.
+[!!!][-API] Fluid (TemplateView): Removed renderSection() and renderWithLayout() from public API in Tx_Fluid_View_TemplateView, as this should only be called from inside Fluid.
+[!!!][TASK] Fluid (ViewHelpers): the <f:section />-ViewHelper now does NOT render itself anymore when encountered in a normal template. Example: Before the change, the template "before <f:section name='...'> middle </f:section> after" was rendered as "before middle after", but now it is only rendered as "before after". Although this is a breaking change, it is quite unlikely that anybody relied on this behavior, as it was inconsistent beforehand.
+[TASK] Fluid (TemplateView): Major refactoring of the layout, partial and section rendering mechanism. This also induces a speedup as retundant rendering is eliminated.
+[+FEATURE] Fluid (ViewHelpers): The <f:render>-ViewHelper can be now used to render sections in the same partial and template. In these cases, all arguments need to be specified explicitely. Additionally, it can now be used to render a section recursively.
+[~TASK] Fluid (Core): Removed some non-API-methods which were never called.
+[+FEATURE] Fluid (ViewHelpers): format.crop ViewHelper now supports all features in Backend mode. Relates to #8648
+[+TASK] Fluid: Set dependency to Extbase 1.2.x in ext_emconf.php to avoid confusions when working with different versions
+[+TASK] Fluid: Backported recent changes from Fluid package:
+[+FEATURE] Fluid (ViewHelpers): added "selectAllByDefault" argument to form.select ViewHelper. Resolves #4984
+~TASK] Fluid (Parser): Got rid of the constructor in Parser\Configuration.
+[+FEATURE] Fluid (ViewHelpers): Added uri.image ViewHelper. This resolves #8233
+[+FEATURE] Fluid (ViewHelpers): Added URI options noCache, noCacheHash, section, format, additionalParams, absolute, addQueryString & argumentsToBeExcludedFromQueryString to FormViewHelper. Resolves #8247 [+BUGFIX] Fluid: Removed a leading backslash in ViewHelperBaseTestcase that led to an error with PHP < 5.3
+[+TASK] Fluid: Backported some recent Fluid changes (Note: this is not a complete backport, there are still changes in Fluid Package that are not backported yet):
+[+BUGFIX] Fluid (ViewHelpers): form.select ViewHelper did only check whether "multiple" attribute was set and not whether it was empty or not. Resolves #5879
+[+FEATURE] Fluid (ViewHelpers): GroupedForViewHelper can now group by object. Resolves #7389
+
+
+HOW TO CREATE THE CHANGELOG
+===========================
+git log [startRevision]..HEAD --pretty=format:"%s%n%b%n" | grep -v "^$" | grep -v "git-svn-id"
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Compatibility/DocbookGeneratorService.php b/typo3/sysext/fluid/Classes/Compatibility/DocbookGeneratorService.php
new file mode 100644 (file)
index 0000000..f6ff4a5
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+namespace TYPO3\CMS\Fluid\Compatibility;
+
+/*                                                                        *
+ * This script is part of the TYPO3 project - inspiring people to share!  *
+ *                                                                        *
+ * TYPO3 is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU General Public License version 2 as published by  *
+ * the Free Software Foundation.                                          *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General      *
+ * Public License for more details.                                       *
+ *                                                                        */
+
+/**
+ * Class extending the docbook generator service for use in typo3 v4.
+ *
+ * Usage in TypoScript:
+ *
+ * config.disableAllHeaderCode = 1
+ * page = PAGE
+ * page.10 = USER_INT
+ * page.10.userFunc = \TYPO3\CMS\Fluid\Compatibility\DocbookGeneratorService->userFunc
+ *
+ * @internal
+ */
+class DocbookGeneratorService extends \TYPO3\CMS\Fluid\Service\DocbookGenerator {
+
+       /**
+        *
+        * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
+        * User function
+        *
+        * @return string
+        */
+       public function userFunc() {
+               $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');
+       }
+
+       /**
+        * Get class names within namespace
+        *
+        * @param string $namespace
+        * @return array
+        */
+       protected function getClassNamesInNamespace($namespace) {
+               $namespaceParts = explode('\\', $namespace);
+               if ($namespaceParts[count($namespaceParts) - 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);
+               return $classNames;
+       }
+
+       /**
+        * Search recursivly class names within namespace
+        *
+        * @param string $namespace
+        * @param string $directory
+        * @param array $classNames
+        * @return void
+        */
+       private function recursiveClassNameSearch($namespace, $directory, &$classNames) {
+
+               $dh = opendir($directory);
+               $counter = 0;
+               while (($file = readdir($dh)) !== FALSE) {
+                       if ($file == '.' || $file == '..' || $file == '.svn') {
+                               continue;
+                       }
+                       if (is_file($directory . $file)) {
+                               if (substr($file, 0, 8) == 'Abstract') {
+                                       continue;
+                               }
+                               $classNames[] = $namespace . substr($file, 0, -4);
+                       } elseif (is_dir($directory . $file)) {
+                               $this->recursiveClassNameSearch($namespace . $file . '\\', $directory . $file . '/', $classNames);
+                       }
+               }
+               closedir($dh);
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Compatibility/TemplateParserBuilder.php b/typo3/sysext/fluid/Classes/Compatibility/TemplateParserBuilder.php
new file mode 100644 (file)
index 0000000..8bfba77
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+namespace TYPO3\CMS\Fluid\Compatibility;
+
+/*                                                                        *
+ * This script is part of the TYPO3 project - inspiring people to share!  *
+ *                                                                        *
+ * TYPO3 is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU General Public License version 2 as published by  *
+ * the Free Software Foundation.                                          *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General      *
+ * Public License for more details.                                       *
+ *                                                                        */
+/**
+ * Build a template parser.
+ * Use this class to get a fresh instance of a correctly initialized Fluid template parser.
+ */
+class TemplateParserBuilder {
+
+       /**
+        * Creates a new TemplateParser which is correctly initialized. This is the correct
+        * way to get a Fluid parser instance.
+        *
+        * @return \TYPO3\CMS\Fluid\Core\Parser\TemplateParser A correctly initialized Template Parser
+        */
+       static public function build() {
+               $templateParser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Fluid\\Core\\Parser\\TemplateParser');
+               $templateParser->injectObjectManager(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'));
+               return $templateParser;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Compiler/AbstractCompiledTemplate.php b/typo3/sysext/fluid/Classes/Core/Compiler/AbstractCompiledTemplate.php
new file mode 100644 (file)
index 0000000..37c37a5
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Compiler;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+/**
+ * Abstract Fluid Compiled template.
+ *
+ * INTERNAL!!
+ */
+abstract class AbstractCompiledTemplate implements \TYPO3\CMS\Fluid\Core\Parser\ParsedTemplateInterface {
+
+       /**
+        * @var array
+        */
+       protected $viewHelpersByPositionAndContext = array();
+
+       // These tokens are replaced by the Backporter for implementing different behavior in TYPO3 v4
+       /**
+        * @var \TYPO3\CMS\Extbase\Object\Container\Container
+        */
+       static protected $objectContainer;
+
+       /**
+        * @var string
+        */
+       static protected $defaultEncoding = NULL;
+
+       /**
+        * Public such that it is callable from within closures
+        *
+        * @param integer $uniqueCounter
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @param string $viewHelperName
+        * @return \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
+        * @internal
+        */
+       public function getViewHelper($uniqueCounter, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext, $viewHelperName) {
+               if (self::$objectContainer === NULL) {
+                       self::$objectContainer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\Container\\Container');
+               }
+               if (isset($this->viewHelpersByPositionAndContext[$uniqueCounter])) {
+                       if ($this->viewHelpersByPositionAndContext[$uniqueCounter]->contains($renderingContext)) {
+                               $viewHelper = $this->viewHelpersByPositionAndContext[$uniqueCounter][$renderingContext];
+                               $viewHelper->resetState();
+                               return $viewHelper;
+                       } else {
+                               $viewHelperInstance = self::$objectContainer->getInstance($viewHelperName);
+                               if ($viewHelperInstance instanceof \TYPO3\CMS\Core\SingletonInterface) {
+                                       $viewHelperInstance->resetState();
+                               }
+                               $this->viewHelpersByPositionAndContext[$uniqueCounter]->attach($renderingContext, $viewHelperInstance);
+                               return $viewHelperInstance;
+                       }
+               } else {
+                       $this->viewHelpersByPositionAndContext[$uniqueCounter] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage');
+                       $viewHelperInstance = self::$objectContainer->getInstance($viewHelperName);
+                       if ($viewHelperInstance instanceof \TYPO3\CMS\Core\SingletonInterface) {
+                               $viewHelperInstance->resetState();
+                       }
+                       $this->viewHelpersByPositionAndContext[$uniqueCounter]->attach($renderingContext, $viewHelperInstance);
+                       return $viewHelperInstance;
+               }
+       }
+
+       /**
+        * @return boolean
+        */
+       public function isCompilable() {
+               return FALSE;
+       }
+
+       /**
+        * @return boolean
+        */
+       public function isCompiled() {
+               return TRUE;
+       }
+
+       /**
+        * @return string
+        * @internal
+        */
+       static public function resolveDefaultEncoding() {
+               if (static::$defaultEncoding === NULL) {
+                       static::$defaultEncoding = 'UTF-8';
+               }
+               return static::$defaultEncoding;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Compiler/TemplateCompiler.php b/typo3/sysext/fluid/Classes/Core/Compiler/TemplateCompiler.php
new file mode 100644 (file)
index 0000000..aebd6f3
--- /dev/null
@@ -0,0 +1,396 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Compiler;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+class TemplateCompiler implements \TYPO3\CMS\Core\SingletonInterface {
+
+       const SHOULD_GENERATE_VIEWHELPER_INVOCATION = '##should_gen_viewhelper##';
+
+       /**
+        * @var \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend
+        */
+       protected $templateCache;
+
+       /**
+        * @var integer
+        */
+       protected $variableCounter = 0;
+
+       /**
+        * @var array
+        */
+       protected $syntaxTreeInstanceCache = array();
+
+       /**
+        * @param \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend $templateCache
+        * @return void
+        */
+       public function setTemplateCache(\TYPO3\CMS\Core\Cache\Frontend\PhpFrontend $templateCache) {
+               $this->templateCache = $templateCache;
+       }
+
+       /**
+        * @param string $identifier
+        * @return boolean
+        */
+       public function has($identifier) {
+               $identifier = $this->sanitizeIdentifier($identifier);
+               return $this->templateCache->has($identifier);
+       }
+
+       /**
+        * @param string $identifier
+        * @return \TYPO3\CMS\Fluid\Core\Parser\ParsedTemplateInterface
+        */
+       public function get($identifier) {
+               $identifier = $this->sanitizeIdentifier($identifier);
+               if (!isset($this->syntaxTreeInstanceCache[$identifier])) {
+                       $this->templateCache->requireOnce($identifier);
+                       $templateClassName = 'FluidCache_' . $identifier;
+                       $this->syntaxTreeInstanceCache[$identifier] = new $templateClassName();
+               }
+               return $this->syntaxTreeInstanceCache[$identifier];
+       }
+
+       /**
+        * @param string $identifier
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $parsingState
+        * @return void
+        */
+       public function store($identifier, \TYPO3\CMS\Fluid\Core\Parser\ParsingState $parsingState) {
+               $identifier = $this->sanitizeIdentifier($identifier);
+               $this->variableCounter = 0;
+               $generatedRenderFunctions = '';
+
+               if ($parsingState->getVariableContainer()->exists('sections')) {
+                       $sections = $parsingState->getVariableContainer()->get('sections');
+                       // TODO: refactor to $parsedTemplate->getSections()
+                       foreach ($sections as $sectionName => $sectionRootNode) {
+                               $generatedRenderFunctions .= $this->generateCodeForSection($this->convertListOfSubNodes($sectionRootNode), 'section_' . sha1($sectionName), 'section ' . $sectionName);
+                       }
+               }
+               $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 = <<<EOD
+%s {
+
+public function getVariableContainer() {
+       // TODO
+       return new \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer();
+}
+public function getLayoutName(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface \$renderingContext) {
+%s
+return %s;
+}
+public function hasLayout() {
+return %s;
+}
+
+%s
+
+}
+EOD;
+               $templateCode = sprintf($templateCode,
+                               $classDefinition,
+                               $convertedLayoutNameNode['initialization'],
+                               $convertedLayoutNameNode['execution'],
+                               ($parsingState->hasLayout() ? 'TRUE' : 'FALSE'),
+                               $generatedRenderFunctions);
+               $this->templateCache->set($identifier, $templateCode);
+       }
+
+       /**
+        * Replaces special characters by underscores
+        *
+        * @see http://www.php.net/manual/en/language.variables.basics.php
+        * @param string $identifier
+        * @return string the sanitized identifier
+        */
+       protected function sanitizeIdentifier($identifier) {
+               return preg_replace('([^a-zA-Z0-9_\\x7f-\\xff])', '_', $identifier);
+       }
+
+       /**
+        * @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;
+%s
+return %s;
+}
+
+EOD;
+               return sprintf($templateCode, $comment, $expectedFunctionName, $converted['initialization'], $converted['execution']);
+       }
+
+       /**
+        * Returns an array with two elements:
+        * - initialization: contains PHP code which is inserted *before* the actual rendering call. Must be valid, i.e. end with semi-colon.
+        * - execution: contains *a single PHP instruction* which needs to return the rendered output of the given element. Should NOT end with semi-colon.
+        *
+        * @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) {
+                       return $this->convertTextNode($node);
+               } elseif ($node instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NumericNode) {
+                       return $this->convertNumericNode($node);
+               } elseif ($node instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode) {
+                       return $this->convertViewHelperNode($node);
+               } elseif ($node instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode) {
+                       return $this->convertObjectAccessorNode($node);
+               } elseif ($node instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ArrayNode) {
+                       return $this->convertArrayNode($node);
+               } elseif ($node instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\RootNode) {
+                       return $this->convertListOfSubNodes($node);
+               } elseif ($node instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\BooleanNode) {
+                       return $this->convertBooleanNode($node);
+               } else {
+                       throw new \TYPO3\CMS\Fluid\Exception('Syntax tree node type "' . get_class($node) . '" is not supported.');
+               }
+       }
+
+       /**
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode $node
+        * @return array
+        * @see convert()
+        */
+       protected function convertTextNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode $node) {
+               return array(
+                       'initialization' => '',
+                       'execution' => '\'' . $this->escapeTextForUseInSingleQuotes($node->getText()) . '\''
+               );
+       }
+
+       /**
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NumericNode $node
+        * @return array
+        * @see convert()
+        */
+       protected function convertNumericNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NumericNode $node) {
+               return array(
+                       'initialization' => '',
+                       'execution' => $node->getValue()
+               );
+       }
+
+       /**
+        * Convert a single ViewHelperNode into its cached representation. If the ViewHelper implements the "Compilable" facet,
+        * the ViewHelper itself is asked for its cached PHP code representation. If not, a ViewHelper is built and then invoked.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode $node
+        * @return array
+        * @see convert()
+        */
+       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);
+                       $initializationPhpCode .= $converted['initialization'];
+                       $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 = '';
+                       $convertedViewHelperExecutionCode = $node->getUninitializedViewHelper()->compile($argumentsVariableName, $renderChildrenClosureVariableName, $viewHelperInitializationPhpCode, $node, $this);
+                       $initializationPhpCode .= $viewHelperInitializationPhpCode;
+                       if ($convertedViewHelperExecutionCode !== self::SHOULD_GENERATE_VIEWHELPER_INVOCATION) {
+                               return array(
+                                       'initialization' => $initializationPhpCode,
+                                       'execution' => $convertedViewHelperExecutionCode
+                               );
+                       }
+               }
+
+               // 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)
+               );
+       }
+
+       /**
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode $node
+        * @return array
+        * @see convert()
+        */
+       protected function convertObjectAccessorNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode $node) {
+               return array(
+                       'initialization' => '',
+                       'execution' => sprintf('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\ObjectAccessorNode::getPropertyPath($renderingContext->getTemplateVariableContainer(), \'%s\', $renderingContext)', $node->getObjectPath())
+               );
+       }
+
+       /**
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ArrayNode $node
+        * @return array
+        * @see convert()
+        */
+       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);
+                               $initializationPhpCode .= $converted['initialization'];
+                               $initializationPhpCode .= sprintf('%s[\'%s\'] = %s;', $arrayVariableName, $key, $converted['execution']) . chr(10);
+                       } elseif (is_numeric($value)) {
+                               // this case might happen for simple values
+                               $initializationPhpCode .= sprintf('%s[\'%s\'] = %s;', $arrayVariableName, $key, $value) . chr(10);
+                       } else {
+                               // this case might happen for simple values
+                               $initializationPhpCode .= sprintf('%s[\'%s\'] = \'%s\';', $arrayVariableName, $key, $this->escapeTextForUseInSingleQuotes($value)) . chr(10);
+                       }
+               }
+               return array(
+                       'initialization' => $initializationPhpCode,
+                       'execution' => $arrayVariableName
+               );
+       }
+
+       /**
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $node
+        * @return array
+        * @see convert()
+        */
+       public function convertListOfSubNodes(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $node) {
+               switch (count($node->getChildNodes())) {
+                       case 0:
+                               return array(
+                                       'initialization' => '',
+                                       'execution' => 'NULL'
+                               );
+                       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
+                               );
+               }
+       }
+
+       /**
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\BooleanNode $node
+        * @return array
+        * @see convert()
+        */
+       protected function convertBooleanNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\BooleanNode $node) {
+               $initializationPhpCode = '// Rendering Boolean node' . chr(10);
+               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'])
+                       );
+               } else {
+                       // simple case, no comparator.
+                       $converted = $this->convert($node->getSyntaxTreeNode());
+                       return array(
+                               'initialization' => $initializationPhpCode . $converted['initialization'],
+                               'execution' => sprintf('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\BooleanNode::convertToBoolean(%s)', $converted['execution'])
+                       );
+               }
+       }
+
+       /**
+        * @param string $text
+        * @return string
+        */
+       protected function escapeTextForUseInSingleQuotes($text) {
+               return str_replace(array('\\', '\''), array('\\\\', '\\\''), $text);
+       }
+
+       /**
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $node
+        * @return string
+        */
+       public function wrapChildNodesInClosure(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $node) {
+               $closure = '';
+               $closure .= 'function() use ($renderingContext, $self) {' . chr(10);
+               $convertedSubNodes = $this->convertListOfSubNodes($node);
+               $closure .= $convertedSubNodes['initialization'];
+               $closure .= sprintf('return %s;', $convertedSubNodes['execution']) . chr(10);
+               $closure .= '}';
+               return $closure;
+       }
+
+       /**
+        * Returns a unique variable name by appending a global index to the given prefix
+        *
+        * @param string $prefix
+        * @return string
+        */
+       public function variableName($prefix) {
+               return '$' . $prefix . $this->variableCounter++;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Exception.php b/typo3/sysext/fluid/Classes/Core/Exception.php
new file mode 100644 (file)
index 0000000..593c932
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+/**
+ * A generic Fluid Core exception.
+ *
+ * @api
+ */
+class Exception extends \TYPO3\CMS\Fluid\Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/Configuration.php b/typo3/sysext/fluid/Classes/Core/Parser/Configuration.php
new file mode 100644 (file)
index 0000000..0a70dbe
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * The parser configuration. Contains all configuration needed to configure
+ * the building of a SyntaxTree.
+ */
+class Configuration {
+
+       /**
+        * Generic interceptors registered with the configuration.
+        *
+        * @var array<\TYPO3\CMS\Extbase\Persistence\ObjectStorage>
+        */
+       protected $interceptors = array();
+
+       /**
+        * Adds an interceptor to apply to values coming from object accessors.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface $interceptor
+        * @return void
+        */
+       public function addInterceptor(\TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface $interceptor) {
+               foreach ($interceptor->getInterceptionPoints() as $interceptionPoint) {
+                       if (!isset($this->interceptors[$interceptionPoint])) {
+                               $this->interceptors[$interceptionPoint] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage');
+                       }
+                       if (!$this->interceptors[$interceptionPoint]->contains($interceptor)) {
+                               $this->interceptors[$interceptionPoint]->attach($interceptor);
+                       }
+               }
+       }
+
+       /**
+        * Returns all interceptors for a given Interception Point.
+        *
+        * @param integer $interceptionPoint one of the \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_* constants,
+        * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface>
+        */
+       public function getInterceptors($interceptionPoint) {
+               if (isset($this->interceptors[$interceptionPoint]) && $this->interceptors[$interceptionPoint] instanceof \TYPO3\CMS\Extbase\Persistence\ObjectStorage) {
+                       return $this->interceptors[$interceptionPoint];
+               }
+               return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage');
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/Exception.php b/typo3/sysext/fluid/Classes/Core/Parser/Exception.php
new file mode 100644 (file)
index 0000000..e3320d1
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+/**
+ * A Parsing Exception
+ *
+ * @api
+ */
+class Exception extends \TYPO3\CMS\Fluid\Core\Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/Interceptor/Escape.php b/typo3/sysext/fluid/Classes/Core/Parser/Interceptor/Escape.php
new file mode 100644 (file)
index 0000000..00a1a55
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\Interceptor;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * An interceptor adding the escape viewhelper to the suitable places.
+ */
+class Escape implements \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface {
+
+       /**
+        * Is the interceptor enabled right now?
+        *
+        * @var boolean
+        */
+       protected $interceptorEnabled = TRUE;
+
+       /**
+        * A stack of ViewHelperNodes which currently disable the interceptor.
+        * Needed to enable the interceptor again.
+        *
+        * @var array<\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface>
+        */
+       protected $viewHelperNodesWhichDisableTheInterceptor = array();
+
+       /**
+        * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
+        * Inject object manager
+        *
+        * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
+        * @return void
+        */
+       public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
+        * Adds a ViewHelper node using the Format\HtmlspecialcharsViewHelper to the given node.
+        * If "escapingInterceptorEnabled" in the ViewHelper is FALSE, will disable itself inside the ViewHelpers body.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $node
+        * @param integer $interceptorPosition One of the INTERCEPT_* constants for the current interception point
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $parsingState the current parsing state. Not needed in this interceptor.
+        * @return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface
+        */
+       public function process(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $node, $interceptorPosition, \TYPO3\CMS\Fluid\Core\Parser\ParsingState $parsingState) {
+               if ($interceptorPosition === \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_OPENING_VIEWHELPER) {
+                       if (!$node->getUninitializedViewHelper()->isEscapingInterceptorEnabled()) {
+                               $this->interceptorEnabled = FALSE;
+                               $this->viewHelperNodesWhichDisableTheInterceptor[] = $node;
+                       }
+               } elseif ($interceptorPosition === \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_CLOSING_VIEWHELPER) {
+                       if (end($this->viewHelperNodesWhichDisableTheInterceptor) === $node) {
+                               array_pop($this->viewHelperNodesWhichDisableTheInterceptor);
+                               if (count($this->viewHelperNodesWhichDisableTheInterceptor) === 0) {
+                                       $this->interceptorEnabled = TRUE;
+                               }
+                       }
+               } elseif ($this->interceptorEnabled && $node instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ObjectAccessorNode) {
+                       $escapeViewHelper = $this->objectManager->get('TYPO3\\CMS\\Fluid\\ViewHelpers\\Format\\HtmlspecialcharsViewHelper');
+                       $node = $this->objectManager->get(
+                               'TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\ViewHelperNode',
+                               $escapeViewHelper,
+                               array('value' => $node)
+                       );
+               }
+               return $node;
+       }
+
+       /**
+        * This interceptor wants to hook into object accessor creation, and opening / closing ViewHelpers.
+        *
+        * @return array Array of INTERCEPT_* constants
+        */
+       public function getInterceptionPoints() {
+               return array(
+                       \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_OPENING_VIEWHELPER,
+                       \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_CLOSING_VIEWHELPER,
+                       \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_OBJECTACCESSOR
+               );
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/InterceptorInterface.php b/typo3/sysext/fluid/Classes/Core/Parser/InterceptorInterface.php
new file mode 100644 (file)
index 0000000..17b35ed
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * An interceptor interface. Interceptors are used in the parsing stage to change
+ * the syntax tree of a template, e.g. by adding viewhelper nodes.
+ */
+interface InterceptorInterface {
+
+       const INTERCEPT_OPENING_VIEWHELPER = 1;
+       const INTERCEPT_CLOSING_VIEWHELPER = 2;
+       const INTERCEPT_TEXT = 3;
+       const INTERCEPT_OBJECTACCESSOR = 4;
+
+       /**
+        * The interceptor can process the given node at will and must return a node
+        * that will be used in place of the given node.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $node
+        * @param integer $interceptorPosition One of the INTERCEPT_* constants for the current interception point
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $parsingState the parsing state
+        * @return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface
+        */
+       public function process(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $node, $interceptorPosition, \TYPO3\CMS\Fluid\Core\Parser\ParsingState $parsingState);
+
+       /**
+        * The interceptor should define at which interception positions it wants to be called.
+        *
+        * @return array Array of INTERCEPT_* constants
+        */
+       public function getInterceptionPoints();
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/ParsedTemplateInterface.php b/typo3/sysext/fluid/Classes/Core/Parser/ParsedTemplateInterface.php
new file mode 100644 (file)
index 0000000..56381b0
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * This interface is returned by \TYPO3\CMS\Fluid\Core\Parser\TemplateParser->parse()
+ * method and is a parsed template
+ */
+interface ParsedTemplateInterface {
+
+       /**
+        * Render the parsed template with rendering context
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext The rendering context to use
+        * @return string Rendered string
+        */
+       public function render(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext);
+
+       /**
+        * Returns a variable container used in the PostParse Facet.
+        *
+        * @todo remove
+        * @return \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer
+        */
+       public function getVariableContainer();
+
+       /**
+        * Returns the name of the layout that is defined within the current template via <f:layout name="..." />
+        * If no layout is defined, this returns NULL
+        * This requires the current rendering context in order to be able to evaluate the layout name
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return string
+        */
+       public function getLayoutName(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext);
+
+       /**
+        * Returns TRUE if the current template has a template defined via <f:layout name="..." />
+        *
+        * @see getLayoutName()
+        * @return boolean
+        */
+       public function hasLayout();
+
+       /**
+        * If the template contains constructs which prevent the compiler from compiling the template
+        * correctly, isCompilable() will return FALSE.
+        *
+        * @return boolean TRUE if the template can be compiled
+        */
+       public function isCompilable();
+
+       /**
+        * @return boolean TRUE if the template is already compiled, FALSE otherwise
+        */
+       public function isCompiled();
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/ParsingState.php b/typo3/sysext/fluid/Classes/Core/Parser/ParsingState.php
new file mode 100644 (file)
index 0000000..de0cb73
--- /dev/null
@@ -0,0 +1,210 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Stores all information relevant for one parsing pass - that is, the root node,
+ * and the current stack of open nodes (nodeStack) and a variable container used
+ * for PostParseFacets.
+ */
+class ParsingState implements \TYPO3\CMS\Fluid\Core\Parser\ParsedTemplateInterface {
+
+       /**
+        * Root node reference
+        *
+        * @var \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\RootNode
+        */
+       protected $rootNode;
+
+       /**
+        * Array of node references currently open.
+        *
+        * @var array
+        */
+       protected $nodeStack = array();
+
+       /**
+        * Variable container where ViewHelpers implementing the PostParseFacet can
+        * store things in.
+        *
+        * @var \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer
+        */
+       protected $variableContainer;
+
+       /**
+        * The layout name of the current template or NULL if the template does not contain a layout definition
+        *
+        * @var \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode
+        */
+       protected $layoutNameNode;
+
+       /**
+        * @var boolean
+        */
+       protected $compilable = TRUE;
+
+       /**
+        * Injects a variable container. ViewHelpers implementing the PostParse
+        * Facet can store information inside this variableContainer.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer $variableContainer
+        * @return void
+        */
+       public function injectVariableContainer(\TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer $variableContainer) {
+               $this->variableContainer = $variableContainer;
+       }
+
+       /**
+        * Set root node of this parsing state
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $rootNode
+        * @return void
+        */
+       public function setRootNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $rootNode) {
+               $this->rootNode = $rootNode;
+       }
+
+       /**
+        * Get root node of this parsing state.
+        *
+        * @return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode The root node
+        */
+       public function getRootNode() {
+               return $this->rootNode;
+       }
+
+       /**
+        * Render the parsed template with rendering context
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext The rendering context to use
+        * @return string Rendered string
+        */
+       public function render(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               return $this->rootNode->evaluate($renderingContext);
+       }
+
+       /**
+        * Push a node to the node stack. The node stack holds all currently open
+        * templating tags.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $node Node to push to node stack
+        * @return void
+        */
+       public function pushNodeToStack(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $node) {
+               array_push($this->nodeStack, $node);
+       }
+
+       /**
+        * Get the top stack element, without removing it.
+        *
+        * @return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode the top stack element.
+        */
+       public function getNodeFromStack() {
+               return $this->nodeStack[count($this->nodeStack) - 1];
+       }
+
+       /**
+        * Pop the top stack element (=remove it) and return it back.
+        *
+        * @return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode the top stack element, which was removed.
+        */
+       public function popNodeFromStack() {
+               return array_pop($this->nodeStack);
+       }
+
+       /**
+        * Count the size of the node stack
+        *
+        * @return integer Number of elements on the node stack (i.e. number of currently open Fluid tags)
+        */
+       public function countNodeStack() {
+               return count($this->nodeStack);
+       }
+
+       /**
+        * Returns a variable container which will be then passed to the postParseFacet.
+        *
+        * @return \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer The variable container or NULL if none has been set yet
+        * @todo Rename to getPostParseVariableContainer
+        */
+       public function getVariableContainer() {
+               return $this->variableContainer;
+       }
+
+       /**
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $layoutNameNode name of the layout that is defined in this template via <f:layout name="..." />
+        * @return void
+        */
+       public function setLayoutNameNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $layoutNameNode) {
+               $this->layoutNameNode = $layoutNameNode;
+       }
+
+       /**
+        * @return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode
+        */
+       public function getLayoutNameNode() {
+               return $this->layoutNameNode;
+       }
+
+       /**
+        * Returns TRUE if the current template has a template defined via <f:layout name="..." />
+        *
+        * @see getLayoutName()
+        * @return boolean
+        */
+       public function hasLayout() {
+               return $this->layoutNameNode !== NULL;
+       }
+
+       /**
+        * Returns the name of the layout that is defined within the current template via <f:layout name="..." />
+        * If no layout is defined, this returns NULL
+        * This requires the current rendering context in order to be able to evaluate the layout name
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return string
+        * @throws \TYPO3\CMS\Fluid\View\Exception
+        */
+       public function getLayoutName(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               if (!$this->hasLayout()) {
+                       return NULL;
+               }
+               $layoutName = $this->layoutNameNode->evaluate($renderingContext);
+               if (!empty($layoutName)) {
+                       return $layoutName;
+               }
+               throw new \TYPO3\CMS\Fluid\View\Exception('The layoutName could not be evaluated to a string', 1296805368);
+       }
+
+       /**
+        * @return boolean
+        */
+       public function isCompilable() {
+               return $this->compilable;
+       }
+
+       /**
+        * @param boolean $compilable
+        */
+       public function setCompilable($compilable) {
+               $this->compilable = $compilable;
+       }
+
+       /**
+        * @return boolean
+        */
+       public function isCompiled() {
+               return FALSE;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/AbstractNode.php b/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/AbstractNode.php
new file mode 100644 (file)
index 0000000..0a6fd86
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Abstract node in the syntax tree which has been built.
+ */
+abstract class AbstractNode implements \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface {
+
+       /**
+        * List of Child Nodes.
+        *
+        * @var array<\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface>
+        */
+       protected $childNodes = array();
+
+       /**
+        * Evaluate all child nodes and return the evaluated results.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return mixed Normally, an object is returned - in case it is concatenated with a string, a string is returned.
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
+        */
+       public function evaluateChildNodes(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               $output = NULL;
+               foreach ($this->childNodes as $subNode) {
+                       if ($output === NULL) {
+                               $output = $subNode->evaluate($renderingContext);
+                       } else {
+                               if (is_object($output)) {
+                                       if (!method_exists($output, '__toString')) {
+                                               throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Cannot cast object of type "' . get_class($output) . '" to string.', 1248356140);
+                                       }
+                                       $output = $output->__toString();
+                               } else {
+                                       $output = (string) $output;
+                               }
+                               $subNodeOutput = $subNode->evaluate($renderingContext);
+
+                               if (is_object($subNodeOutput)) {
+                                       if (!method_exists($subNodeOutput, '__toString')) {
+                                               throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Cannot cast object of type "' . get_class($subNodeOutput) . '" to string.', 1273753083);
+                                       }
+                                       $output .= $subNodeOutput->__toString();
+                               } else {
+                                       $output .= (string) $subNodeOutput;
+                               }
+                       }
+               }
+               return $output;
+       }
+
+       /**
+        * Returns all child nodes for a given node.
+        * This is especially needed to implement the boolean expression language.
+        *
+        * @return array<\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface> A list of nodes
+        */
+       public function getChildNodes() {
+               return $this->childNodes;
+       }
+
+       /**
+        * Appends a subnode to this node. Is used inside the parser to append children
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $childNode The subnode to add
+        * @return void
+        */
+       public function addChildNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $childNode) {
+               $this->childNodes[] = $childNode;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ArrayNode.php b/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ArrayNode.php
new file mode 100644 (file)
index 0000000..ac15627
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Array Syntax Tree Node. Handles JSON-like arrays.
+ */
+class ArrayNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode {
+
+       /**
+        * An associative array. Each key is a string. Each value is either a literal, or an AbstractNode.
+        *
+        * @var array
+        */
+       protected $internalArray = array();
+
+       /**
+        * Constructor.
+        *
+        * @param array $internalArray Array to store
+        */
+       public function __construct($internalArray) {
+               $this->internalArray = $internalArray;
+       }
+
+       /**
+        * Evaluate the array and return an evaluated array
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return array An associative array with literal values
+        */
+       public function evaluate(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               $arrayToBuild = array();
+               foreach ($this->internalArray as $key => $value) {
+                       if ($value instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode) {
+                               $arrayToBuild[$key] = $value->evaluate($renderingContext);
+                       } else {
+                               // TODO - this case should not happen!
+                               $arrayToBuild[$key] = $value;
+                       }
+               }
+               return $arrayToBuild;
+       }
+
+       /**
+        * INTERNAL; DO NOT CALL DIRECTLY!
+        *
+        * @return array
+        */
+       public function getInternalArray() {
+               return $this->internalArray;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/BooleanNode.php b/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/BooleanNode.php
new file mode 100644 (file)
index 0000000..74a73c3
--- /dev/null
@@ -0,0 +1,337 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * A node which is used inside boolean arguments
+ */
+class BooleanNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode {
+
+       /**
+        * List of comparators which are supported in the boolean expression language.
+        *
+        * Make sure that if one string is contained in one another, the longer
+        * string is listed BEFORE the shorter one.
+        * Example: put ">=" before ">"
+        *
+        * @var array
+        */
+       static protected $comparators = array('==', '!=', '%', '>=', '>', '<=', '<');
+
+       /**
+        * A regular expression which checks the text nodes of a boolean expression.
+        * Used to define how the regular expression language should look like.
+        *
+        * @var string
+        */
+       static protected $booleanExpressionTextNodeCheckerRegularExpression = '/
+               ^                 # Start with first input symbol
+               (?:               # start repeat
+                       COMPARATORS   # We allow all comparators
+                       |\s*          # Arbitary spaces
+                       |-?           # Numbers, possibly with the "minus" symbol in front.
+                               [0-9]+    # some digits
+                               (?:       # and optionally a dot, followed by some more digits
+                                       \\.
+                                       [0-9]+
+                               )?
+                       |\'[^\'\\\\]* # single quoted string literals with possibly escaped single quotes
+                               (?:
+                                       \\\\.      # escaped character
+                                       [^\'\\\\]* # unrolled loop following Jeffrey E.F. Friedl
+                               )*\'
+                       |"[^"\\\\]*   # double quoted string literals with possibly escaped double quotes
+                               (?:
+                                       \\\\.     # escaped character
+                                       [^"\\\\]* # unrolled loop following Jeffrey E.F. Friedl
+                               )*"
+               )*
+               $/x';
+
+       /**
+        * Left side of the comparison
+        *
+        * @var \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode
+        */
+       protected $leftSide;
+
+       /**
+        * Right side of the comparison
+        *
+        * @var \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode
+        */
+       protected $rightSide;
+
+       /**
+        * The comparator. One element of self::$comparators. If NULL,
+        * no comparator was found, and self::$syntaxTreeNode should
+        * instead be evaluated.
+        *
+        * @var string
+        */
+       protected $comparator;
+
+       /**
+        * If no comparator was found, the syntax tree node should be
+        * converted to boolean.
+        *
+        * @var \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode
+        */
+       protected $syntaxTreeNode;
+
+       /**
+        * Constructor. Parses the syntax tree node and fills $this->leftSide, $this->rightSide,
+        * $this->comparator and $this->syntaxTreeNode.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
+        */
+       public function __construct(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode) {
+               $childNodes = $syntaxTreeNode->getChildNodes();
+               if (count($childNodes) > 3) {
+                       throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('A boolean expression has more than tree parts.', 1244201848);
+               } elseif (count($childNodes) === 0) {
+                       // In this case, we do not have child nodes; i.e. the current SyntaxTreeNode
+                       // is a text node with a literal comparison like "1 == 1"
+                       $childNodes = array($syntaxTreeNode);
+               }
+
+               $this->leftSide = new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\RootNode();
+               $this->rightSide = new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\RootNode();
+               $this->comparator = NULL;
+               foreach ($childNodes as $childNode) {
+                       if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode && !preg_match(str_replace('COMPARATORS', implode('|', self::$comparators), self::$booleanExpressionTextNodeCheckerRegularExpression), $childNode->getText())) {
+                               // $childNode is text node, and no comparator found.
+                               $this->comparator = NULL;
+                               // skip loop and fall back to classical to boolean conversion.
+                               break;
+                       }
+
+                       if ($this->comparator !== NULL) {
+                               // comparator already set, we are evaluating the right side of the comparator
+                               $this->rightSide->addChildNode($childNode);
+                       } elseif ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode
+                               && ($this->comparator = $this->getComparatorFromString($childNode->getText()))) {
+                               // comparator in current string segment
+                               $explodedString = explode($this->comparator, $childNode->getText());
+                               if (isset($explodedString[0]) && trim($explodedString[0]) !== '') {
+                                       $value = trim($explodedString[0]);
+                                       if (is_numeric($value)) {
+                                               $this->leftSide->addChildNode(new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NumericNode($value));
+                                       } else {
+                                               $this->leftSide->addChildNode(new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode(preg_replace('/(^[\'"]|[\'"]$)/', '', $value)));
+                                       }
+                               }
+                               if (isset($explodedString[1]) && trim($explodedString[1]) !== '') {
+                                       $value = trim($explodedString[1]);
+                                       if (is_numeric($value)) {
+                                               $this->rightSide->addChildNode(new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NumericNode($value));
+                                       } else {
+                                               $this->rightSide->addChildNode(new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode(preg_replace('/(^[\'"]|[\'"]$)/', '', $value)));
+                                       }
+                               }
+                       } else {
+                               // comparator not found yet, on the left side of the comparator
+                               $this->leftSide->addChildNode($childNode);
+                       }
+               }
+
+               if ($this->comparator === NULL) {
+                       // No Comparator found, we need to evaluate the given syntax tree node manually
+                       $this->syntaxTreeNode = $syntaxTreeNode;
+               }
+       }
+
+       /**
+        * @return string
+        * @internal
+        */
+       public function getComparator() {
+               return $this->comparator;
+       }
+
+       /**
+        * @return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode
+        * @internal
+        */
+       public function getSyntaxTreeNode() {
+               return $this->syntaxTreeNode;
+       }
+
+       /**
+        * @return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode
+        * @internal
+        */
+       public function getLeftSide() {
+               return $this->leftSide;
+       }
+
+       /**
+        * @return \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode
+        * @internal
+        */
+       public function getRightSide() {
+               return $this->rightSide;
+       }
+
+       /**
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return boolean the boolean value
+        */
+       public function evaluate(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               if ($this->comparator !== NULL) {
+                       return self::evaluateComparator($this->comparator, $this->leftSide->evaluate($renderingContext), $this->rightSide->evaluate($renderingContext));
+               } else {
+                       $value = $this->syntaxTreeNode->evaluate($renderingContext);
+                       return self::convertToBoolean($value);
+               }
+       }
+
+       /**
+        * Do the actual comparison. Compares $leftSide and $rightSide with $comparator and emits a boolean value.
+        *
+        * Some special rules apply:
+        * - The == and != operators are comparing the Object Identity using === and !==, when one of the two
+        *   operands are objects.
+        * - For arithmetic comparisons (%, >, >=, <, <=), some special rules apply:
+        *   - arrays are only comparable with arrays, else the comparison yields FALSE
+        *   - objects are only comparable with objects, else the comparison yields FALSE
+        *   - the comparison is FALSE when two types are not comparable according to the table
+        *     "Comparison with various types" on http://php.net/manual/en/language.operators.comparison.php
+        *
+        * This function must be static public, as it is also directly called from cached templates.
+        *
+        * @param string $comparator
+        * @param mixed $evaluatedLeftSide
+        * @param mixed $evaluatedRightSide
+        * @return boolean TRUE if comparison of left and right side using the comparator emit TRUE, false otherwise
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
+        */
+       static public function evaluateComparator($comparator, $evaluatedLeftSide, $evaluatedRightSide) {
+               switch ($comparator) {
+                       case '==':
+                               if (is_object($evaluatedLeftSide) || is_object($evaluatedRightSide)) {
+                                       return ($evaluatedLeftSide === $evaluatedRightSide);
+                               } else {
+                                       return ($evaluatedLeftSide == $evaluatedRightSide);
+                               }
+                       case '!=':
+                               if (is_object($evaluatedLeftSide) || is_object($evaluatedRightSide)) {
+                                       return ($evaluatedLeftSide !== $evaluatedRightSide);
+                               } else {
+                                       return ($evaluatedLeftSide != $evaluatedRightSide);
+                               }
+                       case '%':
+                               if (!self::isComparable($evaluatedLeftSide, $evaluatedRightSide)) {
+                                       return FALSE;
+                               }
+                               return (boolean) ((integer) $evaluatedLeftSide % (integer) $evaluatedRightSide);
+                       case '>':
+                               if (!self::isComparable($evaluatedLeftSide, $evaluatedRightSide)) {
+                                       return FALSE;
+                               }
+                               return $evaluatedLeftSide > $evaluatedRightSide;
+                       case '>=':
+                               if (!self::isComparable($evaluatedLeftSide, $evaluatedRightSide)) {
+                                       return FALSE;
+                               }
+                               return $evaluatedLeftSide >= $evaluatedRightSide;
+                       case '<':
+                               if (!self::isComparable($evaluatedLeftSide, $evaluatedRightSide)) {
+                                       return FALSE;
+                               }
+                               return $evaluatedLeftSide < $evaluatedRightSide;
+                       case '<=':
+                               if (!self::isComparable($evaluatedLeftSide, $evaluatedRightSide)) {
+                                       return FALSE;
+                               }
+                               return $evaluatedLeftSide <= $evaluatedRightSide;
+                       default:
+                               throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Comparator "' . $comparator . '" is not implemented.', 1244234398);
+               }
+       }
+
+       /**
+        * Checks whether two operands are comparable (based on their types). This implements
+        * the "Comparison with various types" table from http://php.net/manual/en/language.operators.comparison.php,
+        * only leaving out "array" with "anything" and "object" with anything; as we specify
+        * that arrays and objects are incomparable with anything else than their type.
+        *
+        * @param mixed $evaluatedLeftSide
+        * @param mixed $evaluatedRightSide
+        * @return boolean TRUE if the operands can be compared using arithmetic operators, FALSE otherwise.
+        */
+       static protected function isComparable($evaluatedLeftSide, $evaluatedRightSide) {
+               if ((is_null($evaluatedLeftSide) || is_string($evaluatedLeftSide))
+                       && is_string($evaluatedRightSide)) {
+                       return TRUE;
+               }
+               if (is_bool($evaluatedLeftSide) || is_null($evaluatedLeftSide)) {
+                       return TRUE;
+               }
+               if (is_object($evaluatedLeftSide) && is_object($evaluatedRightSide)) {
+                       return TRUE;
+               }
+               if ((is_string($evaluatedLeftSide) || is_resource($evaluatedLeftSide) || is_numeric($evaluatedLeftSide))
+                       && (is_string($evaluatedRightSide) || is_resource($evaluatedRightSide) || is_numeric($evaluatedRightSide))) {
+                       return TRUE;
+               }
+               if (is_array($evaluatedLeftSide) && is_array($evaluatedRightSide)) {
+                       return TRUE;
+               }
+               return FALSE;
+       }
+
+       /**
+        * Determine if there is a comparator inside $string, and if yes, returns it.
+        *
+        * @param string $string string to check for a comparator inside
+        * @return string The comparator or NULL if none found.
+        */
+       protected function getComparatorFromString($string) {
+               foreach (self::$comparators as $comparator) {
+                       if (strpos($string, $comparator) !== FALSE) {
+                               return $comparator;
+                       }
+               }
+               return NULL;
+       }
+
+       /**
+        * Convert argument strings to their equivalents. Needed to handle strings with a boolean meaning.
+        *
+        * Must be public and static as it is used from inside cached templates.
+        *
+        * @param mixed $value Value to be converted to boolean
+        * @return boolean
+        */
+       static public function convertToBoolean($value) {
+               if (is_bool($value)) {
+                       return $value;
+               }
+               if (is_numeric($value)) {
+                       return $value > 0;
+               }
+               if (is_string($value)) {
+                       return (!empty($value) && strtolower($value) !== 'false');
+               }
+               if (is_array($value) || (is_object($value) && $value instanceof \Countable)) {
+                       return count($value) > 0;
+               }
+               if (is_object($value)) {
+                       return TRUE;
+               }
+               return FALSE;
+       }
+}
+
+?>
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/NodeInterface.php b/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/NodeInterface.php
new file mode 100644 (file)
index 0000000..918a542
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Node in the syntax tree.
+ */
+interface NodeInterface {
+
+       /**
+        * Evaluate all child nodes and return the evaluated results.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return mixed Normally, an object is returned - in case it is concatenated with a string, a string is returned.
+        */
+       public function evaluateChildNodes(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext);
+
+       /**
+        * Returns all child nodes for a given node.
+        *
+        * @return array<\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface> A list of nodes
+        */
+       public function getChildNodes();
+
+       /**
+        * Appends a subnode to this node. Is used inside the parser to append children
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $childNode The subnode to add
+        * @return void
+        */
+       public function addChildNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $childNode);
+
+       /**
+        * Evaluates the node - can return not only strings, but arbitary objects.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return mixed Evaluated node
+        */
+       public function evaluate(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/NumericNode.php b/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/NumericNode.php
new file mode 100644 (file)
index 0000000..6451bc2
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
+
+/*                                                                        *
+ * This script belongs to the TYPO3 Flow package "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!                         *
+ *                                                                        */
+
+/**
+ * Numeric Syntax Tree Node - is a container for numerics.
+ *
+ */
+class NumericNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode {
+
+       /**
+        * Contents of the numeric node
+        * @var number
+        */
+       protected $value;
+
+       /**
+        * Constructor.
+        *
+        * @param string|number $value value to store in this numericNode
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
+        */
+       public function __construct($value) {
+               if (!is_numeric($value)) {
+                       throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Numeric node requires an argument of type number, "' . gettype($value) . '" given.', 1360414192);
+               }
+               $this->value = $value + 0;
+       }
+
+       /**
+        * Return the value associated to the syntax tree.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return number the value stored in this node/subtree.
+        */
+       public function evaluate(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               return $this->value;
+       }
+
+       /**
+        * Getter for value
+        *
+        * @return number The value of this node
+        */
+       public function getValue() {
+               return $this->value;
+       }
+
+       /**
+        * NumericNode does not allow adding child nodes, so this will always throw an exception.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $childNode The subnode to add
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
+        * @return void
+        */
+       public function addChildNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface $childNode) {
+               throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Numeric nodes may not contain child nodes, tried to add "' . get_class($childNode) . '".', 1360414193);
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ObjectAccessorNode.php b/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ObjectAccessorNode.php
new file mode 100644 (file)
index 0000000..93b2de8
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * A node which handles object access. This means it handles structures like {object.accessor.bla}
+ */
+class ObjectAccessorNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode {
+
+       /**
+        * Object path which will be called. Is a list like "post.name.email"
+        *
+        * @var string
+        */
+       protected $objectPath;
+
+       /**
+        * Constructor. Takes an object path as input.
+        *
+        * The first part of the object path has to be a variable in the
+        * TemplateVariableContainer.
+        *
+        * @param string $objectPath An Object Path, like object1.object2.object3
+        */
+       public function __construct($objectPath) {
+               $this->objectPath = $objectPath;
+       }
+
+       /**
+        * Internally used for building up cached templates; do not use directly!
+        *
+        * @return string
+        * @internal
+        */
+       public function getObjectPath() {
+               return $this->objectPath;
+       }
+
+       /**
+        * Evaluate this node and return the correct object.
+        *
+        * Handles each part (denoted by .) in $this->objectPath in the following order:
+        * - call appropriate getter
+        * - call public property, if exists
+        * - fail
+        *
+        * The first part of the object path has to be a variable in the
+        * TemplateVariableContainer.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return object The evaluated object, can be any object type.
+        */
+       public function evaluate(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               return self::getPropertyPath($renderingContext->getTemplateVariableContainer(), $this->objectPath, $renderingContext);
+       }
+
+       /**
+        * Gets a property path from a given object or array.
+        *
+        * If propertyPath is "bla.blubb", then we first call getProperty($object, 'bla'),
+        * and on the resulting object we call getProperty(..., 'blubb').
+        *
+        * For arrays the keys are checked likewise.
+        *
+        * @param mixed $subject An object or array
+        * @param string $propertyPath
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return mixed Value of the property
+        */
+       static public function getPropertyPath($subject, $propertyPath, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               $propertyPathSegments = explode('.', $propertyPath);
+               foreach ($propertyPathSegments as $pathSegment) {
+                       $propertyExists = FALSE;
+                       $propertyValue = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getPropertyInternal($subject, $pathSegment, FALSE, $propertyExists);
+                       if ($propertyExists !== TRUE && (is_array($subject) || $subject instanceof \ArrayAccess) && isset($subject[$pathSegment])) {
+                               $subject = $subject[$pathSegment];
+                       } else {
+                               $subject = $propertyValue;
+                       }
+
+                       if ($subject instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\RenderingContextAwareInterface) {
+                               $subject->setRenderingContext($renderingContext);
+                       }
+               }
+               return $subject;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/RenderingContextAwareInterface.php b/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/RenderingContextAwareInterface.php
new file mode 100644 (file)
index 0000000..45ee403
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Interface for objects which are aware of Fluid's rendering context. All objects
+ * marked with this interface will get the current rendering context injected
+ * by the ObjectAccessorNode on trying to evaluate them.
+ */
+interface RenderingContextAwareInterface {
+
+       /**
+        * Sets the current rendering context
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return void
+        */
+       public function setRenderingContext(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext);
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/RootNode.php b/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/RootNode.php
new file mode 100644 (file)
index 0000000..8786e3d
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Root node of every syntax tree.
+ */
+class RootNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode {
+
+       /**
+        * Evaluate the root node, by evaluating the subtree.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return mixed Evaluated subtree
+        */
+       public function evaluate(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               return $this->evaluateChildNodes($renderingContext);
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/TextNode.php b/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/TextNode.php
new file mode 100644 (file)
index 0000000..c4dad2f
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Text Syntax Tree Node - is a container for strings.
+ */
+class TextNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode {
+
+       /**
+        * Contents of the text node
+        *
+        * @var string
+        */
+       protected $text;
+
+       /**
+        * Constructor.
+        *
+        * @param string $text text to store in this textNode
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
+        */
+       public function __construct($text) {
+               if (!is_string($text)) {
+                       throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Text node requires an argument of type string, "' . gettype($text) . '" given.');
+               }
+               $this->text = $text;
+       }
+
+       /**
+        * Return the text associated to the syntax tree. Text from child nodes is
+        * appended to the text in the node's own text.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return string the text stored in this node/subtree.
+        */
+       public function evaluate(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               return $this->text . $this->evaluateChildNodes($renderingContext);
+       }
+
+       /**
+        * Getter for text
+        *
+        * @return string The text of this node
+        */
+       public function getText() {
+               return $this->text;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ViewHelperNode.php b/typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ViewHelperNode.php
new file mode 100644 (file)
index 0000000..0af2121
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser\SyntaxTree;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Node which will call a ViewHelper associated with this node.
+ */
+class ViewHelperNode extends \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode {
+
+       /**
+        * Class name of view helper
+        *
+        * @var string
+        */
+       protected $viewHelperClassName;
+
+       /**
+        * Arguments of view helper - References to RootNodes.
+        *
+        * @var array
+        */
+       protected $arguments = array();
+
+       /**
+        * The ViewHelper associated with this node
+        *
+        * @var \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
+        */
+       protected $uninitializedViewHelper = NULL;
+
+       /**
+        * A mapping RenderingContext -> ViewHelper to only re-initialize ViewHelpers
+        * when a context change occurs.
+        *
+        * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage
+        */
+       protected $viewHelpersByContext = NULL;
+
+       /**
+        * Constructor.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper $viewHelper The view helper
+        * @param array $arguments Arguments of view helper - each value is a RootNode.
+        */
+       public function __construct(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper $viewHelper, array $arguments) {
+               $this->uninitializedViewHelper = $viewHelper;
+               $this->viewHelpersByContext = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage');
+               $this->arguments = $arguments;
+               $this->viewHelperClassName = get_class($this->uninitializedViewHelper);
+       }
+
+       /**
+        * Returns the attached (but still uninitialized) ViewHelper for this ViewHelperNode.
+        * We need this method because sometimes Interceptors need to ask some information from the ViewHelper.
+        *
+        * @return \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper the attached ViewHelper, if it is initialized
+        */
+       public function getUninitializedViewHelper() {
+               return $this->uninitializedViewHelper;
+       }
+
+       /**
+        * Get class name of view helper
+        *
+        * @return string Class Name of associated view helper
+        */
+       public function getViewHelperClassName() {
+               return $this->viewHelperClassName;
+       }
+
+       /**
+        * INTERNAL - only needed for compiling templates
+        *
+        * @return array
+        * @internal
+        */
+       public function getArguments() {
+               return $this->arguments;
+       }
+
+       /**
+        * Call the view helper associated with this object.
+        *
+        * First, it evaluates the arguments of the view helper.
+        *
+        * 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.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return object evaluated node after the view helper has been called.
+        */
+       public function evaluate(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               if ($this->viewHelpersByContext->contains($renderingContext)) {
+                       $viewHelper = $this->viewHelpersByContext[$renderingContext];
+                       $viewHelper->resetState();
+               } else {
+                       $viewHelper = clone $this->uninitializedViewHelper;
+                       $this->viewHelpersByContext->attach($renderingContext, $viewHelper);
+               }
+
+               $evaluatedArguments = array();
+               if (count($viewHelper->prepareArguments())) {
+                       foreach ($viewHelper->prepareArguments() as $argumentName => $argumentDefinition) {
+                               if (isset($this->arguments[$argumentName])) {
+                                       $argumentValue = $this->arguments[$argumentName];
+                                       $evaluatedArguments[$argumentName] = $argumentValue->evaluate($renderingContext);
+                               } else {
+                                       $evaluatedArguments[$argumentName] = $argumentDefinition->getDefaultValue();
+                               }
+                       }
+               }
+
+               $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;
+       }
+
+       /**
+        * Clean up for serializing.
+        *
+        * @return array
+        */
+       public function __sleep() {
+               return array('viewHelperClassName', 'arguments', 'childNodes');
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Parser/TemplateParser.php b/typo3/sysext/fluid/Classes/Core/Parser/TemplateParser.php
new file mode 100644 (file)
index 0000000..0c7254c
--- /dev/null
@@ -0,0 +1,878 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Parser;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Template parser building up an object syntax tree
+ */
+class TemplateParser {
+
+       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';
+
+       /**
+        * The following two constants are used for tracking whether we are currently
+        * parsing ViewHelper arguments or not. This is used to parse arrays only as
+        * ViewHelper argument.
+        */
+       const CONTEXT_INSIDE_VIEWHELPER_ARGUMENTS = 1;
+       const CONTEXT_OUTSIDE_VIEWHELPER_ARGUMENTS = 2;
+
+       /**
+        * This regular expression splits the input string at all dynamic tags, AND
+        * on all <![CDATA[...]]> sections.
+        */
+       static public $SPLIT_PATTERN_TEMPLATE_DYNAMICTAGS = '/
+               (
+                       (?: <\\/?                                      # 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
+                                               =                                 # =
+                                               (?>                               # either... If we have found an argument, we will not back-track (That does the Atomic Bracket)
+                                                       "(?:\\\\"|[^"])*"              # a double-quoted string
+                                                       |\'(?:\\\\\'|[^\'])*\'        # or a single quoted string
+                                               )\\s*                              #
+                                       )*                                    # Tag arguments can be replaced many times.
+                               \\s*
+                               \\/?>                                      # Closing tag
+                       )
+                       |(?:                                          # Start match CDATA section
+                               <!\\[CDATA\\[.*?\\]\\]>
+                       )
+               )/xs';
+
+       /**
+        * This regular expression scans if the input string is a ViewHelper tag
+        */
+       static public $SCAN_PATTERN_TEMPLATE_VIEWHELPERTAG = '/
+               ^<                                                # A Tag begins with <
+               (?P<NamespaceIdentifier>NAMESPACE):               # Then comes the Namespace prefix followed by a :
+               (?P<MethodIdentifier>                             # Now comes the Name of the ViewHelper
+                       [a-zA-Z0-9\\.]+
+               )
+               (?P<Attributes>                                   # Begin Tag Attributes
+                       (?:                                           # A tag might have multiple attributes
+                               \\s*
+                               [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
+                                       |\'(?:\\\\\'|[^\'])*\'                # or a single quoted string
+                               )                                         #
+                               \\s*
+                       )*                                            # A tag might have multiple attributes
+               )                                                 # End Tag Attributes
+               \\s*
+               (?P<Selfclosing>\\/?)                              # A tag might be selfclosing
+               >$/x';
+
+       /**
+        * This regular expression scans if the input string is a closing ViewHelper
+        * tag.
+        */
+       static public $SCAN_PATTERN_TEMPLATE_CLOSINGVIEWHELPERTAG = '/^<\\/(?P<NamespaceIdentifier>NAMESPACE):(?P<MethodIdentifier>[a-zA-Z0-9\\.]+)\\s*>$/';
+
+       /**
+        * This regular expression splits the tag arguments into its parts
+        */
+       static public $SPLIT_PATTERN_TAGARGUMENTS = '/
+               (?:                                              #
+                       \\s*                                          #
+                       (?P<Argument>                                # The attribute name
+                               [a-zA-Z0-9:-]+                            #
+                       )                                            #
+                       =                                            # =
+                       (?>                                          # If we have found an argument, we will not back-track (That does the Atomic Bracket)
+                               (?P<ValueQuoted>                         # either...
+                                       (?:"(?:\\\\"|[^"])*")                 # a double-quoted string
+                                       |(?:\'(?:\\\\\'|[^\'])*\')           # or a single quoted string
+                               )
+                       )\\s*
+               )
+               /xs';
+
+       /**
+        * This pattern detects CDATA sections and outputs the text between opening
+        * and closing CDATA.
+        */
+       static public $SCAN_PATTERN_CDATA = '/^<!\\[CDATA\\[(.*?)\\]\\]>$/s';
+
+       /**
+        * Pattern which splits the shorthand syntax into different tokens. The
+        * "shorthand syntax" is everything like {...}
+        */
+       static public $SPLIT_PATTERN_SHORTHANDSYNTAX = '/
+               (
+                       {                                # Start of shorthand syntax
+                               (?:                          # Shorthand syntax is either composed of...
+                                       [a-zA-Z0-9\\->_:,.()]     # Various characters
+                                       |"(?:\\\\"|[^"])*"        # Double-quoted strings
+                                       |\'(?:\\\\\'|[^\'])*\'   # Single-quoted strings
+                                       |(?R)                    # Other shorthand syntaxes inside, albeit not in a quoted string
+                                       |\\s+                     # Spaces
+                               )+
+                       }                                # End of shorthand syntax
+               )/x';
+
+       /**
+        * Pattern which detects the object accessor syntax:
+        * {object.some.value}, additionally it detects ViewHelpers like
+        * {f:for(param1:bla)} and chaining like
+        * {object.some.value->f:bla.blubb()->f:bla.blubb2()}
+        *
+        * THIS IS ALMOST THE SAME AS IN $SCAN_PATTERN_SHORTHANDSYNTAX_ARRAYS
+        */
+       static public $SCAN_PATTERN_SHORTHANDSYNTAX_OBJECTACCESSORS = '/
+               ^{                                                      # Start of shorthand syntax
+                                                                       # A shorthand syntax is either...
+                       (?P<Object>[a-zA-Z0-9\\-_.]*)                                     # ... an object accessor
+                       \\s*(?P<Delimiter>(?:->)?)\\s*
+
+                       (?P<ViewHelper>                                 # ... a ViewHelper
+                               [a-zA-Z0-9]+                                # Namespace prefix of ViewHelper (as in $SCAN_PATTERN_TEMPLATE_VIEWHELPERTAG)
+                               :
+                               [a-zA-Z0-9\\.]+                             # Method Identifier (as in $SCAN_PATTERN_TEMPLATE_VIEWHELPERTAG)
+                               \\(                                          # Opening parameter brackets of ViewHelper
+                                       (?P<ViewHelperArguments>                # Start submatch for ViewHelper arguments. This is taken from $SCAN_PATTERN_SHORTHANDSYNTAX_ARRAYS
+                                               (?:
+                                                       \\s*[a-zA-Z0-9\\-_]+                  # The keys of the array
+                                                       \\s*:\\s*                             # Key|Value delimiter :
+                                                       (?:                                 # Possible value options:
+                                                               "(?:\\\\"|[^"])*"                # Double qouoted string
+                                                               |\'(?:\\\\\'|[^\'])*\'          # Single quoted string
+                                                               |[a-zA-Z0-9\\-_.]+               # variable identifiers
+                                                               |{(?P>ViewHelperArguments)}     # Another sub-array
+                                                       )                                   # END possible value options
+                                                       \\s*,?                               # There might be a , to separate different parts of the array
+                                               )*                                  # The above cycle is repeated for all array elements
+                                       )                                       # End ViewHelper Arguments submatch
+                               \\)                                          # Closing parameter brackets of ViewHelper
+                       )?
+                       (?P<AdditionalViewHelpers>                      # There can be more than one ViewHelper chained, by adding more -> and the ViewHelper (recursively)
+                               (?:
+                                       \\s*->\\s*
+                                       (?P>ViewHelper)
+                               )*
+                       )
+               }$/x';
+
+       /**
+        * THIS IS ALMOST THE SAME AS $SCAN_PATTERN_SHORTHANDSYNTAX_OBJECTACCESSORS
+        */
+       static public $SPLIT_PATTERN_SHORTHANDSYNTAX_VIEWHELPER = '/
+
+               (?P<NamespaceIdentifier>[a-zA-Z0-9]+)       # Namespace prefix of ViewHelper (as in $SCAN_PATTERN_TEMPLATE_VIEWHELPERTAG)
+               :
+               (?P<MethodIdentifier>[a-zA-Z0-9\\.]+)
+               \\(                                          # Opening parameter brackets of ViewHelper
+                       (?P<ViewHelperArguments>                # Start submatch for ViewHelper arguments. This is taken from $SCAN_PATTERN_SHORTHANDSYNTAX_ARRAYS
+                               (?:
+                                       \\s*[a-zA-Z0-9\\-_]+                  # The keys of the array
+                                       \\s*:\\s*                             # Key|Value delimiter :
+                                       (?:                                 # Possible value options:
+                                               "(?:\\\\"|[^"])*"                # Double qouoted string
+                                               |\'(?:\\\\\'|[^\'])*\'          # Single quoted string
+                                               |[a-zA-Z0-9\\-_.]+               # variable identifiers
+                                               |{(?P>ViewHelperArguments)}     # Another sub-array
+                                       )                                   # END possible value options
+                                       \\s*,?                               # There might be a , to separate different parts of the array
+                               )*                                  # The above cycle is repeated for all array elements
+                       )                                       # End ViewHelper Arguments submatch
+               \\)                                          # Closing parameter brackets of ViewHelper
+               /x';
+
+       /**
+        * Pattern which detects the array/object syntax like in JavaScript, so it
+        * detects strings like:
+        * {object: value, object2: {nested: array}, object3: "Some string"}
+        *
+        * THIS IS ALMOST THE SAME AS IN SCAN_PATTERN_SHORTHANDSYNTAX_OBJECTACCESSORS
+        */
+       static public $SCAN_PATTERN_SHORTHANDSYNTAX_ARRAYS = '/^
+               (?P<Recursion>                                  # Start the recursive part of the regular expression - describing the array syntax
+                       {                                           # Each array needs to start with {
+                               (?P<Array>                              # Start submatch
+                                       (?:
+                                               \\s*[a-zA-Z0-9\\-_]+              # The keys of the array
+                                               \\s*:\\s*                         # Key|Value delimiter :
+                                               (?:                             # Possible value options:
+                                                       "(?:\\\\"|[^"])*"            # Double qouoted string
+                                                       |\'(?:\\\\\'|[^\'])*\'      # Single quoted string
+                                                       |[a-zA-Z0-9\\-_.]+           # variable identifiers
+                                                       |(?P>Recursion)             # Another sub-array
+                                               )                               # END possible value options
+                                               \\s*,?                           # There might be a , to separate different parts of the array
+                                       )*                                  # The above cycle is repeated for all array elements
+                               )                                       # End array submatch
+                       }                                           # Each array ends with }
+               )$/x';
+
+       /**
+        * This pattern splits an array into its parts. It is quite similar to the
+        * pattern above.
+        */
+       static public $SPLIT_PATTERN_SHORTHANDSYNTAX_ARRAY_PARTS = '/
+               (?P<ArrayPart>                                             # Start submatch
+                       (?P<Key>[a-zA-Z0-9\\-_]+)                               # The keys of the array
+                       \\s*:\\s*                                                   # Key|Value delimiter :
+                       (?:                                                       # Possible value options:
+                               (?P<QuotedString>                                     # Quoted string
+                                       (?:"(?:\\\\"|[^"])*")
+                                       |(?:\'(?:\\\\\'|[^\'])*\')
+                               )
+                               |(?P<VariableIdentifier>[a-zA-Z][a-zA-Z0-9\\-_.]*)    # variable identifiers have to start with a letter
+                               |(?P<Number>[0-9.]+)                                  # Number
+                               |{\\s*(?P<Subarray>(?:(?P>ArrayPart)\\s*,?\\s*)+)\\s*}              # Another sub-array
+                       )                                                         # END possible value options
+               )                                                          # End array part submatch
+       /x';
+
+       /**
+        * 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(
+               'f' => 'TYPO3\\CMS\\Fluid\\ViewHelpers'
+       );
+
+       /**
+        * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
+        * @var \TYPO3\CMS\Fluid\Core\Parser\Configuration
+        */
+       protected $configuration;
+
+       /**
+        * @var array
+        */
+       protected $settings;
+
+       /**
+        * Constructor. Preprocesses the $SCAN_PATTERN_NAMESPACEDECLARATION by
+        * inserting the correct namespace separator.
+        */
+       public function __construct() {
+               self::$SCAN_PATTERN_NAMESPACEDECLARATION = str_replace('LEGACY_NAMESPACE_SEPARATOR', preg_quote(\TYPO3\CMS\Fluid\Fluid::LEGACY_NAMESPACE_SEPARATOR), self::$SCAN_PATTERN_NAMESPACEDECLARATION);
+               self::$SCAN_PATTERN_NAMESPACEDECLARATION = str_replace('FLUID_NAMESPACE_SEPARATOR', preg_quote(\TYPO3\CMS\Fluid\Fluid::NAMESPACE_SEPARATOR), self::$SCAN_PATTERN_NAMESPACEDECLARATION);
+       }
+
+       /**
+        * Injects Fluid settings
+        *
+        * @param array $settings
+        */
+       public function injectSettings(array $settings) {
+               $this->settings = $settings;
+       }
+
+       /**
+        * Inject object factory
+        *
+        * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
+        * @return void
+        */
+       public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
+        * Set the configuration for the parser.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\Configuration $configuration
+        * @return void
+        */
+       public function setConfiguration(\TYPO3\CMS\Fluid\Core\Parser\Configuration $configuration = NULL) {
+               $this->configuration = $configuration;
+       }
+
+       /**
+        * Parses a given template string and returns a parsed template object.
+        *
+        * The resulting ParsedTemplate can then be rendered by calling evaluate() on it.
+        *
+        * Normally, you should use a subclass of AbstractTemplateView instead of calling the
+        * TemplateParser directly.
+        *
+        * @param string $templateString The template to parse as a string
+        * @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, self::CONTEXT_OUTSIDE_VIEWHELPER_ARGUMENTS);
+
+               $variableContainer = $parsingState->getVariableContainer();
+               if ($variableContainer !== NULL && $variableContainer->exists('layoutName')) {
+                       $parsingState->setLayoutNameNode($variableContainer->get('layoutName'));
+               }
+
+               return $parsingState;
+       }
+
+       /**
+        * Gets the namespace definitions found.
+        *
+        * @return array Namespace identifiers and their component name prefix
+        */
+       public function getNamespaces() {
+               return $this->namespaces;
+       }
+
+       /**
+        * Resets the parser to its default values.
+        *
+        * @return void
+        */
+       protected function reset() {
+               $this->namespaces = array(
+                       'f' => 'TYPO3\\CMS\\Fluid\\ViewHelpers'
+               );
+       }
+
+       /**
+        * Extracts namespace definitions out of the given template string and sets
+        * $this->namespaces.
+        *
+        * @param string $templateString Template string to extract the namespaces from
+        * @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) {
+               $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;
+                               }
+                               $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;
+       }
+
+       /**
+        * Splits the template string on all dynamic tags found.
+        *
+        * @param string $templateString Template string to split.
+        * @return array Splitted template
+        */
+       protected function splitTemplateAtDynamicTags($templateString) {
+               $regularExpression = $this->prepareTemplateRegularExpression(self::$SPLIT_PATTERN_TEMPLATE_DYNAMICTAGS);
+               return preg_split($regularExpression, $templateString, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+       }
+
+       /**
+        * 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.
+        * @param integer $context one of the CONTEXT_* constants, defining whether we are inside or outside of ViewHelper arguments currently.
+        * @return \TYPO3\CMS\Fluid\Core\Parser\ParsingState
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
+        */
+       protected function buildObjectTree($splitTemplate, $context) {
+               $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));
+                       } elseif (preg_match($regularExpression_closingViewHelperTag, $templateElement, $matchedVariables) > 0) {
+                               $this->closingViewHelperTagHandler($state, $matchedVariables['NamespaceIdentifier'], $matchedVariables['MethodIdentifier']);
+                       } else {
+                               $this->textAndShorthandSyntaxHandler($state, $templateElement, $context);
+                       }
+               }
+
+               if ($state->countNodeStack() !== 1) {
+                       throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Not all tags were closed!', 1238169398);
+               }
+               return $state;
+       }
+
+       /**
+        * Handles an opening or self-closing view helper tag.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $state Current parsing state
+        * @param string $namespaceIdentifier Namespace identifier - being looked up in $this->namespaces
+        * @param string $methodIdentifier Method identifier
+        * @param string $arguments Arguments string, not yet parsed
+        * @param boolean $selfclosing true, if the tag is a self-closing tag.
+        * @return void
+        */
+       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);
+               }
+       }
+
+       /**
+        * Initialize the given ViewHelper and adds it to the current node and to
+        * the stack.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $state Current parsing state
+        * @param string $namespaceIdentifier Namespace identifier - being looked up in $this->namespaces
+        * @param string $methodIdentifier Method identifier
+        * @param array $argumentsObjectTree Arguments object tree
+        * @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)) {
+                       $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);
+       }
+
+       /**
+        * Throw an exception if there are arguments which were not registered
+        * before.
+        *
+        * @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
+        */
+       protected function abortIfUnregisteredArgumentsExist($expectedArguments, $actualArguments) {
+               $expectedArgumentNames = array();
+               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);
+                       }
+               }
+       }
+
+       /**
+        * Throw an exception if required arguments are missing
+        *
+        * @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
+        */
+       protected function abortIfRequiredArgumentsAreMissing($expectedArguments, $actualArguments) {
+               $actualArgumentNames = array_keys($actualArguments);
+               foreach ($expectedArguments as $expectedArgument) {
+                       if ($expectedArgument->isRequired() && !in_array($expectedArgument->getName(), $actualArgumentNames)) {
+                               throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Required argument "' . $expectedArgument->getName() . '" was not supplied.', 1237823699);
+                       }
+               }
+       }
+
+       /**
+        * Wraps the argument tree, if a node is boolean, into a Boolean syntax tree node
+        *
+        * @param array $argumentDefinitions the argument definitions, key is the argument name, value is the ArgumentDefinition object
+        * @param array $argumentsObjectTree the arguments syntax tree, key is the argument name, value is an AbstractNode
+        * @return void
+        */
+       protected function rewriteBooleanNodesInArgumentsObjectTree($argumentDefinitions, &$argumentsObjectTree) {
+               foreach ($argumentDefinitions as $argumentName => $argumentDefinition) {
+                       if ($argumentDefinition->getType() === 'boolean' && isset($argumentsObjectTree[$argumentName])) {
+                               $argumentsObjectTree[$argumentName] = new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\BooleanNode($argumentsObjectTree[$argumentName]);
+                       }
+               }
+       }
+
+       /**
+        * Resolve a viewhelper name.
+        *
+        * @param string $namespaceIdentifier Namespace identifier for the view helper.
+        * @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) {
+               $explodedViewHelperName = explode('.', $methodIdentifier);
+               $namespaceSeparator = strpos($this->namespaces[$namespaceIdentifier], \TYPO3\CMS\Fluid\Fluid::NAMESPACE_SEPARATOR) !== FALSE ? \TYPO3\CMS\Fluid\Fluid::NAMESPACE_SEPARATOR : \TYPO3\CMS\Fluid\Fluid::LEGACY_NAMESPACE_SEPARATOR;
+               if (count($explodedViewHelperName) > 1) {
+                       $className = implode($namespaceSeparator, array_map('ucfirst', $explodedViewHelperName));
+               } else {
+                       $className = ucfirst($explodedViewHelperName[0]);
+               }
+               $className .= 'ViewHelper';
+               $name = $this->namespaces[$namespaceIdentifier] . $namespaceSeparator . $className;
+               return $name;
+       }
+
+       /**
+        * Handles a closing view helper tag
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $state The current parsing state
+        * @param string $namespaceIdentifier Namespace identifier for the closing tag.
+        * @param string $methodIdentifier Method identifier.
+        * @return void
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
+        */
+       protected function closingViewHelperTagHandler(\TYPO3\CMS\Fluid\Core\Parser\ParsingState $state, $namespaceIdentifier, $methodIdentifier) {
+               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!', 1224256186);
+               }
+               $lastStackElement = $state->popNodeFromStack();
+               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)) {
+                       throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Templating tags not properly nested. Expected: ' . $lastStackElement->getViewHelperClassName() . '; Actual: ' . $this->resolveViewHelperName($namespaceIdentifier, $methodIdentifier), 1224485398);
+               }
+               $this->callInterceptor($lastStackElement, \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_CLOSING_VIEWHELPER, $state);
+       }
+
+       /**
+        * Handles the appearance of an object accessor (like {posts.author.email}).
+        * Creates a new instance of \TYPO3\CMS\Fluid\ObjectAccessorNode.
+        *
+        * Handles ViewHelpers as well which are in the shorthand syntax.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $state The current parsing state
+        * @param string $objectAccessorString String which identifies which objects to fetch
+        * @param string $delimiter
+        * @param string $viewHelperString
+        * @param string $additionalViewHelpersString
+        * @return void
+        */
+       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'])
+                                       );
+                               } else {
+                                       $arguments = array();
+                               }
+                               $this->initializeViewHelperAndAddItToStack($state, $singleMatch['NamespaceIdentifier'], $singleMatch['MethodIdentifier'], $arguments);
+                               $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++) {
+                       $node = $state->popNodeFromStack();
+                       $this->callInterceptor($node, \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_CLOSING_VIEWHELPER, $state);
+               }
+       }
+
+       /**
+        * 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 \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) {
+               if ($this->configuration !== NULL) {
+                       // $this->configuration is UNSET inside the arguments of a ViewHelper.
+                       // That's why the interceptors are only called if the object accesor is not inside a ViewHelper Argument
+                       // This could be a problem if We have a ViewHelper as an argument to another ViewHelper, and an ObjectAccessor nested inside there.
+                       // TODO: Clean up this.
+                       $interceptors = $this->configuration->getInterceptors($interceptionPoint);
+                       if (count($interceptors) > 0) {
+                               foreach ($interceptors as $interceptor) {
+                                       $node = $interceptor->process($node, $interceptionPoint, $state);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Post process the arguments for the ViewHelpers in the object accessor
+        * syntax. We need to convert an array into an array of (only) nodes
+        *
+        * @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)) {
+                               $arguments[$argumentName] = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\TextNode', (string) $argumentValue);
+                       }
+               }
+               return $arguments;
+       }
+
+       /**
+        * Parse arguments of a given tag, and build up the Arguments Object Tree
+        * for each argument.
+        * Returns an associative array, where the key is the name of the argument,
+        * and the value is a single Argument Object Tree.
+        *
+        * @param string $argumentsString All arguments as string
+        * @return array An associative array of objects, where the key is the argument name.
+        */
+       protected function parseArguments($argumentsString) {
+               $argumentsObjectTree = array();
+               $matches = array();
+               if (preg_match_all(self::$SPLIT_PATTERN_TAGARGUMENTS, $argumentsString, $matches, PREG_SET_ORDER) > 0) {
+                       $configurationBackup = $this->configuration;
+                       $this->configuration = NULL;
+                       foreach ($matches as $singleMatch) {
+                               $argument = $singleMatch['Argument'];
+                               $value = $this->unquoteString($singleMatch['ValueQuoted']);
+                               $argumentsObjectTree[$argument] = $this->buildArgumentObjectTree($value);
+                       }
+                       $this->configuration = $configurationBackup;
+               }
+               return $argumentsObjectTree;
+       }
+
+       /**
+        * Build up an argument object tree for the string in $argumentString.
+        * This builds up the tree for a single argument value.
+        *
+        * This method also does some performance optimizations, so in case
+        * no { or < is found, then we just return a TextNode.
+        *
+        * @param string $argumentString
+        * @return SyntaxTree\AbstractNode the corresponding argument object tree.
+        */
+       protected function buildArgumentObjectTree($argumentString) {
+               if (strpos($argumentString, '{') === FALSE && strpos($argumentString, '<') === FALSE) {
+                       return $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\TextNode', $argumentString);
+               }
+               $splitArgument = $this->splitTemplateAtDynamicTags($argumentString);
+               $rootNode = $this->buildObjectTree($splitArgument, self::CONTEXT_INSIDE_VIEWHELPER_ARGUMENTS)->getRootNode();
+               return $rootNode;
+       }
+
+       /**
+        * Removes escapings from a given argument string and trims the outermost
+        * quotes.
+        *
+        * This method is meant as a helper for regular expression results.
+        *
+        * @param string $quotedValue Value to unquote
+        * @return string Unquoted value
+        */
+       protected function unquoteString($quotedValue) {
+               switch ($quotedValue[0]) {
+                       case '"':
+                               $value = str_replace('\\"', '"', preg_replace('/(^"|"$)/', '', $quotedValue));
+                       break;
+                       case "'":
+                               $value = str_replace("\\'", "'", preg_replace('/(^\'|\'$)/', '', $quotedValue));
+                       break;
+                       default:
+                               $value = $quotedValue;
+               }
+               return str_replace('\\\\', '\\', $value);
+       }
+
+       /**
+        * Takes a regular expression template and replaces "NAMESPACE" with the
+        * currently registered namespace identifiers. Returns a regular expression
+        * which is ready to use.
+        *
+        * @param string $regularExpression Regular expression template
+        * @return string Regular expression ready to be used
+        */
+       protected function prepareTemplateRegularExpression($regularExpression) {
+               return str_replace('NAMESPACE', implode('|', array_keys($this->namespaces)), $regularExpression);
+       }
+
+       /**
+        * Handler for everything which is not a ViewHelperNode.
+        *
+        * This includes Text, array syntax, and object accessor syntax.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $state Current parsing state
+        * @param string $text Text to process
+        * @param integer $context one of the CONTEXT_* constants, defining whether we are inside or outside of ViewHelper arguments currently.
+        * @return void
+        */
+       protected function textAndShorthandSyntaxHandler(\TYPO3\CMS\Fluid\Core\Parser\ParsingState $state, $text, $context) {
+               $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'] : '');
+                       } elseif ($context === self::CONTEXT_INSIDE_VIEWHELPER_ARGUMENTS && preg_match(self::$SCAN_PATTERN_SHORTHANDSYNTAX_ARRAYS, $section, $matchedVariables) > 0) {
+                               // We only match arrays if we are INSIDE viewhelper arguments
+                               $this->arrayHandler($state, $matchedVariables['Array']);
+                       } else {
+                               $this->textHandler($state, $section);
+                       }
+               }
+       }
+
+       /**
+        * Handler for array syntax. This creates the array object recursively and
+        * adds it to the current node.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $state The current parsing state
+        * @param string $arrayText The array as string.
+        * @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))
+               );
+       }
+
+       /**
+        * Recursive function which takes the string representation of an array and
+        * builds an object tree from it.
+        *
+        * Deals with the following value types:
+        * - Numbers (Integers and Floats)
+        * - Strings
+        * - Variables
+        * - sub-arrays
+        *
+        * @param string $arrayText Array text
+        * @return SyntaxTree\ArrayNode the array node built up
+        * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception
+        */
+       protected function recursiveArrayHandler($arrayText) {
+               $matches = array();
+               if (preg_match_all(self::$SPLIT_PATTERN_SHORTHANDSYNTAX_ARRAY_PARTS, $arrayText, $matches, PREG_SET_ORDER) > 0) {
+                       $arrayToBuild = array();
+                       foreach ($matches as $singleMatch) {
+                               $arrayKey = $singleMatch['Key'];
+                               if (!empty($singleMatch['VariableIdentifier'])) {
+                                       $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']))) {
+                                       $argumentString = $this->unquoteString($singleMatch['QuotedString']);
+                                       $arrayToBuild[$arrayKey] = $this->buildArgumentObjectTree($argumentString);
+                               } elseif (array_key_exists('Subarray', $singleMatch) && !empty($singleMatch['Subarray'])) {
+                                       $arrayToBuild[$arrayKey] = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\SyntaxTree\\ArrayNode', $this->recursiveArrayHandler($singleMatch['Subarray']));
+                               } else {
+                                       throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('This exception should never be thrown, as the array value has to be of some type (Value given: "' . var_export($singleMatch, TRUE) . '"). Please post your template to the bugtracker at forge.typo3.org.', 1225136013);
+                               }
+                       }
+                       return $arrayToBuild;
+               } else {
+                       throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('This exception should never be thrown, there is most likely some error in the regular expressions. Please post your template to the bugtracker at forge.typo3.org.', 1225136013);
+               }
+       }
+
+       /**
+        * Text node handler
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $state
+        * @param string $text
+        * @return void
+        */
+       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);
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/Rendering/RenderingContext.php b/typo3/sysext/fluid/Classes/Core/Rendering/RenderingContext.php
new file mode 100644 (file)
index 0000000..d7872bc
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Rendering;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+class RenderingContext implements \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface {
+
+       /**
+        * Template Variable Container. Contains all variables available through object accessors in the template
+        *
+        * @var \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer
+        */
+       protected $templateVariableContainer;
+
+       /**
+        * Object manager which is bubbled through. The ViewHelperNode cannot get an ObjectManager injected because
+        * the whole syntax tree should be cacheable
+        *
+        * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
+        * Controller context being passed to the ViewHelper
+        *
+        * @var \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext
+        */
+       protected $controllerContext;
+
+       /**
+        * ViewHelper Variable Container
+        *
+        * @var \TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperVariableContainer
+        */
+       protected $viewHelperVariableContainer;
+
+       /**
+        * Inject the object manager
+        *
+        * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
+        */
+       public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
+        * Returns the object manager. Only the ViewHelperNode should do this.
+        *
+        * @return \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
+        */
+       public function getObjectManager() {
+               return $this->objectManager;
+       }
+
+       /**
+        * Injects the template variable container containing all variables available through ObjectAccessors
+        * in the template
+        *
+        * @param \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer $templateVariableContainer The template variable container to set
+        */
+       public function injectTemplateVariableContainer(\TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer $templateVariableContainer) {
+               $this->templateVariableContainer = $templateVariableContainer;
+       }
+
+       /**
+        * Get the template variable container
+        *
+        * @return \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer The Template Variable Container
+        */
+       public function getTemplateVariableContainer() {
+               return $this->templateVariableContainer;
+       }
+
+       /**
+        * Set the controller context which will be passed to the ViewHelper
+        *
+        * @param \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext The controller context to set
+        */
+       public function setControllerContext(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext) {
+               $this->controllerContext = $controllerContext;
+       }
+
+       /**
+        * Get the controller context which will be passed to the ViewHelper
+        *
+        * @return \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext The controller context to set
+        */
+       public function getControllerContext() {
+               return $this->controllerContext;
+       }
+
+       /**
+        * Set the ViewHelperVariableContainer
+        *
+        * @param \TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperVariableContainer $viewHelperVariableContainer
+        * @return void
+        */
+       public function injectViewHelperVariableContainer(\TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperVariableContainer $viewHelperVariableContainer) {
+               $this->viewHelperVariableContainer = $viewHelperVariableContainer;
+       }
+
+       /**
+        * Get the ViewHelperVariableContainer
+        *
+        * @return \TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperVariableContainer
+        */
+       public function getViewHelperVariableContainer() {
+               return $this->viewHelperVariableContainer;
+       }
+}
+
+?>
diff --git a/typo3/sysext/fluid/Classes/Core/Rendering/RenderingContextInterface.php b/typo3/sysext/fluid/Classes/Core/Rendering/RenderingContextInterface.php
new file mode 100644 (file)
index 0000000..e146172
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\Rendering;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+interface RenderingContextInterface {
+
+       /**
+        * Get the template variable container
+        *
+        * @return \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer The Template Variable Container
+        */
+       public function getTemplateVariableContainer();
+
+       /**
+        * Get the controller context which will be passed to the ViewHelper
+        *
+        * @return \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext The controller context to set
+        */
+       public function getControllerContext();
+
+       /**
+        * Get the ViewHelperVariableContainer
+        *
+        * @return \TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperVariableContainer
+        */
+       public function getViewHelperVariableContainer();
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractConditionViewHelper.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractConditionViewHelper.php
new file mode 100644 (file)
index 0000000..03ed306
--- /dev/null
@@ -0,0 +1,157 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * This view helper is an abstract ViewHelper which implements an if/else condition.
+ * @see TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode::convertArgumentValue() to find see how boolean arguments are evaluated
+ *
+ * = Usage =
+ *
+ * To create a custom Condition ViewHelper, you need to subclass this class, and
+ * implement your own render() method. Inside there, you should call $this->renderThenChild()
+ * if the condition evaluated to TRUE, and $this->renderElseChild() if the condition evaluated
+ * to FALSE.
+ *
+ * Every Condition ViewHelper has a "then" and "else" argument, so it can be used like:
+ * <[aConditionViewHelperName] .... then="condition true" else="condition false" />,
+ * or as well use the "then" and "else" child nodes.
+ *
+ * @see TYPO3\CMS\Fluid\ViewHelpers\IfViewHelper for a more detailed explanation and a simple usage example.
+ * Make sure to NOT OVERRIDE the constructor.
+ *
+ * @api
+ */
+abstract class AbstractConditionViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper implements \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface, \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface {
+
+       /**
+        * An array containing child nodes
+        *
+        * @var array<\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode>
+        */
+       private $childNodes = array();
+
+       /**
+        * Setter for ChildNodes - as defined in ChildNodeAccessInterface
+        *
+        * @param array $childNodes Child nodes of this syntax tree node
+        * @return void
+        */
+       public function setChildNodes(array $childNodes) {
+               $this->childNodes = $childNodes;
+       }
+
+       /**
+        * Initializes the "then" and "else" arguments
+        */
+       public function __construct() {
+               $this->registerArgument('then', 'mixed', 'Value to be returned if the condition if met.', FALSE);
+               $this->registerArgument('else', 'mixed', 'Value to be returned if the condition if not met.', FALSE);
+       }
+
+       /**
+        * Returns value of "then" attribute.
+        * If then attribute is not set, iterates through child nodes and renders ThenViewHelper.
+        * If then attribute is not set and no ThenViewHelper and no ElseViewHelper is found, all child nodes are rendered
+        *
+        * @return string rendered ThenViewHelper or contents of <f:if> if no ThenViewHelper was found
+        * @api
+        */
+       protected function renderThenChild() {
+               if ($this->hasArgument('then')) {
+                       return $this->arguments['then'];
+               }
+               if ($this->hasArgument('__thenClosure')) {
+                       $thenClosure = $this->arguments['__thenClosure'];
+                       return $thenClosure();
+               } elseif ($this->hasArgument('__elseClosure') || $this->hasArgument('else')) {
+                       return '';
+               }
+
+               $elseViewHelperEncountered = FALSE;
+               foreach ($this->childNodes as $childNode) {
+                       if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
+                               && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ThenViewHelper') {
+                               $data = $childNode->evaluate($this->renderingContext);
+                               return $data;
+                       }
+                       if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
+                               && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ElseViewHelper') {
+                               $elseViewHelperEncountered = TRUE;
+                       }
+               }
+
+               if ($elseViewHelperEncountered) {
+                       return '';
+               } else {
+                       return $this->renderChildren();
+               }
+       }
+
+       /**
+        * Returns value of "else" attribute.
+        * If else attribute is not set, iterates through child nodes and renders ElseViewHelper.
+        * If else attribute is not set and no ElseViewHelper is found, an empty string will be returned.
+        *
+        * @return string rendered ElseViewHelper or an empty string if no ThenViewHelper was found
+        * @api
+        */
+       protected function renderElseChild() {
+               if ($this->hasArgument('else')) {
+                       return $this->arguments['else'];
+               }
+               if ($this->hasArgument('__elseClosure')) {
+                       $elseClosure = $this->arguments['__elseClosure'];
+                       return $elseClosure();
+               }
+               foreach ($this->childNodes as $childNode) {
+                       if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
+                               && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ElseViewHelper') {
+                               return $childNode->evaluate($this->renderingContext);
+                       }
+               }
+
+               return '';
+       }
+
+       /**
+        * The compiled ViewHelper adds two new ViewHelper arguments: __thenClosure and __elseClosure.
+        * These contain closures which are be executed to render the then(), respectively else() case.
+        *
+        * @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
+        * @internal
+        */
+       public function compile($argumentsVariableName, $renderChildrenClosureVariableName, &$initializationPhpCode, \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode, \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler) {
+               foreach ($syntaxTreeNode->getChildNodes() as $childNode) {
+                       if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
+                               && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ThenViewHelper') {
+
+                               $childNodesAsClosure = $templateCompiler->wrapChildNodesInClosure($childNode);
+                               $initializationPhpCode .= sprintf('%s[\'__thenClosure\'] = %s;', $argumentsVariableName, $childNodesAsClosure) . chr(10);
+                       }
+                       if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
+                               && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ElseViewHelper') {
+
+                               $childNodesAsClosure = $templateCompiler->wrapChildNodesInClosure($childNode);
+                               $initializationPhpCode .= sprintf('%s[\'__elseClosure\'] = %s;', $argumentsVariableName, $childNodesAsClosure) . chr(10);
+                       }
+               }
+               return \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler::SHOULD_GENERATE_VIEWHELPER_INVOCATION;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractTagBasedViewHelper.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractTagBasedViewHelper.php
new file mode 100644 (file)
index 0000000..53b9901
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Tag based view helper.
+ * Sould be used as the base class for all view helpers which output simple tags, as it provides some
+ * convenience methods to register default attributes, ...
+ *
+ * @api
+ */
+abstract class AbstractTagBasedViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
+
+       /**
+        * Names of all registered tag attributes
+        *
+        * @var array
+        */
+       static private $tagAttributes = array();
+
+       /**
+        * Tag builder instance
+        *
+        * @var \TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder
+        * @api
+        */
+       protected $tag = NULL;
+
+       /**
+        * name of the tag to be created by this view helper
+        *
+        * @var string
+        * @api
+        */
+       protected $tagName = 'div';
+
+       /**
+        * Inject a TagBuilder
+        *
+        * @param \TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder $tagBuilder Tag builder
+        * @return void
+        */
+       public function injectTagBuilder(\TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder $tagBuilder) {
+               $this->tag = $tagBuilder;
+       }
+
+       /**
+        * Constructor
+        *
+        * @api
+        */
+       public function __construct() {
+               $this->registerArgument('additionalAttributes', 'array', 'Additional tag attributes. They will be added directly to the resulting HTML tag.', FALSE);
+       }
+
+       /**
+        * Sets the tag name to $this->tagName.
+        * Additionally, sets all tag attributes which were registered in
+        * $this->tagAttributes and additionalArguments.
+        *
+        * Will be invoked just before the render method.
+        *
+        * @return void
+        * @api
+        */
+       public function initialize() {
+               parent::initialize();
+               $this->tag->reset();
+               $this->tag->setTagName($this->tagName);
+               if ($this->hasArgument('additionalAttributes') && is_array($this->arguments['additionalAttributes'])) {
+                       $this->tag->addAttributes($this->arguments['additionalAttributes']);
+               }
+
+               if (isset(self::$tagAttributes[get_class($this)])) {
+                       foreach (self::$tagAttributes[get_class($this)] as $attributeName) {
+                               if ($this->hasArgument($attributeName) && $this->arguments[$attributeName] !== '') {
+                                       $this->tag->addAttribute($attributeName, $this->arguments[$attributeName]);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Register a new tag attribute. Tag attributes are all arguments which will be directly appended to a tag if you call $this->initializeTag()
+        *
+        * @param string $name Name of tag attribute
+        * @param string $type Type of the tag attribute
+        * @param string $description Description of tag attribute
+        * @param boolean $required set to TRUE if tag attribute is required. Defaults to FALSE.
+        * @param string $default Default value
+        * @return void
+        * @api
+        */
+       protected function registerTagAttribute($name, $type, $description, $required = FALSE, $default = NULL) {
+               $this->registerArgument($name, $type, $description, $required, $default);
+               self::$tagAttributes[get_class($this)][$name] = $name;
+       }
+
+       /**
+        * Registers all standard HTML universal attributes.
+        * Should be used inside registerArguments();
+        *
+        * @return void
+        * @api
+        */
+       protected function registerUniversalTagAttributes() {
+               $this->registerTagAttribute('class', 'string', 'CSS class(es) for this element');
+               $this->registerTagAttribute('dir', 'string', 'Text direction for this HTML element. Allowed strings: "ltr" (left to right), "rtl" (right to left)');
+               $this->registerTagAttribute('id', 'string', 'Unique (in this file) identifier for this HTML element.');
+               $this->registerTagAttribute('lang', 'string', 'Language for this element. Use short names specified in RFC 1766');
+               $this->registerTagAttribute('style', 'string', 'Individual CSS styles for this element');
+               $this->registerTagAttribute('title', 'string', 'Tooltip text of element');
+               $this->registerTagAttribute('accesskey', 'string', 'Keyboard shortcut to access this element');
+               $this->registerTagAttribute('tabindex', 'integer', 'Specifies the tab order of this element');
+               $this->registerTagAttribute('onclick', 'string', 'JavaScript evaluated for the onclick event');
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractViewHelper.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractViewHelper.php
new file mode 100644 (file)
index 0000000..f795093
--- /dev/null
@@ -0,0 +1,488 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * The abstract base class for all view helpers.
+ *
+ * @api
+ */
+abstract class AbstractViewHelper {
+
+       /**
+        * TRUE if arguments have already been initialized
+        *
+        * @var boolean
+        */
+       private $argumentsInitialized = FALSE;
+
+       /**
+        * Stores all \TYPO3\CMS\Fluid\ArgumentDefinition instances
+        *
+        * @var array
+        */
+       private $argumentDefinitions = array();
+
+       /**
+        * Cache of argument definitions; the key is the ViewHelper class name, and the
+        * value is the array of argument definitions.
+        *
+        * In our benchmarks, this cache leads to a 40% improvement when using a certain
+        * ViewHelper class many times throughout the rendering process.
+        *
+        * @var array
+        */
+       static private $argumentDefinitionCache = array();
+
+       /**
+        * Current view helper node
+        *
+        * @var \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
+        */
+       private $viewHelperNode;
+
+       /**
+        * Arguments array.
+        *
+        * @var array
+        * @api
+        */
+       protected $arguments;
+
+       /**
+        * Current variable container reference.
+        *
+        * @var \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer
+        * @api
+        */
+       protected $templateVariableContainer;
+
+       /**
+        * Controller Context to use
+        *
+        * @var \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext
+        * @api
+        */
+       protected $controllerContext;
+
+       /**
+        * @var \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface
+        */
+       protected $renderingContext;
+
+       /**
+        * @var \Closure
+        */
+       protected $renderChildrenClosure = NULL;
+
+       /**
+        * ViewHelper Variable Container
+        *
+        * @var \TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperVariableContainer
+        * @api
+        */
+       protected $viewHelperVariableContainer;
+
+       /**
+        * Reflection service
+        *
+        * @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
+        */
+       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
+        */
+       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
+        */
+       public function setArguments(array $arguments) {
+               $this->arguments = $arguments;
+       }
+
+       /**
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return void
+        */
+       public function setRenderingContext(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
+               $this->renderingContext = $renderingContext;
+               $this->templateVariableContainer = $renderingContext->getTemplateVariableContainer();
+               if ($renderingContext->getControllerContext() !== NULL) {
+                       $this->controllerContext = $renderingContext->getControllerContext();
+               }
+               $this->viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
+       }
+
+       /**
+        * Inject a Reflection service
+        *
+        * @param \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService Reflection service
+        */
+       public function injectReflectionService(\TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService) {
+               $this->reflectionService = $reflectionService;
+       }
+
+       /**
+        * Returns whether the escaping interceptor should be disabled or enabled inside the tags contents.
+        *
+        * THIS METHOD MIGHT CHANGE WITHOUT NOTICE; NO PUBLIC API!
+        *
+        * @return boolean
+        */
+       public function isEscapingInterceptorEnabled() {
+               return $this->escapingInterceptorEnabled;
+       }
+
+       /**
+        * Register a new argument. Call this method from your ViewHelper subclass
+        * inside the initializeArguments() method.
+        *
+        * @param string $name Name of the argument
+        * @param string $type Type of the argument
+        * @param string $description Description of the argument
+        * @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) {
+               if (array_key_exists($name, $this->argumentDefinitions)) {
+                       throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('Argument "' . $name . '" has already been defined, thus it should not be defined again.', 1253036401);
+               }
+               $this->argumentDefinitions[$name] = new \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition($name, $type, $description, $required, $defaultValue);
+               return $this;
+       }
+
+       /**
+        * Overrides a registered argument. Call this method from your ViewHelper subclass
+        * inside the initializeArguments() method if you want to override a previously registered argument.
+        *
+        * @see registerArgument()
+        * @param string $name Name of the argument
+        * @param string $type Type of the argument
+        * @param string $description Description of the argument
+        * @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) {
+               if (!array_key_exists($name, $this->argumentDefinitions)) {
+                       throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('Argument "' . $name . '" has not been defined, thus it can\'t be overridden.', 1279212461);
+               }
+               $this->argumentDefinitions[$name] = new \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition($name, $type, $description, $required, $defaultValue);
+               return $this;
+       }
+
+       /**
+        * Sets all needed attributes needed for the rendering. Called by the
+        * framework. Populates $this->viewHelperNode.
+        * This is PURELY INTERNAL! Never override this method!!
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode $node View Helper node to be set.
+        * @return void
+        */
+       public function setViewHelperNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode $node) {
+               $this->viewHelperNode = $node;
+       }
+
+       /**
+        * Called when being inside a cached template.
+        *
+        * @param \Closure $renderChildrenClosure
+        * @return void
+        */
+       public function setRenderChildrenClosure(\Closure $renderChildrenClosure) {
+               $this->renderChildrenClosure = $renderChildrenClosure;
+       }
+
+       /**
+        * Initialize the arguments of the ViewHelper, and call the render() method of the ViewHelper.
+        *
+        * @return string the rendered ViewHelper.
+        */
+       public function initializeArgumentsAndRender() {
+               $this->validateArguments();
+               $this->initialize();
+
+               return $this->callRenderMethod();
+       }
+
+       /**
+        * Call the render() method and handle errors.
+        *
+        * @return string the rendered ViewHelper
+        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
+        */
+       protected function callRenderMethod() {
+               $renderMethodParameters = array();
+               foreach ($this->argumentDefinitions as $argumentName => $argumentDefinition) {
+                       if ($argumentDefinition->isMethodParameter()) {
+                               $renderMethodParameters[$argumentName] = $this->arguments[$argumentName];
+                       }
+               }
+
+               try {
+                       return call_user_func_array(array($this, 'render'), $renderMethodParameters);
+               } catch (\TYPO3\CMS\Fluid\Core\ViewHelper\Exception $exception) {
+                       // @todo [BW] rethrow exception, log, ignore.. depending on the current context
+                       return $exception->getMessage();
+               }
+       }
+
+       /**
+        * Initializes the view helper before invoking the render method.
+        *
+        * Override this method to solve tasks before the view helper content is rendered.
+        *
+        * @return void
+        * @api
+        */
+       public function initialize() {
+       }
+
+       /**
+        * Helper method which triggers the rendering of everything between the
+        * opening and the closing tag.
+        *
+        * @return mixed The finally rendered child nodes.
+        * @api
+        */
+       public function renderChildren() {
+               if ($this->renderChildrenClosure !== NULL) {
+                       $closure = $this->renderChildrenClosure;
+                       return $closure();
+               }
+               return $this->viewHelperNode->evaluateChildNodes($this->renderingContext);
+       }
+
+       /**
+        * Helper which is mostly needed when calling renderStatic() from within
+        * render().
+        *
+        * No public API yet.
+        *
+        * @return \Closure
+        */
+       protected function buildRenderChildrenClosure() {
+               $self = $this;
+               return function () use ($self) {
+                       return $self->renderChildren();
+               };
+       }
+
+       /**
+        * Initialize all arguments and return them
+        *
+        * @return array Array of \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition instances.
+        */
+       public function prepareArguments() {
+               if (!$this->argumentsInitialized) {
+                       $thisClassName = get_class($this);
+                       if (isset(self::$argumentDefinitionCache[$thisClassName])) {
+                               $this->argumentDefinitions = self::$argumentDefinitionCache[$thisClassName];
+                       } else {
+                               $this->registerRenderMethodArguments();
+                               $this->initializeArguments();
+                               self::$argumentDefinitionCache[$thisClassName] = $this->argumentDefinitions;
+                       }
+                       $this->argumentsInitialized = TRUE;
+               }
+               return $this->argumentDefinitions;
+       }
+
+       /**
+        * 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;
+                       if (isset($parameterInfo['type'])) {
+                               $dataType = $parameterInfo['type'];
+                       } elseif ($parameterInfo['array']) {
+                               $dataType = 'array';
+                       }
+                       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]);
+                               array_shift($explodedAnnotation);
+                               array_shift($explodedAnnotation);
+                               $description = implode(' ', $explodedAnnotation);
+                       }
+                       $defaultValue = NULL;
+                       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);
+                       $i++;
+               }
+       }
+
+       /**
+        * Validate arguments, and throw exception if arguments do not validate.
+        *
+        * @return void
+        * @throws \InvalidArgumentException
+        */
+       public function validateArguments() {
+               $argumentDefinitions = $this->prepareArguments();
+               if (!count($argumentDefinitions)) {
+                       return;
+               }
+               foreach ($argumentDefinitions as $argumentName => $registeredArgument) {
+                       if ($this->hasArgument($argumentName)) {
+                               $type = $registeredArgument->getType();
+                               if ($this->arguments[$argumentName] === $registeredArgument->getDefaultValue()) {
+                                       continue;
+                               }
+                               if ($type === 'array') {
+                                       if (!is_array($this->arguments[$argumentName]) && !$this->arguments[$argumentName] instanceof \ArrayAccess && !$this->arguments[$argumentName] instanceof \Traversable) {
+                                               throw new \InvalidArgumentException('The argument "' . $argumentName . '" was registered with type "array", but is of type "' . gettype($this->arguments[$argumentName]) . '" in view helper "' . get_class($this) . '"', 1237900529);
+                                       }
+                               } elseif ($type === 'boolean') {
+                                       if (!is_bool($this->arguments[$argumentName])) {
+                                               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 (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 {
+                                                       throw new \InvalidArgumentException('The argument "' . $argumentName . '" was registered with type "' . $type . '", but is of type "' . gettype($this->arguments[$argumentName]) . '" in view helper "' . get_class($this) . '".', 1256475113);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Initialize all arguments. You need to override this method and call
+        * $this->registerArgument(...) inside this method, to register all your arguments.
+        *
+        * @return void
+        * @api
+        */
+       public function initializeArguments() {
+       }
+
+       /**
+        * Render method you need to implement for your custom view helper.
+        * Available objects at this point are $this->arguments, and $this->templateVariableContainer.
+        *
+        * Besides, you often need $this->renderChildren().
+        *
+        * @return string rendered string, view helper specific
+        * @api
+        */
+       //abstract public function render();
+
+       /**
+        * Tests if the given $argumentName is set, and not NULL.
+        *
+        * @param string $argumentName
+        * @return boolean TRUE if $argumentName is found, FALSE otherwise
+        * @api
+        */
+       protected function hasArgument($argumentName) {
+               return isset($this->arguments[$argumentName]) && $this->arguments[$argumentName] !== NULL;
+       }
+
+       /**
+        * Default implementation for CompilableInterface. By default,
+        * inserts a renderStatic() call to itself.
+        *
+        * You only should override this method *when you absolutely know what you
+        * are doing*, and really want to influence the generated PHP code during
+        * template compilation directly.
+        *
+        * @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
+        * @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);
+       }
+
+       /**
+        * Default implementation for CompilableInterface. See CompilableInterface
+        * for a detailed description of this method.
+        *
+        * @param array $arguments
+        * @param \Closure $renderChildrenClosure
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return mixed
+        * @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;
+       }
+
+       /**
+        * Resets the ViewHelper state.
+        *
+        * Overwrite this method if you need to get a clean state of your ViewHelper.
+        *
+        * @return void
+        */
+       public function resetState() {
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/ArgumentDefinition.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/ArgumentDefinition.php
new file mode 100644 (file)
index 0000000..909df9a
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Argument definition of each view helper argument
+ */
+class ArgumentDefinition {
+
+       /**
+        * Name of argument
+        *
+        * @var string
+        */
+       protected $name;
+
+       /**
+        * Type of argument
+        *
+        * @var string
+        */
+       protected $type;
+
+       /**
+        * Description of argument
+        *
+        * @var string
+        */
+       protected $description;
+
+       /**
+        * Is argument required?
+        *
+        * @var boolean
+        */
+       protected $required = FALSE;
+
+       /**
+        * Default value for argument
+        *
+        * @var mixed
+        */
+       protected $defaultValue = NULL;
+
+       /**
+        * TRUE if it is a method parameter
+        *
+        * @var boolean
+        */
+       protected $isMethodParameter = FALSE;
+
+       /**
+        * Constructor for this argument definition.
+        *
+        * @param string $name Name of argument
+        * @param string $type Type of argument
+        * @param string $description Description of argument
+        * @param boolean $required TRUE if argument is required
+        * @param mixed $defaultValue Default value
+        * @param boolean $isMethodParameter TRUE if this argument is a method parameter
+        */
+       public function __construct($name, $type, $description, $required, $defaultValue = NULL, $isMethodParameter = FALSE) {
+               $this->name = $name;
+               $this->type = $type;
+               $this->description = $description;
+               $this->required = $required;
+               $this->defaultValue = $defaultValue;
+               $this->isMethodParameter = $isMethodParameter;
+       }
+
+       /**
+        * Get the name of the argument
+        *
+        * @return string Name of argument
+        */
+       public function getName() {
+               return $this->name;
+       }
+
+       /**
+        * Get the type of the argument
+        *
+        * @return string Type of argument
+        */
+       public function getType() {
+               return $this->type;
+       }
+
+       /**
+        * Get the description of the argument
+        *
+        * @return string Description of argument
+        */
+       public function getDescription() {
+               return $this->description;
+       }
+
+       /**
+        * Get the optionality of the argument
+        *
+        * @return boolean TRUE if argument is optional
+        */
+       public function isRequired() {
+               return $this->required;
+       }
+
+       /**
+        * Get the default value, if set
+        *
+        * @return mixed Default value
+        */
+       public function getDefaultValue() {
+               return $this->defaultValue;
+       }
+
+       /**
+        * TRUE if it is a method parameter
+        *
+        * @return boolean TRUE if it's a method parameter
+        */
+       public function isMethodParameter() {
+               return $this->isMethodParameter;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/Arguments.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/Arguments.php
new file mode 100644 (file)
index 0000000..8642111
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper;
+
+/*                                                                        *
+ * 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.                *
+ *                                                                        *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+/**
+ * Arguments list. Wraps an array, but only allows read-only methods on it.
+ * Is available inside every view helper as $this->arguments - and you use it as if it was an array.
+ * However, you can only read, and not write to it.
+ *
+ * @api
+ */
+class Arguments implements \ArrayAccess {
+
+       /**
+        * Array storing the arguments themselves
+        */
+       protected $arguments = array();
+
+       /**
+        * Constructor.
+        *
+        * @param array $arguments Array of arguments
+        * @api
+        */
+       public function __construct(array $arguments) {
+               $this->arguments = $arguments;
+       }
+
+       /**
+        * Checks if a given key exists in the array
+        *
+        * @param string $key Key to check
+        * @return boolean true if exists
+        */
+       public function offsetExists($key) {
+               return array_key_exists($key, $this->arguments);
+       }
+
+       /**
+        * Returns the value to the given key.
+        *
+        * @param string $key Key to get.
+        * @return object associated value
+        */
+       public function offsetGet($key) {
+               if (!array_key_exists($key, $this->arguments)) {
+                       return NULL;
+               }
+               return $this->arguments[$key];
+       }
+
+       /**
+        * Throw exception if you try to set a value.
+        *
+        * @param string $key
+        * @param object $value
+        */
+       public function offsetSet($key, $value) {
+               throw new \TYPO3\CMS\Fluid\Core\Exception('Tried to set argument "' . $key . '", but setting arguments is forbidden.', 1236080693);
+       }
+
+       /**
+        * Throw exception if you try to unset a value.
+        *
+        * @param string $key
+        */
+       public function offsetUnset($key) {
+               throw new \TYPO3\CMS\Fluid\Core\Exception('Tried to unset argument "' . $key . '", but setting arguments is forbidden.', 1236080702);
+       }
+
+       /**
+        * Checks if an argument with the specified name exists
+        *
+        * @param string $argumentName Name of the argument to check for
+        * @return boolean TRUE if such an argument exists, otherwise FALSE
+        * @see offsetExists()
+        */
+       public function hasArgument($argumentName) {
+               return $this->offsetExists($argumentName) && $this->arguments[$argumentName] !== NULL;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/Exception.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/Exception.php
new file mode 100644 (file)
index 0000000..923a81d
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+/**
+ * A ViewHelper Exception
+ *
+ * @api
+ */
+class Exception extends \TYPO3\CMS\Fluid\Core\Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/Exception/InvalidVariableException.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/Exception/InvalidVariableException.php
new file mode 100644 (file)
index 0000000..54315d2
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+/**
+ * A "Invalid Variable" exception.
+ *
+ * @api
+ */
+class InvalidVariableException extends \TYPO3\CMS\Fluid\Core\ViewHelper\Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/Exception/RenderingContextNotAccessibleException.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/Exception/RenderingContextNotAccessibleException.php
new file mode 100644 (file)
index 0000000..0c20fcb
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+/**
+ * A "Rendering Context not Accessible" exception.
+ *
+ * @api
+ */
+class RenderingContextNotAccessibleException extends \TYPO3\CMS\Fluid\Core\ViewHelper\Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/Facets/ChildNodeAccessInterface.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/Facets/ChildNodeAccessInterface.php
new file mode 100644 (file)
index 0000000..fcaabce
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper\Facets;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Child Node Access Facet. View Helpers should implement this interface if they
+ * need access to the direct children in the Syntax Tree at rendering-time.
+ * This might happen if you only want to selectively render a part of the syntax
+ * tree depending on some conditions.
+ * To render subnodes, you can fetch the RenderingContext via $this->renderingContext.
+ *
+ * In most cases, you will not need this facet, and it is NO PUBLIC API!
+ * Right now it is only used internally for conditions, so by subclassing TYPO3\CMS\Fluid\Core\ViewHelpers\AbstractConditionViewHelper, this should be all you need.
+ *
+ * See \TYPO3\CMS\Fluid\ViewHelpers\IfViewHelper for an example how it is used.
+ */
+interface ChildNodeAccessInterface {
+       /**
+        * Sets the direct child nodes of the current syntax tree node.
+        *
+        * @param array<\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode> $childNodes
+        * @return void
+        */
+       public function setChildNodes(array $childNodes);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/Facets/CompilableInterface.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/Facets/CompilableInterface.php
new file mode 100644 (file)
index 0000000..fb51dda
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper\Facets;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * If a ViewHelper implements CompilableInterface, it can directly influence the way
+ * the syntax tree is compiled to a static PHP file.
+ *
+ * For now, this class is NO API.
+ *
+ * There a two ways of using the Compilable Interface.
+ *
+ * Implementing renderStatic()
+ * ===========================
+ * A ViewHelper which implements CompilableInterface and the renderStatic method
+ * is called *statically* through the renderStatic method; and no instance of the
+ * ViewHelper is created.
+ *
+ * This is a case which you can implement if you do not access any *internal state*
+ * in the ViewHelper. This means the following should be true:
+ *
+ * - you do not access $this->arguments, but only the function arguments of render()
+ * - you do not call $this->renderChildren()
+ *
+ * If you have performance problems because the calling overhead of a ViewHelper
+ * is too big, you should implement renderStatic().
+ *
+ * Implementing compile()
+ * ======================
+ *
+ * Some ViewHelpers want to directly manipulate the PHP code which is created in
+ * the compilation run. This is, however, only necessary in very special cases,
+ * like in the AbstractConditionViewHelper or when a ViewHelper is potentially
+ * called thousands of times.
+ *
+ * A ViewHelper which wants to directly influence the resulting PHP code must implement
+ * the CompilableInterface, and only implement the compile() method.
+ */
+interface CompilableInterface {
+
+       /**
+        * Here follows a more detailed description of the arguments of this function:
+        *
+        * $arguments contains a plain array of all arguments this ViewHelper has received,
+        * including the default argument values if an argument has not been specified
+        * in the ViewHelper invocation.
+        *
+        * $renderChildrenClosure is a closure you can execute instead of $this->renderChildren().
+        * It returns the rendered child nodes, so you can simply do $renderChildrenClosure() to execute
+        * it. It does not take any parameters.
+        *
+        * $renderingContext contains references to the TemplateVariableContainer, the
+        * ViewHelperVariableContainer and the ControllerContext.
+        *
+        * @param array $arguments
+        * @param \Closure $renderChildrenClosure
+        * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
+        * @return string the resulting string which is directly shown
+        */
+       static public function renderStatic(array $arguments, \Closure $renderChildrenClosure, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext);
+
+       /**
+        * This method is called on compilation time.
+        *
+        * It has to return a *single* PHP statement without semi-colon or newline
+        * at the end, which will be embedded at various places.
+        *
+        * Furthermore, it can append PHP code to the variable $initializationPhpCode.
+        * In this case, all statements have to end with semi-colon and newline.
+        *
+        * Outputting new variables
+        * ========================
+        * If you want create a new PHP variable, you need to use
+        * $templateCompiler->variableName('nameOfVariable') for this, as all variables
+        * need to be globally unique.
+        *
+        * Return Value
+        * ============
+        * Besides returning a single string, it can also return the constant
+        * \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler::SHOULD_GENERATE_VIEWHELPER_INVOCATION
+        * which means that after the $initializationPhpCode, the ViewHelper invocation
+        * is built as normal. This is especially needed if you want to build new arguments
+        * at run-time, as it is done for the AbstractConditionViewHelper.
+        *
+        * @param string $argumentsVariableName Name of the variable in which the ViewHelper arguments are stored
+        * @param string $renderChildrenClosureVariableName Name of the closure which can be executed to render the child nodes
+        * @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);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/Facets/PostParseInterface.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/Facets/PostParseInterface.php
new file mode 100644 (file)
index 0000000..64ddb7b
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper\Facets;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Post Parse Facet. Your view helper should implement this if you want a callback
+ * to be called directly after the syntax tree node corresponding to this view
+ * helper has been built.
+ *
+ * In the callback, it is possible to store some variables inside the
+ * parseVariableContainer (which is different from the runtime variable container!).
+ * This implicates that you usually have to adjust the \TYPO3\CMS\Fluid\View\TemplateView
+ * in case you implement this facet.
+ *
+ * Normally, this facet is not needed, except in really really rare cases.
+ */
+interface PostParseInterface {
+
+       /**
+        * Callback which is called directly after the corresponding syntax tree
+        * node to this view helper has been built.
+        * This is a parse-time callback, which does not change the rendering of a
+        * view helper.
+        *
+        * You can store some data inside the variableContainer given here, which
+        * can be used f.e. inside the TemplateView.
+        *
+        * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode $syntaxTreeNode The current node in the syntax tree corresponding to this view helper.
+        * @param array $viewHelperArguments View helper arguments as an array of SyntaxTrees. If you really need an argument, make sure to call $viewHelperArguments[$argName]->render(...)!
+        * @param \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer $variableContainer Variable container you can use to pass on some variables to the view.
+        * @return void
+        */
+       static public function postParseEvent(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode $syntaxTreeNode, array $viewHelperArguments, \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer $variableContainer);
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/TagBuilder.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/TagBuilder.php
new file mode 100644 (file)
index 0000000..3113ae4
--- /dev/null
@@ -0,0 +1,240 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * Tag builder. Can be easily accessed in AbstractTagBasedViewHelper
+ *
+ * @api
+ */
+class TagBuilder {
+
+       /**
+        * Name of the Tag to be rendered
+        *
+        * @var string
+        */
+       protected $tagName = '';
+
+       /**
+        * Content of the tag to be rendered
+        *
+        * @var string
+        */
+       protected $content = '';
+
+       /**
+        * Attributes of the tag to be rendered
+        *
+        * @var array
+        */
+       protected $attributes = array();
+
+       /**
+        * Specifies whether this tag needs a closing tag.
+        * E.g. <textarea> cant be self-closing even if its empty
+        *
+        * @var boolean
+        */
+       protected $forceClosingTag = FALSE;
+
+       /**
+        * Constructor
+        *
+        * @param string $tagName name of the tag to be rendered
+        * @param string $tagContent content of the tag to be rendered
+        * @api
+        */
+       public function __construct($tagName = '', $tagContent = '') {
+               $this->setTagName($tagName);
+               $this->setContent($tagContent);
+       }
+
+       /**
+        * Sets the tag name
+        *
+        * @param string $tagName name of the tag to be rendered
+        * @return void
+        * @api
+        */
+       public function setTagName($tagName) {
+               $this->tagName = $tagName;
+       }
+
+       /**
+        * Gets the tag name
+        *
+        * @return string tag name of the tag to be rendered
+        * @api
+        */
+       public function getTagName() {
+               return $this->tagName;
+       }
+
+       /**
+        * Sets the content of the tag
+        *
+        * @param string $tagContent content of the tag to be rendered
+        * @return void
+        * @api
+        */
+       public function setContent($tagContent) {
+               $this->content = $tagContent;
+       }
+
+       /**
+        * Gets the content of the tag
+        *
+        * @return string content of the tag to be rendered
+        * @api
+        */
+       public function getContent() {
+               return $this->content;
+       }
+
+       /**
+        * Returns TRUE if tag contains content, otherwise FALSE
+        *
+        * @return boolean TRUE if tag contains text, otherwise FALSE
+        * @api
+        */
+       public function hasContent() {
+               if ($this->content === NULL) {
+                       return FALSE;
+               }
+               return $this->content !== '';
+       }
+
+       /**
+        * Set this to TRUE to force a closing tag
+        * E.g. <textarea> cant be self-closing even if its empty
+        *
+        * @param boolean $forceClosingTag
+        * @api
+        */
+       public function forceClosingTag($forceClosingTag) {
+               $this->forceClosingTag = $forceClosingTag;
+       }
+
+       /**
+        * 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
+        * @param string $attributeValue attribute value
+        * @param boolean $escapeSpecialCharacters apply htmlspecialchars to attribute value
+        * @return void
+        * @api
+        */
+       public function addAttribute($attributeName, $attributeValue, $escapeSpecialCharacters = TRUE) {
+               if ($escapeSpecialCharacters) {
+                       $attributeValue = htmlspecialchars($attributeValue);
+               }
+               $this->attributes[$attributeName] = $attributeValue;
+       }
+
+       /**
+        * Adds attributes to the $attributes-collection
+        *
+        * @param array $attributes collection of attributes to add. key = attribute name, value = attribute value
+        * @param boolean $escapeSpecialCharacters apply htmlspecialchars to attribute values#
+        * @return void
+        * @api
+        */
+       public function addAttributes(array $attributes, $escapeSpecialCharacters = TRUE) {
+               foreach ($attributes as $attributeName => $attributeValue) {
+                       $this->addAttribute($attributeName, $attributeValue, $escapeSpecialCharacters);
+               }
+       }
+
+       /**
+        * Removes an attribute from the $attributes-collection
+        *
+        * @param string $attributeName name of the attribute to be removed from the tag
+        * @return void
+        * @api
+        */
+       public function removeAttribute($attributeName) {
+               unset($this->attributes[$attributeName]);
+       }
+
+       /**
+        * Resets the TagBuilder by setting all members to their default value
+        *
+        * @return void
+        * @api
+        */
+       public function reset() {
+               $this->tagName = '';
+               $this->content = '';
+               $this->attributes = array();
+               $this->forceClosingTag = FALSE;
+       }
+
+       /**
+        * Renders and returns the tag
+        *
+        * @return string
+        * @api
+        */
+       public function render() {
+               if (empty($this->tagName)) {
+                       return '';
+               }
+               $output = '<' . $this->tagName;
+               foreach ($this->attributes as $attributeName => $attributeValue) {
+                       $output .= ' ' . $attributeName . '="' . $attributeValue . '"';
+               }
+               if ($this->hasContent() || $this->forceClosingTag) {
+                       $output .= '>' . $this->content . '</' . $this->tagName . '>';
+               } else {
+                       $output .= ' />';
+               }
+               return $output;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/Core/ViewHelper/TemplateVariableContainer.php b/typo3/sysext/fluid/Classes/Core/ViewHelper/TemplateVariableContainer.php
new file mode 100644 (file)
index 0000000..dcdb09e
--- /dev/null
@@ -0,0 +1,187 @@
+<?php
+namespace TYPO3\CMS\Fluid\Core\ViewHelper;
+
+/*                                                                        *
+ * 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!                         *
+ *                                                                        */
+
+/**
+ * VariableContainer which stores template variables.
+ * Is used in two contexts:
+ *
+ * 1) Holds the current variables in the template
+ * 2) Holds variables being set during Parsing (set in view helpers implementing the PostParse facet)
+ *
+ * @api
+ */
+class TemplateVariableContainer implements \ArrayAccess {
+
+       /**
+        * List of reserved words that can't be used as variable identifiers in Fluid templates
+        *
+        * @var array
+        */
+       static protected $reservedVariableNames = array('true', 'false', 'on', 'off', 'yes', 'no', '_all');
+
+       /**
+        * Variables stored in context
+        *
+        * @var array
+        */
+       protected $variables = array();
+
+       /**
+        * Constructor. Can take an array, and initializes the variables with it.
+        *
+        * @param array $variableArray
+        * @api
+        */
+       public function __construct(array $variableArray = array()) {
+               $this->variables = $variableArray;
+       }
+
+       /**
+        * Add a variable to the context
+        *
+        * @param string $identifier Identifier of the variable to add
+        * @param mixed $value The variable's value
+        * @return void
+        * @throws Exception\InvalidVariableException
+        * @api
+        */
+       public function add($identifier, $value) {
+               if (array_key_exists($identifier, $this->variables)) {
+                       throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception\InvalidVariableException('Duplicate variable declaration, "' . $identifier . '" already set!', 1224479063);
+               }
+               if (in_array(strtolower($identifier), self::$reservedVariableNames)) {
+                       throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception\InvalidVariableException('"' . $identifier . '" is a reserved variable name and cannot be used as variable identifier.', 1256730379);
+               }
+               $this->variables[$identifier] = $value;
+       }
+
+       /**
+        * Get a variable from the context. Throws exception if variable is not found in context.
+        *
+        * If "_all" is given as identifier, all variables are returned in an array.
+        *
+        * @param string $identifier
+        * @return mixed The variable value identified by $identifier
+        * @throws Exception\InvalidVariableException
+        * @api
+        */
+       public function get($identifier) {
+               if ($identifier === '_all') {
+                       return $this->variables;
+               }
+               if (!array_key_exists($identifier, $this->variables)) {
+                       throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception\InvalidVariableException('Tried to get a variable "' . $identifier . '" which is not stored in the context!', 1224479370);
+               }
+               return $this->variables[$identifier];
+       }
+
+       /**
+        * Remove a variable from context. Throws exception if variable is not found in context.
+        *
+        * @param string $identifier The identifier to remove
+        * @return void
+        * @throws Exception\InvalidVariableException
+        * @api
+        */
+       public function remove($identifier) {</