Commit 89281016 authored by Oliver Hader's avatar Oliver Hader Committed by Oliver Hader
Browse files

[TASK] Prevent undefined array key warnings in ext:dashboard

This change addresses several "undefined array key" issues that have
been identified by PsalmPHP (see issue #98321).

Resolves: #98329
Releases: main, 11.5
Change-Id: Ia348a8dec1590b641c7ed90247afac29ef43e2af
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/75687


Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Susanne Moog's avatarSusanne Moog <look@susi.dev>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Tested-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Klee's avatarOliver Klee <typo3-coding@oliverklee.de>
Reviewed-by: Susanne Moog's avatarSusanne Moog <look@susi.dev>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Reviewed-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
parent cdf920a6
......@@ -28,6 +28,7 @@ use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Dashboard\Dashboard;
use TYPO3\CMS\Dashboard\DashboardInitializationService;
use TYPO3\CMS\Dashboard\DashboardPreset;
use TYPO3\CMS\Dashboard\DashboardPresetRegistry;
use TYPO3\CMS\Dashboard\DashboardRepository;
use TYPO3\CMS\Dashboard\WidgetGroupInitializationService;
......@@ -100,7 +101,7 @@ class DashboardController
protected function setActiveDashboardAction(ServerRequestInterface $request): ResponseInterface
{
$this->saveCurrentDashboard($request->getQueryParams()['currentDashboard']);
$this->saveCurrentDashboard((string)($request->getQueryParams()['currentDashboard'] ?? ''));
$route = $this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'main']);
return new RedirectResponse($route);
}
......@@ -108,9 +109,14 @@ class DashboardController
protected function addDashboardAction(ServerRequestInterface $request): ResponseInterface
{
$parameters = $request->getParsedBody();
$dashboardIdentifier = $parameters['dashboard'] ?? '';
if ($dashboardIdentifier !== '') {
$dashboard = $this->dashboardRepository->create($this->dashboardPresetRepository->getDashboardPresets()[$dashboardIdentifier], (int)$this->getBackendUser()->user['uid'], $parameters['dashboard-title']);
$dashboardIdentifier = (string)($parameters['dashboard'] ?? '');
$dashboardPreset = $this->dashboardPresetRepository->getDashboardPresets()[$dashboardIdentifier] ?? null;
if ($dashboardPreset instanceof DashboardPreset) {
$dashboard = $this->dashboardRepository->create(
$dashboardPreset,
(int)$this->getBackendUser()->user['uid'],
$parameters['dashboard-title'] ?? ''
);
if ($dashboard instanceof Dashboard) {
$this->saveCurrentDashboard($dashboard->getIdentifier());
}
......@@ -141,9 +147,9 @@ class DashboardController
protected function removeWidgetAction(ServerRequestInterface $request): ResponseInterface
{
$parameters = $request->getQueryParams();
$widgetHash = $parameters['widgetHash'];
$widgetHash = $parameters['widgetHash'] ?? '';
$widgets = $this->currentDashboard->getWidgetConfig();
if (array_key_exists($widgetHash, $widgets)) {
if ($widgetHash !== '' && array_key_exists($widgetHash, $widgets)) {
unset($widgets[$widgetHash]);
$this->dashboardRepository->updateWidgetConfig($this->currentDashboard, $widgets);
}
......
......@@ -40,8 +40,9 @@ class WidgetAjaxController
public function getContent(ServerRequestInterface $request): ResponseInterface
{
$queryParams = $request->getQueryParams();
$widget = (string)($queryParams['widget'] ?? '');
try {
$widgetObject = $this->widgetRegistry->getAvailableWidget($request, (string)$queryParams['widget']);
$widgetObject = $this->widgetRegistry->getAvailableWidget($request, $widget);
} catch (\InvalidArgumentException $e) {
return new JsonResponse(['error' => 'Widget is not available!']);
}
......@@ -49,7 +50,7 @@ class WidgetAjaxController
return new JsonResponse(['error' => 'Widget doesn\'t have a valid widget class']);
}
$data = [
'widget' => $queryParams['widget'],
'widget' => $widget,
'content' => $widgetObject->renderWidgetContent(),
'eventdata' => $widgetObject instanceof EventDataInterface ? $widgetObject->getEventData() : [],
];
......@@ -64,7 +65,10 @@ class WidgetAjaxController
$backendUser = $this->getBackendUser();
$body = $request->getParsedBody();
$widgets = [];
foreach ($body['widgets'] as $widget) {
foreach ($body['widgets'] ?? [] as $widget) {
if (!is_string($widget[0] ?? null) || !is_string($widget[1] ?? null)) {
continue;
}
$widgets[$widget[1]] = ['identifier' => $widget[0]];
}
$currentDashboard = $this->dashboardRepository->getDashboardByIdentifier($backendUser->getModuleData('dashboard/current_dashboard/') ?? '');
......
......@@ -116,10 +116,11 @@ class Dashboard
{
$availableWidgets = $this->widgetRegistry->getAvailableWidgets();
foreach ($this->widgetConfig as $hash => $widgetConfig) {
if (array_key_exists($widgetConfig['identifier'], $availableWidgets)) {
$this->widgets[$hash] = $availableWidgets[$widgetConfig['identifier']];
$widgetConfigIdentifier = $widgetConfig['identifier'] ?? '';
if ($widgetConfigIdentifier !== '' && array_key_exists($widgetConfigIdentifier, $availableWidgets)) {
$this->widgets[$hash] = $availableWidgets[$widgetConfigIdentifier];
$widgetObject = $this->widgetRegistry->getAvailableWidget($request, $widgetConfig['identifier']);
$widgetObject = $this->widgetRegistry->getAvailableWidget($request, $widgetConfigIdentifier);
$this->widgetOptions[$hash] = $widgetObject->getOptions();
}
}
......
......@@ -61,7 +61,7 @@ class DashboardInitializationService
protected $javaScriptModuleInstructions = [];
/**
* @var list<string|list<string>>
* @var list<string|array{0:string, 1:string}>
* @deprecated will be removed in TYPO3 v13.0
*/
private $requireJsModules = [];
......@@ -243,7 +243,7 @@ class DashboardInitializationService
}
/**
* @return list<string|list<string>>
* @return list<string|array{0:string, 1:string}>
* @deprecated will be removed in TYPO3 v13.0
*/
public function getRequireJsModules(): array
......
......@@ -206,9 +206,9 @@ class DashboardRepository
{
return GeneralUtility::makeInstance(
Dashboard::class,
$row['identifier'],
$row['title'],
json_decode((string)$row['widgets'], true) ?? [],
$row['identifier'] ?? '',
$row['title'] ?? '',
json_decode((string)($row['widgets'] ?? ''), true) ?? [],
$this->widgetRegistry,
$this->container
);
......
......@@ -25,7 +25,7 @@ class WidgetApi
/**
* Provides default colors to use for charts.
*
* @return array Hex codes of default colors.
* @return array{0:string, 1:string, 2:string, 3:string, 4:string} Hex codes of default colors.
*/
public static function getDefaultChartColors(): array
{
......
......@@ -35,6 +35,9 @@ use TYPO3\CMS\Fluid\View\StandaloneView;
*/
class CtaWidget implements WidgetInterface, RequestAwareWidgetInterface
{
/**
* @var array{text: string}
*/
private readonly array $options;
private ServerRequestInterface $request;
......
......@@ -39,6 +39,9 @@ use TYPO3\CMS\Fluid\View\StandaloneView;
*/
class RssWidget implements WidgetInterface, RequestAwareWidgetInterface
{
/**
* @var array{limit: int, lifeTime: int, feedUrl?: string}
*/
private readonly array $options;
private ServerRequestInterface $request;
......@@ -79,6 +82,9 @@ class RssWidget implements WidgetInterface, RequestAwareWidgetInterface
protected function getRssItems(): array
{
if (empty($this->options['feedUrl'])) {
return [];
}
$cacheHash = md5($this->options['feedUrl']);
if ($items = $this->cache->get($cacheHash)) {
return $items;
......
Supports Markdown
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