diff --git a/REUSE.toml b/REUSE.toml index f91618551c..4143215bee 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -29,6 +29,12 @@ precedence = "aggregate" SPDX-FileCopyrightText = "2025 Nextcloud GmbH and Nextcloud contributors" SPDX-License-Identifier = "AGPL-3.0-or-later" +[[annotations]] +path = ["vendor-bin/rector/composer.json", "vendor-bin/rector/composer.lock", "tests/psalm-baseline.xml"] +precedence = "aggregate" +SPDX-FileCopyrightText = "2026 Nextcloud GmbH and Nextcloud contributors" +SPDX-License-Identifier = "AGPL-3.0-or-later" + [[annotations]] path = ["img/app-dark.svg", "img/app.svg", "img/view.svg", "img/view-dark.svg", "img/material/*.svg"] precedence = "aggregate" diff --git a/composer.json b/composer.json index 28c2f55eca..9576254d77 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "nextcloud/ocp": "dev-stable33", "staabm/annotate-pull-request-from-checkstyle": "^1.8.7", "phpunit/phpunit": "9.6.34", - "psalm/phar": "^5.26.1" + "psalm/phar": "^6.16" }, "config": { "optimize-autoloader": true, @@ -44,6 +44,8 @@ "psalm:fix": "./vendor/bin/psalm.phar --no-cache --alter --issues=InvalidReturnType,InvalidNullableReturnType,MismatchingDocblockParamType,MismatchingDocblockReturnType,MissingParamType,InvalidFalsableReturnType", "psalm:fix:dry": "./vendor/bin/psalm.phar --no-cache --alter --issues=InvalidReturnType,InvalidNullableReturnType,MismatchingDocblockParamType,MismatchingDocblockReturnType,MissingParamType,InvalidFalsableReturnType --dry-run", "openapi": "generate-spec --verbose && (npm run typescript:generate || echo 'Please manually regenerate the typescript OpenAPI models')", + "rector:check": "rector --dry-run", + "rector:fix": "rector", "scoper:update-deps": "./update-scoper-dependencies.sh", "post-install-cmd": [ "composer bin all install --ansi", diff --git a/composer.lock b/composer.lock index 58b0e3d1da..18cbab938c 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": "46861b4f8ab5cf979b0b581545a099c5", + "content-hash": "d6c9394cea791c9e28ff556f1a67bb7b", "packages": [ { "name": "bamarni/composer-bin-plugin", @@ -1424,20 +1424,20 @@ }, { "name": "psalm/phar", - "version": "5.26.1", + "version": "6.16.1", "source": { "type": "git", "url": "https://github.com/psalm/phar.git", - "reference": "8a38e7ad04499a0ccd2c506fd1da6fc01fff4547" + "reference": "11c6b55449667837fc07bb2a456c45a137c05ecd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/psalm/phar/zipball/8a38e7ad04499a0ccd2c506fd1da6fc01fff4547", - "reference": "8a38e7ad04499a0ccd2c506fd1da6fc01fff4547", + "url": "https://api.github.com/repos/psalm/phar/zipball/11c6b55449667837fc07bb2a456c45a137c05ecd", + "reference": "11c6b55449667837fc07bb2a456c45a137c05ecd", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.2" }, "conflict": { "vimeo/psalm": "*" @@ -1453,9 +1453,9 @@ "description": "Composer-based Psalm Phar", "support": { "issues": "https://github.com/psalm/phar/issues", - "source": "https://github.com/psalm/phar/tree/5.26.1" + "source": "https://github.com/psalm/phar/tree/6.16.1" }, - "time": "2024-09-09T16:22:43+00:00" + "time": "2026-03-19T11:11:23+00:00" }, { "name": "psr/clock", diff --git a/lib/Activity/ActivityManager.php b/lib/Activity/ActivityManager.php index 7ec0070972..e7a6e790c3 100644 --- a/lib/Activity/ActivityManager.php +++ b/lib/Activity/ActivityManager.php @@ -47,7 +47,16 @@ public function __construct( ) { } - public function triggerEvent($objectType, $object, $subject, $additionalParams = [], $author = null) { + /** + * @param Row2|Table $object + * @param \OCA\Tables\Model\ImportStats[]|null|string $additionalParams + * @param (array|null)[]|null|string $author + * + * @psalm-param 'tables_row'|'tables_table' $objectType + * @psalm-param array{importStats?: \OCA\Tables\Model\ImportStats}|null|string $additionalParams + * @psalm-param array{before: array|null, after: array|null}|null|string $author + */ + public function triggerEvent(string $objectType, Table|Row2 $object, string $subject, array|string|null $additionalParams = [], array|string|null $author = null) { if ($author === null) { $author = $this->userId; } @@ -58,19 +67,23 @@ public function triggerEvent($objectType, $object, $subject, $additionalParams = if ($event !== null) { $this->sendToUsers($event, $object); } - } catch (\Exception $e) { + } catch (\Exception) { // Ignore exception for undefined activities on update events } } - public function triggerUpdateEvents($objectType, ChangeSet $changeSet, $subject) { + /** + * @psalm-param 'tables_table' $objectType + * @psalm-param 'table_update' $subject + */ + public function triggerUpdateEvents(string $objectType, ChangeSet $changeSet, string $subject) { $previousEntity = $changeSet->getBefore(); $entity = $changeSet->getAfter(); $events = []; if ($previousEntity !== null) { foreach ($entity->getUpdatedFields() as $field => $value) { - $getter = 'get' . ucfirst($field); + $getter = 'get' . ucfirst((string)$field); $subjectComplete = $subject . '_' . $field; $changes = [ 'before' => $previousEntity->$getter(), @@ -82,7 +95,7 @@ public function triggerUpdateEvents($objectType, ChangeSet $changeSet, $subject) if ($event !== null) { $events[] = $event; } - } catch (\Exception $e) { + } catch (\Exception) { // Ignore exception for undefined activities on update events } } @@ -90,7 +103,7 @@ public function triggerUpdateEvents($objectType, ChangeSet $changeSet, $subject) } else { try { $events = [$this->createEvent($objectType, $entity, $subject)]; - } catch (\Exception $e) { + } catch (\Exception) { // Ignore exception for undefined activities on update events } } @@ -100,7 +113,14 @@ public function triggerUpdateEvents($objectType, ChangeSet $changeSet, $subject) } } - private function createEvent($objectType, $object, $subject, $additionalParams = [], $author = null) { + /** + * @psalm-param array{before?: mixed, after?: mixed} $additionalParams + * @psalm-param 'tables_row'|'tables_table' $objectType + * @psalm-param array{before: array|null, after: array|null}|null|string $author + * + * @param (array|null)[]|null|string $author + */ + private function createEvent(string $objectType, Row2|Table $object, string $subject, array $additionalParams = [], array|string|null $author = null) { if ($object instanceof Table) { $objectTitle = $object->getTitle(); $table = $object; @@ -118,7 +138,7 @@ private function createEvent($objectType, $object, $subject, $additionalParams = */ $eventType = 'tables'; $subjectParams = [ - 'author' => $author === null ? $this->userId : $author, + 'author' => $author ?? $this->userId, 'table' => $table ]; switch ($subject) { @@ -181,7 +201,7 @@ private function createEvent($objectType, $object, $subject, $additionalParams = return $event; } - private function sendToUsers(IEvent $event, $object) { + private function sendToUsers(IEvent $event, Row2|Table $object) { if ($object instanceof Table) { $tableId = $object->getId(); $owner = $object->getOwnership(); @@ -204,7 +224,7 @@ private function sendToUsers(IEvent $event, $object) { } } - public function getActivitySubject($language, $subjectIdentifier, $subjectParams = [], $ownActivity = false) { + public function getActivitySubject(string $language, $subjectIdentifier, array $subjectParams = [], bool $ownActivity = false) { $subject = ''; $l = $this->l10nFactory->get(Application::APP_ID, $language); @@ -262,7 +282,7 @@ public function getActivitySubject($language, $subjectIdentifier, $subjectParams return $subject; } - public function getActivityMessage($language, $subjectIdentifier) { + public function getActivityMessage(string $language, $subjectIdentifier) { $l = $this->l10nFactory->get(Application::APP_ID, $language); switch ($subjectIdentifier) { diff --git a/lib/Activity/ChangeSet.php b/lib/Activity/ChangeSet.php index 4ec67cde9d..ea850a537a 100644 --- a/lib/Activity/ChangeSet.php +++ b/lib/Activity/ChangeSet.php @@ -24,11 +24,11 @@ public function __construct( } } - public function setBefore($before) { + public function setBefore(Entity $before) { $this->before = clone $before; } - public function setAfter($after) { + public function setAfter(Entity $after) { $this->after = clone $after; } diff --git a/lib/Activity/TablesProvider.php b/lib/Activity/TablesProvider.php index fe23c4f55d..9f2d07d2ea 100644 --- a/lib/Activity/TablesProvider.php +++ b/lib/Activity/TablesProvider.php @@ -19,10 +19,10 @@ class TablesProvider implements IProvider { public function __construct( private $userId, - private IURLGenerator $urlGenerator, - private ActivityManager $activityManager, - private IUserManager $userManager, - private LoggerInterface $logger, + private readonly IURLGenerator $urlGenerator, + private readonly ActivityManager $activityManager, + private readonly IUserManager $userManager, + private readonly LoggerInterface $logger, ) { } diff --git a/lib/Analytics/AnalyticsDatasource.php b/lib/Analytics/AnalyticsDatasource.php index 170f35ddc8..7fdfa74b72 100644 --- a/lib/Analytics/AnalyticsDatasource.php +++ b/lib/Analytics/AnalyticsDatasource.php @@ -23,31 +23,15 @@ class AnalyticsDatasource implements IDatasource { - private LoggerInterface $logger; - private IL10N $l10n; - private TableService $tableService; - private ViewService $viewService; - private RowService $rowService; - private ColumnService $columnService; - - protected ?string $userId; - public function __construct( - IL10N $l10n, - LoggerInterface $logger, - TableService $tableService, - ViewService $viewService, - ColumnService $columnService, - RowService $rowService, - ?string $userId, + private readonly IL10N $l10n, + private readonly LoggerInterface $logger, + private readonly TableService $tableService, + private readonly ViewService $viewService, + private readonly ColumnService $columnService, + private readonly RowService $rowService, + protected ?string $userId, ) { - $this->l10n = $l10n; - $this->logger = $logger; - $this->tableService = $tableService; - $this->viewService = $viewService; - $this->columnService = $columnService; - $this->rowService = $rowService; - $this->userId = $userId; } /** @@ -110,7 +94,7 @@ public function getTemplate(): array { // concatenate the option-string. The format is tableId:viewId-title $tableString = $tableString . $table->getId() . ':' . $view->getId() . '-' . $view->getTitle() . '/'; } - } catch (PermissionError $e) { + } catch (PermissionError) { // this is a shared table without shared views; continue; } @@ -164,7 +148,7 @@ public function getTemplate(): array { */ public function readData($option): array { // get the ids which come in the format tableId:viewId - $ids = explode(':', $option['tableId']); + $ids = explode(':', (string)$option['tableId']); $this->userId = $option['user_id']; if (count($ids) === 1) { @@ -338,7 +322,7 @@ private function formatBooleanValue(mixed $value): string { return ''; } - private function formatTextValue(Column $column, mixed $value): string { + private function formatTextValue(Column $column, string $value): string { if ($value === null || $value === '') { return ''; } diff --git a/lib/Api/V1Api.php b/lib/Api/V1Api.php index bff1779b07..2e8f0eb565 100644 --- a/lib/Api/V1Api.php +++ b/lib/Api/V1Api.php @@ -16,14 +16,11 @@ use OCP\AppFramework\Db\MultipleObjectsReturnedException; class V1Api { - private RowService $rowService; - private ColumnService $columnService; - private ?string $userId; - - public function __construct(ColumnService $columnService, RowService $rowService, ?string $userId) { - $this->columnService = $columnService; - $this->rowService = $rowService; - $this->userId = $userId; + public function __construct( + private readonly ColumnService $columnService, + private readonly RowService $rowService, + private ?string $userId, + ) { } /** diff --git a/lib/BackgroundJob/ConvertViewColumnsFormat.php b/lib/BackgroundJob/ConvertViewColumnsFormat.php index 8ac5eeed1c..34aed4e53a 100644 --- a/lib/BackgroundJob/ConvertViewColumnsFormat.php +++ b/lib/BackgroundJob/ConvertViewColumnsFormat.php @@ -44,7 +44,7 @@ public function run($argument) { $maxId = 0; // Update each view - while ($view = $result->fetch()) { + while ($view = $result->fetchAssociative()) { $this->processView($view, $updateQb); $maxId = max($maxId, (int)$view['id']); } @@ -67,7 +67,7 @@ private function processView(array $view, \OCP\DB\QueryBuilder\IQueryBuilder $up } // Parse existing columns JSON - $columns = json_decode($view['columns'], true); + $columns = json_decode((string)$view['columns'], true); if (!is_array($columns)) { return; } diff --git a/lib/BackgroundJob/ImportTableJob.php b/lib/BackgroundJob/ImportTableJob.php index cf63446f05..7940505cd8 100644 --- a/lib/BackgroundJob/ImportTableJob.php +++ b/lib/BackgroundJob/ImportTableJob.php @@ -19,12 +19,12 @@ class ImportTableJob extends QueuedJob { public function __construct( ITimeFactory $time, - private IUserManager $userManager, - private IUserSession $userSession, - private ImportService $importService, - private ActivityManager $activityManager, - private TableMapper $tableMapper, - private ViewMapper $viewMapper, + private readonly IUserManager $userManager, + private readonly IUserSession $userSession, + private readonly ImportService $importService, + private readonly ActivityManager $activityManager, + private readonly TableMapper $tableMapper, + private readonly ViewMapper $viewMapper, ) { parent::__construct($time); } diff --git a/lib/Capabilities.php b/lib/Capabilities.php index cfe251f900..59212529c4 100644 --- a/lib/Capabilities.php +++ b/lib/Capabilities.php @@ -19,19 +19,12 @@ * @package OCA\Tables */ class Capabilities implements ICapability { - private IAppManager $appManager; - - private LoggerInterface $logger; - - private IConfig $config; - - private CircleHelper $circleHelper; - - public function __construct(IAppManager $appManager, LoggerInterface $logger, IConfig $config, CircleHelper $circleHelper) { - $this->appManager = $appManager; - $this->logger = $logger; - $this->config = $config; - $this->circleHelper = $circleHelper; + public function __construct( + private readonly IAppManager $appManager, + private readonly LoggerInterface $logger, + private readonly IConfig $config, + private readonly CircleHelper $circleHelper, + ) { } /** diff --git a/lib/Command/AddTable.php b/lib/Command/AddTable.php index 944a7eb7c9..fb6c0cfa91 100644 --- a/lib/Command/AddTable.php +++ b/lib/Command/AddTable.php @@ -20,13 +20,11 @@ use Symfony\Component\Console\Output\OutputInterface; class AddTable extends Command { - protected TableService $tableService; - protected LoggerInterface $logger; - - public function __construct(TableService $tableService, LoggerInterface $logger) { + public function __construct( + protected TableService $tableService, + protected LoggerInterface $logger, + ) { parent::__construct(); - $this->tableService = $tableService; - $this->logger = $logger; } protected function configure(): void { diff --git a/lib/Command/ChangeOwnershipTable.php b/lib/Command/ChangeOwnershipTable.php index de412aa53a..6fbac5cb7d 100644 --- a/lib/Command/ChangeOwnershipTable.php +++ b/lib/Command/ChangeOwnershipTable.php @@ -18,13 +18,11 @@ use Symfony\Component\Console\Output\OutputInterface; class ChangeOwnershipTable extends Command { - protected TableService $tableService; - protected LoggerInterface $logger; - - public function __construct(TableService $tableService, LoggerInterface $logger) { + public function __construct( + protected TableService $tableService, + protected LoggerInterface $logger, + ) { parent::__construct(); - $this->tableService = $tableService; - $this->logger = $logger; } protected function configure(): void { diff --git a/lib/Command/Clean.php b/lib/Command/Clean.php index 40e49efcd5..4617940817 100644 --- a/lib/Command/Clean.php +++ b/lib/Command/Clean.php @@ -28,12 +28,6 @@ class Clean extends Command { public const PRINT_LEVEL_WARNING = 3; public const PRINT_LEVEL_ERROR = 4; - protected ColumnService $columnService; - protected RowService $rowService; - protected TableService $tableService; - protected LoggerInterface $logger; - protected Row2Mapper $rowMapper; - private bool $dry = false; private int $truncateLength = 20; @@ -42,13 +36,14 @@ class Clean extends Command { private OutputInterface $output; - public function __construct(LoggerInterface $logger, ColumnService $columnService, RowService $rowService, TableService $tableService, Row2Mapper $rowMapper) { + public function __construct( + protected LoggerInterface $logger, + protected ColumnService $columnService, + protected RowService $rowService, + protected TableService $tableService, + protected Row2Mapper $rowMapper, + ) { parent::__construct(); - $this->logger = $logger; - $this->columnService = $columnService; - $this->rowService = $rowService; - $this->tableService = $tableService; - $this->rowMapper = $rowMapper; } protected function configure(): void { @@ -141,7 +136,7 @@ private function checkColumns(): void { } catch (InternalError $e) { $this->print('😱️ internal error while looking for column', self::PRINT_LEVEL_ERROR); $this->logger->error('Following error occurred during executing occ command "' . self::class . '"', ['exception' => $e]); - } catch (NotFoundError $e) { + } catch (NotFoundError) { if ($this->output->isVerbose()) { $this->print('corresponding column not found.', self::PRINT_LEVEL_ERROR); } else { diff --git a/lib/Command/CleanLegacy.php b/lib/Command/CleanLegacy.php index b335750b67..915c96ce08 100644 --- a/lib/Command/CleanLegacy.php +++ b/lib/Command/CleanLegacy.php @@ -30,12 +30,6 @@ class CleanLegacy extends Command { public const PRINT_LEVEL_WARNING = 3; public const PRINT_LEVEL_ERROR = 4; - protected ColumnService $columnService; - protected RowService $rowService; - protected TableService $tableService; - protected LoggerInterface $logger; - protected LegacyRowMapper $rowMapper; - private bool $dry = false; private int $truncateLength = 20; @@ -44,13 +38,14 @@ class CleanLegacy extends Command { private OutputInterface $output; - public function __construct(LoggerInterface $logger, ColumnService $columnService, RowService $rowService, TableService $tableService, LegacyRowMapper $rowMapper) { + public function __construct( + protected LoggerInterface $logger, + protected ColumnService $columnService, + protected RowService $rowService, + protected TableService $tableService, + protected LegacyRowMapper $rowMapper, + ) { parent::__construct(); - $this->logger = $logger; - $this->columnService = $columnService; - $this->rowService = $rowService; - $this->tableService = $tableService; - $this->rowMapper = $rowMapper; } protected function configure(): void { @@ -95,7 +90,7 @@ private function getNextRow():void { } catch (MultipleObjectsReturnedException|Exception $e) { $this->print('Error while fetching row', self::PRINT_LEVEL_ERROR); $this->logger->error('Following error occurred during executing occ command "' . self::class . '"', ['exception' => $e]); - } catch (DoesNotExistException $e) { + } catch (DoesNotExistException) { $this->print(''); $this->print('No more rows found.', self::PRINT_LEVEL_INFO); $this->print(''); @@ -130,9 +125,9 @@ private function checkColumns(): void { if (is_array($date->value)) { $date->value = json_encode($date->value); } - $suffix = strlen($date->value) > $this->truncateLength ? '...': ''; + $suffix = strlen((string)$date->value) > $this->truncateLength ? '...': ''; $this->print(''); - $this->print('columnId: ' . $date->columnId . ' -> ' . substr($date->value, 0, $this->truncateLength) . $suffix, self::PRINT_LEVEL_INFO); + $this->print('columnId: ' . $date->columnId . ' -> ' . substr((string)$date->value, 0, $this->truncateLength) . $suffix, self::PRINT_LEVEL_INFO); try { $this->columnService->find($date->columnId, ''); @@ -142,7 +137,7 @@ private function checkColumns(): void { } catch (InternalError $e) { $this->print('😱️ internal error while looking for column', self::PRINT_LEVEL_ERROR); $this->logger->error('Following error occurred during executing occ command "' . self::class . '"', ['exception' => $e]); - } catch (NotFoundError $e) { + } catch (NotFoundError) { if ($this->output->isVerbose()) { $this->print('corresponding column not found.', self::PRINT_LEVEL_ERROR); } else { diff --git a/lib/Command/ListContexts.php b/lib/Command/ListContexts.php index 3b1afbf86f..1e00aa6445 100644 --- a/lib/Command/ListContexts.php +++ b/lib/Command/ListContexts.php @@ -21,19 +21,12 @@ use function json_encode; class ListContexts extends Base { - protected ContextService $contextService; - protected LoggerInterface $logger; - private IConfig $config; - public function __construct( - ContextService $contextService, - LoggerInterface $logger, - IConfig $config, + protected ContextService $contextService, + protected LoggerInterface $logger, + private readonly IConfig $config, ) { parent::__construct(); - $this->contextService = $contextService; - $this->logger = $logger; - $this->config = $config; } protected function configure(): void { diff --git a/lib/Command/ListTables.php b/lib/Command/ListTables.php index a9af050476..46f70a287d 100644 --- a/lib/Command/ListTables.php +++ b/lib/Command/ListTables.php @@ -17,13 +17,11 @@ use Symfony\Component\Console\Output\OutputInterface; class ListTables extends Command { - protected TableService $tableService; - protected LoggerInterface $logger; - - public function __construct(TableService $tableService, LoggerInterface $logger) { + public function __construct( + protected TableService $tableService, + protected LoggerInterface $logger, + ) { parent::__construct(); - $this->tableService = $tableService; - $this->logger = $logger; } protected function configure(): void { diff --git a/lib/Command/RemoveTable.php b/lib/Command/RemoveTable.php index f743d28733..7108a6c341 100644 --- a/lib/Command/RemoveTable.php +++ b/lib/Command/RemoveTable.php @@ -18,13 +18,11 @@ use Symfony\Component\Console\Output\OutputInterface; class RemoveTable extends Command { - protected TableService $tableService; - protected LoggerInterface $logger; - - public function __construct(TableService $tableService, LoggerInterface $logger) { + public function __construct( + protected TableService $tableService, + protected LoggerInterface $logger, + ) { parent::__construct(); - $this->tableService = $tableService; - $this->logger = $logger; } protected function configure(): void { diff --git a/lib/Command/RenameTable.php b/lib/Command/RenameTable.php index d525d65da4..eac168904e 100644 --- a/lib/Command/RenameTable.php +++ b/lib/Command/RenameTable.php @@ -18,13 +18,11 @@ use Symfony\Component\Console\Output\OutputInterface; class RenameTable extends Command { - protected TableService $tableService; - protected LoggerInterface $logger; - - public function __construct(TableService $tableService, LoggerInterface $logger) { + public function __construct( + protected TableService $tableService, + protected LoggerInterface $logger, + ) { parent::__construct(); - $this->tableService = $tableService; - $this->logger = $logger; } protected function configure(): void { diff --git a/lib/Command/ShowContext.php b/lib/Command/ShowContext.php index 248d7d4a69..4721913111 100644 --- a/lib/Command/ShowContext.php +++ b/lib/Command/ShowContext.php @@ -21,19 +21,12 @@ use function json_encode; class ShowContext extends Base { - protected ContextService $contextService; - protected LoggerInterface $logger; - private IConfig $config; - public function __construct( - ContextService $contextService, - LoggerInterface $logger, - IConfig $config, + protected ContextService $contextService, + protected LoggerInterface $logger, + private readonly IConfig $config, ) { parent::__construct(); - $this->contextService = $contextService; - $this->logger = $logger; - $this->config = $config; } protected function configure(): void { @@ -55,13 +48,13 @@ protected function configure(): void { } protected function execute(InputInterface $input, OutputInterface $output): int { - $contextId = trim($input->getArgument('context-id')); + $contextId = trim((string)$input->getArgument('context-id')); if ($contextId === '' || !is_numeric($contextId)) { $output->writeln('Invalid Context ID'); return 1; } - $userId = trim($input->getArgument('user-id')); + $userId = trim((string)$input->getArgument('user-id')); if ($userId === '') { $userId = null; } diff --git a/lib/Command/TransferLegacyRows.php b/lib/Command/TransferLegacyRows.php index 801b748279..417b0dfd35 100644 --- a/lib/Command/TransferLegacyRows.php +++ b/lib/Command/TransferLegacyRows.php @@ -24,19 +24,14 @@ use Symfony\Component\Console\Output\OutputInterface; class TransferLegacyRows extends Command { - protected TableService $tableService; - protected LoggerInterface $logger; - protected LegacyRowMapper $legacyRowMapper; - protected Row2Mapper $rowMapper; - protected ColumnService $columnService; - - public function __construct(TableService $tableService, LoggerInterface $logger, LegacyRowMapper $legacyRowMapper, Row2Mapper $rowMapper, ColumnService $columnService) { + public function __construct( + protected TableService $tableService, + protected LoggerInterface $logger, + protected LegacyRowMapper $legacyRowMapper, + protected Row2Mapper $rowMapper, + protected ColumnService $columnService, + ) { parent::__construct(); - $this->tableService = $tableService; - $this->logger = $logger; - $this->legacyRowMapper = $legacyRowMapper; - $this->rowMapper = $rowMapper; - $this->columnService = $columnService; } protected function configure(): void { @@ -78,7 +73,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int try { $tables = $this->tableService->findAll('', true, true, false); $output->writeln('Found ' . count($tables) . ' table(s)'); - } catch (InternalError $e) { + } catch (InternalError) { $output->writeln('Error while fetching tables. Will aboard.'); return 1; } @@ -89,7 +84,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($tableIds as $tableId) { try { $tables[] = $this->tableService->find((int)ltrim($tableId), true, ''); - } catch (InternalError|NotFoundError|PermissionError $e) { + } catch (InternalError|NotFoundError|PermissionError) { $output->writeln('Could not load table id ' . $tableId . '. Will continue.'); } } @@ -156,7 +151,7 @@ private function deleteDataForTables(array $tables, OutputInterface $output): vo foreach ($tables as $table) { try { $columns = $this->columnService->findAllByTable($table->getId(), ''); - } catch (InternalError|PermissionError $e) { + } catch (InternalError|PermissionError) { $output->writeln('Could not delete data for table ' . $table->getId()); break; } diff --git a/lib/Controller/AOCSController.php b/lib/Controller/AOCSController.php index b74a0839d5..5dce758437 100644 --- a/lib/Controller/AOCSController.php +++ b/lib/Controller/AOCSController.php @@ -22,20 +22,13 @@ abstract class AOCSController extends OCSController { - protected LoggerInterface $logger; - protected string $userId; - protected IL10N $n; - public function __construct( IRequest $request, - LoggerInterface $logger, - IL10N $n, - string $userId, + protected LoggerInterface $logger, + protected IL10N $n, + protected string $userId, ) { parent::__construct(Application::APP_ID, $request); - $this->logger = $logger; - $this->userId = $userId; - $this->n = $n; } /** diff --git a/lib/Controller/Api1Controller.php b/lib/Controller/Api1Controller.php index 1467e46c57..2d7e90a749 100644 --- a/lib/Controller/Api1Controller.php +++ b/lib/Controller/Api1Controller.php @@ -56,52 +56,24 @@ * @psalm-import-type TablesContextNavigation from ResponseDefinitions */ class Api1Controller extends ApiController { - private TableService $tableService; - private ShareService $shareService; - private ColumnService $columnService; - private RowService $rowService; - private ImportService $importService; - private ViewService $viewService; - private RelationService $relationService; - private ViewMapper $viewMapper; - private IL10N $l10N; - - private V1Api $v1Api; - - private ?string $userId; - - protected LoggerInterface $logger; - use Errors; public function __construct( IRequest $request, - TableService $service, - ShareService $shareService, - ColumnService $columnService, - RowService $rowService, - ImportService $importService, - ViewService $viewService, - RelationService $relationService, - ViewMapper $viewMapper, - V1Api $v1Api, - LoggerInterface $logger, - IL10N $l10N, - ?string $userId, + private TableService $tableService, + private ShareService $shareService, + private ColumnService $columnService, + private RowService $rowService, + private ImportService $importService, + private ViewService $viewService, + private RelationService $relationService, + private ViewMapper $viewMapper, + private V1Api $v1Api, + protected LoggerInterface $logger, + private IL10N $l10N, + private ?string $userId, ) { parent::__construct(Application::APP_ID, $request); - $this->tableService = $service; - $this->shareService = $shareService; - $this->columnService = $columnService; - $this->rowService = $rowService; - $this->importService = $importService; - $this->viewService = $viewService; - $this->relationService = $relationService; - $this->viewMapper = $viewMapper; - $this->userId = $userId; - $this->v1Api = $v1Api; - $this->logger = $logger; - $this->l10N = $l10N; } // Tables diff --git a/lib/Controller/ApiFavoriteController.php b/lib/Controller/ApiFavoriteController.php index de23d1f46a..e1ac548cbf 100644 --- a/lib/Controller/ApiFavoriteController.php +++ b/lib/Controller/ApiFavoriteController.php @@ -28,16 +28,14 @@ * @psalm-import-type TablesTable from ResponseDefinitions */ class ApiFavoriteController extends AOCSController { - private FavoritesService $service; - public function __construct( IRequest $request, LoggerInterface $logger, - FavoritesService $service, + private readonly FavoritesService $service, IL10N $n, - string $userId) { + string $userId, + ) { parent::__construct($request, $logger, $n, $userId); - $this->service = $service; } /** diff --git a/lib/Controller/ApiGeneralController.php b/lib/Controller/ApiGeneralController.php index ef26a6c818..13ff01d5ac 100644 --- a/lib/Controller/ApiGeneralController.php +++ b/lib/Controller/ApiGeneralController.php @@ -25,20 +25,15 @@ * @psalm-import-type TablesIndex from ResponseDefinitions */ class ApiGeneralController extends AOCSController { - private TableService $tableService; - private ViewService $viewService; - public function __construct( IRequest $request, - TableService $tableService, - ViewService $viewService, + private readonly TableService $tableService, + private readonly ViewService $viewService, LoggerInterface $logger, IL10N $n, ?string $userId, ) { parent::__construct($request, $logger, $n, $userId); - $this->tableService = $tableService; - $this->viewService = $viewService; } /** diff --git a/lib/Controller/ApiTablesController.php b/lib/Controller/ApiTablesController.php index 7ad79e84de..27681082a6 100644 --- a/lib/Controller/ApiTablesController.php +++ b/lib/Controller/ApiTablesController.php @@ -37,28 +37,18 @@ * @psalm-import-type TablesColumn from ResponseDefinitions */ class ApiTablesController extends AOCSController { - private TableService $service; - private ColumnService $columnService; - private ViewService $viewService; - private IAppManager $appManager; - private IDBConnection $db; - public function __construct( IRequest $request, LoggerInterface $logger, - TableService $service, - ColumnService $columnService, - ViewService $viewService, + private readonly TableService $service, + private readonly ColumnService $columnService, + private readonly ViewService $viewService, IL10N $n, - IAppManager $appManager, - IDBConnection $db, - string $userId) { + private readonly IAppManager $appManager, + private readonly IDBConnection $db, + string $userId, + ) { parent::__construct($request, $logger, $n, $userId); - $this->service = $service; - $this->columnService = $columnService; - $this->appManager = $appManager; - $this->viewService = $viewService; - $this->db = $db; } /** @@ -225,9 +215,7 @@ public function createFromScheme(string $title, string $emoji, string $descripti }, $view['columnSettings']); $inputColumnsArray['columnSettings'] = $newColumns; } else { - $newColumns = array_map(static function (int $colId) use ($colMap): int { - return $colId > 0 ? $colMap[$colId] : $colId; - }, $view['columns']); + $newColumns = array_map(static fn (int $colId): int => $colId > 0 ? $colMap[$colId] : $colId, $view['columns']); $inputColumnsArray['columns'] = $newColumns; } @@ -238,14 +226,12 @@ public function createFromScheme(string $title, string $emoji, string $descripti return $sort; }, $view['sort']); - $newFilter = array_map(static function (array $filters) use ($colMap): array { - return array_map(static function (array $filter) use ($colMap): array { - if ($filter['columnId'] > 0) { - $filter['columnId'] = $colMap[$filter['columnId']]; - } - return $filter; - }, $filters); - }, $view['filter']); + $newFilter = array_map(static fn (array $filters): array => array_map(static function (array $filter) use ($colMap): array { + if ($filter['columnId'] > 0) { + $filter['columnId'] = $colMap[$filter['columnId']]; + } + return $filter; + }, $filters), $view['filter']); $this->viewService->update($newView->getId(), ViewUpdateInput::fromInputArray( array_merge($inputColumnsArray, [ diff --git a/lib/Controller/ContextController.php b/lib/Controller/ContextController.php index 18860fb6b2..0ca77d6410 100644 --- a/lib/Controller/ContextController.php +++ b/lib/Controller/ContextController.php @@ -33,17 +33,14 @@ */ class ContextController extends AOCSController { - private ContextService $contextService; - public function __construct( IRequest $request, LoggerInterface $logger, IL10N $n, string $userId, - ContextService $contextService, + private readonly ContextService $contextService, ) { parent::__construct($request, $logger, $n, $userId); - $this->contextService = $contextService; $this->userId = $userId; } diff --git a/lib/Controller/ImportController.php b/lib/Controller/ImportController.php index 1ad66ed339..f5e655f349 100644 --- a/lib/Controller/ImportController.php +++ b/lib/Controller/ImportController.php @@ -33,35 +33,23 @@ class ImportController extends Controller { 'application/vnd.oasis.opendocument.spreadsheet', ]; - private ImportService $service; - private string $userId; - - protected LoggerInterface $logger; - - private IL10N $l10n; - use Errors; public function __construct( IRequest $request, - LoggerInterface $logger, - ImportService $service, - string $userId, - IL10N $l10n) { + protected LoggerInterface $logger, + private ImportService $service, + private string $userId, + private IL10N $l10n, + ) { parent::__construct(Application::APP_ID, $request); - $this->logger = $logger; - $this->service = $service; - $this->userId = $userId; - $this->l10n = $l10n; } #[NoAdminRequired] #[UserRateLimit(limit: 20, period: 60)] #[RequirePermission(permission: Application::PERMISSION_READ, type: Application::NODE_TYPE_TABLE, idParam: 'tableId')] public function previewImportTable(int $tableId, String $path): DataResponse { - return $this->handleError(function () use ($tableId, $path) { - return $this->service->previewImport($tableId, null, $path); - }); + return $this->handleError(fn () => $this->service->previewImport($tableId, null, $path)); } /** @@ -70,10 +58,9 @@ public function previewImportTable(int $tableId, String $path): DataResponse { #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_CREATE, type: Application::NODE_TYPE_TABLE, idParam: 'tableId')] public function importInTable(int $tableId, String $path, bool $createMissingColumns = true, array $columnsConfig = []): DataResponse { - return $this->handleError(function () use ($tableId, $path, $createMissingColumns, $columnsConfig) { + return $this->handleError( // minimal permission is checked, creating columns requires MANAGE permissions - currently tested on service layer - return $this->service->import($tableId, null, $path, $createMissingColumns, $columnsConfig); - }); + fn () => $this->service->import($tableId, null, $path, $createMissingColumns, $columnsConfig)); } #[NoAdminRequired] @@ -95,9 +82,7 @@ public function importV2InTable(int $tableId, String $path, bool $createMissingC #[UserRateLimit(limit: 20, period: 60)] #[RequirePermission(permission: Application::PERMISSION_CREATE, type: Application::NODE_TYPE_VIEW, idParam: 'viewId')] public function previewImportView(int $viewId, String $path): DataResponse { - return $this->handleError(function () use ($viewId, $path) { - return $this->service->previewImport(null, $viewId, $path); - }); + return $this->handleError(fn () => $this->service->previewImport(null, $viewId, $path)); } /** @@ -106,10 +91,9 @@ public function previewImportView(int $viewId, String $path): DataResponse { #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_CREATE, type: Application::NODE_TYPE_VIEW, idParam: 'viewId')] public function importInView(int $viewId, String $path, bool $createMissingColumns = true, array $columnsConfig = []): DataResponse { - return $this->handleError(function () use ($viewId, $path, $createMissingColumns, $columnsConfig) { + return $this->handleError( // minimal permission is checked, creating columns requires MANAGE permissions - currently tested on service layer - return $this->service->import(null, $viewId, $path, $createMissingColumns, $columnsConfig); - }); + fn () => $this->service->import(null, $viewId, $path, $createMissingColumns, $columnsConfig)); } #[NoAdminRequired] @@ -133,9 +117,7 @@ public function importV2InView(int $viewId, String $path, bool $createMissingCol public function previewUploadImportTable(int $tableId): DataResponse { try { $file = $this->getUploadedFile('uploadfile'); - return $this->handleError(function () use ($tableId, $file) { - return $this->service->previewImport($tableId, null, $file['tmp_name']); - }); + return $this->handleError(fn () => $this->service->previewImport($tableId, null, $file['tmp_name'])); } catch (UploadException|NotPermittedException $e) { $this->logger->error('Upload error', ['exception' => $e]); return new DataResponse(['message' => $e->getMessage()], Http::STATUS_BAD_REQUEST); @@ -151,10 +133,9 @@ public function importUploadInTable(int $tableId, bool $createMissingColumns = t try { $columnsConfigArray = json_decode($columnsConfig, true); $file = $this->getUploadedFile('uploadfile'); - return $this->handleError(function () use ($tableId, $file, $createMissingColumns, $columnsConfigArray) { + return $this->handleError( // minimal permission is checked, creating columns requires MANAGE permissions - currently tested on service layer - return $this->service->import($tableId, null, $file['tmp_name'], $createMissingColumns, $columnsConfigArray); - }); + fn () => $this->service->import($tableId, null, $file['tmp_name'], $createMissingColumns, $columnsConfigArray)); } catch (UploadException|NotPermittedException $e) { $this->logger->error('Upload error', ['exception' => $e]); return new DataResponse(['message' => $e->getMessage()], Http::STATUS_BAD_REQUEST); @@ -167,9 +148,7 @@ public function importUploadInTable(int $tableId, bool $createMissingColumns = t public function previewUploadImportView(int $viewId): DataResponse { try { $file = $this->getUploadedFile('uploadfile'); - return $this->handleError(function () use ($viewId, $file) { - return $this->service->previewImport(null, $viewId, $file['tmp_name']); - }); + return $this->handleError(fn () => $this->service->previewImport(null, $viewId, $file['tmp_name'])); } catch (UploadException|NotPermittedException $e) { $this->logger->error('Upload error', ['exception' => $e]); return new DataResponse(['message' => $e->getMessage()], Http::STATUS_BAD_REQUEST); @@ -204,10 +183,9 @@ public function importUploadInView(int $viewId, bool $createMissingColumns = tru try { $columnsConfigArray = json_decode($columnsConfig, true); $file = $this->getUploadedFile('uploadfile'); - return $this->handleError(function () use ($viewId, $file, $createMissingColumns, $columnsConfigArray) { + return $this->handleError( // minimal permission is checked, creating columns requires MANAGE permissions - currently tested on service layer - return $this->service->import(null, $viewId, $file['tmp_name'], $createMissingColumns, $columnsConfigArray); - }); + fn () => $this->service->import(null, $viewId, $file['tmp_name'], $createMissingColumns, $columnsConfigArray)); } catch (UploadException|NotPermittedException $e) { $this->logger->error('Upload error', ['exception' => $e]); return new DataResponse(['message' => $e->getMessage()], Http::STATUS_BAD_REQUEST); diff --git a/lib/Controller/RowController.php b/lib/Controller/RowController.php index 144089f7e4..452fdde7aa 100644 --- a/lib/Controller/RowController.php +++ b/lib/Controller/RowController.php @@ -31,24 +31,18 @@ public function __construct( #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_READ, type: Application::NODE_TYPE_TABLE, idParam: 'tableId')] public function index(int $tableId): DataResponse { - return $this->handleError(function () use ($tableId) { - return $this->service->findAllByTable($tableId, $this->userId); - }); + return $this->handleError(fn () => $this->service->findAllByTable($tableId, $this->userId)); } #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_READ, type: Application::NODE_TYPE_VIEW, idParam: 'viewId')] public function indexView(int $viewId): DataResponse { - return $this->handleError(function () use ($viewId) { - return $this->service->findAllByView($viewId, $this->userId); - }); + return $this->handleError(fn () => $this->service->findAllByView($viewId, $this->userId)); } #[NoAdminRequired] public function show(int $id): DataResponse { - return $this->handleError(function () use ($id) { - return $this->service->find($id); - }); + return $this->handleError(fn () => $this->service->find($id)); } #[NoAdminRequired] @@ -58,14 +52,7 @@ public function update( ?int $viewId, string $data, ): DataResponse { - return $this->handleError(function () use ( - $id, - $viewId, - $columnId, - $data - ) { - return $this->service->updateSet($id, $viewId, ['columnId' => $columnId, 'value' => $data], $this->userId, null); - }); + return $this->handleError(fn () => $this->service->updateSet($id, $viewId, ['columnId' => $columnId, 'value' => $data], $this->userId, null)); } #[NoAdminRequired] @@ -74,26 +61,16 @@ public function updateSet( ?int $viewId, array $data, ): DataResponse { - return $this->handleError(function () use ( - $id, - $viewId, - $data - ) { - return $this->service->updateSet($id, $viewId, $data, $this->userId, null); - }); + return $this->handleError(fn () => $this->service->updateSet($id, $viewId, $data, $this->userId, null)); } #[NoAdminRequired] public function destroy(int $id): DataResponse { - return $this->handleError(function () use ($id) { - return $this->service->delete($id, null, $this->userId); - }); + return $this->handleError(fn () => $this->service->delete($id, null, $this->userId)); } #[NoAdminRequired] public function destroyByView(int $id, int $viewId): DataResponse { - return $this->handleError(function () use ($id, $viewId) { - return $this->service->delete($id, $viewId, $this->userId); - }); + return $this->handleError(fn () => $this->service->delete($id, $viewId, $this->userId)); } #[NoAdminRequired] diff --git a/lib/Controller/SearchController.php b/lib/Controller/SearchController.php index 13c732a65b..072a4d7950 100644 --- a/lib/Controller/SearchController.php +++ b/lib/Controller/SearchController.php @@ -17,28 +17,20 @@ class SearchController extends Controller { - private SearchService $service; - private string $userId; - private LoggerInterface $logger; - use Errors; public function __construct( IRequest $request, - LoggerInterface $logger, - SearchService $service, - string $userId) { + private LoggerInterface $logger, + private SearchService $service, + private string $userId, + ) { parent::__construct(Application::APP_ID, $request); - $this->userId = $userId; - $this->service = $service; - $this->logger = $logger; } #[NoAdminRequired] public function all(string $term = ''): DataResponse { - return $this->handleError(function () use ($term) { - return $this->service->all($term); - }); + return $this->handleError(fn () => $this->service->all($term)); } } diff --git a/lib/Controller/ShareController.php b/lib/Controller/ShareController.php index 388552d1b8..d011280375 100644 --- a/lib/Controller/ShareController.php +++ b/lib/Controller/ShareController.php @@ -20,27 +20,16 @@ use Psr\Log\LoggerInterface; class ShareController extends Controller { - private ShareService $service; - - private string $userId; - - private ShareManager $shareManager; - - protected LoggerInterface $logger; - use Errors; public function __construct( IRequest $request, - LoggerInterface $logger, - ShareService $service, - ShareManager $shareManager, - string $userId) { + protected LoggerInterface $logger, + private ShareService $service, + private ShareManager $shareManager, + private string $userId, + ) { parent::__construct(Application::APP_ID, $request); - $this->logger = $logger; - $this->service = $service; - $this->shareManager = $shareManager; - $this->userId = $userId; } #[NoAdminRequired] @@ -57,7 +46,7 @@ public function sharePolicy(): DataResponse { public function index(int $tableId): DataResponse { return $this->handleError(function () use ($tableId) { $shares = $this->service->findAll('table', $tableId); - return array_map([$this->service, 'formatForOutput'], $shares); + return array_map($this->service->formatForOutput(...), $shares); }); } @@ -66,15 +55,13 @@ public function index(int $tableId): DataResponse { public function indexView(int $viewId): DataResponse { return $this->handleError(function () use ($viewId) { $shares = $this->service->findAll('view', $viewId); - return array_map([$this->service, 'formatForOutput'], $shares); + return array_map($this->service->formatForOutput(...), $shares); }); } #[NoAdminRequired] public function show(int $id): DataResponse { - return $this->handleError(function () use ($id) { - return $this->service->formatForOutput($this->service->find($id)); - }); + return $this->handleError(fn () => $this->service->formatForOutput($this->service->find($id))); } #[NoAdminRequired] @@ -101,16 +88,12 @@ public function create( $password, $shareTokenObject, ); - return $this->handleError(function () use ($dto) { - return $this->service->create($dto); - }); + return $this->handleError(fn () => $this->service->create($dto)); } #[NoAdminRequired] public function updatePermission(int $id, string $permission, bool $value): DataResponse { - return $this->handleError(function () use ($id, $permission, $value) { - return $this->service->updatePermission($id, [$permission => $value]); - }); + return $this->handleError(fn () => $this->service->updatePermission($id, [$permission => $value])); } #[NoAdminRequired] @@ -121,14 +104,12 @@ public function updatePermissions( bool $permissionUpdate = false, bool $permissionDelete = false, ): DataResponse { - return $this->handleError(function () use ($id, $permissionRead, $permissionCreate, $permissionUpdate, $permissionDelete) { - return $this->service->updatePermission($id, [ - 'read' => $permissionRead, - 'create' => $permissionCreate, - 'update' => $permissionUpdate && $permissionRead, - 'delete' => $permissionDelete && $permissionRead, - ]); - }); + return $this->handleError(fn () => $this->service->updatePermission($id, [ + 'read' => $permissionRead, + 'create' => $permissionCreate, + 'update' => $permissionUpdate && $permissionRead, + 'delete' => $permissionDelete && $permissionRead, + ])); } /** @@ -152,8 +133,6 @@ public function updateDisplayMode(int $id, int $displayMode, string $target = 'd #[NoAdminRequired] public function destroy(int $id): DataResponse { - return $this->handleError(function () use ($id) { - return $this->service->delete($id); - }); + return $this->handleError(fn () => $this->service->delete($id)); } } diff --git a/lib/Controller/TableController.php b/lib/Controller/TableController.php index 11f9a3ad95..cd7c3963f3 100644 --- a/lib/Controller/TableController.php +++ b/lib/Controller/TableController.php @@ -19,53 +19,37 @@ use Psr\Log\LoggerInterface; class TableController extends Controller { - private TableService $service; - - private string $userId; - - protected LoggerInterface $logger; - use Errors; public function __construct( IRequest $request, - LoggerInterface $logger, - TableService $service, - string $userId) { + protected LoggerInterface $logger, + private TableService $service, + private string $userId, + ) { parent::__construct(Application::APP_ID, $request); - $this->logger = $logger; - $this->service = $service; - $this->userId = $userId; } #[NoAdminRequired] public function index(): DataResponse { - return $this->handleError(function () { - return $this->service->findAll($this->userId); - }); + return $this->handleError(fn () => $this->service->findAll($this->userId)); } #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_READ, type: Application::NODE_TYPE_TABLE, idParam: 'id')] public function show(int $id): DataResponse { - return $this->handleError(function () use ($id) { - return $this->service->find($id); - }); + return $this->handleError(fn () => $this->service->find($id)); } #[NoAdminRequired] public function create(string $title, string $template, string $emoji): DataResponse { - return $this->handleError(function () use ($title, $template, $emoji) { - return $this->service->create($title, $template, $emoji); - }); + return $this->handleError(fn () => $this->service->create($title, $template, $emoji)); } #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_MANAGE, type: Application::NODE_TYPE_TABLE, idParam: 'id')] public function destroy(int $id): DataResponse { - return $this->handleError(function () use ($id) { - return $this->service->delete($id); - }); + return $this->handleError(fn () => $this->service->delete($id)); } #[NoAdminRequired] diff --git a/lib/Controller/TableTemplateController.php b/lib/Controller/TableTemplateController.php index 52bfc295a9..32b4bb3707 100644 --- a/lib/Controller/TableTemplateController.php +++ b/lib/Controller/TableTemplateController.php @@ -16,25 +16,18 @@ use Psr\Log\LoggerInterface; class TableTemplateController extends Controller { - private TableTemplateService $service; - - protected LoggerInterface $logger; - use Errors; public function __construct( IRequest $request, - LoggerInterface $logger, - TableTemplateService $service) { + protected LoggerInterface $logger, + private TableTemplateService $service, + ) { parent::__construct(Application::APP_ID, $request); - $this->logger = $logger; - $this->service = $service; } #[NoAdminRequired] public function list(): DataResponse { - return $this->handleError(function () { - return $this->service->getTemplateList(); - }); + return $this->handleError(fn () => $this->service->getTemplateList()); } } diff --git a/lib/Controller/ViewController.php b/lib/Controller/ViewController.php index 474b7a5c20..847996861a 100644 --- a/lib/Controller/ViewController.php +++ b/lib/Controller/ViewController.php @@ -24,62 +24,40 @@ use Psr\Log\LoggerInterface; class ViewController extends Controller { - private ViewService $service; - - private ViewMapper $mapper; - - private TableService $tableService; - - private string $userId; - - protected LoggerInterface $logger; - use Errors; public function __construct( IRequest $request, - LoggerInterface $logger, - ViewService $service, - ViewMapper $mapper, - TableService $tableService, - string $userId) { + protected LoggerInterface $logger, + private ViewService $service, + private ViewMapper $mapper, + private TableService $tableService, + private string $userId, + ) { parent::__construct(Application::APP_ID, $request); - $this->logger = $logger; - $this->service = $service; - $this->mapper = $mapper; - $this->tableService = $tableService; - $this->userId = $userId; } #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_READ, type: Application::NODE_TYPE_TABLE, idParam: 'tableId')] public function index(int $tableId): DataResponse { - return $this->handleError(function () use ($tableId) { - return $this->service->findAll($this->getTable($tableId), $this->userId); - }); + return $this->handleError(fn () => $this->service->findAll($this->getTable($tableId), $this->userId)); } #[NoAdminRequired] public function indexSharedWithMe(): DataResponse { - return $this->handleError(function () { - return $this->service->findSharedViewsWithMe($this->userId); - }); + return $this->handleError(fn () => $this->service->findSharedViewsWithMe($this->userId)); } #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_READ, type: Application::NODE_TYPE_VIEW, idParam: 'id')] public function show(int $id): DataResponse { - return $this->handleError(function () use ($id) { - return $this->service->find($id); - }); + return $this->handleError(fn () => $this->service->find($id)); } #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_MANAGE, type: Application::NODE_TYPE_TABLE, idParam: 'tableId')] public function create(int $tableId, string $title, ?string $emoji): DataResponse { - return $this->handleError(function () use ($tableId, $title, $emoji) { - return $this->service->create($title, $emoji, $this->getTable($tableId, true)); - }); + return $this->handleError(fn () => $this->service->create($title, $emoji, $this->getTable($tableId, true))); } #[NoAdminRequired] @@ -94,9 +72,7 @@ public function update(int $id, array $data): DataResponse { #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_MANAGE, type: Application::NODE_TYPE_VIEW, idParam: 'id')] public function destroy(int $id): DataResponse { - return $this->handleError(function () use ($id) { - return $this->service->delete($id); - }); + return $this->handleError(fn () => $this->service->delete($id)); } /** diff --git a/lib/Db/Column.php b/lib/Db/Column.php index 52698e607f..effe32b426 100644 --- a/lib/Db/Column.php +++ b/lib/Db/Column.php @@ -313,7 +313,7 @@ public function jsonSerialize(): array { } public function getCustomSettingsArray(): array { - return json_decode($this->customSettings, true) ?: []; + return json_decode((string)$this->customSettings, true) ?: []; } /** diff --git a/lib/Db/ColumnMapper.php b/lib/Db/ColumnMapper.php index 527b728d97..229ef65b31 100644 --- a/lib/Db/ColumnMapper.php +++ b/lib/Db/ColumnMapper.php @@ -19,12 +19,13 @@ /** @template-extends QBMapper */ class ColumnMapper extends QBMapper { protected string $table = 'tables_columns'; - private LoggerInterface $logger; - private CappedMemoryCache $cacheColumn; + private readonly CappedMemoryCache $cacheColumn; - public function __construct(IDBConnection $db, LoggerInterface $logger) { + public function __construct( + IDBConnection $db, + private readonly LoggerInterface $logger, + ) { parent::__construct($db, $this->table, Column::class); - $this->logger = $logger; $this->cacheColumn = new CappedMemoryCache(); } @@ -126,7 +127,7 @@ public function findAllIdsByTable(int $tableID): array { ->where($qb->expr()->eq('table_id', $qb->createNamedParameter($tableID))); $result = $qb->executeQuery(); $ids = []; - while ($row = $result->fetch()) { + while ($row = $result->fetchAssociative()) { $ids[] = $row['id']; } return $ids; @@ -155,7 +156,7 @@ public function getColumnTypes(array $neededColumnIds): array { ]; $result = $qb->executeQuery(); try { - while ($row = $result->fetch()) { + while ($row = $result->fetchAssociative()) { $out[$row['id']] = $row['type'] . ($row['subtype'] ? '-' . $row['subtype']: ''); } } finally { diff --git a/lib/Db/ColumnTypes/SelectionColumnQB.php b/lib/Db/ColumnTypes/SelectionColumnQB.php index 7b2f41c0c1..7f00b23cd5 100644 --- a/lib/Db/ColumnTypes/SelectionColumnQB.php +++ b/lib/Db/ColumnTypes/SelectionColumnQB.php @@ -11,7 +11,7 @@ class SelectionColumnQB extends SuperColumnQB implements IColumnTypeQB { public function passSearchValue(IQueryBuilder $qb, string $unformattedSearchValue, string $operator, string $searchValuePlaceHolder): void { - if (substr($unformattedSearchValue, 0, 1) === '@') { + if (str_starts_with($unformattedSearchValue, '@')) { $parts = explode('-', $unformattedSearchValue); $selectedId = intval($parts[2]); $qb->setParameter($searchValuePlaceHolder, $selectedId, IQueryBuilder::PARAM_INT); diff --git a/lib/Db/ColumnTypes/SuperColumnQB.php b/lib/Db/ColumnTypes/SuperColumnQB.php index df436a0f6d..f030becc05 100644 --- a/lib/Db/ColumnTypes/SuperColumnQB.php +++ b/lib/Db/ColumnTypes/SuperColumnQB.php @@ -14,11 +14,11 @@ use Psr\Log\LoggerInterface; class SuperColumnQB implements IColumnTypeQB { - protected LoggerInterface $logger; protected int $platform; - public function __construct(LoggerInterface $logger) { - $this->logger = $logger; + public function __construct( + protected LoggerInterface $logger, + ) { } public function setPlatform(int $platform): void { @@ -61,30 +61,18 @@ public function passSearchValue(IQueryBuilder $qb, string $unformattedSearchValu * @throws InternalError */ private function sqlFilterOperation(string $operator, string $formattedCellValue, string $searchValuePlaceHolder) : string { - switch ($operator) { - case 'begins-with': - case 'ends-with': - case 'contains': - return $formattedCellValue . ' LIKE :' . $searchValuePlaceHolder; - case 'does-not-contain': - return $formattedCellValue . ' NOT LIKE :' . $searchValuePlaceHolder; - case 'is-equal': - return $formattedCellValue . ' = :' . $searchValuePlaceHolder; - case 'is-not-equal': - return $formattedCellValue . ' != :' . $searchValuePlaceHolder; - case 'is-greater-than': - return $formattedCellValue . ' > :' . $searchValuePlaceHolder; - case 'is-greater-than-or-equal': - return $formattedCellValue . ' >= :' . $searchValuePlaceHolder; - case 'is-lower-than': - return $formattedCellValue . ' < :' . $searchValuePlaceHolder; - case 'is-lower-than-or-equal': - return $formattedCellValue . ' <= :' . $searchValuePlaceHolder; - case 'is-empty': - return $formattedCellValue . ' = \'\' OR ' . $formattedCellValue . ' IS NULL'; - default: - throw new InternalError('Operator ' . $operator . ' is not supported.'); - } + return match ($operator) { + 'begins-with', 'ends-with', 'contains' => $formattedCellValue . ' LIKE :' . $searchValuePlaceHolder, + 'does-not-contain' => $formattedCellValue . ' NOT LIKE :' . $searchValuePlaceHolder, + 'is-equal' => $formattedCellValue . ' = :' . $searchValuePlaceHolder, + 'is-not-equal' => $formattedCellValue . ' != :' . $searchValuePlaceHolder, + 'is-greater-than' => $formattedCellValue . ' > :' . $searchValuePlaceHolder, + 'is-greater-than-or-equal' => $formattedCellValue . ' >= :' . $searchValuePlaceHolder, + 'is-lower-than' => $formattedCellValue . ' < :' . $searchValuePlaceHolder, + 'is-lower-than-or-equal' => $formattedCellValue . ' <= :' . $searchValuePlaceHolder, + 'is-empty' => $formattedCellValue . ' = \'\' OR ' . $formattedCellValue . ' IS NULL', + default => throw new InternalError('Operator ' . $operator . ' is not supported.'), + }; } private function getFormattedDataCellValue(string $columnPlaceHolder, int $columnId): string { @@ -105,20 +93,14 @@ private function getFormattedDataCellValue(string $columnPlaceHolder, int $colum * @throws InternalError */ public static function getMetaColumnName(int $metaId): string { - switch ($metaId) { - case Column::TYPE_META_ID: - return 'id'; - case Column::TYPE_META_CREATED_BY: - return 'created_by'; - case Column::TYPE_META_UPDATED_BY: - return 'last_edit_by'; - case Column::TYPE_META_CREATED_AT: - return 'created_at'; - case Column::TYPE_META_UPDATED_AT: - return 'last_edit_at'; - default: - throw new InternalError('No meta data column exists with id ' . $metaId); - } + return match ($metaId) { + Column::TYPE_META_ID => 'id', + Column::TYPE_META_CREATED_BY => 'created_by', + Column::TYPE_META_UPDATED_BY => 'last_edit_by', + Column::TYPE_META_CREATED_AT => 'created_at', + Column::TYPE_META_UPDATED_AT => 'last_edit_at', + default => throw new InternalError('No meta data column exists with id ' . $metaId), + }; } /** @@ -133,7 +115,7 @@ public function addWhereFilterExpression(IQueryBuilder $qb, array $filter, strin $this->passSearchValue($qb, $filter['value'], $filter['operator'], $searchValuePlaceHolder); $columnPlaceHolder = 'column' . $filterId; // qb parameter binding name if ($filter['columnId'] < 0) { // negative ids for meta data columns - return $qb->createFunction($this->sqlFilterOperation($filter['operator'], $this->getMetaColumnName($filter['columnId']), $searchValuePlaceHolder)); + return $qb->createFunction($this->sqlFilterOperation($filter['operator'], static::getMetaColumnName($filter['columnId']), $searchValuePlaceHolder)); } $qb->setParameter($columnPlaceHolder, $filter['columnId'], IQueryBuilder::PARAM_INT); diff --git a/lib/Db/ContextMapper.php b/lib/Db/ContextMapper.php index 3acbbe9633..a39ae430f4 100644 --- a/lib/Db/ContextMapper.php +++ b/lib/Db/ContextMapper.php @@ -154,7 +154,7 @@ public function findAll(?string $userId = null): array { $qb = $this->getFindContextBaseQuery($userId); $result = $qb->executeQuery(); - $r = $result->fetchAll(); + $r = $result->fetchAllAssociative(); $contextIds = []; foreach ($r as $row) { @@ -204,7 +204,7 @@ public function findForNavBar(string $userId): array { )); $result = $qb->executeQuery(); - $r = $result->fetchAll(); + $r = $result->fetchAllAssociative(); $contextIds = []; foreach ($r as $row) { @@ -236,7 +236,7 @@ public function findById(int $contextId, ?string $userId = null): Context { $qb->andWhere($qb->expr()->eq('c.id', $qb->createNamedParameter($contextId, IQueryBuilder::PARAM_INT))); $result = $qb->executeQuery(); - $r = $result->fetchAll(); + $r = $result->fetchAllAssociative(); if (empty($r)) { throw new NotFoundError('Context does not exist'); @@ -256,7 +256,7 @@ public function findAllContainingNode(int $nodeType, int $nodeId, string $userId ->andWhere($qb->expr()->eq('r.node_type', $qb->createNamedParameter($nodeType))); $result = $qb->executeQuery(); - $r = $result->fetchAll(); + $r = $result->fetchAllAssociative(); $contextIds = []; foreach ($r as $row) { diff --git a/lib/Db/ContextNodeRelationMapper.php b/lib/Db/ContextNodeRelationMapper.php index 82eaf7bee6..d7ad72611c 100644 --- a/lib/Db/ContextNodeRelationMapper.php +++ b/lib/Db/ContextNodeRelationMapper.php @@ -39,7 +39,7 @@ public function getRelIdsForNode(int $nodeId, int $nodeType): array { ->andWhere($qb->expr()->eq('node_type', $qb->createNamedParameter($nodeType))); $result = $qb->executeQuery(); $nodeRelIds = []; - while ($row = $result->fetch()) { + while ($row = $result->fetchAssociative()) { $nodeRelIds[] = (int)$row['id']; } return $nodeRelIds; diff --git a/lib/Db/LegacyRowMapper.php b/lib/Db/LegacyRowMapper.php index 95f04a2bb7..f722b58fe3 100644 --- a/lib/Db/LegacyRowMapper.php +++ b/lib/Db/LegacyRowMapper.php @@ -36,25 +36,25 @@ class LegacyRowMapper extends QBMapper { public function __construct( IDBConnection $db, - private LoggerInterface $logger, - private TextColumnQB $textColumnQB, - private SelectionColumnQB $selectionColumnQB, - private NumberColumnQB $numberColumnQB, - private DatetimeColumnQB $datetimeColumnQB, - private SuperColumnQB $genericColumnQB, - private ColumnMapper $columnMapper, - private ColumnsHelper $columnsHelper, - private UserHelper $userHelper, - private Row2Mapper $rowMapper, + private readonly LoggerInterface $logger, + private readonly TextColumnQB $textColumnQB, + private readonly SelectionColumnQB $selectionColumnQB, + private readonly NumberColumnQB $numberColumnQB, + private readonly DatetimeColumnQB $datetimeColumnQB, + private readonly SuperColumnQB $genericColumnQB, + private readonly ColumnMapper $columnMapper, + private readonly ColumnsHelper $columnsHelper, + private readonly UserHelper $userHelper, + private readonly Row2Mapper $rowMapper, ) { parent::__construct($db, $this->table, LegacyRow::class); $this->setPlatform(); } private function setPlatform() { - if (str_contains(strtolower(get_class($this->db->getDatabasePlatform())), 'postgres')) { + if (str_contains(strtolower($this->db->getDatabasePlatform()::class), 'postgres')) { $this->platform = IColumnTypeQB::DB_PLATFORM_PGSQL; - } elseif (str_contains(strtolower(get_class($this->db->getDatabasePlatform())), 'sqlite')) { + } elseif (str_contains(strtolower($this->db->getDatabasePlatform()::class), 'sqlite')) { $this->platform = IColumnTypeQB::DB_PLATFORM_SQLITE; } else { $this->platform = IColumnTypeQB::DB_PLATFORM_MYSQL; @@ -82,17 +82,17 @@ public function find(int $id): LegacyRow { return $this->findEntity($qb); } - private function buildFilterByColumnType($qb, array $filter, string $filterId): ?IQueryFunction { + private function buildFilterByColumnType(IQueryBuilder $qb, array $filter, string $filterId): ?IQueryFunction { try { $columnQbClassName = 'OCA\Tables\Db\ColumnTypes\\'; - $type = explode('-', $filter['columnType'])[0]; + $type = explode('-', (string)$filter['columnType'])[0]; $columnQbClassName .= ucfirst($type) . 'ColumnQB'; /** @var IColumnTypeQB $columnQb */ $columnQb = Server::get($columnQbClassName); return $columnQb->addWhereFilterExpression($qb, $filter, $filterId); - } catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) { + } catch (NotFoundExceptionInterface|ContainerExceptionInterface) { $this->logger->debug('Column type query builder class not found'); } return null; @@ -139,7 +139,7 @@ private function addOrderByRules(IQueryBuilder $qb, array $sortArray) { if ($sortRule['columnId'] < 0) { try { $orderString = SuperColumnQB::getMetaColumnName($sortRule['columnId']); - } catch (InternalError $e) { + } catch (InternalError) { return; } } else { @@ -208,7 +208,7 @@ public function getRowIdsOfView(View $view, $userId): array { $result = $qb->executeQuery(); try { $ids = []; - while ($row = $result->fetch()) { + while ($row = $result->fetchAssociative()) { $ids[] = $row['id']; } return $ids; @@ -297,9 +297,7 @@ public function findAllByView(View $view, string $userId, ?int $limit = null, ?i } $rows = $this->findEntities($qb); foreach ($rows as &$row) { - $row->setDataArray(array_filter($row->getDataArray(), function ($item) use ($view) { - return in_array($item['columnId'], $view->getColumnIds()); - })); + $row->setDataArray(array_filter($row->getDataArray(), fn ($item) => in_array($item['columnId'], $view->getColumnIds()))); } return $rows; } @@ -407,9 +405,7 @@ public function findByView(int $id, View $view): LegacyRow { ->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))); $row = $this->findEntity($qb); - $row->setDataArray(array_filter($row->getDataArray(), function ($item) use ($view) { - return in_array($item['columnId'], $view->getColumnIds()); - })); + $row->setDataArray(array_filter($row->getDataArray(), fn ($item) => in_array($item['columnId'], $view->getColumnIds()))); return $row; } diff --git a/lib/Db/PageContentMapper.php b/lib/Db/PageContentMapper.php index cfd51475da..1359788881 100644 --- a/lib/Db/PageContentMapper.php +++ b/lib/Db/PageContentMapper.php @@ -49,7 +49,7 @@ public function findByPageAndNodeRelation(int $pageId, int $nodeRelId): ?PageCon )); $result = $qb->executeQuery(); - $r = $result->fetch(); + $r = $result->fetchAssociative(); return $r ? $this->mapRowToEntity($r) : null; } diff --git a/lib/Db/PageMapper.php b/lib/Db/PageMapper.php index 113d7c5c46..b7a1ce428a 100644 --- a/lib/Db/PageMapper.php +++ b/lib/Db/PageMapper.php @@ -31,7 +31,7 @@ public function getPageIdsForContext(int $contextId): array { $result = $qb->executeQuery(); $pageIds = []; - while ($row = $result->fetch() + while ($row = $result->fetchAssociative() ) { $pageIds[] = (int)$row['id']; } diff --git a/lib/Db/Row2.php b/lib/Db/Row2.php index dc24f7b335..9ad740f938 100644 --- a/lib/Db/Row2.php +++ b/lib/Db/Row2.php @@ -127,9 +127,7 @@ public function insertOrUpdateCell(array $entry): string { * @param int[] $columns */ public function filterDataByColumns(array $columns): array { - $this->data = array_values(array_filter($this->data, function ($entry) use ($columns) { - return in_array($entry['columnId'], $columns); - })); + $this->data = array_values(array_filter($this->data, fn ($entry) => in_array($entry['columnId'], $columns))); return $this->data; } diff --git a/lib/Db/Row2Mapper.php b/lib/Db/Row2Mapper.php index 7ec48500f9..904ff1fba4 100644 --- a/lib/Db/Row2Mapper.php +++ b/lib/Db/Row2Mapper.php @@ -32,23 +32,15 @@ class Row2Mapper { private const DB_CHUNK_SIZE = 1_000; - private RowSleeveMapper $rowSleeveMapper; - private ?string $userId; - private IDBConnection $db; - private LoggerInterface $logger; - protected UserHelper $userHelper; - protected ColumnMapper $columnMapper; - - private ColumnsHelper $columnsHelper; - - public function __construct(?string $userId, IDBConnection $db, LoggerInterface $logger, UserHelper $userHelper, RowSleeveMapper $rowSleeveMapper, ColumnsHelper $columnsHelper, ColumnMapper $columnMapper) { - $this->rowSleeveMapper = $rowSleeveMapper; - $this->userId = $userId; - $this->db = $db; - $this->logger = $logger; - $this->userHelper = $userHelper; - $this->columnsHelper = $columnsHelper; - $this->columnMapper = $columnMapper; + public function __construct( + private ?string $userId, + private IDBConnection $db, + private LoggerInterface $logger, + protected UserHelper $userHelper, + private RowSleeveMapper $rowSleeveMapper, + private ColumnsHelper $columnsHelper, + protected ColumnMapper $columnMapper, + ) { } /** @@ -67,7 +59,7 @@ public function delete(Row2 $row): Row2 { } catch (Throwable $e) { $this->db->rollBack(); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new Exception(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new Exception(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } return $row; @@ -91,12 +83,12 @@ public function find(int $id, array $columns): Row2 { if (count($rows) === 0) { $e = new Exception('Wanted row not found.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $e = new Exception('Too many results for one wanted row.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } /** @@ -107,7 +99,7 @@ public function findNextId(int $offsetId = -1): ?int { $rowSleeve = $this->rowSleeveMapper->findNext($offsetId); } catch (MultipleObjectsReturnedException|Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (DoesNotExistException) { return null; } @@ -158,10 +150,10 @@ private function getWantedRowIds(string $userId, int $tableId, ?array $filter = $result = $this->db->executeQuery($qb->getSQL(), $qb->getParameters(), $qb->getParameterTypes()); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage(), ); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage(), ); } - return array_map(fn (array $item) => $item['id'], $result->fetchAll()); + return array_map(fn (array $item) => $item['id'], $result->fetchAllAssociative()); } /** @@ -188,7 +180,7 @@ public function findAll(array $showColumnIds, int $tableId, ?int $limit = null, return $this->sortRowsByIds($rows, $wantedRowIdsArray); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -257,14 +249,14 @@ private function getRowsChunk(array $rowIds, array $columnIds): array { $result = $qb->executeQuery(); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage(), ); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage(), ); } try { $sleeves = $this->rowSleeveMapper->findMultiple($rowIds); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } return $this->parseEntities($result, $sleeves); @@ -350,7 +342,7 @@ private function addSortQueryForMultipleSleeveFinder(IQueryBuilder $qb, string $ private function replacePlaceholderValues(array &$filters, string $userId): void { foreach ($filters as &$filterGroup) { foreach ($filterGroup as &$filter) { - if (str_starts_with($filter['value'], '@')) { + if (str_starts_with((string)$filter['value'], '@')) { $columnId = (int)($filter['columnId'] ?? 0); $column = $columnId > 0 ? $this->columnMapper->find($columnId) : null; $filter['value'] = $this->columnsHelper->resolveSearchValue($filter['value'], $userId, $column); @@ -405,7 +397,7 @@ private function getFilter(IQueryBuilder $qb, array $filterGroup): array { } else { $e = new Exception('Needed column (' . $columnId . ') not found.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $filterExpressions[] = $sql; } @@ -421,7 +413,7 @@ private function getFilterExpression(IQueryBuilder $qb, Column $column, string $ $value = $this->getCellMapper($column)->filterValueToQueryParam($column, $value); } catch (DoesNotExistException $e) { $this->logger->error('Cannot filter, because the column does not exist', ['exception' => $e]); - throw new InternalError(get_class($this) . '::' . __FUNCTION__ . ': Cannot filter, because the column does not exist'); + throw new InternalError(static::class . '::' . __FUNCTION__ . ': Cannot filter, because the column does not exist'); } // We try to match the requested value against the default before building the query @@ -441,11 +433,11 @@ private function getFilterExpression(IQueryBuilder $qb, Column $column, string $ switch ($operator) { case 'begins-with': - $includeDefault = str_starts_with((string)($defaultValue ?? ''), $value); + $includeDefault = str_starts_with((string)($defaultValue ?? ''), (string)$value); $filterExpression = $qb->expr()->like('value', $qb->createNamedParameter($this->db->escapeLikeParameter($value) . '%', $paramType)); break; case 'ends-with': - $includeDefault = str_ends_with((string)($defaultValue ?? ''), $value); + $includeDefault = str_ends_with((string)($defaultValue ?? ''), (string)$value); $filterExpression = $qb->expr()->like('value', $qb->createNamedParameter('%' . $this->db->escapeLikeParameter($value), $paramType)); break; case 'contains': @@ -473,7 +465,7 @@ private function getFilterExpression(IQueryBuilder $qb, Column $column, string $ break; } - $includeDefault = str_contains((string)($defaultValue ?? ''), $value); + $includeDefault = str_contains((string)($defaultValue ?? ''), (string)$value); if ($column->getType() === 'selection' && $column->getSubtype() === 'multi') { $value = str_replace(['"', '\''], '', $value); $filterExpression = $qb2->expr()->orX( @@ -518,7 +510,7 @@ private function getFilterExpression(IQueryBuilder $qb, Column $column, string $ $qb->expr()->notIn('sl3.id', $qb->createFunction($qb2->getSQL())) ); } - $includeDefault = !str_contains((string)($defaultValue ?? ''), $value); + $includeDefault = !str_contains((string)($defaultValue ?? ''), (string)$value); if ($column->getType() === 'selection' && $column->getSubtype() === 'multi') { $value = str_replace(['"', '\''], '', $value); $filterExpression = $qb2->expr()->andX( @@ -598,23 +590,14 @@ private function getMetaFilterExpression(IQueryBuilder $qb, int $columnId, strin $qb2->select('id'); $qb2->from('tables_row_sleeves'); - switch ($columnId) { - case Column::TYPE_META_ID: - $qb2->where($this->getSqlOperator($operator, $qb, 'id', (int)$value, IQueryBuilder::PARAM_INT)); - break; - case Column::TYPE_META_CREATED_BY: - $qb2->where($this->getSqlOperator($operator, $qb, 'created_by', $value, IQueryBuilder::PARAM_STR)); - break; - case Column::TYPE_META_CREATED_AT: - $qb2->where($this->getSqlOperator($operator, $qb, 'created_at', new DateTimeImmutable($value), IQueryBuilder::PARAM_DATE)); - break; - case Column::TYPE_META_UPDATED_BY: - $qb2->where($this->getSqlOperator($operator, $qb, 'last_edit_by', $value, IQueryBuilder::PARAM_STR)); - break; - case Column::TYPE_META_UPDATED_AT: - $qb2->where($this->getSqlOperator($operator, $qb, 'last_edit_at', new DateTimeImmutable($value), IQueryBuilder::PARAM_DATE)); - break; - } + match ($columnId) { + Column::TYPE_META_ID => $qb2->where($this->getSqlOperator($operator, $qb, 'id', (int)$value, IQueryBuilder::PARAM_INT)), + Column::TYPE_META_CREATED_BY => $qb2->where($this->getSqlOperator($operator, $qb, 'created_by', $value, IQueryBuilder::PARAM_STR)), + Column::TYPE_META_CREATED_AT => $qb2->where($this->getSqlOperator($operator, $qb, 'created_at', new DateTimeImmutable($value), IQueryBuilder::PARAM_DATE)), + Column::TYPE_META_UPDATED_BY => $qb2->where($this->getSqlOperator($operator, $qb, 'last_edit_by', $value, IQueryBuilder::PARAM_STR)), + Column::TYPE_META_UPDATED_AT => $qb2->where($this->getSqlOperator($operator, $qb, 'last_edit_at', new DateTimeImmutable($value), IQueryBuilder::PARAM_DATE)), + default => $qb2, + }; return $qb2; } @@ -628,32 +611,20 @@ private function getMetaFilterExpression(IQueryBuilder $qb, int $columnId, strin * @throws InternalError */ private function getSqlOperator(string $operator, IQueryBuilder $qb, string $columnName, $value, $paramType): string { - switch ($operator) { - case 'begins-with': - return $qb->expr()->like($columnName, $qb->createNamedParameter('%' . $this->db->escapeLikeParameter($value), $paramType)); - case 'ends-with': - return $qb->expr()->like($columnName, $qb->createNamedParameter($this->db->escapeLikeParameter($value) . '%', $paramType)); - case 'contains': - return $qb->expr()->like($columnName, $qb->createNamedParameter('%' . $this->db->escapeLikeParameter($value) . '%', $paramType)); - case 'does-not-contain': - return $qb->expr()->notLike($columnName, $qb->createNamedParameter('%' . $this->db->escapeLikeParameter($value) . '%', $paramType)); - case 'is-equal': - return $qb->expr()->eq($columnName, $qb->createNamedParameter($value, $paramType)); - case 'is-not-equal': - return $qb->expr()->neq($columnName, $qb->createNamedParameter($value, $paramType)); - case 'is-greater-than': - return $qb->expr()->gt($columnName, $qb->createNamedParameter($value, $paramType)); - case 'is-greater-than-or-equal': - return $qb->expr()->gte($columnName, $qb->createNamedParameter($value, $paramType)); - case 'is-lower-than': - return $qb->expr()->lt($columnName, $qb->createNamedParameter($value, $paramType)); - case 'is-lower-than-or-equal': - return $qb->expr()->lte($columnName, $qb->createNamedParameter($value, $paramType)); - case 'is-empty': - return $qb->expr()->isNull($columnName); - default: - throw new InternalError('Operator ' . $operator . ' is not supported.'); - } + return match ($operator) { + 'begins-with' => $qb->expr()->like($columnName, $qb->createNamedParameter('%' . $this->db->escapeLikeParameter($value), $paramType)), + 'ends-with' => $qb->expr()->like($columnName, $qb->createNamedParameter($this->db->escapeLikeParameter($value) . '%', $paramType)), + 'contains' => $qb->expr()->like($columnName, $qb->createNamedParameter('%' . $this->db->escapeLikeParameter($value) . '%', $paramType)), + 'does-not-contain' => $qb->expr()->notLike($columnName, $qb->createNamedParameter('%' . $this->db->escapeLikeParameter($value) . '%', $paramType)), + 'is-equal' => $qb->expr()->eq($columnName, $qb->createNamedParameter($value, $paramType)), + 'is-not-equal' => $qb->expr()->neq($columnName, $qb->createNamedParameter($value, $paramType)), + 'is-greater-than' => $qb->expr()->gt($columnName, $qb->createNamedParameter($value, $paramType)), + 'is-greater-than-or-equal' => $qb->expr()->gte($columnName, $qb->createNamedParameter($value, $paramType)), + 'is-lower-than' => $qb->expr()->lt($columnName, $qb->createNamedParameter($value, $paramType)), + 'is-lower-than-or-equal' => $qb->expr()->lte($columnName, $qb->createNamedParameter($value, $paramType)), + 'is-empty' => $qb->expr()->isNull($columnName), + default => throw new InternalError('Operator ' . $operator . ' is not supported.'), + }; } /** @@ -679,7 +650,7 @@ private function parseEntities(IResult $result, array $sleeves): array { $keyToRowId = []; $cellMapperCache = []; - while ($rowData = $result->fetch()) { + while ($rowData = $result->fetchAssociative()) { if (!isset($rowData['row_id'], $rows[$rowData['row_id']])) { break; } @@ -769,7 +740,7 @@ public function update(Row2 $row, ?string $userId = null): Row2 { $this->rowSleeveMapper->update($sleeve); } catch (DoesNotExistException|MultipleObjectsReturnedException|Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $this->columnMapper->preloadColumns(array_column($changedCells, 'columnId')); @@ -836,7 +807,7 @@ private function insertCell(int $rowId, int $columnId, $value, ?string $lastEdit $column = $this->columnMapper->find($columnId); } catch (DoesNotExistException $e) { $this->logger->error('Can not insert cell, because the given column-id is not known', ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // insert new cell @@ -890,7 +861,7 @@ private function insertOrUpdateCell(int $rowId, int $columnId, $value): void { $cellMapper = $this->getCellMapper($column); try { if ($cellMapper->hasMultipleValues()) { - $this->atomic(function () use ($cellMapper, $rowId, $columnId, $value) { + $this->atomic(function () use ($cellMapper, $rowId, $columnId, $value): void { // For a usergroup field with mutiple values, each is inserted as a new cell // we need to delete all previous cells for this row and column, otherwise we get duplicates $cellMapper->deleteAllForColumnAndRow($columnId, $rowId); @@ -904,7 +875,7 @@ private function insertOrUpdateCell(int $rowId, int $columnId, $value): void { $this->insertCell($rowId, $columnId, $value); } catch (MultipleObjectsReturnedException|Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -919,7 +890,7 @@ private function getCellMapperFromType(string $columnType): RowCellMapperSuper { return Server::get($cellMapperClassName); } catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -938,7 +909,7 @@ public function deleteDataForColumn(Column $column): void { $this->getCellMapper($column)->deleteAllForColumn($column->getId()); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -986,23 +957,14 @@ public function countRowsForView(View $view, string $userId): int { private function getFormattedDefaultValue(Column $column) { $defaultValue = null; - switch ($column->getType()) { - case Column::TYPE_SELECTION: - $defaultValue = $this->getCellMapper($column)->filterValueToQueryParam($column, $column->getSelectionDefault()); - break; - case Column::TYPE_DATETIME: - $defaultValue = $this->getCellMapper($column)->filterValueToQueryParam($column, $column->getDatetimeDefault()); - break; - case Column::TYPE_NUMBER: - $defaultValue = $this->getCellMapper($column)->filterValueToQueryParam($column, $column->getNumberDefault()); - break; - case Column::TYPE_TEXT: - $defaultValue = $this->getCellMapper($column)->filterValueToQueryParam($column, $column->getTextDefault()); - break; - case Column::TYPE_USERGROUP: - $defaultValue = $this->getCellMapper($column)->filterValueToQueryParam($column, $column->getUsergroupDefault()); - break; - } + $defaultValue = match ($column->getType()) { + Column::TYPE_SELECTION => $this->getCellMapper($column)->filterValueToQueryParam($column, $column->getSelectionDefault()), + Column::TYPE_DATETIME => $this->getCellMapper($column)->filterValueToQueryParam($column, $column->getDatetimeDefault()), + Column::TYPE_NUMBER => $this->getCellMapper($column)->filterValueToQueryParam($column, $column->getNumberDefault()), + Column::TYPE_TEXT => $this->getCellMapper($column)->filterValueToQueryParam($column, $column->getTextDefault()), + Column::TYPE_USERGROUP => $this->getCellMapper($column)->filterValueToQueryParam($column, $column->getUsergroupDefault()), + default => $defaultValue, + }; return $defaultValue; } diff --git a/lib/Db/RowCellMapperSuper.php b/lib/Db/RowCellMapperSuper.php index be377c5d87..460e2095e8 100644 --- a/lib/Db/RowCellMapperSuper.php +++ b/lib/Db/RowCellMapperSuper.php @@ -41,7 +41,10 @@ public function formatRowData(Column $column, array $row) { * Transform value from a filter rule to the actual query parameter used * for constructing the view filter query */ - public function filterValueToQueryParam(Column $column, mixed $value): mixed { + /** + * @param array|float|null|string $value + */ + public function filterValueToQueryParam(Column $column, array|string|float|null $value): mixed { return $value; } diff --git a/lib/Db/RowCellSelectionMapper.php b/lib/Db/RowCellSelectionMapper.php index eba5332f1e..c28e7d46f7 100644 --- a/lib/Db/RowCellSelectionMapper.php +++ b/lib/Db/RowCellSelectionMapper.php @@ -30,12 +30,17 @@ public function applyDataToEntity(Column $column, RowCellSuper $cell, $data): vo } public function formatRowData(Column $column, array $row) { - return json_decode($row['value']); + return json_decode((string)$row['value']); } - private function valueToJsonDbValue(Column $column, $value): string { + /** + * @param array|float|null|string $value + * + * @return array|false|float|string + */ + private function valueToJsonDbValue(Column $column, array|float|string|null $value): array|string|float|false { if ($column->getSubtype() === 'check') { - return json_encode(ltrim($value, '"')); + return json_encode(ltrim((string)$value, '"')); } if ($column->getSubtype() === '' || $column->getSubtype() === null) { diff --git a/lib/Db/RowCellSuper.php b/lib/Db/RowCellSuper.php index 29c3e366bb..58fc632fa6 100644 --- a/lib/Db/RowCellSuper.php +++ b/lib/Db/RowCellSuper.php @@ -60,7 +60,7 @@ public function setColumnIdWrapper(int $columnId) { $this->setColumnId($columnId); } - public function setValueWrapper($value) { + public function setValueWrapper(array|float|null $value) { $this->setValue($value); } } diff --git a/lib/Db/RowSleeveMapper.php b/lib/Db/RowSleeveMapper.php index f5a21fe5c1..f61ed588b3 100644 --- a/lib/Db/RowSleeveMapper.php +++ b/lib/Db/RowSleeveMapper.php @@ -18,11 +18,12 @@ /** @template-extends QBMapper */ class RowSleeveMapper extends QBMapper { protected string $table = 'tables_row_sleeves'; - protected LoggerInterface $logger; - public function __construct(IDBConnection $db, LoggerInterface $logger) { + public function __construct( + IDBConnection $db, + protected LoggerInterface $logger, + ) { parent::__construct($db, $this->table, RowSleeve::class); - $this->logger = $logger; } /** diff --git a/lib/Db/ShareMapper.php b/lib/Db/ShareMapper.php index 72f05c7d8e..4ccfd5483f 100644 --- a/lib/Db/ShareMapper.php +++ b/lib/Db/ShareMapper.php @@ -19,11 +19,12 @@ /** @template-extends QBMapper */ class ShareMapper extends QBMapper { protected string $table = 'tables_shares'; - protected LoggerInterface $logger; - public function __construct(LoggerInterface $logger, IDBConnection $db) { + public function __construct( + protected LoggerInterface $logger, + IDBConnection $db, + ) { parent::__construct($db, $this->table, Share::class); - $this->logger = $logger; } /** diff --git a/lib/Db/Table.php b/lib/Db/Table.php index 418ce443d2..d2ce5c26ce 100644 --- a/lib/Db/Table.php +++ b/lib/Db/Table.php @@ -140,9 +140,7 @@ private function getViewsArray(): array { */ public function getColumnOrderArray(): array { $columnSettings = $this->getColumnOrderSettingsArray(); - usort($columnSettings, static function (ColumnOrderInformation $a, ColumnOrderInformation $b) { - return $a->getOrder() - $b->getOrder(); - }); + usort($columnSettings, static fn (ColumnOrderInformation $a, ColumnOrderInformation $b) => $a->getOrder() - $b->getOrder()); /** @var list $columnSettings */ return array_map(static fn (ColumnOrderInformation $vci): int => $vci->getId(), $columnSettings); } @@ -157,7 +155,7 @@ public function getColumnOrderSettingsArray(): array { } if (is_array($columns[array_key_first($columns)] ?? null)) { - return array_values(array_map(static fn (array $a): ColumnOrderInformation => ColumnOrderInformation::fromArray($a), $columns)); + return array_values(array_map(ColumnOrderInformation::fromArray(...), $columns)); } $result = []; diff --git a/lib/Db/TableMapper.php b/lib/Db/TableMapper.php index e6785f79a1..34aad23d88 100644 --- a/lib/Db/TableMapper.php +++ b/lib/Db/TableMapper.php @@ -23,7 +23,7 @@ class TableMapper extends QBMapper { protected CappedMemoryCache $cache; public function __construct( IDBConnection $db, - private UserHelper $userHelper, + private readonly UserHelper $userHelper, ) { parent::__construct($db, $this->table, Table::class); $this->cache = new CappedMemoryCache(); diff --git a/lib/Db/View.php b/lib/Db/View.php index 34783f76ef..441b522b4f 100644 --- a/lib/Db/View.php +++ b/lib/Db/View.php @@ -98,9 +98,7 @@ public function __construct() { public function getColumnsArray(): array { $columnSettings = $this->getColumnsSettingsArray(); - usort($columnSettings, static function (ViewColumnInformation $a, ViewColumnInformation $b) { - return $a->getOrder() - $b->getOrder(); - }); + usort($columnSettings, static fn (ViewColumnInformation $a, ViewColumnInformation $b) => $a->getOrder() - $b->getOrder()); return array_column($columnSettings, ViewColumnInformation::KEY_ID); } @@ -114,7 +112,7 @@ public function getColumnsSettingsArray(): array { } if (is_array(reset($columns))) { - return array_values(array_map(static fn (array $a): ViewColumnInformation => ViewColumnInformation::fromArray($a), $columns)); + return array_values(array_map(ViewColumnInformation::fromArray(...), $columns)); } $result = []; diff --git a/lib/Db/ViewMapper.php b/lib/Db/ViewMapper.php index 531803be5f..ebf2445528 100644 --- a/lib/Db/ViewMapper.php +++ b/lib/Db/ViewMapper.php @@ -25,7 +25,7 @@ class ViewMapper extends QBMapper { public function __construct( IDBConnection $db, - private UserHelper $userHelper, + private readonly UserHelper $userHelper, ) { parent::__construct($db, $this->table, View::class); $this->cache = new CappedMemoryCache(); diff --git a/lib/Dto/Column.php b/lib/Dto/Column.php index 5a321f1aee..f703f2c8b5 100644 --- a/lib/Dto/Column.php +++ b/lib/Dto/Column.php @@ -9,31 +9,31 @@ class Column { public function __construct( - private ?string $title = null, - private ?string $type = null, - private ?string $subtype = null, - private ?bool $mandatory = null, - private ?string $description = null, - private ?string $textDefault = null, - private ?string $textAllowedPattern = null, - private ?int $textMaxLength = null, - private ?bool $textUnique = null, - private ?float $numberDefault = null, - private ?float $numberMin = null, - private ?float $numberMax = null, - private ?int $numberDecimals = null, - private ?string $numberPrefix = null, - private ?string $numberSuffix = null, - private ?string $selectionOptions = null, - private ?string $selectionDefault = null, - private ?string $datetimeDefault = null, - private ?string $usergroupDefault = null, - private ?bool $usergroupMultipleItems = null, - private ?bool $usergroupSelectUsers = null, - private ?bool $usergroupSelectGroups = null, - private ?bool $usergroupSelectTeams = null, - private ?bool $showUserStatus = null, - private ?string $customSettings = null, + private readonly ?string $title = null, + private readonly ?string $type = null, + private readonly ?string $subtype = null, + private readonly ?bool $mandatory = null, + private readonly ?string $description = null, + private readonly ?string $textDefault = null, + private readonly ?string $textAllowedPattern = null, + private readonly ?int $textMaxLength = null, + private readonly ?bool $textUnique = null, + private readonly ?float $numberDefault = null, + private readonly ?float $numberMin = null, + private readonly ?float $numberMax = null, + private readonly ?int $numberDecimals = null, + private readonly ?string $numberPrefix = null, + private readonly ?string $numberSuffix = null, + private readonly ?string $selectionOptions = null, + private readonly ?string $selectionDefault = null, + private readonly ?string $datetimeDefault = null, + private readonly ?string $usergroupDefault = null, + private readonly ?bool $usergroupMultipleItems = null, + private readonly ?bool $usergroupSelectUsers = null, + private readonly ?bool $usergroupSelectGroups = null, + private readonly ?bool $usergroupSelectTeams = null, + private readonly ?bool $showUserStatus = null, + private readonly ?string $customSettings = null, ) { } diff --git a/lib/Helper/CircleHelper.php b/lib/Helper/CircleHelper.php index b98c871690..34b2477e95 100644 --- a/lib/Helper/CircleHelper.php +++ b/lib/Helper/CircleHelper.php @@ -28,9 +28,9 @@ class CircleHelper { * @psalm-suppress UndefinedClass */ public function __construct( - private LoggerInterface $logger, + private readonly LoggerInterface $logger, IAppManager $appManager, - private IL10N $l10n, + private readonly IL10N $l10n, ) { $this->circlesEnabled = $appManager->isEnabledForUser('circles'); $this->circlesManager = null; @@ -103,9 +103,7 @@ public function getCircleIdsForUser(string $userId): ?array { return null; } - $circleIds = array_map(function (Circle $circle) { - return $circle->getSingleId(); - }, $this->getUserCircles($userId)); + $circleIds = array_map(fn (Circle $circle) => $circle->getSingleId(), $this->getUserCircles($userId)); return $circleIds; } diff --git a/lib/Helper/ColumnsHelper.php b/lib/Helper/ColumnsHelper.php index f926d2ba3c..2ebe0e254d 100644 --- a/lib/Helper/ColumnsHelper.php +++ b/lib/Helper/ColumnsHelper.php @@ -29,8 +29,8 @@ class ColumnsHelper { private array $columnBusinesses = []; public function __construct( - private UserHelper $userHelper, - private CircleHelper $circleHelper, + private readonly UserHelper $userHelper, + private readonly CircleHelper $circleHelper, ) { } @@ -71,15 +71,15 @@ public function resolveSearchValue(string $placeholder, string $userId, ?Column case 'stars-3': return '3'; case 'stars-4': return '4'; case 'stars-5': return '5'; - case 'datetime-date-today': return date('Y-m-d') ? date('Y-m-d') : ''; - case 'datetime-date-start-of-year': return date('Y-01-01') ? date('Y-01-01') : ''; - case 'datetime-date-start-of-month': return date('Y-m-01') ? date('Y-m-01') : ''; + case 'datetime-date-today': return date('Y-m-d') ?: ''; + case 'datetime-date-start-of-year': return date('Y-01-01') ?: ''; + case 'datetime-date-start-of-month': return date('Y-m-01') ?: ''; case 'datetime-date-start-of-week': $day = date('w'); $result = date('Y-m-d', strtotime('-' . $day . ' days')); return $result ?: ''; case 'datetime-time-now': return date('H:i'); - case 'datetime-now': return date('Y-m-d H:i') ? date('Y-m-d H:i') : ''; + case 'datetime-now': return date('Y-m-d H:i') ?: ''; case 'datetime-exact-date': return $additionalValue ?? ''; case 'datetime-days-ahead': $days = max(0, (int)$additionalValue); diff --git a/lib/Helper/GroupHelper.php b/lib/Helper/GroupHelper.php index 83780b1b6a..5ccabc2ad1 100644 --- a/lib/Helper/GroupHelper.php +++ b/lib/Helper/GroupHelper.php @@ -11,12 +11,10 @@ use Psr\Log\LoggerInterface; class GroupHelper { - private LoggerInterface $logger; - private IGroupManager $groupManager; - - public function __construct(LoggerInterface $logger, IGroupManager $groupManager) { - $this->logger = $logger; - $this->groupManager = $groupManager; + public function __construct( + private readonly LoggerInterface $logger, + private readonly IGroupManager $groupManager, + ) { } public function getGroupDisplayName(string $groupId): string { diff --git a/lib/Helper/UserHelper.php b/lib/Helper/UserHelper.php index 3c84cff274..a4d717f2bc 100644 --- a/lib/Helper/UserHelper.php +++ b/lib/Helper/UserHelper.php @@ -15,23 +15,18 @@ use Psr\Log\LoggerInterface; class UserHelper { - private IUserManager $userManager; - - private LoggerInterface $logger; - - private IGroupManager $groupManager; - - public function __construct(IUserManager $userManager, LoggerInterface $logger, IGroupManager $groupManager) { - $this->userManager = $userManager; - $this->logger = $logger; - $this->groupManager = $groupManager; + public function __construct( + private readonly IUserManager $userManager, + private readonly LoggerInterface $logger, + private readonly IGroupManager $groupManager, + ) { } public function getUserDisplayName(string $userId): string { try { $user = $this->getUser($userId); - return $user->getDisplayName() ? $user->getDisplayName() : $userId; - } catch (InternalError $e) { + return $user->getDisplayName() ?: $userId; + } catch (InternalError) { $this->logger->info('no user given, will return userId'); return $userId; } @@ -65,13 +60,11 @@ public function getGroupsForUser(string $userId): array { public function getGroupIdsForUser(string $userId): ?array { try { $userGroups = $this->getGroupsForUser($userId); - } catch (InternalError $e) { + } catch (InternalError) { return null; } - $groupArray = array_map(function (IGroup $group) { - return $group->getGID(); - }, $userGroups); + $groupArray = array_map(fn (IGroup $group) => $group->getGID(), $userGroups); return $groupArray; } } diff --git a/lib/Listener/TablesReferenceListener.php b/lib/Listener/TablesReferenceListener.php index a1a564a388..4f3781c118 100644 --- a/lib/Listener/TablesReferenceListener.php +++ b/lib/Listener/TablesReferenceListener.php @@ -21,7 +21,7 @@ class TablesReferenceListener implements IEventListener { private bool $isLoaded = false; public function __construct( - private IEventDispatcher $eventDispatcher, + private readonly IEventDispatcher $eventDispatcher, ) { } diff --git a/lib/Listener/UserDeletedListener.php b/lib/Listener/UserDeletedListener.php index a035deeabc..69b1944611 100644 --- a/lib/Listener/UserDeletedListener.php +++ b/lib/Listener/UserDeletedListener.php @@ -18,13 +18,10 @@ * @template-implements IEventListener */ class UserDeletedListener implements IEventListener { - private TableService $tableService; - - private LoggerInterface $logger; - - public function __construct(TableService $tableService, LoggerInterface $logger) { - $this->tableService = $tableService; - $this->logger = $logger; + public function __construct( + private readonly TableService $tableService, + private readonly LoggerInterface $logger, + ) { } public function handle(Event $event): void { @@ -42,7 +39,7 @@ public function handle(Event $event): void { $this->tableService->delete($table->getId(), $event->getUser()->getUID()); } $this->logger->debug('tables for the deleted user removed'); - } catch (InternalError $e) { + } catch (InternalError) { } } } diff --git a/lib/Middleware/PermissionMiddleware.php b/lib/Middleware/PermissionMiddleware.php index ab847b400d..ab544c9f69 100644 --- a/lib/Middleware/PermissionMiddleware.php +++ b/lib/Middleware/PermissionMiddleware.php @@ -25,25 +25,13 @@ use OCP\IRequest; class PermissionMiddleware extends Middleware { - private IControllerMethodReflector $reflector; - private PermissionsService $permissionsService; - private ?string $userId; - private IRequest $request; - private ContextService $contextService; - public function __construct( - IControllerMethodReflector $reflector, - PermissionsService $permissionsService, - IRequest $request, - ?string $userId, - ContextService $contextService, + private readonly IControllerMethodReflector $reflector, + private readonly PermissionsService $permissionsService, + private readonly IRequest $request, + private readonly ?string $userId, + private readonly ContextService $contextService, ) { - - $this->reflector = $reflector; - $this->permissionsService = $permissionsService; - $this->userId = $userId; - $this->request = $request; - $this->contextService = $contextService; } /** diff --git a/lib/Middleware/ShareControlMiddleware.php b/lib/Middleware/ShareControlMiddleware.php index 84a3496405..ad81844c39 100644 --- a/lib/Middleware/ShareControlMiddleware.php +++ b/lib/Middleware/ShareControlMiddleware.php @@ -59,7 +59,7 @@ private function assertIsAccessible(string $tokenInput): void { } $allowedTokensJSON = $this->session->get(PublicShareController::DAV_AUTHENTICATED_FRONTEND) ?? '[]'; - $allowedTokens = json_decode($allowedTokensJSON, true); + $allowedTokens = json_decode((string)$allowedTokensJSON, true); if (!is_array($allowedTokens)) { $allowedTokens = []; } diff --git a/lib/Migration/DbRowSleeveSequence.php b/lib/Migration/DbRowSleeveSequence.php index 925f09bd9c..4060689e8f 100644 --- a/lib/Migration/DbRowSleeveSequence.php +++ b/lib/Migration/DbRowSleeveSequence.php @@ -20,6 +20,7 @@ public function __construct( protected IDBConnection $db, protected IConfig $config, protected LoggerInterface $logger, + private readonly \OCP\IAppConfig $appConfig, ) { } @@ -34,31 +35,29 @@ public function getName() { * @inheritDoc */ public function run(IOutput $output) { - $legacyRowTransferRunComplete = $this->config->getAppValue('tables', 'legacyRowTransferRunComplete', 'false') === 'true'; - $sequenceRepairComplete = $this->config->getAppValue('tables', 'sequenceRepairComplete', 'false') === 'true'; + $legacyRowTransferRunComplete = $this->appConfig->getValue('tables', 'legacyRowTransferRunComplete', 'false') === 'true'; + $sequenceRepairComplete = $this->appConfig->getValue('tables', 'sequenceRepairComplete', 'false') === 'true'; if (!$legacyRowTransferRunComplete || $sequenceRepairComplete) { return; } $platform = $this->db->getDatabasePlatform(); if (!$platform->supportsSequences()) { - $this->config->setAppValue('tables', 'sequenceRepairComplete', 'true'); + $this->appConfig->setValue('tables', 'sequenceRepairComplete', 'true'); return; } $newSequenceOffset = $this->getNewOffset(); if ($newSequenceOffset === null) { // no data, no op - $this->config->setAppValue('tables', 'sequenceRepairComplete', 'true'); + $this->appConfig->setValue('tables', 'sequenceRepairComplete', 'true'); return; } $schema = $this->db->createSchema(); $sequences = $schema->getSequences(); - $candidates = array_filter($sequences, function (string $sequenceName): bool { - return str_contains($sequenceName, 'tables_row_sleeves'); - }, ARRAY_FILTER_USE_KEY); + $candidates = array_filter($sequences, fn (string $sequenceName): bool => str_contains($sequenceName, 'tables_row_sleeves'), ARRAY_FILTER_USE_KEY); if (count($candidates) > 1) { $this->logger->error('Unexpected number of sequences, aborting.', [ @@ -68,14 +67,14 @@ public function run(IOutput $output) { throw new \LogicException('Failed to find the correct sequence.'); } elseif (count($candidates) === 0) { // 🤷 - $this->config->setAppValue('tables', 'sequenceRepairComplete', 'true'); + $this->appConfig->setValue('tables', 'sequenceRepairComplete', 'true'); return; } /** @var Sequence $sequence */ $sequence = $candidates[array_key_first($candidates)]; $this->db->executeStatement(sprintf('ALTER SEQUENCE %s RESTART START WITH %d', $sequence->getName(), $newSequenceOffset)); - $this->config->setAppValue('tables', 'sequenceRepairComplete', 'true'); + $this->appConfig->setValue('tables', 'sequenceRepairComplete', 'true'); } protected function getNewOffset(): ?int { @@ -95,7 +94,7 @@ protected function getMaxIdFromTable(string $tableName): ?int { ->from($tableName) ->executeQuery(); - $row = $result->fetch(); + $row = $result->fetchAssociative(); $result->closeCursor(); return $row ? (int)$row[array_key_first($row)] : null; diff --git a/lib/Migration/FixContextsDefaults.php b/lib/Migration/FixContextsDefaults.php index 1b0d477e26..bf036f2673 100644 --- a/lib/Migration/FixContextsDefaults.php +++ b/lib/Migration/FixContextsDefaults.php @@ -21,6 +21,7 @@ class FixContextsDefaults implements IRepairStep { public function __construct( protected IConfig $config, protected IDBConnection $dbc, + private readonly \OCP\IAppConfig $appConfig, ) { } @@ -35,7 +36,7 @@ public function getName() { * @inheritDoc */ public function run(IOutput $output) { - $appVersion = $this->config->getAppValue(Application::APP_ID, 'installed_version', '0.0'); + $appVersion = $this->appConfig->getValue(Application::APP_ID, 'installed_version', '0.0'); if (\version_compare($appVersion, '0.8.0-beta.1', '>')) { $output->info('Not applicable, skipping.'); return; diff --git a/lib/Migration/NewDbStructureRepairStep.php b/lib/Migration/NewDbStructureRepairStep.php index 6f12f2f0cf..adfa0ee6ad 100644 --- a/lib/Migration/NewDbStructureRepairStep.php +++ b/lib/Migration/NewDbStructureRepairStep.php @@ -23,20 +23,15 @@ class NewDbStructureRepairStep implements IRepairStep { - protected LoggerInterface $logger; - protected TableService $tableService; - protected LegacyRowMapper $legacyRowMapper; - protected Row2Mapper $rowMapper; - protected ColumnService $columnService; - protected IConfig $config; - - public function __construct(LoggerInterface $logger, TableService $tableService, ColumnService $columnService, LegacyRowMapper $legacyRowMapper, Row2Mapper $rowMapper, IConfig $config) { - $this->logger = $logger; - $this->tableService = $tableService; - $this->columnService = $columnService; - $this->legacyRowMapper = $legacyRowMapper; - $this->rowMapper = $rowMapper; - $this->config = $config; + public function __construct( + protected LoggerInterface $logger, + protected TableService $tableService, + protected ColumnService $columnService, + protected LegacyRowMapper $legacyRowMapper, + protected Row2Mapper $rowMapper, + protected IConfig $config, + private readonly \OCP\IAppConfig $appConfig, + ) { } /** @@ -50,7 +45,7 @@ public function getName(): string { * @param IOutput $output */ public function run(IOutput $output) { - $legacyRowTransferRunComplete = $this->config->getAppValue('tables', 'legacyRowTransferRunComplete', 'false'); + $legacyRowTransferRunComplete = $this->appConfig->getValue('tables', 'legacyRowTransferRunComplete', 'false'); if ($legacyRowTransferRunComplete === 'true') { return; @@ -60,12 +55,12 @@ public function run(IOutput $output) { try { $tables = $this->tableService->findAll('', true, true, false); $output->info('Found ' . count($tables) . ' table(s)'); - } catch (InternalError $e) { + } catch (InternalError) { $output->warning('Error while fetching tables. Will aboard.'); return; } $this->transferDataForTables($tables, $output); - $this->config->setAppValue('tables', 'legacyRowTransferRunComplete', 'true'); + $this->appConfig->setValue('tables', 'legacyRowTransferRunComplete', 'true'); } /** diff --git a/lib/Migration/ResetPublicSharePermissions.php b/lib/Migration/ResetPublicSharePermissions.php index 9cda262da0..341673d349 100644 --- a/lib/Migration/ResetPublicSharePermissions.php +++ b/lib/Migration/ResetPublicSharePermissions.php @@ -22,6 +22,7 @@ class ResetPublicSharePermissions implements IRepairStep { public function __construct( protected IConfig $config, protected IDBConnection $dbc, + private readonly \OCP\IAppConfig $appConfig, ) { } @@ -30,7 +31,7 @@ public function getName(): string { } public function run(IOutput $output): void { - $appVersion = $this->config->getAppValue(Application::APP_ID, 'installed_version', '0.0'); + $appVersion = $this->appConfig->getValue(Application::APP_ID, 'installed_version', '0.0'); if (\version_compare($appVersion, '2.0.2', '>=')) { $output->info('Not applicable, skipping.'); return; diff --git a/lib/Migration/Version001000Date20240328000000.php b/lib/Migration/Version001000Date20240328000000.php index e462cf0413..d48aad9503 100644 --- a/lib/Migration/Version001000Date20240328000000.php +++ b/lib/Migration/Version001000Date20240328000000.php @@ -30,6 +30,6 @@ public function __construct( */ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { // Register background job to convert column format - $this->jobList->add("OCA\Tables\BackgroundJob\ConvertViewColumnsFormat"); + $this->jobList->add(\OCA\Tables\BackgroundJob\ConvertViewColumnsFormat::class); } } diff --git a/lib/Migration/Version1000Date20260324000000.php b/lib/Migration/Version1000Date20260324000000.php index 9c2bbd584d..cd8db93b40 100644 --- a/lib/Migration/Version1000Date20260324000000.php +++ b/lib/Migration/Version1000Date20260324000000.php @@ -16,10 +16,9 @@ use Override; class Version1000Date20260324000000 extends SimpleMigrationStep { - private IDBConnection $connection; - - public function __construct(IDBConnection $connection) { - $this->connection = $connection; + public function __construct( + private readonly IDBConnection $connection, + ) { } #[Override] diff --git a/lib/Model/RowDataInput.php b/lib/Model/RowDataInput.php index dbef7fde0b..21f54cd2f9 100644 --- a/lib/Model/RowDataInput.php +++ b/lib/Model/RowDataInput.php @@ -24,7 +24,10 @@ class RowDataInput implements ArrayAccess, Iterator { /** @psalm-var array */ protected array $data = []; - public function add(int $columnId, mixed $value): self { + /** + * @param array|float|int|null|string $value + */ + public function add(int $columnId, array|string|int|float|null $value): self { $this->data[] = [self::DATA_KEY => $columnId, self::DATA_VAL => $value]; return $this; } diff --git a/lib/Model/TableScheme.php b/lib/Model/TableScheme.php index 00d9dc6b90..414f15737d 100644 --- a/lib/Model/TableScheme.php +++ b/lib/Model/TableScheme.php @@ -13,28 +13,18 @@ class TableScheme implements JsonSerializable { - protected ?string $title = null; - protected ?string $emoji = null; - - /** @var Column[]|null */ - protected ?array $columns = null; - - /** @var View[]|null */ - protected ?array $views = null; - protected ?string $description = null; - protected ?string $tablesVersion = null; - protected array $columnOrder = []; - protected array $sort = []; - - public function __construct(string $title, string $emoji, array $columns, array $view, string $description, string $tablesVersion, array $columnOrder = [], array $sort = []) { - $this->tablesVersion = $tablesVersion; - $this->title = $title; - $this->emoji = $emoji; - $this->columns = $columns; - $this->description = $description; - $this->views = $view; - $this->columnOrder = $columnOrder; - $this->sort = $sort; + public function __construct( + protected ?string $title, + protected ?string $emoji, + /** @var Column[]|null */ + protected ?array $columns, + /** @var View[]|null */ + protected ?array $views, + protected ?string $description, + protected ?string $tablesVersion, + protected array $columnOrder = [], + protected array $sort = [], + ) { } public function getTitle():string { diff --git a/lib/Reference/ContentReferenceHelper.php b/lib/Reference/ContentReferenceHelper.php index ae161bf7f6..f7a9cb09bd 100644 --- a/lib/Reference/ContentReferenceHelper.php +++ b/lib/Reference/ContentReferenceHelper.php @@ -91,9 +91,9 @@ public function resolveReference(string $referenceText): ?IReference { } else { $e = new Exception('Could not map ' . $referenceText . ' to any known type.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } - } catch (Exception|Throwable $e) { + } catch (Exception|Throwable) { /** @psalm-suppress InvalidReturnStatement */ return $this->linkReferenceProvider->resolveReference($referenceText); } @@ -113,7 +113,7 @@ public function resolveReference(string $referenceText): ?IReference { $referenceInfo['title'] = $element->getTitle(); } - $reference->setDescription($element->getOwnerDisplayName() ? $element->getOwnerDisplayName() : $element->getOwnership()); + $reference->setDescription($element->getOwnerDisplayName() ?: $element->getOwnership()); $referenceInfo['ownership'] = $element->getOwnership(); $referenceInfo['ownerDisplayName'] = $element->getOwnerDisplayName(); @@ -136,7 +136,7 @@ public function resolveReference(string $referenceText): ?IReference { } elseif ($this->matchReference($referenceText, 'view')) { $referenceInfo['columns'] = $this->columnService->findAllByView($elementId); } - } catch (InternalError|NotFoundError|PermissionError|DoesNotExistException|MultipleObjectsReturnedException $e) { + } catch (InternalError|NotFoundError|PermissionError|DoesNotExistException|MultipleObjectsReturnedException) { } // add rows data @@ -146,7 +146,7 @@ public function resolveReference(string $referenceText): ?IReference { } elseif ($this->matchReference($referenceText, 'view')) { $referenceInfo['rows'] = $this->rowService->findAllByView($elementId, $this->userId, 100, 0); } - } catch (InternalError|PermissionError|DoesNotExistException|MultipleObjectsReturnedException $e) { + } catch (InternalError|PermissionError|DoesNotExistException|MultipleObjectsReturnedException) { } $reference->setRichObject( diff --git a/lib/Reference/ContentReferenceProvider.php b/lib/Reference/ContentReferenceProvider.php index 7799b8a209..0e65969ae7 100644 --- a/lib/Reference/ContentReferenceProvider.php +++ b/lib/Reference/ContentReferenceProvider.php @@ -12,11 +12,12 @@ use OCP\Collaboration\Reference\IReferenceProvider; class ContentReferenceProvider implements IReferenceProvider { - private ContentReferenceHelper $referenceHelper; - private ReferenceManager $referenceManager; + private readonly ReferenceManager $referenceManager; - public function __construct(ContentReferenceHelper $referenceHelper, ReferenceManager $referenceManager) { - $this->referenceHelper = $referenceHelper; + public function __construct( + private readonly ContentReferenceHelper $referenceHelper, + ReferenceManager $referenceManager, + ) { $this->referenceManager = $referenceManager; } diff --git a/lib/Reference/ReferenceHelper.php b/lib/Reference/ReferenceHelper.php index 034af148e7..0ac644942a 100644 --- a/lib/Reference/ReferenceHelper.php +++ b/lib/Reference/ReferenceHelper.php @@ -27,35 +27,20 @@ class ReferenceHelper { protected const RICH_OBJECT_TYPE = Application::APP_ID . '_link'; - - protected ?string $userId; - protected IURLGenerator $urlGenerator; protected LinkReferenceProvider $linkReferenceProvider; - protected ViewService $viewService; - protected TableService $tableService; - protected ColumnService $columnService; - protected RowService $rowService; - protected IConfig $config; - protected LoggerInterface $logger; - - public function __construct(IURLGenerator $urlGenerator, - ViewService $viewService, - TableService $tableService, - ColumnService $columnService, - RowService $rowService, + + public function __construct( + protected IURLGenerator $urlGenerator, + protected ViewService $viewService, + protected TableService $tableService, + protected ColumnService $columnService, + protected RowService $rowService, LinkReferenceProvider $linkReferenceProvider, - ?string $userId, - IConfig $config, - LoggerInterface $logger) { - $this->userId = $userId; - $this->urlGenerator = $urlGenerator; + protected ?string $userId, + protected IConfig $config, + protected LoggerInterface $logger, + ) { $this->linkReferenceProvider = $linkReferenceProvider; - $this->viewService = $viewService; - $this->tableService = $tableService; - $this->rowService = $rowService; - $this->columnService = $columnService; - $this->config = $config; - $this->logger = $logger; } public function matchReference(string $referenceText, ?string $type = null): bool { @@ -106,9 +91,9 @@ public function resolveReference(string $referenceText): ?IReference { } else { $e = new Exception('Neither table nor view is given.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } - } catch (Exception|Throwable $e) { + } catch (Exception|Throwable) { /** @psalm-suppress InvalidReturnStatement */ return $this->linkReferenceProvider->resolveReference($referenceText); } @@ -125,7 +110,7 @@ public function resolveReference(string $referenceText): ?IReference { $referenceInfo['title'] = $element->getTitle(); } - $reference->setDescription($element->getOwnerDisplayName() ? $element->getOwnerDisplayName() : $element->getOwnership()); + $reference->setDescription($element->getOwnerDisplayName() ?: $element->getOwnership()); $referenceInfo['ownership'] = $element->getOwnership(); $referenceInfo['ownerDisplayName'] = $element->getOwnerDisplayName(); @@ -146,7 +131,7 @@ public function resolveReference(string $referenceText): ?IReference { } elseif ($this->matchReference($referenceText, 'view')) { $referenceInfo['rows'] = $this->rowService->findAllByView($elementId, $this->userId, 10, 0); } - } catch (InternalError|PermissionError|DoesNotExistException|MultipleObjectsReturnedException $e) { + } catch (InternalError|PermissionError|DoesNotExistException|MultipleObjectsReturnedException) { // TODO add logging } @@ -221,7 +206,7 @@ private function randomString(int $length): string { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $randString = ''; for ($i = 0; $i < $length; $i++) { - $randString = $characters[rand(0, strlen($characters))]; + $randString = $characters[random_int(0, strlen($characters))]; } return $randString; } diff --git a/lib/Reference/ReferenceProvider.php b/lib/Reference/ReferenceProvider.php index 09ec9e9322..1e828e8c3c 100644 --- a/lib/Reference/ReferenceProvider.php +++ b/lib/Reference/ReferenceProvider.php @@ -16,16 +16,15 @@ use OCP\IURLGenerator; class ReferenceProvider extends ADiscoverableReferenceProvider implements ISearchableReferenceProvider { - private ReferenceHelper $referenceHelper; - private ReferenceManager $referenceManager; - private IURLGenerator $urlGenerator; - private IL10N $l10n; + private readonly ReferenceManager $referenceManager; - public function __construct(IL10N $l10n, IURLGenerator $urlGenerator, ReferenceHelper $referenceHelper, ReferenceManager $referenceManager) { - $this->referenceHelper = $referenceHelper; + public function __construct( + private readonly IL10N $l10n, + private readonly IURLGenerator $urlGenerator, + private readonly ReferenceHelper $referenceHelper, + ReferenceManager $referenceManager, + ) { $this->referenceManager = $referenceManager; - $this->urlGenerator = $urlGenerator; - $this->l10n = $l10n; } /** diff --git a/lib/Search/SearchTablesProvider.php b/lib/Search/SearchTablesProvider.php index 858e5dbf6d..97c51a47d0 100644 --- a/lib/Search/SearchTablesProvider.php +++ b/lib/Search/SearchTablesProvider.php @@ -23,22 +23,13 @@ use OCP\Search\SearchResultEntry; class SearchTablesProvider implements IProvider { - private IAppManager $appManager; - private IL10N $l10n; - private ViewService $viewService; - private TableService $tableService; - private IURLGenerator $urlGenerator; - - public function __construct(IAppManager $appManager, - IL10N $l10n, - ViewService $viewService, - TableService $tableService, - IURLGenerator $urlGenerator) { - $this->appManager = $appManager; - $this->l10n = $l10n; - $this->viewService = $viewService; - $this->tableService = $tableService; - $this->urlGenerator = $urlGenerator; + public function __construct( + private readonly IAppManager $appManager, + private readonly IL10N $l10n, + private readonly ViewService $viewService, + private readonly TableService $tableService, + private readonly IURLGenerator $urlGenerator, + ) { } /** @@ -59,7 +50,7 @@ public function getName(): string { * @inheritDoc */ public function getOrder(string $route, array $routeParameters): int { - if (strpos($route, Application::APP_ID . '.') === 0) { + if (str_starts_with($route, Application::APP_ID . '.')) { // Active app, prefer Tables results return -1; } @@ -89,29 +80,25 @@ public function search(IUser $user, ISearchQuery $query): SearchResult { // look for tables $tables = $this->tableService->search($term, $limit, $offset); - $formattedTablesResults = array_map(function (Table $table) use ($appIconUrl): SearchResultEntry { - return new SearchResultEntry( - $appIconUrl, - $table->getEmoji() . ' ' . $table->getTitle(), - ($table->getOwnerDisplayName() ? $table->getOwnerDisplayName() : $table->getOwnership()) . ', ' . $this->l10n->n('%n row', '%n rows', $table->getRowsCount()) . ', ' . $this->l10n->t('table'), - $this->getInternalLink($table->getId(), 'table'), - '', - false - ); - }, $tables); + $formattedTablesResults = array_map(fn (Table $table): SearchResultEntry => new SearchResultEntry( + $appIconUrl, + $table->getEmoji() . ' ' . $table->getTitle(), + ($table->getOwnerDisplayName() ?: $table->getOwnership()) . ', ' . $this->l10n->n('%n row', '%n rows', $table->getRowsCount()) . ', ' . $this->l10n->t('table'), + $this->getInternalLink($table->getId(), 'table'), + '', + false + ), $tables); // look for views $views = $this->viewService->search($term, $limit, $offset); - $formattedViewResults = array_map(function (View $view) use ($viewIconUrl): SearchResultEntry { - return new SearchResultEntry( - $viewIconUrl, - $view->getEmoji() . ' ' . $view->getTitle(), - ($view->getOwnerDisplayName() ? $view->getOwnerDisplayName(): $view->getOwnership()) . ', ' . $this->l10n->n('%n row', '%n rows', $view->getRowsCount()) . ', ' . $this->l10n->t('table view'), - $this->getInternalLink($view->getId(), 'view'), - '', - false - ); - }, $views); + $formattedViewResults = array_map(fn (View $view): SearchResultEntry => new SearchResultEntry( + $viewIconUrl, + $view->getEmoji() . ' ' . $view->getTitle(), + ($view->getOwnerDisplayName() ?: $view->getOwnership()) . ', ' . $this->l10n->n('%n row', '%n rows', $view->getRowsCount()) . ', ' . $this->l10n->t('table view'), + $this->getInternalLink($view->getId(), 'view'), + '', + false + ), $views); return SearchResult::paginated( $this->getName(), diff --git a/lib/Service/ColumnService.php b/lib/Service/ColumnService.php index 1f7322e8f1..1d8e7c0a35 100644 --- a/lib/Service/ColumnService.php +++ b/lib/Service/ColumnService.php @@ -34,20 +34,6 @@ * @psalm-import-type TablesColumn from ResponseDefinitions */ class ColumnService extends SuperService { - private ColumnMapper $mapper; - - private TableMapper $tableMapper; - - private ViewService $viewService; - - private RowService $rowService; - - private IL10N $l; - - private UserHelper $userHelper; - - private ColumnDtoValidator $columnDtoValidator; - /** @var array Per-request cache of sorted column-id order, keyed by tableId. */ private array $columnOrderCache = []; @@ -55,22 +41,15 @@ public function __construct( PermissionsService $permissionsService, LoggerInterface $logger, ?string $userId, - ColumnMapper $mapper, - TableMapper $tableMapper, - ViewService $viewService, - RowService $rowService, - IL10N $l, - UserHelper $userHelper, - ColumnDtoValidator $columnDtoValidator, + private readonly ColumnMapper $mapper, + private readonly TableMapper $tableMapper, + private readonly ViewService $viewService, + private readonly RowService $rowService, + private readonly IL10N $l, + private readonly UserHelper $userHelper, + private readonly ColumnDtoValidator $columnDtoValidator, ) { parent::__construct($logger, $userId, $permissionsService); - $this->mapper = $mapper; - $this->tableMapper = $tableMapper; - $this->viewService = $viewService; - $this->rowService = $rowService; - $this->l = $l; - $this->userHelper = $userHelper; - $this->columnDtoValidator = $columnDtoValidator; } /** @@ -113,7 +92,7 @@ public function findAllByTable(int $tableId, ?string $userId = null, ?Table $tab return $columns; } catch (\OCP\DB\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } else { throw new PermissionError('no read access to table id = ' . $tableId); @@ -131,7 +110,7 @@ public function findAllByManagedView(View $view, string $userId): array { return $this->enhanceColumns($this->mapper->findAllByTable($view->getTableId()), $view); } catch (\OCP\DB\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } else { throw new PermissionError('no manage access to view id = ' . $view->getId()); @@ -152,13 +131,13 @@ public function findAllByView(int $viewId, ?string $userId = null): array { $view = $this->viewService->find($viewId, true, $userId); } catch (InternalError|MultipleObjectsReturnedException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (PermissionError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new PermissionError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new PermissionError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $viewColumns = $this->mapper->findAll($view->getColumnIds()); @@ -250,31 +229,31 @@ public function create( $view = $this->viewService->find($viewId, true, $userId); } catch (InternalError|MultipleObjectsReturnedException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (PermissionError $e) { throw new PermissionError('Can not load given view, no permission.'); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } try { $table = $this->tableMapper->find($view->getTableId()); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (MultipleObjectsReturnedException|\OCP\DB\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } elseif ($tableId) { try { $table = $this->tableMapper->find($tableId); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (MultipleObjectsReturnedException|\OCP\DB\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } else { throw new InternalError('Cannot create column without table or view in context'); @@ -314,7 +293,7 @@ public function create( $entity = $this->mapper->insert($item); } catch (\OCP\DB\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if (isset($view) && $view) { // Add columns to view(s) @@ -325,12 +304,12 @@ public function create( $view = $this->viewService->find($viewId); } catch (InternalError|MultipleObjectsReturnedException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); - } catch (PermissionError $e) { + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + } catch (PermissionError) { throw new PermissionError('Can not add column to view, no permission.'); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $this->viewService->addColumnToView($view, $entity, $userId); @@ -509,10 +488,10 @@ public function delete(int $id, bool $skipRowCleanup = false, ?string $userId = $item = $this->mapper->find($id); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (MultipleObjectsReturnedException|\OCP\DB\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security @@ -525,13 +504,13 @@ public function delete(int $id, bool $skipRowCleanup = false, ?string $userId = $this->rowService->deleteColumnDataFromRows($item); } catch (InternalError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } try { $table = $this->tableMapper->find($item->getTableId()); } catch (DoesNotExistException|MultipleObjectsReturnedException|\OCP\DB\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $this->viewService->deleteColumnDataFromViews($id, $table); } @@ -540,7 +519,7 @@ public function delete(int $id, bool $skipRowCleanup = false, ?string $userId = $this->mapper->delete($item); } catch (\OCP\DB\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } return $this->enhanceColumn($item); } @@ -573,7 +552,7 @@ public function findOrCreateColumnsByTitleForTableAsArray(?int $tableId, ?int $v } else { $e = new Exception('Either tableId nor viewId is given.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $i = -1; diff --git a/lib/Service/ColumnTypes/DatetimeBusiness.php b/lib/Service/ColumnTypes/DatetimeBusiness.php index 08ed85733e..855aceea20 100644 --- a/lib/Service/ColumnTypes/DatetimeBusiness.php +++ b/lib/Service/ColumnTypes/DatetimeBusiness.php @@ -16,9 +16,10 @@ class DatetimeBusiness extends SuperBusiness { /** * @param mixed $value (string|null) * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { if ($value === '' || $value === null) { return ''; } @@ -53,7 +54,7 @@ public function canBeParsed($value, Column $column): bool { try { new DateTime($value); - } catch (Exception $e) { + } catch (Exception) { return false; } return true; diff --git a/lib/Service/ColumnTypes/DatetimeDateBusiness.php b/lib/Service/ColumnTypes/DatetimeDateBusiness.php index bfebd46241..2d18aa9b04 100644 --- a/lib/Service/ColumnTypes/DatetimeDateBusiness.php +++ b/lib/Service/ColumnTypes/DatetimeDateBusiness.php @@ -14,9 +14,10 @@ class DatetimeDateBusiness extends SuperBusiness { /** * @param mixed $value (string|null) * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { return json_encode($this->isValidDate((string)$value, 'Y-m-d') ? (string)$value : ''); } diff --git a/lib/Service/ColumnTypes/DatetimeTimeBusiness.php b/lib/Service/ColumnTypes/DatetimeTimeBusiness.php index 2d182d3b03..fbb125fd9d 100644 --- a/lib/Service/ColumnTypes/DatetimeTimeBusiness.php +++ b/lib/Service/ColumnTypes/DatetimeTimeBusiness.php @@ -14,9 +14,10 @@ class DatetimeTimeBusiness extends SuperBusiness { /** * @param mixed $value (string|null) * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { return json_encode($this->isValidDate((string)$value, 'H:i') ? $value : ''); } diff --git a/lib/Service/ColumnTypes/IColumnTypeBusiness.php b/lib/Service/ColumnTypes/IColumnTypeBusiness.php index 37854635e8..e327fed284 100644 --- a/lib/Service/ColumnTypes/IColumnTypeBusiness.php +++ b/lib/Service/ColumnTypes/IColumnTypeBusiness.php @@ -21,9 +21,9 @@ interface IColumnTypeBusiness { * * @param mixed $value * @param Column $column - * @return string value stringify + * @return string|false value stringify */ - public function parseValue($value, Column $column): string; + public function parseValue($value, Column $column): string|false; /** * Tests if the given value can be parsed to a value of the column type @@ -57,7 +57,7 @@ public function canBeParsedDisplayValue($value, Column $column): bool; * * @param mixed $value * @param Column $column - * @return string + * @return string|false */ - public function parseDisplayValue($value, Column $column): string; + public function parseDisplayValue($value, Column $column): string|false; } diff --git a/lib/Service/ColumnTypes/NumberBusiness.php b/lib/Service/ColumnTypes/NumberBusiness.php index a0a549a48b..af723f32a0 100644 --- a/lib/Service/ColumnTypes/NumberBusiness.php +++ b/lib/Service/ColumnTypes/NumberBusiness.php @@ -14,9 +14,10 @@ class NumberBusiness extends SuperBusiness { /** * @param mixed $value (int|float|string|null) * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { if ($value === null) { return ''; } diff --git a/lib/Service/ColumnTypes/NumberProgressBusiness.php b/lib/Service/ColumnTypes/NumberProgressBusiness.php index ecfb5a9e10..8c2c6f0968 100644 --- a/lib/Service/ColumnTypes/NumberProgressBusiness.php +++ b/lib/Service/ColumnTypes/NumberProgressBusiness.php @@ -14,9 +14,10 @@ class NumberProgressBusiness extends SuperBusiness { /** * @param mixed $value (int|string|null) * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { return json_encode((int)$value); } diff --git a/lib/Service/ColumnTypes/NumberStarsBusiness.php b/lib/Service/ColumnTypes/NumberStarsBusiness.php index d3aef89ba1..1ef3f28104 100644 --- a/lib/Service/ColumnTypes/NumberStarsBusiness.php +++ b/lib/Service/ColumnTypes/NumberStarsBusiness.php @@ -14,9 +14,10 @@ class NumberStarsBusiness extends SuperBusiness { /** * @param mixed $value (null|int|string) * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { return json_encode((int)$value); } diff --git a/lib/Service/ColumnTypes/RelationBusiness.php b/lib/Service/ColumnTypes/RelationBusiness.php index 7ca0a73ba8..f072904cd5 100644 --- a/lib/Service/ColumnTypes/RelationBusiness.php +++ b/lib/Service/ColumnTypes/RelationBusiness.php @@ -16,7 +16,7 @@ class RelationBusiness extends SuperBusiness implements IColumnTypeBusiness { public function __construct( LoggerInterface $logger, - private RelationService $relationService, + private readonly RelationService $relationService, ) { parent::__construct($logger); } @@ -24,11 +24,12 @@ public function __construct( /** * @param mixed $value (array|string|null) * @param Column|null $column - * @return string + * + * @return false|string */ - public function parseValue($value, ?Column $column = null): string { + public function parseValue($value, ?Column $column = null): string|false { if (!$column) { - $this->logger->warning('No column given, but expected on ' . __FUNCTION__ . ' within ' . __CLASS__, ['exception' => new \Exception()]); + $this->logger->warning('No column given, but expected on ' . __FUNCTION__ . ' within ' . self::class, ['exception' => new \Exception()]); return ''; } @@ -54,7 +55,7 @@ public function parseValue($value, ?Column $column = null): string { */ public function canBeParsed($value, ?Column $column = null): bool { if (!$column) { - $this->logger->warning('No column given, but expected on ' . __FUNCTION__ . ' within ' . __CLASS__, ['exception' => new \Exception()]); + $this->logger->warning('No column given, but expected on ' . __FUNCTION__ . ' within ' . self::class, ['exception' => new \Exception()]); return false; } if ($value === null) { diff --git a/lib/Service/ColumnTypes/SelectionBusiness.php b/lib/Service/ColumnTypes/SelectionBusiness.php index 3fd6f19c76..14ba1bee97 100644 --- a/lib/Service/ColumnTypes/SelectionBusiness.php +++ b/lib/Service/ColumnTypes/SelectionBusiness.php @@ -14,9 +14,10 @@ class SelectionBusiness extends SuperBusiness { /** * @param mixed $value (array|string|null) * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { $intValue = (int)$value; if (!is_numeric($value) || $intValue != $value) { return ''; @@ -31,7 +32,10 @@ public function parseValue($value, Column $column): string { return ''; } - public function parseDisplayValue($value, Column $column): string { + /** + * @return false|string + */ + public function parseDisplayValue($value, Column $column): string|false { foreach ($column->getSelectionOptionsArray() as $option) { if ($option['label'] === $value) { return json_encode($option['id']); diff --git a/lib/Service/ColumnTypes/SelectionCheckBusiness.php b/lib/Service/ColumnTypes/SelectionCheckBusiness.php index 73fa3baa2e..fa22adab6d 100644 --- a/lib/Service/ColumnTypes/SelectionCheckBusiness.php +++ b/lib/Service/ColumnTypes/SelectionCheckBusiness.php @@ -16,9 +16,10 @@ class SelectionCheckBusiness extends SuperBusiness { /** * @param mixed $value * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { $found = in_array($value, self::PATTERN_POSITIVE, true); return json_encode($found ? 'true' : 'false'); } diff --git a/lib/Service/ColumnTypes/SelectionMultiBusiness.php b/lib/Service/ColumnTypes/SelectionMultiBusiness.php index b8799a6613..e0c6fa0abf 100644 --- a/lib/Service/ColumnTypes/SelectionMultiBusiness.php +++ b/lib/Service/ColumnTypes/SelectionMultiBusiness.php @@ -16,9 +16,10 @@ class SelectionMultiBusiness extends SuperBusiness { /** * @param mixed $value (array|string|null) * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { if ($value === null) { return json_encode([]); } @@ -27,7 +28,7 @@ public function parseValue($value, Column $column): string { $wasString = false; if (is_string($value)) { - $value = array_map('trim', explode(',', $value)); + $value = array_map(trim(...), explode(',', $value)); $wasString = true; } @@ -81,7 +82,7 @@ public function canBeParsed($value, Column $column): bool { $wasString = false; if (is_string($value)) { - $value = array_map('trim', explode(',', $value)); + $value = array_map(trim(...), explode(',', $value)); $wasString = true; } diff --git a/lib/Service/ColumnTypes/SuperBusiness.php b/lib/Service/ColumnTypes/SuperBusiness.php index 61c2995c79..bfe9ddcd11 100644 --- a/lib/Service/ColumnTypes/SuperBusiness.php +++ b/lib/Service/ColumnTypes/SuperBusiness.php @@ -13,22 +13,25 @@ class SuperBusiness implements IColumnTypeBusiness { - protected LoggerInterface $logger; - - public function __construct(LoggerInterface $logger) { - $this->logger = $logger; + public function __construct( + protected LoggerInterface $logger, + ) { } /** * @param mixed $value * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { return json_encode($value); } - public function parseDisplayValue($value, Column $column): string { + /** + * @return false|string + */ + public function parseDisplayValue($value, Column $column): string|false { return $this->parseValue($value, $column); } diff --git a/lib/Service/ColumnTypes/TextLineBusiness.php b/lib/Service/ColumnTypes/TextLineBusiness.php index 8f5a06ddb0..75e76d9865 100644 --- a/lib/Service/ColumnTypes/TextLineBusiness.php +++ b/lib/Service/ColumnTypes/TextLineBusiness.php @@ -17,8 +17,8 @@ class TextLineBusiness extends SuperBusiness { public function __construct( LoggerInterface $logger, - private Row2Mapper $row2Mapper, - private IL10N $n, + private readonly Row2Mapper $row2Mapper, + private readonly IL10N $n, ) { parent::__construct($logger); } diff --git a/lib/Service/ColumnTypes/TextLinkBusiness.php b/lib/Service/ColumnTypes/TextLinkBusiness.php index a3b6dcb974..ca5ece0eb2 100644 --- a/lib/Service/ColumnTypes/TextLinkBusiness.php +++ b/lib/Service/ColumnTypes/TextLinkBusiness.php @@ -18,7 +18,7 @@ class TextLinkBusiness extends SuperBusiness { public function __construct( LoggerInterface $logger, - private IL10N $n, + private readonly IL10N $n, ) { parent::__construct($logger); } @@ -26,9 +26,10 @@ public function __construct( /** * @param mixed $value (string|null) * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { if ($value === null) { return ''; } @@ -44,7 +45,7 @@ public function parseValue($value, Column $column): string { } // if is json (this is the default case, other formats are backward compatibility - $data = json_decode($value, true); + $data = json_decode((string)$value, true); if ($data !== null) { if (isset($data['resourceUrl'])) { return json_encode(json_encode([ @@ -63,7 +64,7 @@ public function parseValue($value, Column $column): string { } // if is just a url (old implementation) - preg_match('/(http|https)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', $value, $matches); + preg_match('/(http|https)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', (string)$value, $matches); if (empty($matches)) { return ''; } @@ -83,12 +84,12 @@ public function canBeParsed($value, Column $column): bool { if (!$value) { return true; } - preg_match('/(.*) \((http.*)\)/', $value, $matches); + preg_match('/(.*) \((http.*)\)/', (string)$value, $matches); if (!empty($matches) && $matches[0] && $matches[1]) { return true; } - $data = json_decode($value, true); + $data = json_decode((string)$value, true); if ($data !== null) { if (!isset($data['resourceUrl']) && !isset($data['value'])) { $this->logger->error('Value ' . $value . ' cannot be parsed as the column ' . $column->getId() . ' as it contains incomplete data'); @@ -105,12 +106,12 @@ public function canBeParsed($value, Column $column): bool { return true; } - preg_match('/(http|https)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', $value, $matches); + preg_match('/(http|https)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', (string)$value, $matches); return !empty($matches); } public function validateValue(mixed $value, Column $column, string $userId, int $tableId, ?int $rowId): void { - $data = json_decode($value, true); + $data = json_decode((string)$value, true); // Only allow URLs that start with http or https if (isset($data['value']) && !$this->isValidUrlProtocol($data['value'])) { diff --git a/lib/Service/ColumnTypes/UsergroupBusiness.php b/lib/Service/ColumnTypes/UsergroupBusiness.php index 116596a3bf..ac24de2c1b 100644 --- a/lib/Service/ColumnTypes/UsergroupBusiness.php +++ b/lib/Service/ColumnTypes/UsergroupBusiness.php @@ -83,9 +83,10 @@ public function validateValue(mixed $value, Column $column, string $userId, int * * @param mixed $value (array|string|null) * @param Column $column - * @return string + * + * @return false|string */ - public function parseValue($value, Column $column): string { + public function parseValue($value, Column $column): string|false { if ($value === null) { return json_encode([]); } diff --git a/lib/Service/ContextService.php b/lib/Service/ContextService.php index 9a32490199..c7e9387288 100644 --- a/lib/Service/ContextService.php +++ b/lib/Service/ContextService.php @@ -132,7 +132,7 @@ public function create(string $name, string $iconName, string $description, arra $context->setOwnerId($ownerId); $context->setOwnerType($ownerType); - $this->atomic(function () use ($context, $nodes) { + $this->atomic(function () use ($context, $nodes): void { $this->contextMapper->insert($context); if (!empty($nodes)) { @@ -322,7 +322,7 @@ public function delete(int $contextId, string $userId): Context { public function deleteNodeRel(int $nodeId, int $nodeType): void { try { $nodeRelIds = $this->contextNodeRelMapper->getRelIdsForNode($nodeId, $nodeType); - $this->atomic(function () use ($nodeRelIds) { + $this->atomic(function () use ($nodeRelIds): void { $this->pageContentMapper->deleteByNodeRelIds($nodeRelIds); $this->contextNodeRelMapper->deleteByNodeRelIds($nodeRelIds); }, $this->dbc); diff --git a/lib/Service/FavoritesService.php b/lib/Service/FavoritesService.php index cb09d62807..53ba4cd6f8 100644 --- a/lib/Service/FavoritesService.php +++ b/lib/Service/FavoritesService.php @@ -19,20 +19,14 @@ class FavoritesService { - private IDBConnection $connection; - private PermissionsService $permissionsService; - private ?string $userId; private bool $cached = false; - private CappedMemoryCache $cache; + private readonly CappedMemoryCache $cache; public function __construct( - IDBConnection $connection, - PermissionsService $permissionsService, - ?string $userId, + private readonly IDBConnection $connection, + private readonly PermissionsService $permissionsService, + private readonly ?string $userId, ) { - $this->connection = $connection; - $this->permissionsService = $permissionsService; - $this->userId = $userId; // The cache usage is currently not unique to the user id as only a memory cache is used $this->cache = new CappedMemoryCache(); } @@ -49,7 +43,7 @@ public function isFavorite(int $nodeType, int $id): bool { ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($this->userId))); $result = $qb->executeQuery(); - while ($row = $result->fetch()) { + while ($row = $result->fetchAssociative()) { $this->cache->set(sprintf('%d_%d', $row['node_type'], $row['node_id']), true); } } @@ -133,7 +127,7 @@ public function findAll(?string $userId = null): array { $result = $qb->executeQuery(); $rows = []; - while ($row = $result->fetch()) { + while ($row = $result->fetchAssociative()) { $rows[] = $row; } return $rows; diff --git a/lib/Service/ImportService.php b/lib/Service/ImportService.php index d8adc4b521..96f043be38 100644 --- a/lib/Service/ImportService.php +++ b/lib/Service/ImportService.php @@ -52,13 +52,7 @@ class ImportService extends SuperService { - private IRootFolder $rootFolder; - private ColumnService $columnService; - private RowService $rowService; - private TableService $tableService; - private ViewService $viewService; - private IUserManager $userManager; - private IAppData $appData; + private readonly IAppData $appData; private ?int $tableId = null; private ?int $viewId = null; @@ -90,24 +84,18 @@ public function __construct( PermissionsService $permissionsService, LoggerInterface $logger, ?string $userId, - IRootFolder $rootFolder, - ColumnService $columnService, - RowService $rowService, - TableService $tableService, - ViewService $viewService, - IUserManager $userManager, + private readonly IRootFolder $rootFolder, + private readonly ColumnService $columnService, + private readonly RowService $rowService, + private readonly TableService $tableService, + private readonly ViewService $viewService, + private readonly IUserManager $userManager, private readonly ColumnsHelper $columnsHelper, - private IJobList $jobList, - private ITempManager $tempManager, + private readonly IJobList $jobList, + private readonly ITempManager $tempManager, IAppDataFactory $appDataFactory, ) { parent::__construct($logger, $userId, $permissionsService); - $this->rootFolder = $rootFolder; - $this->columnService = $columnService; - $this->rowService = $rowService; - $this->tableService = $tableService; - $this->viewService = $viewService; - $this->userManager = $userManager; $this->appData = $appDataFactory->get(Application::APP_ID); } @@ -119,7 +107,7 @@ public function previewImport(?int $tableId, ?int $viewId, string $path): array } else { $e = new \Exception('Neither tableId nor viewId is given.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $this->createUnknownColumns = false; @@ -218,7 +206,7 @@ private function getPreviewData(Worksheet $worksheet): array { 'numberPrefix' => $this->rawColumnDataTypes[$colIndex]['number_prefix'] ?? '', 'numberSuffix' => $this->rawColumnDataTypes[$colIndex]['number_suffix'] ?? '', ]; - if (mb_strtolower($title) === Column::META_ID_TITLE) { + if (mb_strtolower((string)$title) === Column::META_ID_TITLE) { $column['id'] = Column::TYPE_META_ID; } @@ -343,12 +331,12 @@ public function import(?int $tableId, ?int $viewId, string $path, bool $createMi if (!$this->tableId && !$this->viewId) { $e = new \Exception('Neither tableId nor viewId is given.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if ($this->tableId && $this->viewId) { $e = new LogicException('Both table ID and view ID are provided, but only one of them is allowed'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if ($this->userId === null || $this->userManager->get($this->userId) === null) { @@ -433,12 +421,12 @@ public function scheduleImport(?int $tableId, ?int $viewId, string $path, bool $ if (!$this->tableId && !$this->viewId) { $e = new \Exception('Neither tableId nor viewId is given.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if ($this->tableId && $this->viewId) { $e = new \LogicException('Both table ID and view ID are provided, but only one of them is allowed'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if ($this->userId === null || $this->userManager->get($this->userId) === null) { @@ -574,7 +562,10 @@ private function loop(Worksheet $worksheet): void { /* * @return string Stringified value */ - private function parseValueByColumnType(string $value, Column $column, IColumnTypeBusiness $columnBusiness): string { + /** + * @return false|string + */ + private function parseValueByColumnType(string $value, Column $column, IColumnTypeBusiness $columnBusiness): string|false { try { if (!$columnBusiness->canBeParsedDisplayValue($value, $column)) { $this->logger->warning('Value ' . $value . ' could not be parsed for column ' . $column->getTitle()); @@ -697,14 +688,17 @@ private function upsertRow(Row $row, array $columnBusinesses): void { $this->countErrors++; } catch (NotFoundError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage(), 0, $e); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage(), 0, $e); } catch (\Throwable $e) { $this->countErrors++; $this->logger->error('Error while creating/updating new row for import.', ['exception' => $e]); } } - private function valueToDateTimeImmutable(mixed $value): ?DateTimeImmutable { + /** + * @param null|string $value + */ + private function valueToDateTimeImmutable(?string $value): ?DateTimeImmutable { if ( $value === false || $value === null @@ -759,7 +753,7 @@ private function getColumns(Row $firstRow, Row $secondRow): void { if ($cell && $cell->getValue() !== null && $cell->getValue() !== '') { $title = $cell->getValue(); - if (!$this->columnsConfig && mb_strtolower($title) === Column::META_ID_TITLE) { + if (!$this->columnsConfig && mb_strtolower((string)$title) === Column::META_ID_TITLE) { $this->idColumnIndex = $index; $titles[] = $title; $dataTypes[] = $this->parseColumnDataType($secondRowCellIterator->current()); diff --git a/lib/Service/NodeService.php b/lib/Service/NodeService.php index f4c9b33c4b..d51c99d9e5 100644 --- a/lib/Service/NodeService.php +++ b/lib/Service/NodeService.php @@ -59,9 +59,7 @@ public function getPublicDataOfNode(string $nodeType, int $nodeId): array { private function publicDataOfTable(int $id): array { $table = $this->tableService->find($id, false, ''); /** @var array{title: string, emoji: string, description: string, createdAt: string, lastEditAt: string, rowsCount: int} */ - return array_filter($table->jsonSerialize(), static function (string $key): bool { - return in_array($key, self::PUBLIC_NODE_KEYS, true); - }, ARRAY_FILTER_USE_KEY); + return array_filter($table->jsonSerialize(), static fn (string $key): bool => in_array($key, self::PUBLIC_NODE_KEYS, true), ARRAY_FILTER_USE_KEY); } /** @@ -73,8 +71,6 @@ private function publicDataOfTable(int $id): array { private function publicDataOfView(int $id): array { $view = $this->viewService->find($id, false, ''); /** @var array{title: string, emoji: string, description: string, createdAt: string, lastEditAt: string, rowsCount: int} */ - return array_filter($view->jsonSerialize(), static function (string $key): bool { - return in_array($key, self::PUBLIC_NODE_KEYS, true); - }, ARRAY_FILTER_USE_KEY); + return array_filter($view->jsonSerialize(), static fn (string $key): bool => in_array($key, self::PUBLIC_NODE_KEYS, true), ARRAY_FILTER_USE_KEY); } } diff --git a/lib/Service/PermissionsService.php b/lib/Service/PermissionsService.php index 74f3169692..f60097cc40 100644 --- a/lib/Service/PermissionsService.php +++ b/lib/Service/PermissionsService.php @@ -29,26 +29,8 @@ use Throwable; class PermissionsService { - private TableMapper $tableMapper; - - private ViewMapper $viewMapper; - - private ShareMapper $shareMapper; - - private UserHelper $userHelper; - - private CircleHelper $circleHelper; - - protected LoggerInterface $logger; - - protected ?string $userId = null; - - protected bool $isCli = false; - private bool $isPublicContext = false; - private ContextMapper $contextMapper; - /** @var array> Per-request group IDs keyed by user ID. */ private array $groupIdsByUserId = []; @@ -62,25 +44,16 @@ class PermissionsService { private array $contextPermissionsByNode = []; public function __construct( - LoggerInterface $logger, - ?string $userId, - TableMapper $tableMapper, - ViewMapper $viewMapper, - ShareMapper $shareMapper, - ContextMapper $contextMapper, - UserHelper $userHelper, - CircleHelper $circleHelper, - bool $isCLI, + protected LoggerInterface $logger, + protected ?string $userId, + private readonly TableMapper $tableMapper, + private readonly ViewMapper $viewMapper, + private readonly ShareMapper $shareMapper, + private readonly ContextMapper $contextMapper, + private readonly UserHelper $userHelper, + private readonly CircleHelper $circleHelper, + protected bool $isCLI, ) { - $this->tableMapper = $tableMapper; - $this->viewMapper = $viewMapper; - $this->shareMapper = $shareMapper; - $this->userHelper = $userHelper; - $this->logger = $logger; - $this->userId = $userId; - $this->isCli = $isCLI; - $this->contextMapper = $contextMapper; - $this->circleHelper = $circleHelper; } /** @@ -97,12 +70,12 @@ public function preCheckUserId(?string $userId = null, bool $canBeEmpty = true): if ($userId === null) { $e = new \Exception(); - $error = 'PreCheck for userId failed, requested in ' . get_class($this) . '.'; + $error = 'PreCheck for userId failed, requested in ' . static::class . '.'; $this->logger->debug($error, ['exception' => new \Exception()]); throw new InternalError($error); } - if ($userId === '' && !$this->isCli && !$canBeEmpty) { + if ($userId === '' && !$this->isCLI && !$canBeEmpty) { $error = 'Try to set no user in context, but request is not allowed.'; $this->logger->warning($error); throw new InternalError($error); @@ -124,7 +97,7 @@ public function canReadTable(Table $table, ?string $userId = null): bool { public function canUpdateTable(Table $table, ?string $userId = null): bool { try { $userId = $this->preCheckUserId($userId); - } catch (InternalError $e) { + } catch (InternalError) { return false; } @@ -184,10 +157,10 @@ public function isNodeOwnerById(int $nodeType, int $nodeId, ?string $userId = nu public function canManageContextById(int $contextId, ?string $userId = null): bool { try { $context = $this->contextMapper->findById($contextId, $userId); - } catch (DoesNotExistException $e) { + } catch (DoesNotExistException) { $this->logger->warning('Context does not exist'); return false; - } catch (MultipleObjectsReturnedException $e) { + } catch (MultipleObjectsReturnedException) { $this->logger->warning('Multiple contexts found for this ID'); return false; } catch (Exception $e) { @@ -210,7 +183,7 @@ public function canAccessContextById(int $contextId, ?string $userId = null): bo try { $this->contextMapper->findById($contextId, $userId ?? $this->userId); return true; - } catch (NotFoundError $e) { + } catch (NotFoundError) { return false; } } @@ -259,10 +232,10 @@ public function canManageContext(Context $context, ?string $userId = null): bool public function canManageTableById(int $tableId, ?string $userId = null): bool { try { $table = $this->tableMapper->find($tableId); - } catch (MultipleObjectsReturnedException $e) { + } catch (MultipleObjectsReturnedException) { $this->logger->warning('Multiple tables were found for this id'); return false; - } catch (DoesNotExistException $e) { + } catch (DoesNotExistException) { $this->logger->warning('No table was found for this id'); return false; } catch (Exception $e) { @@ -275,10 +248,10 @@ public function canManageTableById(int $tableId, ?string $userId = null): bool { public function canManageViewById(int $viewId, ?string $userId = null): bool { try { $view = $this->viewMapper->find($viewId); - } catch (MultipleObjectsReturnedException $e) { + } catch (MultipleObjectsReturnedException) { $this->logger->warning('Multiple tables were found for this id'); return false; - } catch (DoesNotExistException $e) { + } catch (DoesNotExistException) { $this->logger->warning('No table was found for this id'); return false; } catch (InternalError|Exception $e) { @@ -497,41 +470,31 @@ public function getSharedPermissionsIfSharedWithMe(int $elementId, string $eleme // be fetched specifically. $manage = ( - array_reduce($shares, static function (bool $carry, Share $share): bool { - return $carry || ($share->getPermissionManage()); - }, false) + array_reduce($shares, static fn (bool $carry, Share $share): bool => $carry || ($share->getPermissionManage()), false) || ($table && $this->canManageTable($table, $userId)) ); $create = ( $manage - || array_reduce($shares, static function (bool $carry, Share $share): bool { - return $carry || ($share->getPermissionCreate()); - }, false) + || array_reduce($shares, static fn (bool $carry, Share $share): bool => $carry || ($share->getPermissionCreate()), false) || ($table && $this->canCreateRows($table, 'table', $userId)) ); $update = ( $manage - || array_reduce($shares, static function (bool $carry, Share $share): bool { - return $carry || ($share->getPermissionUpdate()); - }, false) + || array_reduce($shares, static fn (bool $carry, Share $share): bool => $carry || ($share->getPermissionUpdate()), false) || ($table && $this->canUpdateTable($table, $userId)) ); $delete = ( $manage - || array_reduce($shares, static function (bool $carry, Share $share): bool { - return $carry || ($share->getPermissionDelete()); - }, false) + || array_reduce($shares, static fn (bool $carry, Share $share): bool => $carry || ($share->getPermissionDelete()), false) || ($table && $this->canDeleteRowsByTableId($table->getId(), $userId)) ); $read = ( $manage || $update || $delete - || array_reduce($shares, static function (bool $carry, Share $share): bool { - return $carry || ($share->getPermissionRead()); - }, false) + || array_reduce($shares, static fn (bool $carry, Share $share): bool => $carry || ($share->getPermissionRead()), false) || ($table && $this->canReadTable($table, $userId)) ); @@ -726,7 +689,7 @@ private function basisCheck(Table|View|Context $element, string $nodeType, ?stri } if ($userId === '') { - return $this->isCli || $this->isPublicContext; + return $this->isCLI || $this->isPublicContext; } if ($this->userIsElementOwner($element, $userId, $nodeType)) { @@ -743,7 +706,7 @@ private function basisCheck(Table|View|Context $element, string $nodeType, ?stri if ($permissions->manage) { return true; } - } catch (NotFoundError $e) { + } catch (NotFoundError) { return false; } return false; diff --git a/lib/Service/RelationService.php b/lib/Service/RelationService.php index 7c53b3b875..5928e13727 100644 --- a/lib/Service/RelationService.php +++ b/lib/Service/RelationService.php @@ -21,11 +21,11 @@ class RelationService { private array $cacheRelationData = []; public function __construct( - private ColumnMapper $columnMapper, - private ViewMapper $viewMapper, - private Row2Mapper $row2Mapper, - private ColumnService $columnService, - private ?string $userId, + private readonly ColumnMapper $columnMapper, + private readonly ViewMapper $viewMapper, + private readonly Row2Mapper $row2Mapper, + private readonly ColumnService $columnService, + private readonly ?string $userId, ) { } @@ -42,9 +42,7 @@ public function getRelationsForTable(int $tableId): array { // Check table permissions through ColumnService $columns = $this->columnService->findAllByTable($tableId); - $relationColumns = array_filter($columns, function ($column) { - return $column->getType() === Column::TYPE_RELATION; - }); + $relationColumns = array_filter($columns, fn ($column) => $column->getType() === Column::TYPE_RELATION); return $this->getRelationsForColumns($relationColumns); } @@ -62,9 +60,7 @@ public function getRelationsForView(int $viewId): array { // Check view permissions through ColumnService $columns = $this->columnService->findAllByView($viewId); - $relationColumns = array_filter($columns, function ($column) { - return $column->getType() === Column::TYPE_RELATION; - }); + $relationColumns = array_filter($columns, fn ($column) => $column->getType() === Column::TYPE_RELATION); return $this->getRelationsForColumns($relationColumns); } @@ -186,7 +182,7 @@ private function getRelationDataForTarget(string $target, Column $column): array $this->userId ); } - } catch (DoesNotExistException $e) { + } catch (DoesNotExistException) { $this->cacheRelationData[$cacheKey] = []; return []; } @@ -194,9 +190,7 @@ private function getRelationDataForTarget(string $target, Column $column): array $result = []; foreach ($rows as $row) { $data = $row->getData(); - $displayFieldData = array_filter($data, function ($item) use ($settings) { - return $item['columnId'] === (int)$settings[Column::RELATION_LABEL_COLUMN]; - }); + $displayFieldData = array_filter($data, fn ($item) => $item['columnId'] === (int)$settings[Column::RELATION_LABEL_COLUMN]); $value = reset($displayFieldData)['value'] ?? null; // Structure compatible with Row2 format: {id: int, label: string} diff --git a/lib/Service/RowService.php b/lib/Service/RowService.php index 2c37ca335a..276f92096d 100644 --- a/lib/Service/RowService.php +++ b/lib/Service/RowService.php @@ -49,14 +49,14 @@ public function __construct( LoggerInterface $logger, ?string $userId, PermissionsService $permissionsService, - private ColumnMapper $columnMapper, - private ViewMapper $viewMapper, - private TableMapper $tableMapper, - private Row2Mapper $row2Mapper, - private IEventDispatcher $eventDispatcher, - private ColumnsHelper $columnsHelper, - private ActivityManager $activityManager, - private IDBConnection $connection, + private readonly ColumnMapper $columnMapper, + private readonly ViewMapper $viewMapper, + private readonly TableMapper $tableMapper, + private readonly Row2Mapper $row2Mapper, + private readonly IEventDispatcher $eventDispatcher, + private readonly ColumnsHelper $columnsHelper, + private readonly ActivityManager $activityManager, + private readonly IDBConnection $connection, ) { parent::__construct($logger, $userId, $permissionsService); @@ -175,10 +175,10 @@ public function find(int $rowId): Row2 { $row = $this->row2Mapper->find($rowId, $columns); } catch (Exception|MultipleObjectsReturnedException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (NotFoundError|DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } return $row; @@ -204,7 +204,7 @@ public function create(?int $tableId, ?int $viewId, RowDataInput|array $data, ?s if ($this->userId === null || ($this->userId === '' && !$this->isPublicContext)) { $e = new \Exception('No user id in context, but needed.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $view = null; @@ -217,7 +217,7 @@ public function create(?int $tableId, ?int $viewId, RowDataInput|array $data, ?s throw new NotFoundError('Given view could not be found. More details can be found in the log.'); } catch (InternalError|Exception|MultipleObjectsReturnedException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security @@ -235,7 +235,7 @@ public function create(?int $tableId, ?int $viewId, RowDataInput|array $data, ?s throw new NotFoundError('Given table could not be found. More details can be found in the log.'); } catch (MultipleObjectsReturnedException|Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security @@ -250,7 +250,7 @@ public function create(?int $tableId, ?int $viewId, RowDataInput|array $data, ?s throw new InternalError('Cannot create row without table or view in context'); } - $tableId = $tableId ?? $view->getTableId(); + $tableId ??= $view->getTableId(); $data = $data instanceof RowDataInput ? $data : RowDataInput::fromArray($data); $data = $this->cleanupAndValidateData($data, $columns, $tableId, $viewId); @@ -273,7 +273,7 @@ public function create(?int $tableId, ?int $viewId, RowDataInput|array $data, ?s return $this->filterRowResult($view, $insertedRow); } catch (InternalError|Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -392,7 +392,7 @@ private function cleanupAndValidateData(RowDataInput $data, array $columns, ?int if (!$column) { $e = new \Exception('No column found, can not parse value.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if (!empty($readOnlyColumns[$entry['columnId']])) { @@ -550,16 +550,16 @@ private function getRowById(int $rowId): Row2 { if ($this->row2Mapper->getTableIdForRow($rowId) === null) { $e = new \Exception('No table id in row, but needed.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $row = $this->row2Mapper->find($rowId, $this->columnMapper->findAllByTable($this->row2Mapper->getTableIdForRow($rowId))); $row->markAsLoaded(); } catch (InternalError|DoesNotExistException|MultipleObjectsReturnedException|Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (NotFoundError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $this->tmpRows[$rowId] = $row; return $row; @@ -593,17 +593,17 @@ public function updateSet( if ($this->userId === null || ($this->userId === '' && !$this->isPublicContext)) { $e = new \Exception('No user id in context, but needed.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } try { $item = $this->getRowById($id); } catch (InternalError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (NotFoundError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if ($viewId) { @@ -611,29 +611,29 @@ public function updateSet( if (!$this->permissionsService->canReadRowsByElementId($viewId, 'view', $userId)) { $e = new \Exception('Row not found.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if (!$this->permissionsService->canUpdateRowsByViewId($viewId, $userId)) { $e = new \Exception('Update row is not allowed.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new PermissionError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new PermissionError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } try { $view = $this->viewMapper->find($viewId); } catch (InternalError|MultipleObjectsReturnedException|Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // is row in view? if (!$this->row2Mapper->isRowInViewPresent($id, $view, $userId)) { $e = new \Exception('Update row is not allowed.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // fetch all needed columns @@ -641,7 +641,7 @@ public function updateSet( $columns = $this->columnMapper->findAll($view->getColumnIds()); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } else { if ($tableId === null) { @@ -650,25 +650,25 @@ public function updateSet( if ($tableId !== $item->getTableId()) { $e = new \Exception('Row does not belong to table with id ' . $tableId); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security if (!$this->permissionsService->canReadRowsByElementId($item->getTableId(), 'table', $userId)) { $e = new \Exception('Row not found.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if (!$this->permissionsService->canUpdateRowsByTableId($tableId, $userId)) { $e = new \Exception('Update row is not allowed.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new PermissionError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new PermissionError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } try { $columns = $this->columnMapper->findAllByTable($tableId); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -722,10 +722,10 @@ public function delete(int $id, ?int $viewId, string $userId, ?int $tableId = nu $item = $this->getRowById($id); } catch (InternalError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (NotFoundError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if ($viewId) { @@ -733,41 +733,41 @@ public function delete(int $id, ?int $viewId, string $userId, ?int $tableId = nu if (!$this->permissionsService->canReadRowsByElementId($viewId, 'view', $userId)) { $e = new \Exception('Row not found.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if (!$this->permissionsService->canDeleteRowsByViewId($viewId)) { $e = new \Exception('Update row is not allowed.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new PermissionError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new PermissionError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } try { $view = $this->viewMapper->find($viewId); } catch (InternalError|DoesNotExistException|MultipleObjectsReturnedException|Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if (!$this->row2Mapper->isRowInViewPresent($id, $view, $userId)) { $e = new \Exception('Update row is not allowed.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } else { if ($tableId !== null && $tableId !== $item->getTableId()) { $e = new \Exception('Row does not belong to table with id ' . $tableId); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security if (!$this->permissionsService->canReadRowsByElementId($item->getTableId(), 'table', $userId)) { $e = new \Exception('Row not found.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if (!$this->permissionsService->canDeleteRowsByTableId($item->getTableId())) { $e = new \Exception('Update row is not allowed.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new PermissionError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new PermissionError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -787,7 +787,7 @@ public function delete(int $id, ?int $viewId, string $userId, ?int $tableId = nu return $this->filterRowResult($view ?? null, $deletedRow); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -870,7 +870,7 @@ public function isRowInViewPresent(int $rowId, int $viewId, string $userId): boo if (!$this->permissionsService->canReadRowsByElementId($viewId, 'view', $userId)) { $e = new \Exception('Row not found.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new PermissionError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new PermissionError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $view = $this->viewMapper->find($viewId); diff --git a/lib/Service/SearchService.php b/lib/Service/SearchService.php index dee78cdc75..7ea106cf40 100644 --- a/lib/Service/SearchService.php +++ b/lib/Service/SearchService.php @@ -14,15 +14,15 @@ class SearchService extends SuperService { - private RowService $rowService; - private TableService $tableService; - private ViewService $viewService; - - public function __construct(PermissionsService $permissionsService, LoggerInterface $logger, ?string $userId, RowService $rowService, TableService $tableService, ViewService $viewService) { + public function __construct( + PermissionsService $permissionsService, + LoggerInterface $logger, + ?string $userId, + private readonly RowService $rowService, + private readonly TableService $tableService, + private readonly ViewService $viewService, + ) { parent::__construct($logger, $userId, $permissionsService); - $this->rowService = $rowService; - $this->tableService = $tableService; - $this->viewService = $viewService; } public function all(string $term = ''): array { diff --git a/lib/Service/ShareService.php b/lib/Service/ShareService.php index 72f8a09524..ac2c7f8594 100644 --- a/lib/Service/ShareService.php +++ b/lib/Service/ShareService.php @@ -180,7 +180,7 @@ public function createLinkShare(Table|View $node, ?string $password = null): Sha $password, $this->generateShareToken(), )); - } catch (InternalError $e) { + } catch (InternalError) { } } throw $e; @@ -331,7 +331,7 @@ private function buildBaseShare( if (!$this->userId) { $e = new \Exception('No user given.'); $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } if ($receiverType === ShareReceiverType::GROUP && !$this->shareManager->allowGroupSharing()) { throw new PermissionError('Group sharing is disabled by your administrator.'); @@ -555,7 +555,7 @@ private function applyPermissions(Share $item, array $permissions): Share { return $this->mapper->update($item); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -572,10 +572,10 @@ public function updatePermission(int $id, array $permissions): Share { $item = $this->mapper->find($id); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (MultipleObjectsReturnedException|Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $this->assertSharePermissionUpdateAllowedWhenSharingRestricted($item, $permissions); @@ -598,7 +598,7 @@ public function updateDisplayMode(int $shareId, int $displayMode, string $userId if ($item->getNodeType() !== 'context') { // Contexts-only property - throw new InvalidArgumentException(get_class($this) . ' - ' . __FUNCTION__ . ': nav bar display mode can be set for shared contexts only'); + throw new InvalidArgumentException(static::class . ' - ' . __FUNCTION__ . ': nav bar display mode can be set for shared contexts only'); } if ($userId === '') { @@ -616,10 +616,10 @@ public function updateDisplayMode(int $shareId, int $displayMode, string $userId return $this->contextNavigationMapper->setDisplayModeByShareId($shareId, $displayMode, $userId); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (Exception|MultipleObjectsReturnedException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -635,10 +635,10 @@ public function delete(int $id): Share { $item = $this->mapper->find($id); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (MultipleObjectsReturnedException|Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security @@ -653,7 +653,7 @@ public function delete(int $id): Share { } } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } return $this->addReceiverDisplayName($item); } @@ -714,7 +714,7 @@ public function deleteAllForView(View $view):void { public function deleteAllForContext(Context $context): void { try { - $this->atomic(function () use ($context) { + $this->atomic(function () use ($context): void { $shares = $this->mapper->findAllSharesForNode('context', $context->getId(), $this->userId); foreach ($shares as $share) { $this->contextNavigationMapper->deleteByShareId($share->getId()); diff --git a/lib/Service/SuperService.php b/lib/Service/SuperService.php index 13ed13f249..c1b0dc29ff 100644 --- a/lib/Service/SuperService.php +++ b/lib/Service/SuperService.php @@ -10,18 +10,13 @@ use Psr\Log\LoggerInterface; class SuperService { - protected PermissionsService $permissionsService; - - protected LoggerInterface $logger; - - protected ?string $userId; - protected bool $isPublicContext = false; - public function __construct(LoggerInterface $logger, ?string $userId, PermissionsService $permissionsService) { - $this->permissionsService = $permissionsService; - $this->logger = $logger; - $this->userId = $userId; + public function __construct( + protected LoggerInterface $logger, + protected ?string $userId, + protected PermissionsService $permissionsService, + ) { } public function setPublicContext(): void { diff --git a/lib/Service/Support/DefaultAuditLogService.php b/lib/Service/Support/DefaultAuditLogService.php index b069c667bc..2d27230009 100644 --- a/lib/Service/Support/DefaultAuditLogService.php +++ b/lib/Service/Support/DefaultAuditLogService.php @@ -13,7 +13,7 @@ final class DefaultAuditLogService implements AuditLogServiceInterface { public function __construct( - private IEventDispatcher $eventDispatcher, + private readonly IEventDispatcher $eventDispatcher, ) { } diff --git a/lib/Service/TableService.php b/lib/Service/TableService.php index c06f89ccfd..9965494187 100644 --- a/lib/Service/TableService.php +++ b/lib/Service/TableService.php @@ -103,7 +103,7 @@ public function findAll(?string $userId = null, bool $skipTableEnhancement = fal $allTables[$tutorialTable->getId()] = $tutorialTable; } catch (InternalError|PermissionError|DoesNotExistException|MultipleObjectsReturnedException|OcpDbException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -178,21 +178,21 @@ private function enhanceTable(Table $table, string $userId): void { try { $shares = $this->shareService->findAll('table', $table->getId()); $table->setHasShares(count($shares) !== 0); - } catch (InternalError $e) { + } catch (InternalError) { } } // add the rows count try { $table->setRowsCount($this->rowService->getRowsCount($table->getId())); - } catch (PermissionError $e) { + } catch (PermissionError) { $table->setRowsCount(0); } // add the column count try { $table->setColumnsCount($this->columnService->getColumnsCount($table->getId())); - } catch (PermissionError $e) { + } catch (PermissionError) { $table->setColumnsCount(0); } @@ -216,11 +216,11 @@ private function setIsSharedState(Table $table, string $userId): void { $permissions = $this->shareService->getSharedPermissionsIfSharedWithMe($table->getId(), 'table', $userId); $table->setIsShared(true); $table->setOnSharePermissions($permissions); - } catch (NotFoundError $e) { + } catch (NotFoundError) { try { $table->setOnSharePermissions($this->permissionsService->getPermissionArrayForNodeFromContexts($table->getId(), 'table', $userId)); $table->setIsShared(true); - } catch (NotFoundError $e) { + } catch (NotFoundError) { } } } else { @@ -301,7 +301,7 @@ public function create(string $title, string $template, ?string $emoji, ?string $table = $this->tableTemplateService->makeTemplate($newTable, $template); } catch (InternalError|PermissionError|DoesNotExistException|MultipleObjectsReturnedException|OcpDbException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } else { $table = $this->addOwnerDisplayName($newTable); @@ -311,7 +311,7 @@ public function create(string $title, string $template, ?string $emoji, ?string $this->enhanceTable($table, $userId); } catch (InternalError|PermissionError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $this->activityManager->triggerEvent( objectType: ActivityManager::TABLES_OBJECT_TABLE, @@ -343,10 +343,10 @@ public function setOwner(int $id, string $newOwnerUserId, ?string $userId = null $table = $this->mapper->find($id); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (MultipleObjectsReturnedException|OcpDbException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security @@ -393,10 +393,10 @@ public function delete(int $id, ?string $userId = null): Table { $item = $this->mapper->find($id); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (MultipleObjectsReturnedException|OcpDbException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security @@ -409,7 +409,7 @@ public function delete(int $id, ?string $userId = null): Table { $this->rowService->deleteAllByTable($id, $userId); } catch (PermissionError|OcpDbException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // delete all views for that table @@ -419,7 +419,7 @@ public function delete(int $id, ?string $userId = null): Table { $this->viewService->deleteAllByTable($item, $userId); } catch (InternalError|PermissionError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // delete all columns for that table @@ -427,14 +427,14 @@ public function delete(int $id, ?string $userId = null): Table { $columns = $this->columnService->findAllByTable($id, $userId, $item); } catch (InternalError|PermissionError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } foreach ($columns as $column) { try { $this->columnService->delete($column->id, true, $userId); } catch (InternalError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -449,7 +449,7 @@ public function delete(int $id, ?string $userId = null): Table { $this->mapper->delete($item); } catch (OcpDbException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $event = new TableDeletedEvent(table: $item); @@ -485,10 +485,10 @@ public function update(int $id, ?string $title, ?string $emoji, ?string $descrip $table = $this->mapper->find($id); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (MultipleObjectsReturnedException|OcpDbException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security @@ -523,13 +523,13 @@ public function update(int $id, ?string $title, ?string $emoji, ?string $descrip $table = $this->mapper->update($table); } catch (OcpDbException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } try { $this->enhanceTable($table, $userId); } catch (InternalError|PermissionError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } $changes->setAfter($table); $this->activityManager->triggerUpdateEvents( @@ -556,7 +556,7 @@ public function search(string $term, int $limit = 100, int $offset = 0, ?string $this->enhanceTable($table, $userId); } return $tables; - } catch (InternalError|PermissionError|OcpDbException $e) { + } catch (InternalError|PermissionError|OcpDbException) { return []; } } diff --git a/lib/Service/TableTemplateService.php b/lib/Service/TableTemplateService.php index 8bab583984..3da17e6ecd 100644 --- a/lib/Service/TableTemplateService.php +++ b/lib/Service/TableTemplateService.php @@ -30,11 +30,11 @@ class TableTemplateService { public function __construct( protected LoggerInterface $logger, - private IL10N $l, - private ColumnService $columnService, - private ?string $userId, - private RowService $rowService, - private ViewService $viewService, + private readonly IL10N $l, + private readonly ColumnService $columnService, + private readonly ?string $userId, + private readonly RowService $rowService, + private readonly ViewService $viewService, protected Defaults $themingDefaults, ) { } @@ -493,13 +493,9 @@ private function makeVacationRequests(Table $table):void { * @return list */ private function columnsToInputArray(array $columns): array { - $columns = array_filter($columns, static function ($item) { - return $item instanceof Column; - }); + $columns = array_filter($columns, static fn ($item) => $item instanceof Column); return array_map( - static function (Column $column, int $index): array { - return ['columnId' => $column->getId(), 'order' => $index]; - }, + static fn (Column $column, int $index): array => ['columnId' => $column->getId(), 'order' => $index], array_values($columns), array_keys(array_values($columns)) ); } @@ -813,7 +809,7 @@ private function createRow(Table $table, array $values): void { $this->logger->warning('Exception occurred while creating a row: ' . $e->getMessage()); } catch (NotFoundError $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } diff --git a/lib/Service/ValueObject/ColumnOrderInformation.php b/lib/Service/ValueObject/ColumnOrderInformation.php index e7d0a12945..f0b4b4192b 100644 --- a/lib/Service/ValueObject/ColumnOrderInformation.php +++ b/lib/Service/ValueObject/ColumnOrderInformation.php @@ -84,7 +84,7 @@ public function jsonSerialize(): array { ]; } - protected function ensureType(string $offset, mixed $value): int|bool { + protected function ensureType(string $offset, bool|int $value): int|bool { return match ($offset) { self::KEY_ID, self::KEY_ORDER => (int)$value, diff --git a/lib/Service/ValueObject/ShareCreate.php b/lib/Service/ValueObject/ShareCreate.php index 77f870d829..4619df1acd 100644 --- a/lib/Service/ValueObject/ShareCreate.php +++ b/lib/Service/ValueObject/ShareCreate.php @@ -11,18 +11,18 @@ class ShareCreate { public function __construct( - private int $nodeId, - private string $nodeType, - private string $receiver, - private string $receiverType, - private bool $permissionRead, - private bool $permissionCreate, - private bool $permissionUpdate, - private bool $permissionDelete, - private bool $permissionManage, - private int $displayMode, - private ?string $password = null, - private ?ShareToken $shareToken = null, + private readonly int $nodeId, + private readonly string $nodeType, + private readonly string $receiver, + private readonly string $receiverType, + private readonly bool $permissionRead, + private readonly bool $permissionCreate, + private readonly bool $permissionUpdate, + private readonly bool $permissionDelete, + private readonly bool $permissionManage, + private readonly int $displayMode, + private readonly ?string $password = null, + private readonly ?ShareToken $shareToken = null, ) { } diff --git a/lib/Service/ValueObject/ShareToken.php b/lib/Service/ValueObject/ShareToken.php index 0ad1b31e58..29d848414d 100644 --- a/lib/Service/ValueObject/ShareToken.php +++ b/lib/Service/ValueObject/ShareToken.php @@ -34,7 +34,7 @@ public function __construct( } } - public function __toString() { + public function __toString(): string { return $this->token; } } diff --git a/lib/Service/ViewService.php b/lib/Service/ViewService.php index 8c5ad15890..68fd3dec83 100644 --- a/lib/Service/ViewService.php +++ b/lib/Service/ViewService.php @@ -41,43 +41,20 @@ * @psalm-import-type TablesView from ResponseDefinitions */ class ViewService extends SuperService { - private ViewMapper $mapper; - - private ShareService $shareService; - - private RowService $rowService; - - protected UserHelper $userHelper; - - protected FavoritesService $favoritesService; - - protected IL10N $l; - private ContextService $contextService; - - protected IEventDispatcher $eventDispatcher; - public function __construct( PermissionsService $permissionsService, LoggerInterface $logger, ?string $userId, - ViewMapper $mapper, - ShareService $shareService, - RowService $rowService, - UserHelper $userHelper, - FavoritesService $favoritesService, - IEventDispatcher $eventDispatcher, - ContextService $contextService, - IL10N $l, + private readonly ViewMapper $mapper, + private readonly ShareService $shareService, + private readonly RowService $rowService, + protected UserHelper $userHelper, + protected FavoritesService $favoritesService, + protected IEventDispatcher $eventDispatcher, + private readonly ContextService $contextService, + protected IL10N $l, ) { parent::__construct($logger, $userId, $permissionsService); - $this->l = $l; - $this->mapper = $mapper; - $this->shareService = $shareService; - $this->rowService = $rowService; - $this->userHelper = $userHelper; - $this->favoritesService = $favoritesService; - $this->eventDispatcher = $eventDispatcher; - $this->contextService = $contextService; } /** @@ -135,10 +112,10 @@ public function find(int $id, bool $skipEnhancement = false, ?string $userId = n $view = $this->mapper->find($id); } catch (InternalError|\OCP\DB\Exception|MultipleObjectsReturnedException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security @@ -255,7 +232,7 @@ public function update(int $id, ViewUpdateInput $data, ?string $userId = null, b $insertableValue = json_encode($value); } - $setterMethod = 'set' . ucfirst($parameter->value); + $setterMethod = 'set' . ucfirst((string)$parameter->value); $view->$setterMethod($insertableValue ?? $value); } @@ -308,10 +285,10 @@ public function delete(int $id, ?string $userId = null): View { $view = $this->mapper->find($id); } catch (InternalError|MultipleObjectsReturnedException|\OCP\DB\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } catch (DoesNotExistException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new NotFoundError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new NotFoundError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } // security @@ -333,7 +310,7 @@ public function delete(int $id, ?string $userId = null): View { return $deletedView; } catch (\OCP\DB\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); + throw new InternalError(static::class . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } } @@ -388,7 +365,7 @@ private function enhanceView(View $view, string $userId): void { // add the rows count try { $view->setRowsCount($this->rowService->getViewRowsCount($view, $userId)); - } catch (InternalError|PermissionError $e) { + } catch (InternalError|PermissionError) { } // Remove detailed view filtering and sorting information if necessary @@ -454,7 +431,7 @@ private function setIsSharedState(View $view, string $userId): void { manage: $permissions->manage, manageTable: $canManageTable, )); - } catch (NotFoundError $e) { + } catch (NotFoundError) { } catch (\Exception $e) { $this->logger->warning('Exception occurred while setting shared permissions: ' . $e->getMessage() . ' No permissions granted.'); $view->setOnSharePermissions(new Permissions()); @@ -465,7 +442,7 @@ private function setIsSharedState(View $view, string $userId): void { try { $allShares = $this->shareService->findAll('view', $view->getId()); $view->setHasShares(count($allShares) !== 0); - } catch (InternalError $e) { + } catch (InternalError) { } } } else { @@ -506,18 +483,14 @@ public function deleteColumnDataFromViews(int $columnId, Table $table): void { throw new InternalError($e->getMessage()); } foreach ($views as $view) { - $filteredSortingRules = array_filter($view->getSortArray(), static function (array $sort) use ($columnId) { - return $sort['columnId'] !== $columnId; - }); + $filteredSortingRules = array_filter($view->getSortArray(), static fn (array $sort) => $sort['columnId'] !== $columnId); $filteredSortingRules = array_values($filteredSortingRules); $applicableFilterArray = $this->removeColumnFromFilters($view->getFilterArray(), $columnId); $applicableViewColumnInformationRecords = array_filter( $view->getColumnsSettingsArray(), - static function (ViewColumnInformation $viewColumnInformation) use ($columnId): bool { - return $viewColumnInformation->getId() !== $columnId; - } + static fn (ViewColumnInformation $viewColumnInformation): bool => $viewColumnInformation->getId() !== $columnId ); $viewUpdateInput = new ViewUpdateInput( @@ -564,7 +537,7 @@ public function search(string $term, int $limit = 100, int $offset = 0, ?string $this->enhanceView($view, $userId); } return $views; - } catch (InternalError|\OCP\DB\Exception $e) { + } catch (InternalError|\OCP\DB\Exception) { return []; } } diff --git a/psalm.xml b/psalm.xml index c5e79501f8..ed19174be3 100644 --- a/psalm.xml +++ b/psalm.xml @@ -4,13 +4,13 @@ - SPDX-License-Identifier: AGPL-3.0-or-later --> diff --git a/rector.php b/rector.php new file mode 100644 index 0000000000..e2e4cb9e36 --- /dev/null +++ b/rector.php @@ -0,0 +1,27 @@ +withPaths([ + __DIR__ . '/appinfo', + __DIR__ . '/lib', + __DIR__ . '/tests', + ]) + ->withSkip([ + __DIR__ . '/lib/Vendor', + __DIR__ . '/tests/integration/vendor', + ]) + ->withPhpSets(php81: true) + ->withTypeCoverageLevel(0) + ->withSets([ + NextcloudSets::NEXTCLOUD_33, + ]); diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php index 3bd2bc8c90..0c40f4a508 100644 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ b/tests/integration/features/bootstrap/FeatureContext.php @@ -68,7 +68,7 @@ class FeatureContext implements Context { private $importColumnData = null; // use CommandLineTrait; - private CollectionManager $collectionManager; + private readonly CollectionManager $collectionManager; /** @var array|null Decoded relations response data, stored to allow multiple assertion steps */ private ?array $relationsData = null; @@ -125,7 +125,7 @@ public function createTableV2(string $user, string $title, string $tableName, ?s $newTable = $this->getDataFromResponse($this->response)['ocs']['data']; $this->tableIds[$tableName] = $newTable['id']; - $this->collectionManager->register($newTable, 'table', $newTable['id'], $tableName, function () use ($user, $tableName) { + $this->collectionManager->register($newTable, 'table', $newTable['id'], $tableName, function () use ($user, $tableName): void { $this->deleteTableV2($user, $tableName); }); @@ -515,9 +515,7 @@ public function createCsvFile(string $user, string $file, TableNode $table): voi private function tableNodeToCsv(TableNode $node) { $resource = fopen('php://temp', 'rb+'); foreach ($node->getRows() as $row) { - $fields = array_map(function ($cell) { - return str_replace('{rowId}', $this->rowId, $cell); - }, $row); + $fields = array_map(fn ($cell) => str_replace('{rowId}', $this->rowId, $cell), $row); fputcsv($resource, $fields); } @@ -696,7 +694,7 @@ public function createView(string $user, string $title, string $tableName, strin $newItem = $this->getDataFromResponse($this->response); $this->viewIds[$viewName] = $newItem['id']; - $this->collectionManager->register($newItem, 'view', $newItem['id'], $viewName, function () use ($user, $viewName) { + $this->collectionManager->register($newItem, 'view', $newItem['id'], $viewName, function () use ($user, $viewName): void { $this->deleteViewWithoutAssertion($user, $viewName); unset($this->viewIds[$viewName]); }); @@ -739,7 +737,7 @@ public function createTable(string $user, string $title, string $tableName, ?str $newTable = $this->getDataFromResponse($this->response); $this->tableId = $newTable['id']; $this->tableIds[$tableName] = $newTable['id']; - $this->collectionManager->register($newTable, 'table', $newTable['id'], $tableName, function () use ($user, $tableName) { + $this->collectionManager->register($newTable, 'table', $newTable['id'], $tableName, function () use ($user, $tableName): void { $this->deleteViewWithoutAssertion($user, $tableName); unset($this->tableIds[$tableName]); }); @@ -1339,7 +1337,7 @@ public function createColumn(string $title, ?TableNode $properties = null): void $props = ['title' => $title]; foreach ($properties->getRows() as [$key, $value]) { if ($key === 'customSettings') { - $value = json_decode($value, true); + $value = json_decode((string)$value, true); } $props[$key] = $value; } @@ -1371,7 +1369,7 @@ public function createColumn(string $title, ?TableNode $properties = null): void } $value = match (true) { - $key === 'customSettings' => json_decode($value, true), + $key === 'customSettings' => json_decode((string)$value, true), $value === 'true' => true, $value === 'false' => false, $value === 'null' => null, @@ -2018,7 +2016,7 @@ public function assertResponseErrorMatchesWith(string $error): void { * @return string */ private function extractRequestTokenFromResponse(ResponseInterface $response): string { - return substr(preg_replace('/(.*)data-requesttoken="(.*)">(.*)/sm', '\2', $response->getBody()->getContents()), 0, 89); + return substr((string)preg_replace('/(.*)data-requesttoken="(.*)">(.*)/sm', '\2', $response->getBody()->getContents()), 0, 89); } /** @@ -2059,7 +2057,7 @@ public function sendRequestFullUrl($verb, $fullUrl, $body = null, array $headers $options = array_merge($options, ['cookies' => $this->getUserCookieJar($this->currentUser)]); if ($this->currentUser === 'admin') { $options['auth'] = ['admin', 'admin']; - } elseif (strpos($this->currentUser, 'guest') !== 0) { + } elseif (!str_starts_with($this->currentUser, 'guest')) { $options['auth'] = [$this->currentUser, self::TEST_PASSWORD]; } if ($body instanceof TableNode) { @@ -2078,9 +2076,7 @@ public function sendRequestFullUrl($verb, $fullUrl, $body = null, array $headers try { $this->response = $client->{$verb}($fullUrl, $options); - } catch (ClientException $ex) { - $this->response = $ex->getResponse(); - } catch (\GuzzleHttp\Exception\ServerException $ex) { + } catch (ClientException|\GuzzleHttp\Exception\ServerException $ex) { $this->response = $ex->getResponse(); } } @@ -2201,7 +2197,7 @@ public function attemptCreateContext(string $user, string $alias, string $name, $exceptionCaught = false; try { $this->createContext($user, $alias, $name, $icon, $description, $table); - } catch (ExpectationFailedException $e) { + } catch (ExpectationFailedException) { $exceptionCaught = true; } @@ -2241,7 +2237,7 @@ public function createContext(string $user, string $alias, string $name, string $newContext = $this->getDataFromResponse($this->response)['ocs']['data']; - $this->collectionManager->register($newContext, 'context', $newContext['id'], $alias, function () use ($newContext) { + $this->collectionManager->register($newContext, 'context', $newContext['id'], $alias, function () use ($newContext): void { $this->deleteContextWithFetchCheck($newContext['id'], $newContext['owner']); }); @@ -2296,7 +2292,7 @@ public function theFetchedContextHasFollowingData(string $contextAlias, TableNod Assert::assertEquals($value, $actualData['iconName']); break; case 'node': - [$strType, $alias, $strPermission] = explode(':', $value); + [$strType, $alias, $strPermission] = explode(':', (string)$value); $nodeType = $strType === 'table' ? 0 : 1; $nodeId = $nodeType === 0 ? $this->tableIds[$alias] : $this->viewIds[$alias]; $permissions = $this->humanReadablePermissionToInt($strPermission); @@ -2309,7 +2305,7 @@ public function theFetchedContextHasFollowingData(string $contextAlias, TableNod Assert::assertTrue($found); break; case 'page': - [$pageType, $contentNodesCount] = explode(':', $value); + [$pageType, $contentNodesCount] = explode(':', (string)$value); $found = false; foreach ($actualData['pages'] as $actualPageData) { $found = $found || ($actualPageData['type'] === $pageType @@ -2336,7 +2332,7 @@ public function theFetchedContextDoesNotContainFollowingData(string $contextAlia Assert::assertNotEquals($value, $actualData['iconName']); break; case 'node': - [$strType, $alias, $strPermission] = explode(':', $value); + [$strType, $alias, $strPermission] = explode(':', (string)$value); $nodeType = $strType === 'table' ? 0 : 1; $nodeId = $nodeType === 0 ? $this->tableIds[$alias] : $this->viewIds[$alias]; $permissions = $this->humanReadablePermissionToInt($strPermission); @@ -2349,7 +2345,7 @@ public function theFetchedContextDoesNotContainFollowingData(string $contextAlia Assert::assertFalse($found); break; case 'page': - [$pageType, $contentNodesCount] = explode(':', $value); + [$pageType, $contentNodesCount] = explode(':', (string)$value); $found = false; foreach ($actualData['pages'] as $actualPageData) { $found = $found || ($actualPageData['type'] === $pageType @@ -2368,7 +2364,7 @@ public function userAttemptsToFetchContext(string $user, string $contextAlias): $caughtException = false; try { $this->userFetchesContext($user, $contextAlias); - } catch (ExpectationFailedException $e) { + } catch (ExpectationFailedException) { $caughtException = true; } @@ -2418,9 +2414,7 @@ public function theyWillFindContextsAndNoOther(string $contextAliasList): void { $receivedContexts = $this->getDataFromResponse($this->response)['ocs']['data']; $aliases = $contextAliasList === '' ? [] : explode(',', $contextAliasList); - $expectedContextIds = array_map(function (string $alias) { - return $this->collectionManager->getByAlias('context', trim($alias))['id']; - }, $aliases); + $expectedContextIds = array_map(fn (string $alias) => $this->collectionManager->getByAlias('context', trim($alias))['id'], $aliases); sort($expectedContextIds); $actualContextIds = []; @@ -2691,7 +2685,7 @@ public function userAttemptsToDeleteContext(string $user, string $contextAlias): $exceptionCaught = false; try { $this->deleteContext($context['id'], $user); - } catch (ExpectationFailedException $e) { + } catch (ExpectationFailedException) { $exceptionCaught = true; } @@ -2752,7 +2746,7 @@ public function userTransfersTheTheContextTo(string $user, string $contextAlias, ); if ($this->response->getStatusCode() === 200) { $context['owner'] = $recipientUser; - $this->collectionManager->update($context, 'context', $context['id'], function () use ($context, $recipientUser) { + $this->collectionManager->update($context, 'context', $context['id'], function () use ($context, $recipientUser): void { $this->deleteContextWithFetchCheck($context['id'], $recipientUser); }); } diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml index 47f0999d1a..a1e98c08da 100644 --- a/tests/psalm-baseline.xml +++ b/tests/psalm-baseline.xml @@ -1,9 +1,5 @@ - - + diff --git a/tests/unit/Database/DatabaseTestCase.php b/tests/unit/Database/DatabaseTestCase.php index a4412307a3..8041520c93 100644 --- a/tests/unit/Database/DatabaseTestCase.php +++ b/tests/unit/Database/DatabaseTestCase.php @@ -95,15 +95,13 @@ protected function cleanupTablesData(): void { $table = substr($table, strpos($table, '.') + 1); return str_replace($this->connection->getPrefix(), '', $table); }, $tables); - $tablesToClean = array_filter($tablesToClean, function ($table) { - return strpos($table, 'tables_') === 0; - }); + $tablesToClean = array_filter($tablesToClean, fn ($table) => str_starts_with((string)$table, 'tables_')); // Sort tables by deletion priority due to foreign key constraints usort($tablesToClean, function ($tableA, $tableB) { $getPriority = function ($table) { // 1. row_cells tables (depend on row_sleeves and columns) - highest priority - if (strpos($table, 'tables_row_cells_') === 0) { + if (str_starts_with($table, 'tables_row_cells_')) { return 1; } // 2. row_sleeves (depend on tables) diff --git a/tests/unit/Db/EntityVirtualPropertiesTest.php b/tests/unit/Db/EntityVirtualPropertiesTest.php index db5305b8d1..58cbd40cc5 100644 --- a/tests/unit/Db/EntityVirtualPropertiesTest.php +++ b/tests/unit/Db/EntityVirtualPropertiesTest.php @@ -112,7 +112,7 @@ private function isEntityClass(string $className): bool { } $parentClass = $parentClass->getParentClass(); } - } catch (\ReflectionException $e) { + } catch (\ReflectionException) { // Class doesn't exist or can't be loaded return false; } @@ -228,7 +228,6 @@ private function getTableNameFromClass(string $className): ?string { if ($reflection->hasProperty('table')) { $tableProperty = $reflection->getProperty('table'); if (PHP_VERSION_ID < 80200) { - $tableProperty->setAccessible(true); } // Create instance to get table name @@ -247,7 +246,6 @@ private function getTableNameFromClass(string $className): ?string { if ($mapperReflection->hasProperty('table')) { $tableProperty = $mapperReflection->getProperty('table'); if (PHP_VERSION_ID < 80200) { - $tableProperty->setAccessible(true); } // Create mapper instance to get table name @@ -299,7 +297,7 @@ private function getVirtualProperties(ReflectionClass $reflection): array { } $parentClass = $parentClass->getParentClass(); } - } catch (\Exception $e) { + } catch (\Exception) { // If we can't get VIRTUAL_PROPERTIES, return empty array } diff --git a/tests/unit/Service/ShareServiceTest.php b/tests/unit/Service/ShareServiceTest.php index 2e1e46a905..278713ecee 100644 --- a/tests/unit/Service/ShareServiceTest.php +++ b/tests/unit/Service/ShareServiceTest.php @@ -83,9 +83,7 @@ protected function setUp(): void { } public function testCreateContextShareSetsAllPermissionsFalse(): void { - $this->mapper->method('insert')->willReturnCallback(function (Share $share) { - return $share; - }); + $this->mapper->method('insert')->willReturnCallback(fn (Share $share) => $share); $share = $this->shareService->create( new ShareCreate( diff --git a/tests/unit/Service/Support/DefaultAuditLogServiceTest.php b/tests/unit/Service/Support/DefaultAuditLogServiceTest.php index 7e6275c6e7..669890f7b9 100644 --- a/tests/unit/Service/Support/DefaultAuditLogServiceTest.php +++ b/tests/unit/Service/Support/DefaultAuditLogServiceTest.php @@ -30,9 +30,7 @@ public function testLog(): void { $this->eventDispatcher ->expects($this->once()) ->method('dispatchTyped') - ->with($this->callback(function (CriticalActionPerformedEvent $event) use ($message, $context) { - return $event->getLogMessage() === $message && $event->getParameters() === $context; - })); + ->with($this->callback(fn (CriticalActionPerformedEvent $event) => $event->getLogMessage() === $message && $event->getParameters() === $context)); $this->service->log($message, $context); } diff --git a/tests/unit/TablesMigratorTest.php b/tests/unit/TablesMigratorTest.php index 856d91adc3..8dd0eb54f3 100644 --- a/tests/unit/TablesMigratorTest.php +++ b/tests/unit/TablesMigratorTest.php @@ -254,12 +254,10 @@ public function testImportAppliesColumnOrderAndSortWithColumnIdRemapping(): void 'sort' => [['columnId' => 10, 'mode' => 'ASC']], ]; - $importSource->method('getFileContents')->willReturnCallback(static function (string $file) use ($tableData): string { - return match ($file) { - 'tables.json' => json_encode([$tableData]), - 'columns.json' => json_encode([['id' => 10, 'tableId' => 1]]), - default => json_encode([]), - }; + $importSource->method('getFileContents')->willReturnCallback(static fn (string $file): string => match ($file) { + 'tables.json' => json_encode([$tableData]), + 'columns.json' => json_encode([['id' => 10, 'tableId' => 1]]), + default => json_encode([]), }); $newTable = new Table(); diff --git a/vendor-bin/rector/composer.json b/vendor-bin/rector/composer.json new file mode 100644 index 0000000000..7986cadbe6 --- /dev/null +++ b/vendor-bin/rector/composer.json @@ -0,0 +1,11 @@ +{ + "require-dev": { + "rector/rector": "^2.0", + "nextcloud/rector": "^0.5.2" + }, + "autoload": { + "classmap": [ + "vendor/nextcloud/ocp/OCP/" + ] + } +} diff --git a/vendor-bin/rector/composer.lock b/vendor-bin/rector/composer.lock new file mode 100644 index 0000000000..2fcb78724c --- /dev/null +++ b/vendor-bin/rector/composer.lock @@ -0,0 +1,621 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "faa1d517d94063e2d9198e288793e3c0", + "packages": [], + "packages-dev": [ + { + "name": "nextcloud/ocp", + "version": "v34.0.1", + "source": { + "type": "git", + "url": "https://github.com/nextcloud-deps/ocp.git", + "reference": "3f920a7f46bae0c55643579ce25b6644a09065ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/3f920a7f46bae0c55643579ce25b6644a09065ff", + "reference": "3f920a7f46bae0c55643579ce25b6644a09065ff", + "shasum": "" + }, + "require": { + "php": "~8.2 || ~8.3 || ~8.4 || ~8.5", + "psr/clock": "^1.0", + "psr/container": "^2.0.2", + "psr/event-dispatcher": "^1.0", + "psr/http-client": "^1.0.3", + "psr/log": "^3.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-stable34": "34.0.0-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Christoph Wurst", + "email": "christoph@winzerhof-wurst.at" + }, + { + "name": "Joas Schilling", + "email": "coding@schilljs.com" + } + ], + "description": "Composer package containing Nextcloud's public OCP API and the unstable NCU API", + "support": { + "issues": "https://github.com/nextcloud-deps/ocp/issues", + "source": "https://github.com/nextcloud-deps/ocp/tree/v34.0.1" + }, + "time": "2026-06-18T02:35:58+00:00" + }, + { + "name": "nextcloud/rector", + "version": "v0.5.2", + "source": { + "type": "git", + "url": "https://github.com/nextcloud-libraries/rector.git", + "reference": "9967d62256cd7507f1104491fb2c427456481b56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud-libraries/rector/zipball/9967d62256cd7507f1104491fb2c427456481b56", + "reference": "9967d62256cd7507f1104491fb2c427456481b56", + "shasum": "" + }, + "require": { + "nextcloud/ocp": ">=27", + "php": "^8.1", + "rector/rector": "^2.0.4", + "webmozart/assert": "^1.11" + }, + "require-dev": { + "phpunit/phpunit": "^10.5", + "ramsey/devtools": "^2.0" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/devtools": { + "memory-limit": "-1", + "command-prefix": "dev" + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "OCP\\": "vendor/nextcloud/ocp/OCP", + "Nextcloud\\Rector\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Christoph Wurst", + "email": "christoph@winzerhof-wurst.at", + "homepage": "https://wuc.me" + } + ], + "description": "Rector upgrade rules for Nextcloud", + "keywords": [ + "nextcloud", + "refactoring" + ], + "support": { + "issues": "https://github.com/nextcloud-libraries/rector/issues", + "source": "https://github.com/nextcloud-libraries/rector/tree/v0.5.2" + }, + "time": "2026-06-15T06:39:12+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.2.2", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e5cc34d491a90e79c216d824f60fe21fd4d93bd6", + "reference": "e5cc34d491a90e79c216d824f60fe21fd4d93bd6", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ondřej Mirtes" + }, + { + "name": "Markus Staab" + }, + { + "name": "Vincent Langlet" + } + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2026-06-05T09:00:01+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "rector/rector", + "version": "2.5.2", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "49ff6339174bdbdf50b0b35ecbcff14a05ac9e24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/49ff6339174bdbdf50b0b35ecbcff14a05ac9e24", + "reference": "49ff6339174bdbdf50b0b35ecbcff14a05ac9e24", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "phpstan/phpstan": "^2.2.2" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "suggest": { + "ext-dom": "To manipulate phpunit.xml via the custom-rule command" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "homepage": "https://getrector.com/", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/2.5.2" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2026-06-22T11:39:33+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", + "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-filter": "*", + "php": "^7.2 || ^8.0" + }, + "suggest": { + "ext-intl": "", + "ext-simplexml": "", + "ext-spl": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.12.1" + }, + "time": "2025-10-29T15:56:20+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.9.0" +}