diff options
Diffstat (limited to 'apps/dashboard/lib')
-rw-r--r-- | apps/dashboard/lib/Controller/DashboardApiController.php | 108 | ||||
-rw-r--r-- | apps/dashboard/lib/Controller/DashboardController.php | 82 | ||||
-rw-r--r-- | apps/dashboard/lib/Controller/LayoutApiController.php | 56 | ||||
-rw-r--r-- | apps/dashboard/lib/ResponseDefinitions.php | 30 | ||||
-rw-r--r-- | apps/dashboard/lib/Service/DashboardService.php | 71 |
5 files changed, 173 insertions, 174 deletions
diff --git a/apps/dashboard/lib/Controller/DashboardApiController.php b/apps/dashboard/lib/Controller/DashboardApiController.php index 329b045c461..d31cede85b7 100644 --- a/apps/dashboard/lib/Controller/DashboardApiController.php +++ b/apps/dashboard/lib/Controller/DashboardApiController.php @@ -3,33 +3,18 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2021 Julien Veyssier <eneiluj@posteo.net> - * - * @author Julien Veyssier <eneiluj@posteo.net> - * @author Kate Döen <kate.doeen@nextcloud.com> - * @author Richard Steinmetz <richard@steinmetz.cloud> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Dashboard\Controller; use OCA\Dashboard\ResponseDefinitions; +use OCA\Dashboard\Service\DashboardService; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\ApiRoute; +use OCP\AppFramework\Http\Attribute\NoAdminRequired; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; use OCP\Dashboard\IAPIWidget; @@ -60,6 +45,7 @@ class DashboardApiController extends OCSController { private IManager $dashboardManager, private IConfig $config, private ?string $userId, + private DashboardService $service, ) { parent::__construct($appName, $request); } @@ -83,19 +69,19 @@ class DashboardApiController extends OCSController { } /** - * @NoAdminRequired - * @NoCSRFRequired - * * Get the items for the widgets * * @param array<string, string> $sinceIds Array indexed by widget Ids, contains date/id from which we want the new items * @param int $limit Limit number of result items per widget * @psalm-param int<1, 30> $limit - * @param string[] $widgets Limit results to specific widgets - * @return DataResponse<Http::STATUS_OK, array<string, DashboardWidgetItem[]>, array{}> + * @param list<string> $widgets Limit results to specific widgets + * @return DataResponse<Http::STATUS_OK, array<string, list<DashboardWidgetItem>>, array{}> * * 200: Widget items returned */ + #[NoAdminRequired] + #[NoCSRFRequired] + #[ApiRoute(verb: 'GET', url: '/api/v1/widget-items')] public function getWidgetItems(array $sinceIds = [], int $limit = 7, array $widgets = []): DataResponse { $items = []; $widgets = $this->getShownWidgets($widgets); @@ -111,19 +97,19 @@ class DashboardApiController extends OCSController { } /** - * @NoAdminRequired - * @NoCSRFRequired - * * Get the items for the widgets * * @param array<string, string> $sinceIds Array indexed by widget Ids, contains date/id from which we want the new items * @param int $limit Limit number of result items per widget, not more than 30 are allowed * @psalm-param int<1, 30> $limit - * @param string[] $widgets Limit results to specific widgets + * @param list<string> $widgets Limit results to specific widgets * @return DataResponse<Http::STATUS_OK, array<string, DashboardWidgetItems>, array{}> * * 200: Widget items returned */ + #[NoAdminRequired] + #[NoCSRFRequired] + #[ApiRoute(verb: 'GET', url: '/api/v2/widget-items')] public function getWidgetItemsV2(array $sinceIds = [], int $limit = 7, array $widgets = []): DataResponse { $items = []; $widgets = $this->getShownWidgets($widgets); @@ -141,13 +127,13 @@ class DashboardApiController extends OCSController { /** * Get the widgets * - * @NoAdminRequired - * @NoCSRFRequired - * * @return DataResponse<Http::STATUS_OK, array<string, DashboardWidget>, array{}> * * 200: Widgets returned */ + #[NoAdminRequired] + #[NoCSRFRequired] + #[ApiRoute(verb: 'GET', url: '/api/v1/widgets')] public function getWidgets(): DataResponse { $widgets = $this->dashboardManager->getWidgets(); @@ -189,4 +175,60 @@ class DashboardApiController extends OCSController { return new DataResponse($items); } + + /** + * Get the layout + * + * @return DataResponse<Http::STATUS_OK, array{layout: list<string>}, array{}> + * + * 200: Layout returned + */ + #[NoAdminRequired] + #[ApiRoute(verb: 'GET', url: '/api/v3/layout')] + public function getLayout(): DataResponse { + return new DataResponse(['layout' => $this->service->getLayout()]); + } + + /** + * Update the layout + * + * @param list<string> $layout The new layout + * @return DataResponse<Http::STATUS_OK, array{layout: list<string>}, array{}> + * + * 200: Statuses updated successfully + */ + #[NoAdminRequired] + #[ApiRoute(verb: 'POST', url: '/api/v3/layout')] + public function updateLayout(array $layout): DataResponse { + $this->config->setUserValue($this->userId, 'dashboard', 'layout', implode(',', $layout)); + return new DataResponse(['layout' => $layout]); + } + + /** + * Get the statuses + * + * @return DataResponse<Http::STATUS_OK, array{statuses: list<string>}, array{}> + * + * 200: Statuses returned + */ + #[NoAdminRequired] + #[ApiRoute(verb: 'GET', url: '/api/v3/statuses')] + public function getStatuses(): DataResponse { + return new DataResponse(['statuses' => $this->service->getStatuses()]); + } + + /** + * Update the statuses + * + * @param list<string> $statuses The new statuses + * @return DataResponse<Http::STATUS_OK, array{statuses: list<string>}, array{}> + * + * 200: Statuses updated successfully + */ + #[NoAdminRequired] + #[ApiRoute(verb: 'POST', url: '/api/v3/statuses')] + public function updateStatuses(array $statuses): DataResponse { + $this->config->setUserValue($this->userId, 'dashboard', 'statuses', implode(',', $statuses)); + return new DataResponse(['statuses' => $statuses]); + } } diff --git a/apps/dashboard/lib/Controller/DashboardController.php b/apps/dashboard/lib/Controller/DashboardController.php index e5cda4adf11..da7e0901115 100644 --- a/apps/dashboard/lib/Controller/DashboardController.php +++ b/apps/dashboard/lib/Controller/DashboardController.php @@ -3,45 +3,28 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net> - * - * @author Julien Veyssier <eneiluj@posteo.net> - * @author Julius Härtl <jus@bitgrid.net> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Kate Döen <kate.doeen@nextcloud.com> - * @author Eduardo Morales <eduardo.morales@nextcloud.com> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Dashboard\Controller; +use OCA\Dashboard\Service\DashboardService; use OCP\AppFramework\Controller; -use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\FrontpageRoute; +use OCP\AppFramework\Http\Attribute\NoAdminRequired; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\Attribute\OpenAPI; -use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\FeaturePolicy; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; +use OCP\Dashboard\IIconWidget; use OCP\Dashboard\IManager; use OCP\Dashboard\IWidget; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IL10N; use OCP\IRequest; +use OCP\Util; #[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)] class DashboardController extends Controller { @@ -54,41 +37,38 @@ class DashboardController extends Controller { private IManager $dashboardManager, private IConfig $config, private IL10N $l10n, - private ?string $userId + private ?string $userId, + private DashboardService $service, ) { parent::__construct($appName, $request); } /** - * @NoCSRFRequired - * @NoAdminRequired * @return TemplateResponse */ + #[NoCSRFRequired] + #[NoAdminRequired] + #[FrontpageRoute(verb: 'GET', url: '/')] public function index(): TemplateResponse { - \OCP\Util::addStyle('dashboard', 'dashboard'); - \OCP\Util::addScript('dashboard', 'main', 'theming'); + Util::addStyle('dashboard', 'dashboard'); + Util::addScript('dashboard', 'main', 'theming'); - $systemDefault = $this->config->getAppValue('dashboard', 'layout', 'recommendations,spreed,mail,calendar'); - $userLayout = explode(',', $this->config->getUserValue($this->userId, 'dashboard', 'layout', $systemDefault)); $widgets = array_map(function (IWidget $widget) { return [ 'id' => $widget->getId(), 'title' => $widget->getTitle(), 'iconClass' => $widget->getIconClass(), + 'iconUrl' => $widget instanceof IIconWidget ? $widget->getIconUrl() : '', 'url' => $widget->getUrl() ]; }, $this->dashboardManager->getWidgets()); - $configStatuses = $this->config->getUserValue($this->userId, 'dashboard', 'statuses', ''); - $statuses = json_decode($configStatuses, true); - // We avoid getting an empty array as it will not produce an object in UI's JS - // It does not matter if some statuses are missing from the array, missing ones are considered enabled - $statuses = ($statuses && count($statuses) > 0) ? $statuses : ['weather' => true]; $this->initialState->provideInitialState('panels', $widgets); - $this->initialState->provideInitialState('statuses', $statuses); - $this->initialState->provideInitialState('layout', $userLayout); + $this->initialState->provideInitialState('statuses', $this->service->getStatuses()); + $this->initialState->provideInitialState('layout', $this->service->getLayout()); $this->initialState->provideInitialState('appStoreEnabled', $this->config->getSystemValueBool('appstoreenabled', true)); $this->initialState->provideInitialState('firstRun', $this->config->getUserValue($this->userId, 'dashboard', 'firstRun', '1') === '1'); + $this->initialState->provideInitialState('birthdate', $this->service->getBirthdate()); $this->config->setUserValue($this->userId, 'dashboard', 'firstRun', '0'); $response = new TemplateResponse('dashboard', 'index', [ @@ -98,30 +78,10 @@ class DashboardController extends Controller { ]); // For the weather widget we should allow the geolocation - $featurePolicy = new Http\FeaturePolicy(); + $featurePolicy = new FeaturePolicy(); $featurePolicy->addAllowedGeoLocationDomain('\'self\''); $response->setFeaturePolicy($featurePolicy); return $response; } - - /** - * @NoAdminRequired - * @param string $layout - * @return JSONResponse - */ - public function updateLayout(string $layout): JSONResponse { - $this->config->setUserValue($this->userId, 'dashboard', 'layout', $layout); - return new JSONResponse(['layout' => $layout]); - } - - /** - * @NoAdminRequired - * @param string $statuses - * @return JSONResponse - */ - public function updateStatuses(string $statuses): JSONResponse { - $this->config->setUserValue($this->userId, 'dashboard', 'statuses', $statuses); - return new JSONResponse(['statuses' => $statuses]); - } } diff --git a/apps/dashboard/lib/Controller/LayoutApiController.php b/apps/dashboard/lib/Controller/LayoutApiController.php deleted file mode 100644 index e603997a854..00000000000 --- a/apps/dashboard/lib/Controller/LayoutApiController.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php - -declare(strict_types=1); - -/** - * @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net> - * - * @author Julius Härtl <jus@bitgrid.net> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ -namespace OCA\Dashboard\Controller; - -use OCP\AppFramework\Http\JSONResponse; -use OCP\AppFramework\OCSController; -use OCP\IConfig; -use OCP\IRequest; - -class LayoutApiController extends OCSController { - - public function __construct( - string $appName, - IRequest $request, - private IConfig $config, - private ?string $userId, - ) { - parent::__construct($appName, $request); - - } - - /** - * @NoAdminRequired - * - * @param string $layout - * @return JSONResponse - */ - public function create(string $layout): JSONResponse { - $layout = htmlspecialchars($layout); - $this->config->setUserValue($this->userId, 'dashboard', 'layout', $layout); - return new JSONResponse(['layout' => $layout]); - } -} diff --git a/apps/dashboard/lib/ResponseDefinitions.php b/apps/dashboard/lib/ResponseDefinitions.php index 5592af1a324..be5a4d56883 100644 --- a/apps/dashboard/lib/ResponseDefinitions.php +++ b/apps/dashboard/lib/ResponseDefinitions.php @@ -3,26 +3,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2023 Kate Döen <kate.doeen@nextcloud.com> - * - * @author Kate Döen <kate.doeen@nextcloud.com> - * @author Richard Steinmetz <richard@steinmetz.cloud> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Dashboard; @@ -36,13 +18,13 @@ namespace OCA\Dashboard; * icon_url: string, * widget_url: ?string, * item_icons_round: bool, - * item_api_versions: int[], + * item_api_versions: list<int>, * reload_interval: int, - * buttons?: array{ + * buttons?: list<array{ * type: string, * text: string, * link: string, - * }[], + * }>, * } * * @psalm-type DashboardWidgetItem = array{ @@ -55,7 +37,7 @@ namespace OCA\Dashboard; * } * * @psalm-type DashboardWidgetItems = array{ - * items: DashboardWidgetItem[], + * items: list<DashboardWidgetItem>, * emptyContentMessage: string, * halfEmptyContentMessage: string, * } diff --git a/apps/dashboard/lib/Service/DashboardService.php b/apps/dashboard/lib/Service/DashboardService.php new file mode 100644 index 00000000000..bb5333c2cc7 --- /dev/null +++ b/apps/dashboard/lib/Service/DashboardService.php @@ -0,0 +1,71 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\Dashboard\Service; + +use JsonException; +use OCP\Accounts\IAccountManager; +use OCP\Accounts\PropertyDoesNotExistException; +use OCP\IConfig; +use OCP\IUserManager; + +class DashboardService { + public function __construct( + private IConfig $config, + private ?string $userId, + private IUserManager $userManager, + private IAccountManager $accountManager, + ) { + + } + + /** + * @return list<string> + */ + public function getLayout(): array { + $systemDefault = $this->config->getAppValue('dashboard', 'layout', 'recommendations,spreed,mail,calendar'); + return array_values(array_filter(explode(',', $this->config->getUserValue($this->userId, 'dashboard', 'layout', $systemDefault)), fn (string $value) => $value !== '')); + } + + /** + * @return list<string> + */ + public function getStatuses() { + $configStatuses = $this->config->getUserValue($this->userId, 'dashboard', 'statuses', ''); + try { + // Parse the old format + /** @var array<string, bool> $statuses */ + $statuses = json_decode($configStatuses, true, 512, JSON_THROW_ON_ERROR); + // We avoid getting an empty array as it will not produce an object in UI's JS + return array_keys(array_filter($statuses, static fn (bool $value) => $value)); + } catch (JsonException $e) { + return array_values(array_filter(explode(',', $configStatuses), fn (string $value) => $value !== '')); + } + } + + public function getBirthdate(): string { + if ($this->userId === null) { + return ''; + } + + $user = $this->userManager->get($this->userId); + if ($user === null) { + return ''; + } + + $account = $this->accountManager->getAccount($user); + + try { + $birthdate = $account->getProperty(IAccountManager::PROPERTY_BIRTHDATE); + } catch (PropertyDoesNotExistException) { + return ''; + } + + return $birthdate->getValue(); + } +} |