[TASK] Reduce complexity in frontend functional tests 15/30515/5
authorOliver Hader <oliver@typo3.org>
Fri, 30 May 2014 15:56:06 +0000 (17:56 +0200)
committerOliver Hader <oliver.hader@typo3.org>
Thu, 12 Jun 2014 15:52:02 +0000 (17:52 +0200)
Testing the frontend behavior in functional tests creates
currently an own PHP sub-request to execute TypoScript in
frontent context.
Several hooks collect called cObjects and try to find the
correct nesting levels. Albeit this is working for the
current tests, it is way too complex for extending the
tests for further scenarios like for FAL and Extbase.

The hook magic is resolved and explicit render functions,
called via TypoScript, collect the data an output aggregated
JSON data in the end. Besides that the PHP sub-request
execution now re-uses the PHPUnit utilities to determine
and run the accordant executables.

Resolves: #59487
Releases: 6.2
Change-Id: Ic9eeadee5471a3e0e40d2dffb69b38dec16a0aa1
Reviewed-on: https://review.typo3.org/30515
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
13 files changed:
typo3/sysext/core/Tests/Functional/Fixtures/Frontend/AdditionalConfiguration.php
typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts
typo3/sysext/core/Tests/Functional/Fixtures/Frontend/request.tpl [new file with mode: 0644]
typo3/sysext/core/Tests/Functional/Framework/Frontend/Hook/ContentObjectRendererWatcher.php [deleted file]
typo3/sysext/core/Tests/Functional/Framework/Frontend/Hook/DatabaseConnectionWatcher.php [deleted file]
typo3/sysext/core/Tests/Functional/Framework/Frontend/RenderElement.php [deleted file]
typo3/sysext/core/Tests/Functional/Framework/Frontend/RenderLevel.php [deleted file]
typo3/sysext/core/Tests/Functional/Framework/Frontend/Renderer.php [new file with mode: 0644]
typo3/sysext/core/Tests/Functional/Framework/Frontend/RequestBootstrap.php
typo3/sysext/core/Tests/Functional/Framework/Scripts/Request.php [deleted file]
typo3/sysext/core/Tests/FunctionalTestCase.php
typo3/sysext/frontend/Classes/ContentObject/ContentContentObject.php
typo3/sysext/frontend/Classes/ContentObject/FilesContentObject.php

index d8319fb..80e0364 100644 (file)
@@ -14,13 +14,5 @@ $GLOBALS['TYPO3_CONF_VARS']['FE']['debug'] = FALSE;
 if (TYPO3_MODE === 'FE') {
        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser']['FunctionalTest'] =
                'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\BackendUserHandler->initialize';
-       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_db.php']['queryProcessors']['FunctionalTest'] =
-               'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\DatabaseConnectionWatcher';
-       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['cObjTypeAndClass']['FunctionalTest'] =
-               array('CONTENT', 'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\ContentObjectRendererWatcher');
-       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['postInit']['FunctionalTest'] =
-               'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\ContentObjectRendererWatcher';
-       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['isOutputting']['FunctionalTest'] =
-               'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\ContentObjectRendererWatcher->show';
 }
 ?>
\ No newline at end of file
index e89f117..d74e7c0 100644 (file)
@@ -8,50 +8,75 @@ config {
        sys_language_uid = 0
        sys_language_mode = ignore
        sys_language_overlay = 1
-#      additionalHeaders = Content-Type: application/json; charset=utf-8
-}
+       additionalHeaders = Content-Type: application/json; charset=utf-8
 
