Skip to content
Snippets Groups Projects
Commit 307318e2 authored by Georg Ringer's avatar Georg Ringer
Browse files

[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
parent 71515a7e
Branches
Tags
No related merge requests found
......@@ -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;
......
<?php
namespace TYPO3\CMS\Core\Tests\Tree\TableConfiguration;
/***************************************************************
* Copyright notice
*
* (c) 2012 Helmut Hummel <helmut.hummel@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.
* 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
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment