From 4ba2ebcb2c95c1d6060d34428e0d5c0c0b11139d Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Fri, 27 Mar 2020 11:43:04 +0100 Subject: [PATCH] [TASK] Move ArrayBrowser to EXT:backend Resolves: #90851 Releases: master Change-Id: I472845920d31449164a632b0edae442dd2b56f7d Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63945 Tested-by: Georg Ringer <georg.ringer@gmail.com> Tested-by: TYPO3com <noreply@typo3.com> Tested-by: Susanne Moog <look@susi.dev> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> Reviewed-by: Susanne Moog <look@susi.dev> --- composer.json | 1 + composer.lock | 80 +++++++++++++++- .../Classes/View}/ArrayBrowser.php | 94 +++++++------------ .../backend/Migrations/Code/ClassAliasMap.php | 4 + .../Migrations/Code/LegacyClassesForIde.php | 10 ++ .../Tests/Unit/View}/ArrayBrowserTest.php | 23 ++--- typo3/sysext/backend/composer.json | 5 + .../Controller/ConfigurationController.php | 7 +- 8 files changed, 137 insertions(+), 87 deletions(-) rename typo3/sysext/{lowlevel/Classes/Utility => backend/Classes/View}/ArrayBrowser.php (66%) create mode 100644 typo3/sysext/backend/Migrations/Code/ClassAliasMap.php create mode 100644 typo3/sysext/backend/Migrations/Code/LegacyClassesForIde.php rename typo3/sysext/{lowlevel/Tests/Unit/Utility => backend/Tests/Unit/View}/ArrayBrowserTest.php (62%) diff --git a/composer.json b/composer.json index 0d285da7a7b1..13431cd9fdfa 100644 --- a/composer.json +++ b/composer.json @@ -111,6 +111,7 @@ "extra": { "typo3/class-alias-loader": { "class-alias-maps": [ + "typo3/sysext/backend/Migrations/Code/ClassAliasMap.php", "typo3/sysext/core/Migrations/Code/ClassAliasMap.php" ], "always-add-alias-loader": true diff --git a/composer.lock b/composer.lock index 1d8d1fd259a6..94c06aaad677 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "94ae18647513c4fc9f99421d1e862fd2", + "content-hash": "2d684052fe95bcec22364661e424f214", "packages": [ { "name": "cogpowered/finediff", @@ -5897,8 +5897,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "role": "lead", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], "description": "Utility class for timing", @@ -6813,8 +6813,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "role": "lead", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], "description": "Collection of value objects that represent the types of the PHP type system", @@ -7404,6 +7404,16 @@ "MIT" ], "description": "Auto bind parameters for your Symfony applications", + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + }, + { + "url": "https://www.patreon.com/rectorphp", + "type": "patreon" + } + ], "time": "2020-01-20T12:20:56+00:00" }, { @@ -7446,6 +7456,16 @@ "MIT" ], "description": "Autowire array parameters for your Symfony applications", + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + }, + { + "url": "https://www.patreon.com/rectorphp", + "type": "patreon" + } + ], "time": "2020-01-20T12:20:56+00:00" }, { @@ -7496,6 +7516,16 @@ "MIT" ], "description": "Set of Symplify rules for PHP_CodeSniffer and PHP CS Fixer.", + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + }, + { + "url": "https://www.patreon.com/rectorphp", + "type": "patreon" + } + ], "time": "2020-01-20T12:20:56+00:00" }, { @@ -7567,6 +7597,16 @@ "MIT" ], "description": "Use Coding Standard with 0-knowledge of PHP-CS-Fixer and PHP_CodeSniffer.", + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + }, + { + "url": "https://www.patreon.com/rectorphp", + "type": "patreon" + } + ], "time": "2020-01-20T12:20:56+00:00" }, { @@ -7613,6 +7653,16 @@ "MIT" ], "description": "Dependency Injection, Console and Kernel toolkit for Symplify packages.", + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + }, + { + "url": "https://www.patreon.com/rectorphp", + "type": "patreon" + } + ], "time": "2020-01-11T14:08:27+00:00" }, { @@ -7656,6 +7706,16 @@ "MIT" ], "description": "Resolve config and sets from configs and cli opptions for CLI applications", + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + }, + { + "url": "https://www.patreon.com/rectorphp", + "type": "patreon" + } + ], "time": "2020-01-20T12:20:56+00:00" }, { @@ -7699,6 +7759,16 @@ "MIT" ], "description": "Sanitized FileInfo with safe getRealPath() and other handy methods", + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + }, + { + "url": "https://www.patreon.com/rectorphp", + "type": "patreon" + } + ], "time": "2020-01-19T20:47:40+00:00" }, { diff --git a/typo3/sysext/lowlevel/Classes/Utility/ArrayBrowser.php b/typo3/sysext/backend/Classes/View/ArrayBrowser.php similarity index 66% rename from typo3/sysext/lowlevel/Classes/Utility/ArrayBrowser.php rename to typo3/sysext/backend/Classes/View/ArrayBrowser.php index e1ea46e903ce..140cfe2ce809 100644 --- a/typo3/sysext/lowlevel/Classes/Utility/ArrayBrowser.php +++ b/typo3/sysext/backend/Classes/View/ArrayBrowser.php @@ -1,5 +1,7 @@ <?php -namespace TYPO3\CMS\Lowlevel\Utility; +declare(strict_types = 1); + +namespace TYPO3\CMS\Backend\View; /* * This file is part of the TYPO3 CMS project. @@ -14,13 +16,15 @@ namespace TYPO3\CMS\Lowlevel\Utility; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Backend\Routing\Route; +use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Core\Utility\MathUtility; /** - * Class for displaying an array as a tree - * See the extension 'lowlevel' /config (Backend module 'Tools > Configuration') - * @internal just a helper class for internal usage + * Class for displaying an array as a tree which can collapse / expand. + * + * See the extension 'lowlevel' / config (Backend module 'Tools > Configuration') + * @internal just a helper class for internal usage. */ class ArrayBrowser { @@ -29,13 +33,6 @@ class ArrayBrowser */ public $expAll = false; - /** - * If set, will expand all (depthKeys is obsolete then) (and no links are applied) - * - * @var bool - */ - public $dontLinkVar = false; - /** * If set, the variable keys are not linked. * @@ -51,14 +48,6 @@ class ArrayBrowser */ public $searchKeys = []; - /** - * After calling the getSearchKeys function this array is populated with the - * key-positions in the array which contains values matching the search. - * - * @var int - */ - public $fixedLgd = 1; - /** * If set, the values are truncated with "..." appended if longer than a certain * length. @@ -72,21 +61,32 @@ class ArrayBrowser * * @var bool */ - public $searchKeysToo = false; + public $searchKeysToo = true; /** - * If set, array keys are subject to the search too. + * @var UriBuilder + */ + protected $uriBuilder; + + /** + * If null then there are no links set. * - * @var string + * @var Route|null */ - public $varName = ''; + protected $route; + + public function __construct(Route $route = null) + { + $this->route = $route; + $this->uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); + } /** * Set var name here if you want links to the variable name. * * Make browsable tree * Before calling this function you may want to set some of the internal vars like - * depthKeys, regexMode and fixedLgd. + * depthKeys and regexMode. * * @param array $array The array to display * @param string $positionKey Key-position id. Build up during recursive calls - [key1].[key2].[key3] - and so on. @@ -96,10 +96,8 @@ class ArrayBrowser { $output = '<ul class="list-tree text-monospace">'; if ($positionKey) { - $positionKey = $positionKey . '.'; + $positionKey .= '.'; } - /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */ - $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class); foreach ($array as $key => $value) { $depth = $positionKey . $key; if (is_object($value) && !$value instanceof \Traversable) { @@ -107,14 +105,14 @@ class ArrayBrowser } $isArray = is_iterable($value); $isResult = (bool)$this->searchKeys[$depth]; - $isExpanded = $isArray && ($this->depthKeys[$depth] || $this->expAll); + $isExpanded = $isArray && (!empty($this->depthKeys[$depth]) || $this->expAll); $output .= '<li' . ($isResult ? ' class="active"' : '') . '>'; $output .= '<span class="list-tree-group">'; - if ($isArray && !$this->expAll) { + if ($isArray && !$this->expAll && $this->route) { $goto = 'a' . substr(md5($depth), 0, 6); - $output .= '<a class="list-tree-control' . ($isExpanded ? ' list-tree-control-open' : ' list-tree-control-closed') . '" id="' . $goto . '" href="' . htmlspecialchars((string)$uriBuilder->buildUriFromRoutePath(GeneralUtility::_GP('route')) . '&node[' . rawurlencode($depth) . ']=' . ($isExpanded ? 0 : 1) . '#' . $goto) . '"><i class="fa"></i></a> '; + $output .= '<a class="list-tree-control' . ($isExpanded ? ' list-tree-control-open' : ' list-tree-control-closed') . '" id="' . $goto . '" href="' . htmlspecialchars((string)$this->uriBuilder->buildUriFromRoute($this->route->getOption('_identifier'), ['node' => [rawurldecode($depth) => $isExpanded ? 0 : 1]]) . '#' . $goto) . '"><i class="fa"></i></a> '; } - $output .= $this->wrapArrayKey($key, $depth, !$isArray ? $value : ''); + $output .= '<span class="list-tree-label">' . htmlspecialchars($key) . '</span>'; if (!$isArray) { $output .= ' = <span class="list-tree-value">' . htmlspecialchars($value) . '</span>'; } @@ -131,34 +129,6 @@ class ArrayBrowser return $output; } - /** - * Wrapping the value in bold tags etc. - * - * @param string $label The title string - * @param string $depth Depth path - * @param string $theValue The value for the array entry. - * @return string Title string, htmlspecialchars()'ed - */ - public function wrapArrayKey($label, $depth, $theValue) - { - // Protect label: - $label = htmlspecialchars($label); - /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */ - $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class); - // If varname is set: - if ($this->varName && !$this->dontLinkVar) { - $variableName = $this->varName - . '[\'' . str_replace('.', '\'][\'', $depth) . '\'] = ' - . (!MathUtility::canBeInterpretedAsInteger($theValue) ? '\'' - . addslashes($theValue) . '\'' : $theValue) . '; '; - $label = '<a class="list-tree-label" href="' - . htmlspecialchars((string)$uriBuilder->buildUriFromRoutePath(GeneralUtility::_GP('route')) - . '&varname=' . urlencode($variableName)) - . '#varname">' . $label . '</a>'; - } - return '<span class="list-tree-label">' . $label . '</span>'; - } - /** * Creates an array with "depthKeys" which will expand the array to show the search results * @@ -172,7 +142,7 @@ class ArrayBrowser public function getSearchKeys($keyArr, $depth_in, $searchString, $keyArray) { if ($depth_in) { - $depth_in = $depth_in . '.'; + $depth_in .= '.'; } foreach ($keyArr as $key => $value) { $depth = $depth_in . $key; @@ -214,7 +184,7 @@ class ArrayBrowser { $tsbrArray = []; foreach ($arr as $theK => $theV) { - $theKeyParts = explode('.', $theK); + $theKeyParts = explode('.', (string)$theK); $depth = ''; $c = count($theKeyParts); $a = 0; diff --git a/typo3/sysext/backend/Migrations/Code/ClassAliasMap.php b/typo3/sysext/backend/Migrations/Code/ClassAliasMap.php new file mode 100644 index 000000000000..dc59d52ac815 --- /dev/null +++ b/typo3/sysext/backend/Migrations/Code/ClassAliasMap.php @@ -0,0 +1,4 @@ +<?php +return [ + 'TYPO3\\CMS\\Lowlevel\\Utility\\ArrayBrowser' => \TYPO3\CMS\Backend\View\ArrayBrowser::class +]; diff --git a/typo3/sysext/backend/Migrations/Code/LegacyClassesForIde.php b/typo3/sysext/backend/Migrations/Code/LegacyClassesForIde.php new file mode 100644 index 000000000000..5090f638557e --- /dev/null +++ b/typo3/sysext/backend/Migrations/Code/LegacyClassesForIde.php @@ -0,0 +1,10 @@ +<?php +namespace { + die('Access denied'); +} + +namespace TYPO3\CMS\Lowlevel\Utility { + class ArrayBrowser extends \TYPO3\CMS\Backend\View\ArrayBrowser + { + } +} diff --git a/typo3/sysext/lowlevel/Tests/Unit/Utility/ArrayBrowserTest.php b/typo3/sysext/backend/Tests/Unit/View/ArrayBrowserTest.php similarity index 62% rename from typo3/sysext/lowlevel/Tests/Unit/Utility/ArrayBrowserTest.php rename to typo3/sysext/backend/Tests/Unit/View/ArrayBrowserTest.php index 6f5b3b456ba9..bf6c56bf9aca 100644 --- a/typo3/sysext/lowlevel/Tests/Unit/Utility/ArrayBrowserTest.php +++ b/typo3/sysext/backend/Tests/Unit/View/ArrayBrowserTest.php @@ -1,5 +1,5 @@ <?php -namespace TYPO3\CMS\Lowlevel\Tests\Unit\Utility; +namespace TYPO3\CMS\Backend\Tests\Unit\View; /* * This file is part of the TYPO3 CMS project. @@ -14,23 +14,12 @@ namespace TYPO3\CMS\Lowlevel\Tests\Unit\Utility; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Backend\View\ArrayBrowser; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; -/** - * Testcase for the \TYPO3\CMS\Lowlevel\Utility\ArrayBrowser class in the TYPO3 Core. - */ class ArrayBrowserTest extends UnitTestCase { - /** - * @var \TYPO3\CMS\Lowlevel\Utility\ArrayBrowser - */ - protected $subject; - - protected function setUp(): void - { - parent::setUp(); - $this->subject = new \TYPO3\CMS\Lowlevel\Utility\ArrayBrowser(); - } + protected $resetSingletonInstances = true; /////////////////////////////// // Tests concerning depthKeys @@ -40,7 +29,8 @@ class ArrayBrowserTest extends UnitTestCase */ public function depthKeysWithEmptyFirstParameterAddsNothing() { - self::assertEquals([], $this->subject->depthKeys([], [])); + $subject = new ArrayBrowser(); + self::assertEquals([], $subject->depthKeys([], [])); } /** @@ -48,6 +38,7 @@ class ArrayBrowserTest extends UnitTestCase */ public function depthKeysWithNumericKeyAddsOneNumberForKeyFromFirstArray() { - self::assertEquals([0 => 1], $this->subject->depthKeys(['foo'], [])); + $subject = new ArrayBrowser(); + self::assertEquals([0 => 1], $subject->depthKeys(['foo'], [])); } } diff --git a/typo3/sysext/backend/composer.json b/typo3/sysext/backend/composer.json index 10e1567ff91d..2f0c3096f25b 100644 --- a/typo3/sysext/backend/composer.json +++ b/typo3/sysext/backend/composer.json @@ -48,6 +48,11 @@ "partOfMinimalUsableSystem": true }, "extension-key": "backend" + }, + "typo3/class-alias-loader": { + "class-alias-maps": [ + "Migrations/Code/ClassAliasMap.php" + ] } }, "autoload": { diff --git a/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php b/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php index 1de45c7d28db..947fdbf1c8bd 100644 --- a/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php +++ b/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php @@ -21,6 +21,7 @@ use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Backend\Configuration\SiteTcaConfiguration; use TYPO3\CMS\Backend\Routing\Router; use TYPO3\CMS\Backend\Template\ModuleTemplate; +use TYPO3\CMS\Backend\View\ArrayBrowser; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\EventDispatcher\ListenerProvider; use TYPO3\CMS\Core\Http\HtmlResponse; @@ -32,7 +33,6 @@ use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Fluid\View\StandaloneView; use TYPO3\CMS\Form\Mvc\Configuration\ConfigurationManager; use TYPO3\CMS\Form\Mvc\Configuration\ConfigurationManagerInterface; -use TYPO3\CMS\Lowlevel\Utility\ArrayBrowser; /** * View configuration arrays in the backend @@ -267,9 +267,8 @@ class ConfigurationController } // Prepare array renderer class, apply search and expand / collapse states - $arrayBrowser = GeneralUtility::makeInstance(ArrayBrowser::class); - $arrayBrowser->dontLinkVar = true; - $arrayBrowser->searchKeysToo = true; + $route = GeneralUtility::makeInstance(Router::class)->match(GeneralUtility::_GP('route')); + $arrayBrowser = GeneralUtility::makeInstance(ArrayBrowser::class, $route); $arrayBrowser->regexMode = $moduleState['regexSearch']; $node = $queryParams['node']; if ($searchString) { -- GitLab