From 307318e246ca2136f14fd99452b111aeb6d0380f Mon Sep 17 00:00:00 2001 From: Georg Ringer Date: Sat, 27 Oct 2012 19:17:58 +0200 Subject: [PATCH] [TASK] Add possibility for a custom TCA TreeProvider Currently the tca tree uses its own DataProvider which makes sense but this is not extendable. Adding 3 additional lines would make it possible to use a custom provider. Needed e.g. in EXT:news to be able to render a tca tree with some BE user/-group restrictions ... Change-Id: Idc9bee2ede810e930c17a31ed08688b5654759ff Resolves: #42447 Releases: 6.0 Reviewed-on: http://review.typo3.org/15980 Reviewed-by: Helmut Hummel Tested-by: Helmut Hummel Reviewed-by: Georg Ringer Tested-by: Georg Ringer --- .../TreeDataProviderFactory.php | 76 ++++++----- .../TreeDataProviderFactoryTest.php | 129 ++++++++++++++++++ 2 files changed, 172 insertions(+), 33 deletions(-) create mode 100644 typo3/sysext/core/Tests/Unit/Tree/TableConfiguration/TreeDataProviderFactoryTest.php diff --git a/typo3/sysext/core/Classes/Tree/TableConfiguration/TreeDataProviderFactory.php b/typo3/sysext/core/Classes/Tree/TableConfiguration/TreeDataProviderFactory.php index 2242ed3d5f38..ff8079a1496d 100644 --- a/typo3/sysext/core/Classes/Tree/TableConfiguration/TreeDataProviderFactory.php +++ b/typo3/sysext/core/Classes/Tree/TableConfiguration/TreeDataProviderFactory.php @@ -39,18 +39,30 @@ class TreeDataProviderFactory { * Gets the data provider, depending on TCA configuration * * @param array $tcaConfiguration - * @return \TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider + * @param $table + * @param $field + * @param $currentValue + * @return DatabaseTreeDataProvider * @throws \InvalidArgumentException */ static public function getDataProvider(array $tcaConfiguration, $table, $field, $currentValue) { + /** @var $dataProvider \TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider */ $dataProvider = NULL; + if (!isset($tcaConfiguration['treeConfig']) | !is_array($tcaConfiguration['treeConfig'])) { + throw new \InvalidArgumentException('TCA Tree configuration is invalid: "treeConfig" array is missing', 1288215890); + } + + if (!empty($tcaConfiguration['treeConfig']['dataProvider'])) { + $dataProvider = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($tcaConfiguration['treeConfig']['dataProvider'], $tcaConfiguration, $table, $field, $currentValue); + } if (!isset($tcaConfiguration['internal_type'])) { $tcaConfiguration['internal_type'] = 'db'; } - if ($tcaConfiguration['internal_type'] == 'db') { + if ($tcaConfiguration['internal_type'] === 'db') { $unselectableUids = array(); - /** @var $dataProvider \TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider */ - $dataProvider = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Tree\\TableConfiguration\\DatabaseTreeDataProvider'); + if ($dataProvider === NULL) { + $dataProvider = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Tree\\TableConfiguration\\DatabaseTreeDataProvider'); + } if (isset($tcaConfiguration['foreign_table'])) { $tableName = $tcaConfiguration['foreign_table']; $dataProvider->setTableName($tableName); @@ -68,39 +80,37 @@ class TreeDataProviderFactory { } $dataProvider->setTreeId(md5($table . '|' . $field)); $dataProvider->setSelectedList($currentValue); - if (isset($tcaConfiguration['treeConfig']) && is_array($tcaConfiguration['treeConfig'])) { - $treeConfiguration = $tcaConfiguration['treeConfig']; - if (isset($treeConfiguration['rootUid'])) { - $dataProvider->setRootUid(intval($treeConfiguration['rootUid'])); - } - if (isset($treeConfiguration['appearance']['expandAll'])) { - $dataProvider->setExpandAll((bool) $treeConfiguration['appearance']['expandAll']); - } - if (isset($treeConfiguration['appearance']['maxLevels'])) { - $dataProvider->setLevelMaximum(intval($treeConfiguration['appearance']['maxLevels'])); - } - if (isset($treeConfiguration['appearance']['nonSelectableLevels'])) { - $dataProvider->setNonSelectableLevelList($treeConfiguration['appearance']['nonSelectableLevels']); - } elseif (isset($treeConfiguration['rootUid'])) { - $dataProvider->setNonSelectableLevelList(''); - } - if (isset($treeConfiguration['childrenField'])) { - $dataProvider->setLookupMode(\t3lib_tree_tca_DatabaseTreeDataProvider::MODE_CHILDREN); - $dataProvider->setLookupField($treeConfiguration['childrenField']); - } elseif (isset($treeConfiguration['parentField'])) { - $dataProvider->setLookupMode(\t3lib_tree_tca_DatabaseTreeDataProvider::MODE_PARENT); - $dataProvider->setLookupField($treeConfiguration['parentField']); - } else { - throw new \InvalidArgumentException('TCA Tree configuration is invalid: neither "childrenField" nor "parentField" is set', 1288215889); - } - $dataProvider->setItemUnselectableList($unselectableUids); + + $treeConfiguration = $tcaConfiguration['treeConfig']; + if (isset($treeConfiguration['rootUid'])) { + $dataProvider->setRootUid(intval($treeConfiguration['rootUid'])); + } + if (isset($treeConfiguration['appearance']['expandAll'])) { + $dataProvider->setExpandAll((bool) $treeConfiguration['appearance']['expandAll']); + } + if (isset($treeConfiguration['appearance']['maxLevels'])) { + $dataProvider->setLevelMaximum(intval($treeConfiguration['appearance']['maxLevels'])); + } + if (isset($treeConfiguration['appearance']['nonSelectableLevels'])) { + $dataProvider->setNonSelectableLevelList($treeConfiguration['appearance']['nonSelectableLevels']); + } elseif (isset($treeConfiguration['rootUid'])) { + $dataProvider->setNonSelectableLevelList(''); + } + if (isset($treeConfiguration['childrenField'])) { + $dataProvider->setLookupMode(\t3lib_tree_tca_DatabaseTreeDataProvider::MODE_CHILDREN); + $dataProvider->setLookupField($treeConfiguration['childrenField']); + } elseif (isset($treeConfiguration['parentField'])) { + $dataProvider->setLookupMode(\t3lib_tree_tca_DatabaseTreeDataProvider::MODE_PARENT); + $dataProvider->setLookupField($treeConfiguration['parentField']); } else { - throw new \InvalidArgumentException('TCA Tree configuration is invalid: "treeConfig" array is missing', 1288215890); + throw new \InvalidArgumentException('TCA Tree configuration is invalid: neither "childrenField" nor "parentField" is set', 1288215889); } - } elseif ($tcaConfiguration['internal_type'] == 'file') { + $dataProvider->setItemUnselectableList($unselectableUids); + + } elseif ($tcaConfiguration['internal_type'] === 'file' && $dataProvider === NULL) { // TODO Not implemented yet throw new \InvalidArgumentException('TCA Tree configuration is invalid: tree for "internal_type=file" not implemented yet', 1288215891); - } else { + } elseif ($dataProvider === NULL) { throw new \InvalidArgumentException('TCA Tree configuration is invalid: tree for "internal_type=' . $tcaConfiguration['internal_type'] . '" not implemented yet', 1288215892); } return $dataProvider; diff --git a/typo3/sysext/core/Tests/Unit/Tree/TableConfiguration/TreeDataProviderFactoryTest.php b/typo3/sysext/core/Tests/Unit/Tree/TableConfiguration/TreeDataProviderFactoryTest.php new file mode 100644 index 000000000000..1f3c33afd49b --- /dev/null +++ b/typo3/sysext/core/Tests/Unit/Tree/TableConfiguration/TreeDataProviderFactoryTest.php @@ -0,0 +1,129 @@ + + * 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. + * A copy is found in the textfile GPL.txt and important notices to the license + * from the author is found in LICENSE.txt distributed with these scripts. + * + * + * 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! + ***************************************************************/ + +/** + * Testcase for TYPO3\CMS\Core\Tree\TableConfiguration\TreeDataProviderFactory + */ +class TreeDataProviderFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase { + + /** + * @var \TYPO3\CMS\Core\Tree\TableConfiguration\TreeDataProviderFactory + */ + protected $fixture; + + public function setUp() { + $this->fixture = new \TYPO3\CMS\Core\Tree\TableConfiguration\TreeDataProviderFactory(); + $GLOBALS['TCA'] = array(); + $GLOBALS['TCA']['foo'] = array(); + $GLOBALS['TCA']['foo']['ctrl'] = array(); + $GLOBALS['TCA']['foo']['ctrl']['label'] = 'labelFoo'; + $GLOBALS['TCA']['foo']['columns'] = array(); + } + + /** + * @return array + */ + public function invalidConfigurationDataProvider() { + return array( + 'Empty Configuration' => array(array()), + 'File Configuration' => array(array( + 'internal_type' => 'file', + 'treeConfig' => array(), + )), + 'Unknown Type' => array(array( + 'internal_type' => 'foo', + 'treeConfig' => array(), + )), + 'No foreign table' => array(array( + 'internal_type' => 'db', + 'treeConfig' => array(), + )), + 'No tree configuration' => array(array( + 'internal_type' => 'db', + 'foreign_table' => 'foo', + )), + 'Tree configuration not array' => array(array( + 'internal_type' => 'db', + 'foreign_table' => 'foo', + 'treeConfig' => 'bar', + )), + 'Tree configuration missing childer and parent field' => array(array( + 'internal_type' => 'db', + 'foreign_table' => 'foo', + 'treeConfig' => array(), + )), + ); + } + + /** + * @param array $tcaConfiguration + * @test + * @dataProvider invalidConfigurationDataProvider + * @expectedException \InvalidArgumentException + */ + public function factoryThrowsExceptionIfInvalidConfigurationIsGiven(array $tcaConfiguration) { + $this->fixture->getDataProvider($tcaConfiguration, 'foo', 'bar', array('uid' => 1)); + } + + /** + * @test + */ + public function configuredDataProviderClassIsInstantiated() { + $dataProviderMockClassName = uniqid('tx_coretest_tree_data_provider'); + eval('class ' . $dataProviderMockClassName . ' { + function __construct($configuration) { + } + }'); + + $tcaConfiguration = array('treeConfig' => array('dataProvider' => $dataProviderMockClassName), 'internal_type' => 'foo'); + $dataProvider = $this->fixture->getDataProvider($tcaConfiguration, 'foo', 'bar', array('uid' => 1)); + + $this->assertInstanceOf($dataProviderMockClassName, $dataProvider); + } + + /** + * @test + */ + public function configuredDataProviderClassIsInstantiatedWithTcaConfigurationInConstructor() { + $dataProviderMockClassName = uniqid('tx_coretest_tree_data_provider'); + $tcaConfiguration = array('treeConfig' => array('dataProvider' => $dataProviderMockClassName), 'internal_type' => 'foo'); + $classCode = 'class ' . $dataProviderMockClassName . ' { + function __construct($configuration) { + if (!is_array($configuration)) throw new Exception(\'Failed asserting that the contructor arguments are an array\'); + if ($configuration !== ' . var_export($tcaConfiguration, TRUE) . ') throw new Exception(\'Failed asserting that the contructor arguments are correctly passed\'); + } + }'; + eval($classCode); + $dataProvider = $this->fixture->getDataProvider($tcaConfiguration, 'foo', 'bar', array('uid' => 1)); + + $this->assertInstanceOf($dataProviderMockClassName, $dataProvider); + } +} + +?> \ No newline at end of file -- 2.20.1