Commit 6c2fe86e authored by Saskia Schreiber's avatar Saskia Schreiber Committed by Andreas Wolf
Browse files

[TASK] Decouple TreeController from UserSettingsController

Introduce a general wrapper for backend user configuration.

Resolves: #84353
Releases: master
Change-Id: Iddf01a18527ea732dc1c857e153880af57a492fd
Reviewed-on: https://review.typo3.org/56239

Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Andreas Wolf's avatarAndreas Wolf <andreas.wolf@typo3.org>
Tested-by: Andreas Wolf's avatarAndreas Wolf <andreas.wolf@typo3.org>
parent ac1844ef
<?php
declare(strict_types = 1);
namespace TYPO3\CMS\Backend\Configuration;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Convenience wrapper for backend user configuration
*
* @internal
*/
class BackendUserConfiguration
{
/**
* @var BackendUserAuthentication
*/
protected $backendUser;
/**
* @param BackendUserAuthentication|null $backendUser
*/
public function __construct(BackendUserAuthentication $backendUser = null)
{
$this->backendUser = $backendUser ?: $GLOBALS['BE_USER'];
}
/**
* Returns a specific user setting
*
* @param string $key Identifier, allows also dotted notation for subarrays
* @return mixed Value associated
*/
public function get(string $key)
{
return (strpos($key, '.') !== false) ? $this->getFromDottedNotation($key) : $this->backendUser->uc[$key];
}
/**
* Get all user settings
*
* @return mixed all values, usually a multi-dimensional array
*/
public function getAll()
{
return $this->backendUser->uc;
}
/**
* Sets user settings by key/value pair
*
* @param string $key
* @param mixed $value
*/
public function set(string $key, $value): void
{
if (strpos($key, '.') !== false) {
$this->setFromDottedNotation($key, $value);
} else {
$this->backendUser->uc[$key] = $value;
}
$this->backendUser->writeUC($this->backendUser->uc);
}
/**
* Adds an value to an Comma-separated list
* stored in $key of user settings
*
* @param string $key
* @param mixed $value
*/
public function addToList(string $key, $value): void
{
$list = $this->get($key);
if (!isset($list)) {
$list = $value;
} elseif (!GeneralUtility::inList($list, $value)) {
$list .= ',' . $value;
}
$this->set($key, $list);
}
/**
* Removes an value from an Comma-separated list
* stored $key of user settings
*
* @param string $key
* @param mixed $value
*/
public function removeFromList(string $key, $value): void
{
$list = $this->get($key);
if (GeneralUtility::inList($list, $value)) {
$list = GeneralUtility::trimExplode(',', $list, true);
$list = ArrayUtility::removeArrayEntryByValue($list, $value);
$this->set($key, implode(',', $list));
}
}
/**
* Resets the user settings to the default
*/
public function clear(): void
{
$this->backendUser->resetUC();
}
/**
* Unsets a key in user settings
*
* @param string $key
*/
public function unsetOption(string $key): void
{
if (isset($this->backendUser->uc[$key])) {
unset($this->backendUser->uc[$key]);
$this->backendUser->writeUC($this->backendUser->uc);
}
}
/**
* Computes the subarray from dotted notation
*
* @param $key string Dotted notation of subkeys like moduleData.module1.general.checked
* @return mixed value of the settings
*/
protected function getFromDottedNotation(string $key)
{
$subkeys = GeneralUtility::trimExplode('.', $key);
$configuration = $this->backendUser->uc;
foreach ($subkeys as $subkey) {
if (isset($configuration[$subkey])) {
$configuration = &$configuration[$subkey];
} else {
$configuration = [];
break;
}
}
return $configuration;
}
/**
* Sets the value of a key written in dotted notation
*
* @param string $key
* @param mixed $value
*/
protected function setFromDottedNotation(string $key, $value): void
{
$subkeys = GeneralUtility::trimExplode('.', $key, true);
$lastKey = $subkeys[count($subkeys) - 1];
$configuration = &$this->backendUser->uc;
foreach ($subkeys as $subkey) {
if ($subkey === $lastKey) {
$configuration[$subkey] = $value;
} else {
$configuration = &$configuration[$subkey];
}
}
}
}
......@@ -17,7 +17,7 @@ namespace TYPO3\CMS\Backend\Controller\Page;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Controller\UserSettingsController;
use TYPO3\CMS\Backend\Configuration\BackendUserConfiguration;
use TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
......@@ -178,8 +178,8 @@ class TreeController
$this->addIdAsPrefix = (bool)$this->getBackendUser()->getTSConfigVal('options.pageTree.showPageIdWithTitle');
$this->addDomainName = (bool)$this->getBackendUser()->getTSConfigVal('options.pageTree.showDomainNameWithTitle');
$this->showMountPathAboveMounts = (bool)$this->getBackendUser()->getTSConfigVal('options.pageTree.showPathAboveMounts');
$userSettingsController = GeneralUtility::makeInstance(UserSettingsController::class);
$this->expandedState = $userSettingsController->process('get', 'BackendComponents.States.Pagetree');
$backendUserConfiguration = GeneralUtility::makeInstance(BackendUserConfiguration::class);
$this->expandedState = $backendUserConfiguration->get('BackendComponents.States.Pagetree');
if (is_object($this->expandedState->stateHash)) {
$this->expandedState = (array)$this->expandedState->stateHash;
} else {
......
......@@ -17,8 +17,8 @@ namespace TYPO3\CMS\Backend\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Configuration\BackendUserConfiguration;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
......@@ -27,6 +27,19 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
*/
class UserSettingsController
{
/**
* @var BackendUserConfiguration
*/
protected $backendUserConfiguration;
/**
* Initializes the backendUserConfiguration
*/
public function __construct()
{
$this->backendUserConfiguration = GeneralUtility::makeInstance(BackendUserConfiguration::class);
}
/**
* Processes all AJAX calls and returns a JSON for the data
*
......@@ -39,9 +52,9 @@ class UserSettingsController
$action = $request->getParsedBody()['action'] ?? $request->getQueryParams()['action'];
$key = $request->getParsedBody()['key'] ?? $request->getQueryParams()['key'];
$value = $request->getParsedBody()['value'] ?? $request->getQueryParams()['value'];
$data = $this->process($action, $key, $value);
$content = $this->process($action, $key, $value);
return (new JsonResponse())->setPayload($content);
return (new JsonResponse())->setPayload($data);
}
/**
......@@ -56,29 +69,29 @@ class UserSettingsController
{
switch ($action) {
case 'get':
$content = $this->get($key);
$content = $this->backendUserConfiguration->get($key);
break;
case 'getAll':
$content = $this->getAll();
$content = $this->backendUserConfiguration->getAll();
break;
case 'set':
$this->set($key, $value);
$content = $this->getAll();
$this->backendUserConfiguration->set($key, $value);
$content = $this->backendUserConfiguration->getAll();
break;
case 'addToList':
$this->addToList($key, $value);
$content = $this->getAll();
$this->backendUserConfiguration->addToList($key, $value);
$content = $this->backendUserConfiguration->getAll();
break;
case 'removeFromList':
$this->removeFromList($key, $value);
$content = $this->getAll();
$this->backendUserConfiguration->removeFromList($key, $value);
$content = $this->backendUserConfiguration->getAll();
break;
case 'unset':
$this->unsetOption($key);
$content = $this->getAll();
$this->backendUserConfiguration->unsetOption($key);
$content = $this->backendUserConfiguration->getAll();
break;
case 'clear':
$this->clear();
$this->backendUserConfiguration->clear();
$content = ['result' => true];
break;
default:
......@@ -87,152 +100,4 @@ class UserSettingsController
return $content;
}
/**
* Returns a specific user setting
*
* @param string $key Identifier, allows also dotted notation for subarrays
* @return mixed Value associated
*/
protected function get($key)
{
return (strpos($key, '.') !== false) ? $this->getFromDottedNotation($key) : $this->getBackendUser()->uc[$key];
}
/**
* Get all user settings
*
* @return mixed all values, usually a multi-dimensional array
*/
protected function getAll()
{
return $this->getBackendUser()->uc;
}
/**
* Sets user settings by key/value pair
*
* @param string $key
* @param mixed $value
*/
protected function set($key, $value)
{
$beUser = $this->getBackendUser();
if (strpos($key, '.') !== false) {
$this->setFromDottedNotation($key, $value);
} else {
$beUser->uc[$key] = $value;
}
$beUser->writeUC($beUser->uc);
}
/**
* Adds an value to an Comma-separated list
* stored $key of user settings
*
* @param string $key
* @param mixed $value
*/
protected function addToList($key, $value)
{
$list = $this->get($key);
if (!isset($list)) {
$list = $value;
} else {
if (!GeneralUtility::inList($list, $value)) {
$list .= ',' . $value;
}
}
$this->set($key, $list);
}
/**
* Removes an value from an Comma-separated list
* stored $key of user settings
*
* @param string $key
* @param mixed $value
*/
protected function removeFromList($key, $value)
{
$list = $this->get($key);
if (GeneralUtility::inList($list, $value)) {
$list = GeneralUtility::trimExplode(',', $list, true);
$list = ArrayUtility::removeArrayEntryByValue($list, $value);
$this->set($key, implode(',', $list));
}
}
/**
* Resets the user settings to the default
*/
protected function clear()
{
$this->getBackendUser()->resetUC();
}
/**
* Unsets a key in user settings
*
* @param string $key
*/
protected function unsetOption($key)
{
$beUser = $this->getBackendUser();
if (isset($beUser->uc[$key])) {
unset($beUser->uc[$key]);
$beUser->writeUC($beUser->uc);
}
}
/**
* Computes the subarray from dotted notation
*
* @param $key string Dotted notation of subkeys like moduleData.module1.general.checked
* @return mixed value of the settings
*/
protected function getFromDottedNotation($key)
{
$subkeys = GeneralUtility::trimExplode('.', $key);
$array = $this->getBackendUser()->uc;
foreach ($subkeys as $subkey) {
if (isset($array[$subkey])) {
$array = &$array[$subkey];
} else {
$array = [];
break;
}
}
return $array;
}
/**
* Sets the value of a key written in dotted notation
*
* @param string $key
* @param mixed $value
*/
protected function setFromDottedNotation($key, $value)
{
$subkeys = GeneralUtility::trimExplode('.', $key, true);
$lastKey = $subkeys[count($subkeys) - 1];
$array = &$this->getBackendUser()->uc;
foreach ($subkeys as $subkey) {
if ($subkey === $lastKey) {
$array[$subkey] = $value;
} else {
$array = &$array[$subkey];
}
}
}
/**
* Returns the current BE user.
*
* @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
*/
protected function getBackendUser()
{
return $GLOBALS['BE_USER'];
}
}
<?php
declare(strict_types = 1);
namespace TYPO3\CMS\Backend\Tests\Unit\Configuration;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Configuration\BackendUserConfiguration;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/**
* Testcase for TYPO3\CMS\Backend\Configuration\BackendUserConfiguration
*/
class BackendUserConfigurationTest extends UnitTestCase
{
/**
* @var BackendUserConfiguration
*/
protected $backendUserConfiguration;
/**
* @var BackendUserAuthentication|\Prophecy\Prophecy\ObjectProphecy
*/
protected $backendUser;
/**
* Set up this testcase
*/
protected function setUp()
{
/** @var BackendUserAuthentication|\Prophecy\Prophecy\ObjectProphecy */
$this->backendUser = $this->prophesize(BackendUserAuthentication::class);
$this->backendUserConfiguration = new BackendUserConfiguration($this->backendUser->reveal());
}
/**
* @test
*/
public function getsConfiguration()
{
$this->backendUser->reveal()->uc = [
'key' => 'A',
'nested' => [
'key' => 'B',
],
];
$this->assertEquals('A', $this->backendUserConfiguration->get('key'));
$this->assertEquals('B', $this->backendUserConfiguration->get('nested.key'));
}
/**
* @test
*/
public function getsAllConfiguration()
{
$configuration = [
'foo' => 'A',
'bar' => 'B',
];
$this->backendUser->reveal()->uc = $configuration;
$this->assertEquals($configuration, $this->backendUserConfiguration->getAll());
}
/**
* @test
*/
public function setsConfiguration()
{
$this->backendUser->reveal()->uc = [
'foo' => 'A',
];
$this->backendUserConfiguration->set('foo', 'X');
$this->backendUserConfiguration->set('bar', 'Y');
$this->backendUserConfiguration->set('nested.bar', 'Z');
$expected = [
'foo' => 'X',
'bar' => 'Y',
'nested' => [
'bar' => 'Z',
],
];
$this->backendUser->writeUC($expected)->shouldHaveBeenCalled();
}
/**
* @test
*/
public function addsToListConfigurationOption()
{
$this->backendUser->reveal()->uc = [
'foo' => 'A',
'nested' => [
'foo' => '',
],
];
$this->backendUserConfiguration->addToList('foo', 'X');
$this->backendUserConfiguration->addToList('nested.foo', 'X');
$this->backendUserConfiguration->addToList('nested.foo', 'Z');
$this->backendUserConfiguration->addToList('nested.foo', 'Z');
$expected = [
'foo' => 'A,X',
'nested' => [
'foo' => '',
],
];
$this->backendUser->writeUC($expected)->shouldHaveBeenCalled();
$expected = [
'foo' => 'A,X',
'nested' => [
'foo' => ',X',
],
];
$this->backendUser->writeUC($expected)->shouldHaveBeenCalled();
$expected = [
'foo' => 'A,X',
'nested' => [
'foo' => ',X,Z',
],
];
$this->backendUser->writeUC($expected)->shouldHaveBeenCalled();
}
/**
* @test
*/
public function removesFromListConfigurationOption()
{
$this->backendUser->reveal()->uc = [