-watcher {
-       tableFields {
-               pages = uid,_ORIG_uid,pid,sorting,title
-               sys_category = uid,_ORIG_uid,_LOCALIZED_UID,pid,sys_language_uid,title,parent,items,sys_language_uid
-               tt_content = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,header,categories,tx_irretutorial_1nff_hotels
-               tx_irretutorial_1nff_hotel = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,offers
-               tx_irretutorial_1nff_offer = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,prices
-               tx_irretutorial_1nff_price = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,price
-               tx_irretutorial_1ncsv_hotel = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,offers
-               tx_irretutorial_1ncsv_offer = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,prices
-               tx_irretutorial_1ncsv_price = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,price
-               tx_testdatahandler_element = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title
+       watcher {
+               tableFields {
+                       pages = uid,_ORIG_uid,pid,sorting,title
+                       sys_category = uid,_ORIG_uid,_LOCALIZED_UID,pid,sys_language_uid,title,parent,items,sys_language_uid
+                       sys_file = uid,_ORIG_uid,_LOCALIZED_UID,pid,title,sys_language_uid
+                       sys_file_reference = uid,_ORIG_uid,_LOCALIZED_UID,title,description,alternative,link,downloadname,missing,identifier,file,pid,sys_language_uid,title,parent,items,sys_language_uid,uid_local,uid_foreign,tablenames,fieldname,table_local
+                       tt_content = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,header,categories,tx_irretutorial_1nff_hotels
+                       tx_irretutorial_1nff_hotel = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,offers
+                       tx_irretutorial_1nff_offer = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,prices
+                       tx_irretutorial_1nff_price = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,price
+                       tx_irretutorial_1ncsv_hotel = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,offers
+                       tx_irretutorial_1ncsv_offer = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,prices
+                       tx_irretutorial_1ncsv_price = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,price
+                       tx_testdatahandler_element = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title
+               }
        }
 }
 
+lib.watcherDataObject = COA
+lib.watcherDataObject {
+       1 = LOAD_REGISTER
+       1.watcher.dataWrap = |
+       2 = USER
+       2.userFunc = TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Renderer->addRecordData
+       99 = RESTORE_REGISTER
+}
+
+lib.watcherFileObject = COA
+lib.watcherFileObject {
+       1 = LOAD_REGISTER
+       1.watcher.dataWrap = |
+       2 = USER
+       2.userFunc = TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Renderer->addFileData
+       99 = RESTORE_REGISTER
+}
+
 page = PAGE
 page {
+       1 = LOAD_REGISTER
+       1.watcher.dataWrap = pages:{field:uid}
+       2 = USER
+       2.userFunc = TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Renderer->addRecordData
        10 = CONTENT
        10 {
-               watcher.parentRecordField = __pages
+               stdWrap.required = 1
                table = pages
                select {
                        orderBy = sorting
                        pidInList = this
                }
+               renderObj < lib.watcherDataObject
+               renderObj.1.watcher.dataWrap = {register:watcher}|.__pages/pages:{field:uid}
        }
        20 = CONTENT
        20 {
-               watcher.parentRecordField = __contents
                table = tt_content
                select {
                        orderBy = sorting
                        where = colPos=0
                        languageField = sys_language_uid
                }
-               renderObj = COA
+               renderObj < lib.watcherDataObject
+               renderObj.1.watcher.dataWrap = {register:watcher}|.__contents/tt_content:{field:uid}
                renderObj {
                        10 = CONTENT
                        10 {
                                if.isTrue.field = categories
-                               watcher.parentRecordField = categories
                                table = sys_category
                                select {
                                        pidInList = root,-1
@@ -63,11 +88,12 @@ page {
                                        orderBy = sys_category_record_mm.sorting_foreign
                                        languageField = sys_category.sys_language_uid
                                }
+                               renderObj < lib.watcherDataObject
+                               renderObj.1.watcher.dataWrap = {register:watcher}|.categories/sys_category:{field:uid}
                        }
                        20 = CONTENT
                        20 {
                                if.isTrue.field = tx_irretutorial_1nff_hotels
-                               watcher.parentRecordField = tx_irretutorial_1nff_hotels
                                table = tx_irretutorial_1nff_hotel
                                select {
                                        orderBy = sorting
@@ -76,37 +102,44 @@ page {
                                        where.wrap = parenttable="tt_content" AND parentid=|
                                        languageField = sys_language_uid
                                }
-                               renderObj = CONTENT
+                               renderObj < lib.watcherDataObject
+                               renderObj.1.watcher.dataWrap = {register:watcher}|.tx_irretutorial_1nff_hotels/tx_irretutorial_1nff_hotel:{field:uid}
                                renderObj {
-                                       if.isTrue.field = offers
-                                       watcher.parentRecordField = offers
-                                       table = tx_irretutorial_1nff_offer
-                                       select {
-                                               orderBy = sorting
-                                               where.field = uid
-                                               where.intval = 1
-                                               where.wrap = parenttable="tx_irretutorial_1nff_hotel" AND parentid=|
-                                               languageField = sys_language_uid
-                                       }
-                                       renderObj = CONTENT
-                                       renderObj {
-                                               if.isTrue.field = prices
-                                               watcher.parentRecordField = prices
-                                               table = tx_irretutorial_1nff_price
+                                       10 = CONTENT
+                                       10 {
+                                               if.isTrue.field = offers
+                                               table = tx_irretutorial_1nff_offer
                                                select {
                                                        orderBy = sorting
                                                        where.field = uid
                                                        where.intval = 1
-                                                       where.wrap = parenttable="tx_irretutorial_1nff_offer" AND parentid=|
+                                                       where.wrap = parenttable="tx_irretutorial_1nff_hotel" AND parentid=|
                                                        languageField = sys_language_uid
                                                }
+                                               renderObj < lib.watcherDataObject
+                                               renderObj.1.watcher.dataWrap = {register:watcher}|.offers/tx_irretutorial_1nff_offer:{field:uid}
+                                               renderObj {
+                                                       10 = CONTENT
+                                                       10 {
+                                                               if.isTrue.field = prices
+                                                               table = tx_irretutorial_1nff_price
+                                                               select {
+                                                                       orderBy = sorting
+                                                                       where.field = uid
+                                                                       where.intval = 1
+                                                                       where.wrap = parenttable="tx_irretutorial_1nff_offer" AND parentid=|
+                                                                       languageField = sys_language_uid
+                                                               }
+                                                               renderObj < lib.watcherDataObject
+                                                               renderObj.1.watcher.dataWrap = {register:watcher}|.prices/tx_irretutorial_1nff_price:{field:uid}
+                                                       }
+                                               }
                                        }
                                }
                        }
                        30 = CONTENT
                        30 {
                                if.isTrue.field = tx_irretutorial_1ncsv_hotels
-                               watcher.parentRecordField = tx_irretutorial_1ncsv_hotels
                                table = tx_irretutorial_1ncsv_hotel
                                select {
                                        uidInList.data = field:tx_irretutorial_1ncsv_hotels
@@ -114,35 +147,51 @@ page {
                                        # not including sys_language_uid lookup
                                        # languageField = sys_language_uid
                                }
-                               renderObj = CONTENT
+                               renderObj < lib.watcherDataObject
+                               renderObj.1.watcher.dataWrap = {register:watcher}|.tx_irretutorial_1ncsv_hotels/tx_irretutorial_1ncsv_hotel:{field:uid}
                                renderObj {
-                                       if.isTrue.field = offers
-                                       watcher.parentRecordField = offers
-                                       table = tx_irretutorial_1ncsv_offer
-                                       select {
-                                               uidInList.data = field:offers
-                                               orderBy = sorting
-                                               # not including sys_language_uid lookup
-                                               # languageField = sys_language_uid
-                                       }
-                                       renderObj = CONTENT
-                                       renderObj {
-                                               if.isTrue.field = prices
-                                               watcher.parentRecordField = prices
-                                               table = tx_irretutorial_1ncsv_price
+                                       10 = CONTENT
+                                       10 {
+                                               if.isTrue.field = offers
+                                               table = tx_irretutorial_1ncsv_offer
                                                select {
-                                                       uidInList.data = field:prices
+                                                       uidInList.data = field:offers
                                                        orderBy = sorting
                                                        # not including sys_language_uid lookup
                                                        # languageField = sys_language_uid
                                                }
+                                               renderObj < lib.watcherDataObject
+                                               renderObj.1.watcher.dataWrap = {register:watcher}|.offers/tx_irretutorial_1ncsv_offer:{field:uid}
+                                               renderObj {
+                                                       10 = CONTENT
+                                                       10 {
+                                                               if.isTrue.field = prices
+                                                               table = tx_irretutorial_1ncsv_price
+                                                               select {
+                                                                       uidInList.data = field:prices
+                                                                       orderBy = sorting
+                                                                       # not including sys_language_uid lookup
+                                                                       # languageField = sys_language_uid
+                                                               }
+                                                               renderObj < lib.watcherDataObject
+                                                               renderObj.1.watcher.dataWrap = {register:watcher}|.prices/tx_irretutorial_1ncsv_price:{field:uid}
+                                                       }
+                                               }
                                        }
                                }
                        }
+                       40 = FILES
+                       40 {
+                               if.isTrue.field = image
+                               references {
+                                       fieldName = image
+                               }
+                               renderObj < lib.watcherFileObject
+                               renderObj.1.watcher.dataWrap = {register:watcher}|.image/
+                       }
                        50 = CONTENT
                        50 {
                                if.isTrue.field = tx_testdatahandler_select
-                               watcher.parentRecordField = tx_testdatahandler_select
                                table = tx_testdatahandler_element
                                select {
                                        uidInList.data = field:tx_testdatahandler_select
@@ -151,11 +200,12 @@ page {
                                        # not including sys_language_uid lookup
                                        # languageField = sys_language_uid
                                }
+                               renderObj < lib.watcherDataObject
+                               renderObj.1.watcher.dataWrap = {register:watcher}|.tx_testdatahandler_select/tx_testdatahandler_element:{field:uid}
                        }
                        60 = CONTENT
                        60 {
                                if.isTrue.field = tx_testdatahandler_group
-                               watcher.parentRecordField = tx_testdatahandler_group
                                table = tx_testdatahandler_element
                                select {
                                        uidInList.data = field:tx_testdatahandler_group
@@ -164,9 +214,12 @@ page {
                                        # not including sys_language_uid lookup
                                        # languageField = sys_language_uid
                                }
+                               renderObj < lib.watcherDataObject
+                               renderObj.1.watcher.dataWrap = {register:watcher}|.tx_testdatahandler_group/tx_testdatahandler_element:{field:uid}
                        }
                }
        }
+       stdWrap.postUserFunc = TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Renderer->render
 }
 
 [globalVar = GP:L = 1]
diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/request.tpl b/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/request.tpl
new file mode 100644 (file)
index 0000000..56feed1
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+require '{originalRoot}typo3/sysext/core/Classes/Core/CliBootstrap.php';
+\TYPO3\CMS\Core\Core\CliBootstrap::checkEnvironmentOrDie();
+
+require '{originalRoot}typo3/sysext/core/Tests/Functional/Framework/Frontend/RequestBootstrap.php';
+\TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\RequestBootstrap::setGlobalVariables({arguments});
+\TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\RequestBootstrap::executeAndOutput();
+?>
\ No newline at end of file
diff --git a/typo3/sysext/core/Tests/Functional/Framework/Frontend/Hook/ContentObjectRendererWatcher.php b/typo3/sysext/core/Tests/Functional/Framework/Frontend/Hook/ContentObjectRendererWatcher.php
deleted file mode 100644 (file)
index 9f2ab17..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-<?php
-namespace TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Hook;
-
-/***************************************************************
- * Copyright notice
- *
- * (c) 2014 Oliver Hader <oliver.hader@typo3.org>
- * All rights reserved
- *
- * This script is part of the TYPO3 project. The TYPO3 project is
- * free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The GNU General Public License can be found at
- * http://www.gnu.org/copyleft/gpl.html.
- *
- * This script is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-use TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\RenderLevel;
-use TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\RenderElement;
-
-/**
- * Watcher for the content object rendering process
- */
-class ContentObjectRendererWatcher implements \TYPO3\CMS\Frontend\ContentObject\ContentObjectPostInitHookInterface, \TYPO3\CMS\Core\SingletonInterface {
-
-       /**
-        * @var RenderLevel
-        */
-       protected $renderLevel;
-
-       /**
-        * @var RenderElement
-        */
-       protected $nextParentRenderElement;
-
-       /**
-        * @var array
-        */
-       protected $nextParentConfiguration;
-
-       /**
-        * Holds parent objects (cObj) locally
-        * to avoid spl_object_hash() reassignments.
-        *
-        * @var array
-        */
-       protected $localParentObjects = array();
-
-       /**
-        * @param string $name
-        * @param NULL|array $configuration
-        * @param string $typoScriptKey
-        * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $parentObject
-        * @return string
-        */
-       public function cObjGetSingleExt($name, $configuration, $typoScriptKey, \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $parentObject) {
-               $this->localParentObjects[] = $parentObject;
-               $this->nextParentRenderElement = NULL;
-               $this->nextParentConfiguration = NULL;
-
-               if (($foundRenderElement = $this->renderLevel->findRenderElement($parentObject)) !== NULL) {
-                       $this->nextParentRenderElement = $foundRenderElement;
-                       $this->nextParentConfiguration = $configuration;
-                       if (!empty($configuration['table'])) {
-                               $this->nextParentRenderElement->addExpectedTableName($configuration['table']);
-                       }
-               }
-
-               if (!empty($configuration['if.']) && !$parentObject->checkIf($configuration['if.'])) {
-                       return '';
-               }
-
-               $contentObject = $parentObject->getContentObject($name);
-               if ($contentObject) {
-                       $contentObject->render($configuration);
-               }
-
-               return '';
-       }
-
-       /**
-        * Hook for post processing the initialization of ContentObjectRenderer
-        *
-        * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $parentObject Parent content object
-        */
-       public function postProcessContentObjectInitialization(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer &$parentObject) {
-               $this->localParentObjects[] = $parentObject;
-
-               if (!isset($this->renderLevel)) {
-                       $this->renderLevel = RenderLevel::create($parentObject);
-                       $this->renderLevel->add($parentObject);
-               } elseif (($foundRenderLevel = $this->renderLevel->findRenderLevel($parentObject)) !== NULL) {
-                       $foundRenderLevel->add($parentObject);
-               } elseif ($this->nextParentRenderElement !== NULL) {
-                       $level = $this->nextParentRenderElement->add($parentObject);
-                       $level->add($parentObject);
-                       if (!empty($this->nextParentConfiguration['watcher.']['parentRecordField'])) {
-                               $level->setParentRecordField($this->nextParentConfiguration['watcher.']['parentRecordField']);
-                       }
-                       $this->nextParentRenderElement = NULL;
-                       $this->nextParentConfiguration = NULL;
-               }
-       }
-
-       /**
-        * @param string $query
-        * @param string $fromTable
-        */
-       public function addQuery($query, $fromTable) {
-               if ($this->nextParentRenderElement === NULL) {
-                       return;
-               }
-
-               $this->nextParentRenderElement->addQuery($query, $fromTable);
-       }
-
-       /**
-        * @param array $parameters
-        * @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $frontendController
-        */
-       public function show(array $parameters, \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $frontendController) {
-               if (!isset($this->renderLevel) || empty($parameters['enableOutput']) || !empty($frontendController->content)) {
-                       return;
-               }
-
-               $tableFields = NULL;
-               if (!empty($this->getFrontendController()->tmpl->setup['watcher.']['tableFields.'])) {
-                       $tableFields = $this->getFrontendController()->tmpl->setup['watcher.']['tableFields.'];
-                       foreach ($tableFields as &$fieldList) {
-                               $fieldList = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $fieldList, TRUE);
-                       }
-                       unset($fieldList);
-               }
-
-               $structureData = $this->renderLevel->structureData($tableFields);
-
-               $result = array(
-                       'structure' => $structureData,
-                       'structurePaths' => $this->getStructurePaths($structureData),
-                       'records' => $this->renderLevel->mergeData($tableFields),
-                       'queries' => $this->renderLevel->mergeQueries(),
-               );
-
-               $frontendController->content = json_encode($result);
-       }
-
-       /**
-        * @param array $structureData
-        * @param array $currentStructurePaths
-        * @return array
-        */
-       protected function getStructurePaths(array $structureData, array $currentStructurePaths = array()) {
-               $structurePaths = array();
-
-               foreach ($structureData as $recordIdentifier => $recordData) {
-                       $structurePaths[$recordIdentifier][] = $currentStructurePaths;
-                       foreach ($recordData as $fieldName => $fieldValue) {
-                               if (!is_array($fieldValue)) {
-                                       continue;
-                               }
-
-                               $nestedStructurePaths = $this->getStructurePaths(
-                                       $fieldValue,
-                                       array_merge($currentStructurePaths, array($recordIdentifier, $fieldName))
-                               );
-
-                               foreach ($nestedStructurePaths as $nestedRecordIdentifier => $nestedStructurePathDetails) {
-                                       $structurePaths[$nestedRecordIdentifier] = array_merge(
-                                                       (array)$structurePaths[$nestedRecordIdentifier],
-                                               $nestedStructurePathDetails
-                                       );
-                               }
-                       }
-               }
-
-               return $structurePaths;
-       }
-
-       /**
-        * @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
-        */
-       protected function getFrontendController() {
-               return $GLOBALS['TSFE'];
-       }
-
-}
diff --git a/typo3/sysext/core/Tests/Functional/Framework/Frontend/Hook/DatabaseConnectionWatcher.php b/typo3/sysext/core/Tests/Functional/Framework/Frontend/Hook/DatabaseConnectionWatcher.php
deleted file mode 100644 (file)
index 02f0d7f..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-<?php
-namespace TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Hook;
-
-/***************************************************************
- * Copyright notice
- *
- * (c) 2014 Oliver Hader <oliver.hader@typo3.org>
- * All rights reserved
- *
- * This script is part of the TYPO3 project. The TYPO3 project is
- * free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The GNU General Public License can be found at
- * http://www.gnu.org/copyleft/gpl.html.
- *
- * This script is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-/**
- * Watcher for executed database queries
- */
-class DatabaseConnectionWatcher implements \TYPO3\CMS\Core\Database\PostProcessQueryHookInterface, \TYPO3\CMS\Core\SingletonInterface {
-
-       /**
-        * @var array
-        */
-       protected $queries = array();
-
-       /**
-        * Constructs this object and ensures that full database
-        * queries are stored locally in the DatabaseConnection.
-        */
-       public function __construct() {
-               $this->getDatabaseConnection()->store_lastBuiltQuery = TRUE;
-       }
-
-       public function getQueries() {
-               return $this->queries;
-       }
-
-       /**
-        * Post-processor for the SELECTquery method.
-        *
-        * @param string $select_fields Fields to be selected
-        * @param string $from_table Table to select data from
-        * @param string $where_clause Where clause
-        * @param string $groupBy Group by statement
-        * @param string $orderBy Order by statement
-        * @param integer $limit Database return limit
-        * @param \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject
-        * @return void
-        */
-       public function exec_SELECTquery_postProcessAction(&$select_fields, &$from_table, &$where_clause, &$groupBy, &$orderBy, &$limit, \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject) {
-               $this->getContentObjectRendererWatcher()->addQuery(
-                       $parentObject->debug_lastBuiltQuery,
-                       $from_table
-               );
-       }
-
-       /**
-        * Post-processor for the exec_INSERTquery method.
-        *
-        * @param string $table Database table name
-        * @param array $fieldsValues Field values as key => value pairs
-        * @param string /array $noQuoteFields List/array of keys NOT to quote
-        * @param \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject
-        * @return void
-        */
-       public function exec_INSERTquery_postProcessAction(&$table, array &$fieldsValues, &$noQuoteFields, \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject) {
-       }
-
-       /**
-        * Post-processor for the exec_INSERTmultipleRows method.
-        *
-        * @param string $table Database table name
-        * @param array $fields Field names
-        * @param array $rows Table rows
-        * @param string /array $noQuoteFields List/array of keys NOT to quote
-        * @param \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject
-        * @return void
-        */
-       public function exec_INSERTmultipleRows_postProcessAction(&$table, array &$fields, array &$rows, &$noQuoteFields, \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject) {
-       }
-
-       /**
-        * Post-processor for the exec_UPDATEquery method.
-        *
-        * @param string $table Database table name
-        * @param string $where WHERE clause
-        * @param array $fieldsValues Field values as key => value pairs
-        * @param string /array $noQuoteFields List/array of keys NOT to quote
-        * @param \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject
-        * @return void
-        */
-       public function exec_UPDATEquery_postProcessAction(&$table, &$where, array &$fieldsValues, &$noQuoteFields, \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject) {
-       }
-
-       /**
-        * Post-processor for the exec_DELETEquery method.
-        *
-        * @param string $table Database table name
-        * @param string $where WHERE clause
-        * @param \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject
-        * @return void
-        */
-       public function exec_DELETEquery_postProcessAction(&$table, &$where, \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject) {
-       }
-
-       /**
-        * Post-processor for the exec_TRUNCATEquery method.
-        *
-        * @param string $table Database table name
-        * @param \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject
-        * @return void
-        */
-       public function exec_TRUNCATEquery_postProcessAction(&$table, \TYPO3\CMS\Core\Database\DatabaseConnection $parentObject) {
-       }
-
-       /**
-        * @return ContentObjectRendererWatcher
-        */
-       protected function getContentObjectRendererWatcher() {
-               return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
-                       'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\ContentObjectRendererWatcher'
-               );
-       }
-
-       /**
-        * @return \TYPO3\CMS\Core\Database\DatabaseConnection
-        */
-       protected function getDatabaseConnection() {
-               return $GLOBALS['TYPO3_DB'];
-       }
-
-}
diff --git a/typo3/sysext/core/Tests/Functional/Framework/Frontend/RenderElement.php b/typo3/sysext/core/Tests/Functional/Framework/Frontend/RenderElement.php
deleted file mode 100644 (file)
index ec37466..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-<?php
-namespace TYPO3\CMS\Core\Tests\Functional\Framework\Frontend;
-
-/***************************************************************
- * Copyright notice
- *
- * (c) 2014 Oliver Hader <oliver.hader@typo3.org>
- * All rights reserved
- *
- * This script is part of the TYPO3 project. The TYPO3 project is
- * free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The GNU General Public License can be found at
- * http://www.gnu.org/copyleft/gpl.html.
- *
- * This script is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-use \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
-
-/**
- * Model of rendered content elements
- */
-class RenderElement {
-
-       /**
-        * @var array
-        */
-       protected $recordData;
-
-       /**
-        * @var string
-        */
-       protected $recordIdentifier;
-
-       /**
-        * @var string
-        */
-       protected $recordTableName;
-
-       /**
-        * @var array|RenderLevel[]
-        */
-       protected $levels = array();
-
-       /**
-        * @var array
-        */
-       protected $expectedTableNames = array();
-
-       /**
-        * @var array
-        */
-       protected $queries = array();
-
-       /**
-        * @param ContentObjectRenderer $contentObjectRenderer
-        * @return RenderElement
-        */
-       public static function create(ContentObjectRenderer $contentObjectRenderer) {
-               return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
-                       'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\RenderElement',
-                       $contentObjectRenderer
-               );
-       }
-
-       /**
-        * @param ContentObjectRenderer $contentObjectRenderer
-        */
-       public function __construct(ContentObjectRenderer $contentObjectRenderer) {
-               $this->recordIdentifier = $contentObjectRenderer->currentRecord;
-               list($this->recordTableName) = explode(':', $this->recordIdentifier);
-               $this->recordData = $contentObjectRenderer->data;
-       }
-
-       /**
-        * @param ContentObjectRenderer $contentObjectRenderer
-        * @return RenderLevel
-        */
-       public function add(ContentObjectRenderer $contentObjectRenderer) {
-               $level = RenderLevel::create($contentObjectRenderer);
-               $level->setParentRecordIdentifier($this->recordIdentifier);
-               $this->levels[] = $level;
-               return $level;
-       }
-
-       /**
-        * @return string
-        */
-       public function getRecordIdentifier() {
-               return $this->recordIdentifier;
-       }
-
-       /**
-        * @param string $expectedTableName
-        */
-       public function addExpectedTableName($expectedTableName) {
-               if (!$this->hasExpectedTableName($expectedTableName)) {
-                       $this->expectedTableNames[] = $expectedTableName;
-               }
-       }
-
-       /**
-        * @param string $tableName
-        * @return bool
-        */
-       public function hasExpectedTableName($tableName) {
-               if (in_array($tableName, $this->expectedTableNames)) {
-                       return TRUE;
-               }
-               // Handling JOIN constructions
-               // e.g. "sys_category JOIN sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid"
-               foreach ($this->getExpectedTableNames() as $expectedTableName) {
-                       if (strpos($tableName, $expectedTableName . ' ') === 0) {
-                               return TRUE;
-                       }
-               }
-               return FALSE;
-       }
-
-       /**
-        * @return array
-        */
-       public function getExpectedTableNames() {
-               return $this->expectedTableNames;
-       }
-
-       /**
-        * @param string $query
-        * @param string $fromTable
-        */
-       public function addQuery($query, $fromTable) {
-               if (empty($this->expectedTableNames) || $this->hasExpectedTableName($fromTable)) {
-                       $this->queries[] = $query;
-               }
-       }
-
-       /**
-        * @param ContentObjectRenderer $contentObjectRenderer
-        * @return NULL|RenderLevel
-        */
-       public function findRenderLevel(ContentObjectRenderer $contentObjectRenderer) {
-               if (empty($this->levels)) {
-                       return NULL;
-               }
-
-               foreach ($this->levels as $level) {
-                       $result = $level->findRenderLevel($contentObjectRenderer);
-                       if ($result !== NULL) {
-                               return $result;
-                       }
-               }
-
-               return NULL;
-       }
-
-       /**
-        * @param NULL|array $tableFields
-        * @return array
-        */
-       public function getRecordData(array $tableFields = NULL) {
-               $recordData = $this->recordData;
-
-               if (!empty($tableFields[$this->recordTableName])) {
-                       $recordData = array_intersect_key(
-                               $recordData,
-                               array_flip($tableFields[$this->recordTableName])
-                       );
-               }
-
-               return $recordData;
-       }
-
-       /**
-        * @param NULL|array $tableFields
-        * @return array
-        */
-       public function structureData(array $tableFields = NULL) {
-               $data = array(
-                       $this->recordIdentifier => $this->getRecordData($tableFields)
-               );
-
-               foreach ($this->levels as $level) {
-                       $parentRecordIdentifier = $level->getParentRecordIdentifier();
-                       $parentRecordField = $level->getParentRecordField();
-
-                       foreach ($level->getElements() as $element) {
-                               if (empty($parentRecordIdentifier) || empty($parentRecordField) || !isset($data[$parentRecordIdentifier])) {
-                                       $data = array_merge($data, $element->structureData($tableFields));
-                                       continue;
-                               }
-
-                               if (!isset($data[$parentRecordIdentifier][$parentRecordField]) || !is_array($data[$parentRecordIdentifier][$parentRecordField])) {
-                                       $data[$parentRecordIdentifier][$parentRecordField] = array();
-                               }
-
-                               $data[$parentRecordIdentifier][$parentRecordField] = array_merge(
-                                       $data[$parentRecordIdentifier][$parentRecordField],
-                                       $element->structureData($tableFields)
-                               );
-                       }
-               }
-
-               return $data;
-       }
-
-       /**
-        * @param NULL|array $tableFields
-        * @return array
-        */
-       public function mergeData(array $tableFields = NULL) {
-               $data = array(
-                       $this->recordIdentifier => $this->getRecordData($tableFields),
-               );
-               foreach ($this->levels as $level) {
-                       $data = array_merge($data, $level->mergeData($tableFields));
-               }
-               return $data;
-       }
-
-       /**
-        * @return array
-        */
-       public function mergeQueries() {
-               $queries = $this->queries;
-               foreach ($this->levels as $level) {
-                       $queries = array_merge($queries, $level->mergeQueries());
-               }
-               return $queries;
-       }
-
-}
diff --git a/typo3/sysext/core/Tests/Functional/Framework/Frontend/RenderLevel.php b/typo3/sysext/core/Tests/Functional/Framework/Frontend/RenderLevel.php
deleted file mode 100644 (file)
index 545e318..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-<?php
-namespace TYPO3\CMS\Core\Tests\Functional\Framework\Frontend;
-
-/***************************************************************
- * Copyright notice
- *
- * (c) 2014 Oliver Hader <oliver.hader@typo3.org>
- * All rights reserved
- *
- * This script is part of the TYPO3 project. The TYPO3 project is
- * free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The GNU General Public License can be found at
- * http://www.gnu.org/copyleft/gpl.html.
- *
- * This script is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-use \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
-
-/**
- * Model of rendered content levels
- */
-class RenderLevel {
-
-       /**
-        * @var string
-        */
-       protected $identifier;
-
-       /**
-        * @var string
-        */
-       protected $parentRecordIdentifier;
-
-       /**
-        * @var string
-        */
-       protected $parentRecordField;
-
-       /**
-        * @var array|RenderElement[]
-        */
-       protected $elements = array();
-
-       /**
-        * @param ContentObjectRenderer $contentObjectRenderer
-        * @return RenderLevel
-        */
-       public static function create(ContentObjectRenderer $contentObjectRenderer) {
-               return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
-                       'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\RenderLevel',
-                       $contentObjectRenderer
-               );
-       }
-
-       /**
-        * @param ContentObjectRenderer $contentObjectRenderer
-        */
-       public function __construct(ContentObjectRenderer $contentObjectRenderer) {
-               $this->identifier = spl_object_hash($contentObjectRenderer);
-       }
-
-       /**
-        * @return string
-        */
-       public function getIdentifier() {
-               return $this->identifier;
-       }
-
-       /**
-        * @param string $parentRecordIdentifier
-        */
-       public function setParentRecordIdentifier($parentRecordIdentifier) {
-               $this->parentRecordIdentifier = $parentRecordIdentifier;
-       }
-
-       public function getParentRecordIdentifier() {
-               return $this->parentRecordIdentifier;
-       }
-
-       /**
-        * @param string $parentRecordField
-        */
-       public function setParentRecordField($parentRecordField) {
-               $this->parentRecordField = $parentRecordField;
-       }
-
-       /**
-        * @return string
-        */
-       public function getParentRecordField() {
-               return $this->parentRecordField;
-       }
-
-       /**
-        * @return array|RenderElement[]
-        */
-       public function getElements() {
-               return $this->elements;
-       }
-
-       /**
-        * @param ContentObjectRenderer $contentObjectRenderer
-        * @return RenderElement
-        */
-       public function add(ContentObjectRenderer $contentObjectRenderer) {
-               $element = RenderElement::create($contentObjectRenderer);
-               $this->elements[] = $element;
-               return $element;
-       }
-
-       /**
-        * @param ContentObjectRenderer $contentObjectRenderer
-        * @return NULL|RenderLevel
-        */
-       public function findRenderLevel(ContentObjectRenderer $contentObjectRenderer) {
-               if (spl_object_hash($contentObjectRenderer) === $this->identifier) {
-                       return $this;
-               }
-
-               foreach ($this->elements as $element) {
-                       $result = $element->findRenderLevel($contentObjectRenderer);
-                       if ($result !== NULL) {
-                               return $result;
-                       }
-               }
-
-               return NULL;
-       }
-
-       /**
-        * @param ContentObjectRenderer $contentObjectRenderer
-        * @return NULL|RenderElement
-        */
-       public function findRenderElement(ContentObjectRenderer $contentObjectRenderer) {
-               $foundRenderLevel = $this->findRenderLevel($contentObjectRenderer);
-
-               if ($foundRenderLevel === NULL) {
-                       return NULL;
-               }
-
-               if ($foundRenderLevel !== $this) {
-                       return $foundRenderLevel->findRenderElement($contentObjectRenderer);
-               }
-
-
-               foreach ($this->elements as $element) {
-                       if ($element->getRecordIdentifier() === $contentObjectRenderer->currentRecord) {
-                               return $element;
-                       }
-               }
-
-               return NULL;
-       }
-
-       /**
-        * @param NULL|array $tableFields
-        * @return array
-        */
-       public function structureData(array $tableFields = NULL) {
-               $data = array();
-
-               foreach ($this->elements as $element) {
-                       $data = array_merge($data, $element->structureData($tableFields));
-               }
-
-               return $data;
-       }
-
-       /**
-        * @param NULL|array $tableFields
-        * @return array
-        */
-       public function mergeData(array $tableFields = NULL) {
-               $data = array();
-
-               foreach ($this->elements as $element) {
-                       $data = array_merge($data, $element->mergeData($tableFields));
-               }
-
-               return $data;
-       }
-
-       /**
-        * @return array
-        */
-       public function mergeQueries() {
-               $queries = array();
-
-               foreach ($this->elements as $element) {
-                       $queries = array_merge($queries, $element->mergeQueries());
-               }
-
-               return $queries;
-       }
-
-}
diff --git a/typo3/sysext/core/Tests/Functional/Framework/Frontend/Renderer.php b/typo3/sysext/core/Tests/Functional/Framework/Frontend/Renderer.php
new file mode 100644 (file)
index 0000000..956a159
--- /dev/null
@@ -0,0 +1,179 @@
+<?php
+namespace TYPO3\CMS\Core\Tests\Functional\Framework\Frontend;
+
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2014 Oliver Hader <oliver.hader@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Model of frontend response
+ */
+class Renderer implements \TYPO3\CMS\Core\SingletonInterface {
+
+       /**
+        * @var array
+        */
+       protected $tableFields;
+
+       /**
+        * @var array
+        */
+       protected $structure = array();
+
+       /**
+        * @var array
+        */
+       protected $structurePaths = array();
+
+       /**
+        * @var array
+        */
+       protected $records = array();
+
+       /**
+        * @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
+        */
+       public $cObj;
+
+       public function addRecordData($content, array $configuration = NULL) {
+               $recordIdentifier = $this->cObj->currentRecord;
+               list($tableName) = explode(':', $recordIdentifier);
+               $currentWatcherValue = $this->getCurrentWatcherValue();
+               $position = strpos($currentWatcherValue, '/' . $recordIdentifier);
+
+               $recordData = $this->filterFields($tableName, $this->cObj->data);
+               $this->records[$recordIdentifier] = $recordData;
+
+               if ($currentWatcherValue === $recordIdentifier) {
+                       $this->structure[$recordIdentifier] = $recordData;
+                       $this->structurePaths[$recordIdentifier] = array(array());
+               } elseif(!empty($position)) {
+                       $levelIdentifier = substr($currentWatcherValue, 0, $position);
+                       $this->addToStructure($levelIdentifier, $recordIdentifier, $recordData);
+               }
+       }
+
+       public function addFileData($content, array $configuration = NULL) {
+               $currentFile = $this->cObj->getCurrentFile();
+
+               if ($currentFile instanceof \TYPO3\CMS\Core\Resource\File) {
+                       $tableName = 'sys_file';
+               } elseif ($currentFile instanceof \TYPO3\CMS\Core\Resource\FileReference) {
+                       $tableName = 'sys_file_reference';
+               } else {
+                       return;
+               }
+
+               $recordData = $this->filterFields($tableName, $currentFile->getProperties());
+               $recordIdentifier = $tableName . ':' . $currentFile->getUid();
+               $this->records[$recordIdentifier] = $recordData;
+
+               $currentWatcherValue = $this->getCurrentWatcherValue();
+               $levelIdentifier = rtrim($currentWatcherValue, '/');
+               $this->addToStructure($levelIdentifier, $recordIdentifier, $recordData);
+       }
+
+       /**
+        * @param string $tableName
+        * @param array $recordData
+        * @return array
+        */
+       protected function filterFields($tableName, array $recordData) {
+               $recordData = array_intersect_key(
+                       $recordData,
+                       array_flip($this->getTableFields($tableName))
+               );
+               return $recordData;
+       }
+
+       protected function addToStructure($levelIdentifier, $recordIdentifier, array $recordData) {
+               $steps = explode('/', $levelIdentifier);
+               $structurePaths = array();
+               $structure = &$this->structure;
+
+               foreach ($steps as $step) {
+                       list($identifier, $fieldName) = explode('.', $step);
+                       $structurePaths[] = $identifier;
+                       $structurePaths[] = $fieldName;
+                       if (!isset($structure[$identifier])) {
+                               return;
+                       }
+                       $structure = &$structure[$identifier];
+                       if (!isset($structure[$fieldName]) || !is_array($structure[$fieldName])) {
+                               $structure[$fieldName] = array();
+                       }
+                       $structure = &$structure[$fieldName];
+               }
+
+               $structure[$recordIdentifier] = $recordData;
+               $this->structurePaths[$recordIdentifier][] = $structurePaths;
+       }
+
+       /**
+        * @param array $parameters
+        * @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $frontendController
+        */
+       public function render($content, array $configuration = NULL) {
+               $result = array(
+                       'structure' => $this->structure,
+                       'structurePaths' => $this->structurePaths,
+                       'records' => $this->records,
+               );
+               $content = json_encode($result);
+               return $content;
+       }
+
+       /**
+        * @param string $tableName
+        * @return array
+        */
+       protected function getTableFields($tableName) {
+               if (!isset($this->tableFields) && !empty($this->getFrontendController()->tmpl->setup['config.']['watcher.']['tableFields.'])) {
+                       $this->tableFields = $this->getFrontendController()->tmpl->setup['config.']['watcher.']['tableFields.'];
+                       foreach ($this->tableFields as &$fieldList) {
+                               $fieldList = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $fieldList, TRUE);
+                       }
+                       unset($fieldList);
+               }
+
+               return (!empty($this->tableFields[$tableName]) ? $this->tableFields[$tableName] : array());
+       }
+
+       /**
+        * @return string
+        */
+       protected function getCurrentWatcherValue() {
+               $watcherValue = NULL;
+               if (isset($this->getFrontendController()->register['watcher'])) {
+                       $watcherValue = $this->getFrontendController()->register['watcher'];
+               }
+               return $watcherValue;
+       }
+
+       /**
+        * @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
+        */
+       protected function getFrontendController() {
+               return $GLOBALS['TSFE'];
+       }
+
+}
index 623a023..c789401 100644 (file)
@@ -32,8 +32,8 @@ class RequestBootstrap {
        /**
         * @return void
         */
-       static public function setGlobalVariables() {
-               if (empty($_SERVER['argv'][1]) || ($requestArguments = json_decode($_SERVER['argv'][1], TRUE)) === FALSE) {
+       static public function setGlobalVariables(array $requestArguments = NULL) {
+               if (empty($requestArguments)) {
                        die('No JSON encoded arguments given');
                }
 
diff --git a/typo3/sysext/core/Tests/Functional/Framework/Scripts/Request.php b/typo3/sysext/core/Tests/Functional/Framework/Scripts/Request.php
deleted file mode 100644 (file)
index ff599a6..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-require dirname(dirname(dirname(dirname(__DIR__)))) . '/Classes/Core/CliBootstrap.php';
-\TYPO3\CMS\Core\Core\CliBootstrap::checkEnvironmentOrDie();
-
-require dirname(__DIR__) . '/Frontend/RequestBootstrap.php';
-\TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\RequestBootstrap::setGlobalVariables();
-\TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\RequestBootstrap::executeAndOutput();
-?>
\ No newline at end of file
index 6b5d0e7..68f45ce 100644 (file)
@@ -345,24 +345,7 @@ abstract class FunctionalTestCase extends BaseTestCase {
                $pageId = (int)$pageId;
                $languageId = (int)$languageId;
 
-               $phpExecutable = 'php';
-               if (defined('PHP_BINARY')) {
-                       $phpExecutable = PHP_BINARY;
-               } elseif (TYPO3_OS !== 'WIN' && defined('PHP_BINDIR')) {
-                       $phpExecutable = rtrim(PHP_BINDIR, '/') . '/php';
-               } else {
-                       foreach(explode(';', $_SERVER['Path']) as $path) {
-                               $path = rtrim(strtr($path, '\\', '/'), '/') . '/';
-                               $phpFile = 'php' . (TYPO3_OS === 'WIN' ? '.exe' : '');
-                               if (file_exists($path . $phpFile) && is_file($path . $phpFile)) {
-                                       $phpExecutable = $path . $phpFile;
-                                       break;
-                               }
-                       }
-               }
-
                $additionalParameter = '';
-
                if (!empty($backendUserId)) {
                        $additionalParameter .= '&backendUserId=' . (int)$backendUserId;
                }
@@ -375,23 +358,17 @@ abstract class FunctionalTestCase extends BaseTestCase {
                        'requestUrl' => 'http://localhost/?id=' . $pageId . '&L=' . $languageId . $additionalParameter,
                );
 
-               if (TYPO3_OS !== 'WIN') {
-                       $commandParts = array(
-                               escapeshellcmd($phpExecutable),
-                               escapeshellarg(ORIGINAL_ROOT . 'typo3/sysext/core/Tests/Functional/Framework/Scripts/Request.php'),
-                               escapeshellarg(json_encode($arguments)),
-                       );
-               } else {
-                       $commandParts = array(
-                               escapeshellcmd($phpExecutable),
-                               escapeshellarg(ORIGINAL_ROOT . 'typo3/sysext/core/Tests/Functional/Framework/Scripts/Request.php'),
-                               strtr(escapeshellarg(strtr(json_encode($arguments), array('&' => '^&', '"' => '"""'))), '   ', '"""'),
-                       );
-               }
+               $template = new \Text_Template(ORIGINAL_ROOT . 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/request.tpl');
+               $template->setVar(
+                       array(
+                               'arguments' => var_export($arguments, TRUE),
+                               'originalRoot' => ORIGINAL_ROOT,
+                       )
+               );
 
-               $command = trim(implode(' ', $commandParts));
-               $response = shell_exec($command);
-               $result = json_decode($response, TRUE);
+               $php = \PHPUnit_Util_PHP::factory();
+               $response = $php->runJob($template->render());
+               $result = json_decode($response['stdout'], TRUE);
 
                if ($result === FALSE) {
                        $this->fail('Frontend Response is empty');
index f0e8032..bfaff70 100644 (file)
@@ -42,6 +42,10 @@ class ContentContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractCon
         * @return string Output
         */
        public function render($conf = array()) {
+               if (!empty($conf['if.']) && !$this->cObj->checkIf($conf['if.'])) {
+                       return '';
+               }
+
                $theValue = '';
                $originalRec = $GLOBALS['TSFE']->currentRecord;
                // If the currentRecord is set, we register, that this record has invoked this function.
index e5c4da1..9ae3c56 100644 (file)
@@ -59,6 +59,10 @@ class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractConte
         * @return string Output
         */
        public function render($conf = array()) {
+               if (!empty($conf['if.']) && !$this->cObj->checkIf($conf['if.'])) {
+                       return '';
+               }
+
                $fileObjects = array();
                // Getting the files
                if ($conf['references'] || $conf['references.']) {