diff --git a/app/AppKernel.php b/app/AppKernel.php index e60dc2039..0b0cf7455 100644 --- a/app/AppKernel.php +++ b/app/AppKernel.php @@ -1,8 +1,39 @@ getEnvironment(), ['dev', 'test'], true)) { - $bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle(); - $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); - $bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(); + $bundles[] = new DebugBundle(); + $bundles[] = new WebProfilerBundle(); + $bundles[] = new DoctrineFixturesBundle(); if ('test' === $this->getEnvironment()) { - $bundles[] = new DAMA\DoctrineTestBundle\DAMADoctrineTestBundle(); + $bundles[] = new DAMADoctrineTestBundle(); } if ('dev' === $this->getEnvironment()) { - $bundles[] = new Symfony\Bundle\MakerBundle\MakerBundle(); - $bundles[] = new Symfony\Bundle\WebServerBundle\WebServerBundle(); + $bundles[] = new MakerBundle(); + $bundles[] = new WebServerBundle(); } } @@ -69,13 +100,13 @@ class AppKernel extends Kernel { $loader->load($this->getProjectDir() . '/app/config/config_' . $this->getEnvironment() . '.yml'); - $loader->load(function (ContainerBuilder $container) { + $loader->load(function (ContainerBuilder $container): void { // $container->setParameter('container.autowiring.strict_mode', true); // $container->setParameter('container.dumper.inline_class_loader', true); $container->addObjectResource($this); }); - $loader->load(function (ContainerBuilder $container) { + $loader->load(function (ContainerBuilder $container): void { $this->processDatabaseParameters($container); $this->defineRedisUrlEnvVar($container); $this->defineRabbitMqUrlEnvVar($container); @@ -89,19 +120,12 @@ class AppKernel extends Kernel private function processDatabaseParameters(ContainerBuilder $container) { - switch ($container->getParameter('database_driver')) { - case 'pdo_mysql': - $scheme = 'mysql'; - break; - case 'pdo_pgsql': - $scheme = 'pgsql'; - break; - case 'pdo_sqlite': - $scheme = 'sqlite'; - break; - default: - throw new RuntimeException('Unsupported database driver: ' . $container->getParameter('database_driver')); - } + $scheme = match ($container->getParameter('database_driver')) { + 'pdo_mysql' => 'mysql', + 'pdo_pgsql' => 'pgsql', + 'pdo_sqlite' => 'sqlite', + default => throw new RuntimeException('Unsupported database driver: ' . $container->getParameter('database_driver')), + }; $container->setParameter('database_scheme', $scheme); diff --git a/composer-dependency-analyser.php b/composer-dependency-analyser.php index 03c391b99..6cc280497 100644 --- a/composer-dependency-analyser.php +++ b/composer-dependency-analyser.php @@ -37,11 +37,11 @@ $config 'phpstan/phpstan-symfony', 'psr/http-client', 'psr/http-factory', + 'rector/rector', 'scheb/2fa-trusted-device', 'shipmonk/composer-dependency-analyser', 'symfony/asset', 'symfony/css-selector', - 'symfony/doctrine-bridge', 'symfony/google-mailer', 'symfony/intl', 'symfony/phpunit-bridge', @@ -62,6 +62,9 @@ $config 'symfony/web-profiler-bundle', 'symfony/web-server-bundle', ], [ErrorType::DEV_DEPENDENCY_IN_PROD]) + ->ignoreErrorsOnPackages([ + 'gedmo/doctrine-extensions', + ], [ErrorType::SHADOW_DEPENDENCY]) ; return $config; diff --git a/composer.json b/composer.json index 45cdaf1cc..fd95d1d4a 100644 --- a/composer.json +++ b/composer.json @@ -173,6 +173,7 @@ "phpstan/phpstan-phpunit": "^1.4.2", "phpstan/phpstan-symfony": "^1.4.13", "phpunit/phpunit": "^9.6.22", + "rector/rector": "^1.2", "shipmonk/composer-dependency-analyser": "^1.8.2", "symfony/css-selector": "^5.4.45", "symfony/debug-bundle": "^5.4.45", diff --git a/composer.lock b/composer.lock index 880448c57..b648b40c5 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": "df71f834528625c49553a128ca93e4aa", + "content-hash": "00b8f95df6ec0572c06ad6f34847405c", "packages": [ { "name": "babdev/pagerfanta-bundle", @@ -17856,6 +17856,65 @@ ], "time": "2024-06-11T12:45:25+00:00" }, + { + "name": "rector/rector", + "version": "1.2.10", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "40f9cf38c05296bd32f444121336a521a293fa61" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/40f9cf38c05296bd32f444121336a521a293fa61", + "reference": "40f9cf38c05296bd32f444121336a521a293fa61", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.12.5" + }, + "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", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/1.2.10" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2024-11-08T13:59:10+00:00" + }, { "name": "sebastian/cli-parser", "version": "1.0.2", diff --git a/fixtures/IgnoreOriginInstanceRuleFixtures.php b/fixtures/IgnoreOriginInstanceRuleFixtures.php index b02cfcba3..f425a0f1f 100644 --- a/fixtures/IgnoreOriginInstanceRuleFixtures.php +++ b/fixtures/IgnoreOriginInstanceRuleFixtures.php @@ -8,11 +8,9 @@ use Wallabag\Entity\IgnoreOriginInstanceRule; class IgnoreOriginInstanceRuleFixtures extends Fixture { - private array $defaultIgnoreOriginInstanceRules; - - public function __construct(array $defaultIgnoreOriginInstanceRules) - { - $this->defaultIgnoreOriginInstanceRules = $defaultIgnoreOriginInstanceRules; + public function __construct( + private readonly array $defaultIgnoreOriginInstanceRules, + ) { } public function load(ObjectManager $manager): void diff --git a/fixtures/InternalSettingFixtures.php b/fixtures/InternalSettingFixtures.php index a09971968..1ca6d79cd 100644 --- a/fixtures/InternalSettingFixtures.php +++ b/fixtures/InternalSettingFixtures.php @@ -8,11 +8,9 @@ use Wallabag\Entity\InternalSetting; class InternalSettingFixtures extends Fixture { - private array $defaultInternalSettings; - - public function __construct(array $defaultInternalSettings) - { - $this->defaultInternalSettings = $defaultInternalSettings; + public function __construct( + private readonly array $defaultInternalSettings, + ) { } public function load(ObjectManager $manager): void diff --git a/fixtures/SiteCredentialFixtures.php b/fixtures/SiteCredentialFixtures.php index 5b95abe25..2657d9cec 100644 --- a/fixtures/SiteCredentialFixtures.php +++ b/fixtures/SiteCredentialFixtures.php @@ -11,11 +11,9 @@ use Wallabag\Helper\CryptoProxy; class SiteCredentialFixtures extends Fixture implements DependentFixtureInterface { - private CryptoProxy $cryptoProxy; - - public function __construct(CryptoProxy $cryptoProxy) - { - $this->cryptoProxy = $cryptoProxy; + public function __construct( + private readonly CryptoProxy $cryptoProxy, + ) { } public function load(ObjectManager $manager): void diff --git a/rector.php b/rector.php new file mode 100644 index 000000000..1304330e0 --- /dev/null +++ b/rector.php @@ -0,0 +1,28 @@ +withPaths([ + __DIR__ . '/app', + __DIR__ . '/fixtures', + __DIR__ . '/src', + __DIR__ . '/tests', + __DIR__ . '/web', + ]) + ->withRootFiles() + ->withImportNames(importShortClasses: false) + ->withAttributesSets(symfony: true, doctrine: true, gedmo: true, jms: true, sensiolabs: true) + ->withConfiguredRule(ClassPropertyAssignToConstructorPromotionRector::class, [ + 'inline_public' => true, + ]) + ->withSkip([ + ClassPropertyAssignToConstructorPromotionRector::class => [ + __DIR__ . '/src/Entity/*', + ], + ]) + ->withPhpSets() + ->withTypeCoverageLevel(0); diff --git a/src/Command/CleanDownloadedImagesCommand.php b/src/Command/CleanDownloadedImagesCommand.php index c57cb248a..b35825828 100644 --- a/src/Command/CleanDownloadedImagesCommand.php +++ b/src/Command/CleanDownloadedImagesCommand.php @@ -16,14 +16,10 @@ class CleanDownloadedImagesCommand extends Command protected static $defaultName = 'wallabag:clean-downloaded-images'; protected static $defaultDescription = 'Cleans downloaded images which are no more associated to an entry'; - private EntryRepository $entryRepository; - private DownloadImages $downloadImages; - - public function __construct(EntryRepository $entryRepository, DownloadImages $downloadImages) - { - $this->entryRepository = $entryRepository; - $this->downloadImages = $downloadImages; - + public function __construct( + private readonly EntryRepository $entryRepository, + private readonly DownloadImages $downloadImages, + ) { parent::__construct(); } diff --git a/src/Command/CleanDuplicatesCommand.php b/src/Command/CleanDuplicatesCommand.php index 184146aec..6d68f00de 100644 --- a/src/Command/CleanDuplicatesCommand.php +++ b/src/Command/CleanDuplicatesCommand.php @@ -21,16 +21,12 @@ class CleanDuplicatesCommand extends Command protected SymfonyStyle $io; protected int $duplicates = 0; - private EntityManagerInterface $entityManager; - private EntryRepository $entryRepository; - private UserRepository $userRepository; - - public function __construct(EntityManagerInterface $entityManager, EntryRepository $entryRepository, UserRepository $userRepository) - { - $this->entityManager = $entityManager; - $this->entryRepository = $entryRepository; - $this->userRepository = $userRepository; + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly EntryRepository $entryRepository, + private readonly UserRepository $userRepository, + ) { parent::__construct(); } @@ -55,7 +51,7 @@ class CleanDuplicatesCommand extends Command try { $user = $this->getUser($username); $this->cleanDuplicates($user); - } catch (NoResultException $e) { + } catch (NoResultException) { $this->io->error(\sprintf('User "%s" not found.', $username)); return 1; @@ -104,8 +100,8 @@ class CleanDuplicatesCommand extends Command private function similarUrl($url) { - if (\in_array(substr($url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls - return substr($url, 0, \strlen($url)); + if (\in_array(substr((string) $url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls + return substr((string) $url, 0, \strlen((string) $url)); } return $url; diff --git a/src/Command/ExportCommand.php b/src/Command/ExportCommand.php index f651157a6..85fc85991 100644 --- a/src/Command/ExportCommand.php +++ b/src/Command/ExportCommand.php @@ -17,18 +17,12 @@ class ExportCommand extends Command protected static $defaultName = 'wallabag:export'; protected static $defaultDescription = 'Export all entries for an user'; - private EntryRepository $entryRepository; - private UserRepository $userRepository; - private EntriesExport $entriesExport; - private string $projectDir; - - public function __construct(EntryRepository $entryRepository, UserRepository $userRepository, EntriesExport $entriesExport, string $projectDir) - { - $this->entryRepository = $entryRepository; - $this->userRepository = $userRepository; - $this->entriesExport = $entriesExport; - $this->projectDir = $projectDir; - + public function __construct( + private readonly EntryRepository $entryRepository, + private readonly UserRepository $userRepository, + private readonly EntriesExport $entriesExport, + private readonly string $projectDir, + ) { parent::__construct(); } diff --git a/src/Command/GenerateUrlHashesCommand.php b/src/Command/GenerateUrlHashesCommand.php index 4583fa140..df50fd164 100644 --- a/src/Command/GenerateUrlHashesCommand.php +++ b/src/Command/GenerateUrlHashesCommand.php @@ -19,16 +19,12 @@ class GenerateUrlHashesCommand extends Command protected static $defaultDescription = 'Generates hashed urls for each entry'; protected OutputInterface $output; - private EntityManagerInterface $entityManager; - private EntryRepository $entryRepository; - private UserRepository $userRepository; - - public function __construct(EntityManagerInterface $entityManager, EntryRepository $entryRepository, UserRepository $userRepository) - { - $this->entityManager = $entityManager; - $this->entryRepository = $entryRepository; - $this->userRepository = $userRepository; + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly EntryRepository $entryRepository, + private readonly UserRepository $userRepository, + ) { parent::__construct(); } @@ -49,7 +45,7 @@ class GenerateUrlHashesCommand extends Command try { $user = $this->getUser($username); $this->generateHashedUrls($user); - } catch (NoResultException $e) { + } catch (NoResultException) { $output->writeln(\sprintf('User "%s" not found.', $username)); return 1; diff --git a/src/Command/Import/ImportCommand.php b/src/Command/Import/ImportCommand.php index 0005797a5..2f5b6ba18 100644 --- a/src/Command/Import/ImportCommand.php +++ b/src/Command/Import/ImportCommand.php @@ -33,55 +33,23 @@ class ImportCommand extends Command protected static $defaultName = 'wallabag:import'; protected static $defaultDescription = 'Import entries from a JSON export'; - private EntityManagerInterface $entityManager; - private TokenStorageInterface $tokenStorage; - private UserRepository $userRepository; - private WallabagV2Import $wallabagV2Import; - private FirefoxImport $firefoxImport; - private ChromeImport $chromeImport; - private ReadabilityImport $readabilityImport; - private InstapaperImport $instapaperImport; - private PinboardImport $pinboardImport; - private DeliciousImport $deliciousImport; - private OmnivoreImport $omnivoreImport; - private WallabagV1Import $wallabagV1Import; - private ElcuratorImport $elcuratorImport; - private ShaarliImport $shaarliImport; - private PocketHtmlImport $pocketHtmlImport; - public function __construct( - EntityManagerInterface $entityManager, - TokenStorageInterface $tokenStorage, - UserRepository $userRepository, - WallabagV2Import $wallabagV2Import, - FirefoxImport $firefoxImport, - ChromeImport $chromeImport, - ReadabilityImport $readabilityImport, - InstapaperImport $instapaperImport, - PinboardImport $pinboardImport, - DeliciousImport $deliciousImport, - WallabagV1Import $wallabagV1Import, - ElcuratorImport $elcuratorImport, - ShaarliImport $shaarliImport, - PocketHtmlImport $pocketHtmlImport, - OmnivoreImport $omnivoreImport, + private readonly EntityManagerInterface $entityManager, + private readonly TokenStorageInterface $tokenStorage, + private readonly UserRepository $userRepository, + private readonly WallabagV2Import $wallabagV2Import, + private readonly FirefoxImport $firefoxImport, + private readonly ChromeImport $chromeImport, + private readonly ReadabilityImport $readabilityImport, + private readonly InstapaperImport $instapaperImport, + private readonly PinboardImport $pinboardImport, + private readonly DeliciousImport $deliciousImport, + private readonly WallabagV1Import $wallabagV1Import, + private readonly ElcuratorImport $elcuratorImport, + private readonly ShaarliImport $shaarliImport, + private readonly PocketHtmlImport $pocketHtmlImport, + private readonly OmnivoreImport $omnivoreImport, ) { - $this->entityManager = $entityManager; - $this->tokenStorage = $tokenStorage; - $this->userRepository = $userRepository; - $this->wallabagV2Import = $wallabagV2Import; - $this->firefoxImport = $firefoxImport; - $this->chromeImport = $chromeImport; - $this->readabilityImport = $readabilityImport; - $this->instapaperImport = $instapaperImport; - $this->pinboardImport = $pinboardImport; - $this->deliciousImport = $deliciousImport; - $this->omnivoreImport = $omnivoreImport; - $this->wallabagV1Import = $wallabagV1Import; - $this->elcuratorImport = $elcuratorImport; - $this->shaarliImport = $shaarliImport; - $this->pocketHtmlImport = $pocketHtmlImport; - parent::__construct(); } @@ -107,9 +75,7 @@ class ImportCommand extends Command // Turning off doctrine default logs queries for saving memory $middlewares = $this->entityManager->getConnection()->getConfiguration()->getMiddlewares(); - $middlewaresWithoutLogging = array_filter($middlewares, function (Middleware $middleware) { - return !$middleware instanceof LoggingMiddleware; - }); + $middlewaresWithoutLogging = array_filter($middlewares, fn (Middleware $middleware) => !$middleware instanceof LoggingMiddleware); $this->entityManager->getConnection()->getConfiguration()->setMiddlewares($middlewaresWithoutLogging); if ($input->getOption('useUserId')) { @@ -131,43 +97,20 @@ class ImportCommand extends Command $this->tokenStorage->setToken($token); $user = $this->tokenStorage->getToken()->getUser(); - switch ($input->getOption('importer')) { - case 'v2': - $import = $this->wallabagV2Import; - break; - case 'firefox': - $import = $this->firefoxImport; - break; - case 'chrome': - $import = $this->chromeImport; - break; - case 'readability': - $import = $this->readabilityImport; - break; - case 'instapaper': - $import = $this->instapaperImport; - break; - case 'pinboard': - $import = $this->pinboardImport; - break; - case 'delicious': - $import = $this->deliciousImport; - break; - case 'elcurator': - $import = $this->elcuratorImport; - break; - case 'shaarli': - $import = $this->shaarliImport; - break; - case 'pocket': - $import = $this->pocketHtmlImport; - break; - case 'omnivore': - $import = $this->omnivoreImport; - break; - default: - $import = $this->wallabagV1Import; - } + $import = match ($input->getOption('importer')) { + 'v2' => $this->wallabagV2Import, + 'firefox' => $this->firefoxImport, + 'chrome' => $this->chromeImport, + 'readability' => $this->readabilityImport, + 'instapaper' => $this->instapaperImport, + 'pinboard' => $this->pinboardImport, + 'delicious' => $this->deliciousImport, + 'elcurator' => $this->elcuratorImport, + 'shaarli' => $this->shaarliImport, + 'pocket' => $this->pocketHtmlImport, + 'omnivore' => $this->omnivoreImport, + default => $this->wallabagV1Import, + }; $import->setMarkAsRead($input->getOption('markAsRead')); $import->setDisableContentUpdate($input->getOption('disableContentUpdate')); diff --git a/src/Command/Import/RedisWorkerCommand.php b/src/Command/Import/RedisWorkerCommand.php index b12e88f5a..266863be2 100644 --- a/src/Command/Import/RedisWorkerCommand.php +++ b/src/Command/Import/RedisWorkerCommand.php @@ -16,12 +16,9 @@ class RedisWorkerCommand extends Command protected static $defaultName = 'wallabag:import:redis-worker'; protected static $defaultDescription = 'Launch Redis worker'; - private $container; - - public function __construct(ContainerInterface $container) - { - $this->container = $container; - + public function __construct( + private readonly ContainerInterface $container, + ) { parent::__construct(); } diff --git a/src/Command/InstallCommand.php b/src/Command/InstallCommand.php index 4c23d598d..026bb4e8e 100644 --- a/src/Command/InstallCommand.php +++ b/src/Command/InstallCommand.php @@ -37,24 +37,15 @@ class InstallCommand extends Command 'curl_multi_init', ]; - private EntityManagerInterface $entityManager; - private EventDispatcherInterface $dispatcher; - private UserManagerInterface $userManager; - private TableMetadataStorageConfiguration $tableMetadataStorageConfiguration; - private string $databaseDriver; - private array $defaultSettings; - private array $defaultIgnoreOriginInstanceRules; - - public function __construct(EntityManagerInterface $entityManager, EventDispatcherInterface $dispatcher, UserManagerInterface $userManager, TableMetadataStorageConfiguration $tableMetadataStorageConfiguration, string $databaseDriver, array $defaultSettings, array $defaultIgnoreOriginInstanceRules) - { - $this->entityManager = $entityManager; - $this->dispatcher = $dispatcher; - $this->userManager = $userManager; - $this->tableMetadataStorageConfiguration = $tableMetadataStorageConfiguration; - $this->databaseDriver = $databaseDriver; - $this->defaultSettings = $defaultSettings; - $this->defaultIgnoreOriginInstanceRules = $defaultIgnoreOriginInstanceRules; - + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly EventDispatcherInterface $dispatcher, + private readonly UserManagerInterface $userManager, + private readonly TableMetadataStorageConfiguration $tableMetadataStorageConfiguration, + private readonly string $databaseDriver, + private readonly array $defaultSettings, + private readonly array $defaultIgnoreOriginInstanceRules, + ) { parent::__construct(); } @@ -153,7 +144,7 @@ class InstallCommand extends Command // return version should be like "PostgreSQL 9.5.4 on x86_64-apple-darwin15.6.0, compiled by Apple LLVM version 8.0.0 (clang-800.0.38), 64-bit" $version = $conn->executeQuery('SELECT version();')->fetchOne(); - preg_match('/PostgreSQL ([0-9\.]+)/i', $version, $matches); + preg_match('/PostgreSQL ([0-9\.]+)/i', (string) $version, $matches); if (isset($matches[1]) & version_compare($matches[1], '9.2.0', '<')) { $fulfilled = false; @@ -411,7 +402,7 @@ class InstallCommand extends Command try { return \in_array($databaseName, $schemaManager->listDatabases(), true); - } catch (DriverException $e) { + } catch (DriverException) { // it means we weren't able to get database list, assume the database doesn't exist return false; diff --git a/src/Command/ListUserCommand.php b/src/Command/ListUserCommand.php index 6085955b4..b76e059d3 100644 --- a/src/Command/ListUserCommand.php +++ b/src/Command/ListUserCommand.php @@ -15,12 +15,9 @@ class ListUserCommand extends Command protected static $defaultName = 'wallabag:user:list'; protected static $defaultDescription = 'List all users'; - private UserRepository $userRepository; - - public function __construct(UserRepository $userRepository) - { - $this->userRepository = $userRepository; - + public function __construct( + private readonly UserRepository $userRepository, + ) { parent::__construct(); } diff --git a/src/Command/ReloadEntryCommand.php b/src/Command/ReloadEntryCommand.php index aab6bb69f..2ba48d2fe 100644 --- a/src/Command/ReloadEntryCommand.php +++ b/src/Command/ReloadEntryCommand.php @@ -21,20 +21,13 @@ class ReloadEntryCommand extends Command protected static $defaultName = 'wallabag:entry:reload'; protected static $defaultDescription = 'Reload entries'; - private EntryRepository $entryRepository; - private UserRepository $userRepository; - private EntityManagerInterface $entityManager; - private ContentProxy $contentProxy; - private EventDispatcherInterface $dispatcher; - - public function __construct(EntryRepository $entryRepository, UserRepository $userRepository, EntityManagerInterface $entityManager, ContentProxy $contentProxy, EventDispatcherInterface $dispatcher) - { - $this->entryRepository = $entryRepository; - $this->userRepository = $userRepository; - $this->entityManager = $entityManager; - $this->contentProxy = $contentProxy; - $this->dispatcher = $dispatcher; - + public function __construct( + private readonly EntryRepository $entryRepository, + private readonly UserRepository $userRepository, + private readonly EntityManagerInterface $entityManager, + private readonly ContentProxy $contentProxy, + private readonly EventDispatcherInterface $dispatcher, + ) { parent::__construct(); } @@ -62,7 +55,7 @@ class ReloadEntryCommand extends Command $userId = $this->userRepository ->findOneByUserName($username) ->getId(); - } catch (NoResultException $e) { + } catch (NoResultException) { $io->error(\sprintf('User "%s" not found.', $username)); return 1; diff --git a/src/Command/ShowUserCommand.php b/src/Command/ShowUserCommand.php index 124daa87c..ad03c63bc 100644 --- a/src/Command/ShowUserCommand.php +++ b/src/Command/ShowUserCommand.php @@ -17,12 +17,10 @@ class ShowUserCommand extends Command protected static $defaultDescription = 'Show user details'; protected SymfonyStyle $io; - private UserRepository $userRepository; - - public function __construct(UserRepository $userRepository) - { - $this->userRepository = $userRepository; + public function __construct( + private readonly UserRepository $userRepository, + ) { parent::__construct(); } @@ -46,7 +44,7 @@ class ShowUserCommand extends Command try { $user = $this->getUser($username); $this->showUser($user); - } catch (NoResultException $e) { + } catch (NoResultException) { $this->io->error(\sprintf('User "%s" not found.', $username)); return 1; diff --git a/src/Command/TagAllCommand.php b/src/Command/TagAllCommand.php index 8d933e086..4a0fa0905 100644 --- a/src/Command/TagAllCommand.php +++ b/src/Command/TagAllCommand.php @@ -18,16 +18,11 @@ class TagAllCommand extends Command protected static $defaultName = 'wallabag:tag:all'; protected static $defaultDescription = 'Tag all entries using the tagging rules.'; - private EntityManagerInterface $entityManager; - private RuleBasedTagger $ruleBasedTagger; - private UserRepository $userRepository; - - public function __construct(EntityManagerInterface $entityManager, RuleBasedTagger $ruleBasedTagger, UserRepository $userRepository) - { - $this->entityManager = $entityManager; - $this->ruleBasedTagger = $ruleBasedTagger; - $this->userRepository = $userRepository; - + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly RuleBasedTagger $ruleBasedTagger, + private readonly UserRepository $userRepository, + ) { parent::__construct(); } @@ -48,7 +43,7 @@ class TagAllCommand extends Command try { $user = $this->getUser($input->getArgument('username')); - } catch (NoResultException $e) { + } catch (NoResultException) { $io->error(\sprintf('User "%s" not found.', $input->getArgument('username'))); return 1; diff --git a/src/Command/UpdatePicturesPathCommand.php b/src/Command/UpdatePicturesPathCommand.php index e78316e5c..40f144369 100644 --- a/src/Command/UpdatePicturesPathCommand.php +++ b/src/Command/UpdatePicturesPathCommand.php @@ -15,15 +15,11 @@ class UpdatePicturesPathCommand extends Command protected static $defaultName = 'wallabag:update-pictures-path'; protected static $defaultDescription = 'Update the path of the pictures for each entry when you changed your wallabag instance URL.'; - private EntityManagerInterface $entityManager; - private EntryRepository $entryRepository; - private string $wallabagUrl; - - public function __construct(EntityManagerInterface $entityManager, EntryRepository $entryRepository, $wallabagUrl) - { - $this->entityManager = $entityManager; - $this->entryRepository = $entryRepository; - $this->wallabagUrl = $wallabagUrl; + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly EntryRepository $entryRepository, + private readonly string $wallabagUrl, + ) { parent::__construct(); } diff --git a/src/Consumer/AbstractConsumer.php b/src/Consumer/AbstractConsumer.php index 3d635b0f3..7a0736114 100644 --- a/src/Consumer/AbstractConsumer.php +++ b/src/Consumer/AbstractConsumer.php @@ -7,25 +7,19 @@ use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Wallabag\Entity\Entry; -use Wallabag\Entity\Tag; use Wallabag\Event\EntrySavedEvent; use Wallabag\Import\AbstractImport; use Wallabag\Repository\UserRepository; abstract class AbstractConsumer { - protected $em; - protected $userRepository; - protected $import; - protected $eventDispatcher; - protected $logger; - - public function __construct(EntityManagerInterface $em, UserRepository $userRepository, AbstractImport $import, EventDispatcherInterface $eventDispatcher, ?LoggerInterface $logger = null) - { - $this->em = $em; - $this->userRepository = $userRepository; - $this->import = $import; - $this->eventDispatcher = $eventDispatcher; + public function __construct( + protected EntityManagerInterface $em, + protected UserRepository $userRepository, + protected AbstractImport $import, + protected EventDispatcherInterface $eventDispatcher, + protected ?LoggerInterface $logger = null, + ) { $this->logger = $logger ?: new NullLogger(); } @@ -74,9 +68,7 @@ abstract class AbstractConsumer // entry saved, dispatch event about it! $this->eventDispatcher->dispatch(new EntrySavedEvent($entry), EntrySavedEvent::NAME); - // clear only affected entities - $this->em->clear(Entry::class); - $this->em->clear(Tag::class); + $this->em->clear(); } catch (\Exception $e) { $this->logger->warning('Unable to save entry', ['entry' => $storedEntry, 'exception' => $e]); diff --git a/src/Consumer/RabbitMQConsumerTotalProxy.php b/src/Consumer/RabbitMQConsumerTotalProxy.php index 41e4fd491..b32a0653a 100644 --- a/src/Consumer/RabbitMQConsumerTotalProxy.php +++ b/src/Consumer/RabbitMQConsumerTotalProxy.php @@ -10,48 +10,21 @@ use OldSound\RabbitMqBundle\RabbitMq\Consumer; */ class RabbitMQConsumerTotalProxy { - private Consumer $pocketConsumer; - private Consumer $readabilityConsumer; - private Consumer $wallabagV1Consumer; - private Consumer $wallabagV2Consumer; - private Consumer $firefoxConsumer; - private Consumer $chromeConsumer; - private Consumer $instapaperConsumer; - private Consumer $pinboardConsumer; - private Consumer $deliciousConsumer; - private Consumer $elcuratorConsumer; - private Consumer $shaarliConsumer; - private Consumer $pocketHtmlConsumer; - private Consumer $omnivoreConsumer; - public function __construct( - Consumer $pocketConsumer, - Consumer $readabilityConsumer, - Consumer $wallabagV1Consumer, - Consumer $wallabagV2Consumer, - Consumer $firefoxConsumer, - Consumer $chromeConsumer, - Consumer $instapaperConsumer, - Consumer $pinboardConsumer, - Consumer $deliciousConsumer, - Consumer $elcuratorConsumer, - Consumer $shaarliConsumer, - Consumer $pocketHtmlConsumer, - Consumer $omnivoreConsumer, + private readonly Consumer $pocketConsumer, + private readonly Consumer $readabilityConsumer, + private readonly Consumer $wallabagV1Consumer, + private readonly Consumer $wallabagV2Consumer, + private readonly Consumer $firefoxConsumer, + private readonly Consumer $chromeConsumer, + private readonly Consumer $instapaperConsumer, + private readonly Consumer $pinboardConsumer, + private readonly Consumer $deliciousConsumer, + private readonly Consumer $elcuratorConsumer, + private readonly Consumer $shaarliConsumer, + private readonly Consumer $pocketHtmlConsumer, + private readonly Consumer $omnivoreConsumer, ) { - $this->pocketConsumer = $pocketConsumer; - $this->readabilityConsumer = $readabilityConsumer; - $this->wallabagV1Consumer = $wallabagV1Consumer; - $this->wallabagV2Consumer = $wallabagV2Consumer; - $this->firefoxConsumer = $firefoxConsumer; - $this->chromeConsumer = $chromeConsumer; - $this->instapaperConsumer = $instapaperConsumer; - $this->pinboardConsumer = $pinboardConsumer; - $this->deliciousConsumer = $deliciousConsumer; - $this->elcuratorConsumer = $elcuratorConsumer; - $this->shaarliConsumer = $shaarliConsumer; - $this->pocketHtmlConsumer = $pocketHtmlConsumer; - $this->omnivoreConsumer = $omnivoreConsumer; } /** diff --git a/src/Controller/AnnotationController.php b/src/Controller/AnnotationController.php index 2a07c70b4..5c88969d7 100644 --- a/src/Controller/AnnotationController.php +++ b/src/Controller/AnnotationController.php @@ -20,15 +20,11 @@ use Wallabag\Repository\AnnotationRepository; class AnnotationController extends AbstractFOSRestController { - protected EntityManagerInterface $entityManager; - protected SerializerInterface $serializer; - protected FormFactoryInterface $formFactory; - - public function __construct(EntityManagerInterface $entityManager, SerializerInterface $serializer, FormFactoryInterface $formFactory) - { - $this->entityManager = $entityManager; - $this->serializer = $serializer; - $this->formFactory = $formFactory; + public function __construct( + protected EntityManagerInterface $entityManager, + protected SerializerInterface $serializer, + protected FormFactoryInterface $formFactory, + ) { } /** @@ -36,11 +32,10 @@ class AnnotationController extends AbstractFOSRestController * * @see Api\WallabagRestController * - * @Route("/annotations/{entry}.{_format}", name="annotations_get_annotations", methods={"GET"}, defaults={"_format": "json"}) - * @IsGranted("LIST_ANNOTATIONS", subject="entry") - * * @return JsonResponse */ + #[Route(path: '/annotations/{entry}.{_format}', name: 'annotations_get_annotations', methods: ['GET'], defaults: ['_format' => 'json'])] + #[IsGranted('LIST_ANNOTATIONS', subject: 'entry')] public function getAnnotationsAction(Entry $entry, AnnotationRepository $annotationRepository) { $annotationRows = $annotationRepository->findByEntryIdAndUserId($entry->getId(), $this->getUser()->getId()); @@ -58,11 +53,10 @@ class AnnotationController extends AbstractFOSRestController * * @see Api\WallabagRestController * - * @Route("/annotations/{entry}.{_format}", name="annotations_post_annotation", methods={"POST"}, defaults={"_format": "json"}) - * @IsGranted("CREATE_ANNOTATIONS", subject="entry") - * * @return JsonResponse */ + #[Route(path: '/annotations/{entry}.{_format}', name: 'annotations_post_annotation', methods: ['POST'], defaults: ['_format' => 'json'])] + #[IsGranted('CREATE_ANNOTATIONS', subject: 'entry')] public function postAnnotationAction(Request $request, Entry $entry) { $data = json_decode($request->getContent(), true); @@ -93,11 +87,10 @@ class AnnotationController extends AbstractFOSRestController * * @see Api\WallabagRestController * - * @Route("/annotations/{annotation}.{_format}", name="annotations_put_annotation", methods={"PUT"}, defaults={"_format": "json"}) - * @IsGranted("EDIT", subject="annotation") - * * @return JsonResponse */ + #[Route(path: '/annotations/{annotation}.{_format}', name: 'annotations_put_annotation', methods: ['PUT'], defaults: ['_format' => 'json'])] + #[IsGranted('EDIT', subject: 'annotation')] public function putAnnotationAction(Request $request, Annotation $annotation) { try { @@ -129,11 +122,10 @@ class AnnotationController extends AbstractFOSRestController * * @see Api\WallabagRestController * - * @Route("/annotations/{annotation}.{_format}", name="annotations_delete_annotation", methods={"DELETE"}, defaults={"_format": "json"}) - * @IsGranted("DELETE", subject="annotation") - * * @return JsonResponse */ + #[Route(path: '/annotations/{annotation}.{_format}', name: 'annotations_delete_annotation', methods: ['DELETE'], defaults: ['_format' => 'json'])] + #[IsGranted('DELETE', subject: 'annotation')] public function deleteAnnotationAction(Annotation $annotation) { try { diff --git a/src/Controller/Api/AnnotationRestController.php b/src/Controller/Api/AnnotationRestController.php index 31e6150fb..ee3285b03 100644 --- a/src/Controller/Api/AnnotationRestController.php +++ b/src/Controller/Api/AnnotationRestController.php @@ -35,11 +35,10 @@ class AnnotationRestController extends WallabagRestController * ) * ) * - * @Route("/api/annotations/{entry}.{_format}", name="api_get_annotations", methods={"GET"}, defaults={"_format": "json"}) - * @IsGranted("LIST_ANNOTATIONS", subject="entry") - * * @return Response */ + #[Route(path: '/api/annotations/{entry}.{_format}', name: 'api_get_annotations', methods: ['GET'], defaults: ['_format' => 'json'])] + #[IsGranted('LIST_ANNOTATIONS', subject: 'entry')] public function getAnnotationsAction(Entry $entry) { return $this->forward('Wallabag\Controller\AnnotationController::getAnnotationsAction', [ @@ -100,11 +99,10 @@ class AnnotationRestController extends WallabagRestController * ) * ) * - * @Route("/api/annotations/{entry}.{_format}", name="api_post_annotation", methods={"POST"}, defaults={"_format": "json"}) - * @IsGranted("CREATE_ANNOTATIONS", subject="entry") - * * @return Response */ + #[Route(path: '/api/annotations/{entry}.{_format}', name: 'api_post_annotation', methods: ['POST'], defaults: ['_format' => 'json'])] + #[IsGranted('CREATE_ANNOTATIONS', subject: 'entry')] public function postAnnotationAction(Request $request, Entry $entry) { return $this->forward('Wallabag\Controller\AnnotationController::postAnnotationAction', [ @@ -135,11 +133,10 @@ class AnnotationRestController extends WallabagRestController * ) * ) * - * @Route("/api/annotations/{annotation}.{_format}", name="api_put_annotation", methods={"PUT"}, defaults={"_format": "json"}) - * @IsGranted("EDIT", subject="annotation") - * * @return Response */ + #[Route(path: '/api/annotations/{annotation}.{_format}', name: 'api_put_annotation', methods: ['PUT'], defaults: ['_format' => 'json'])] + #[IsGranted('EDIT', subject: 'annotation')] public function putAnnotationAction(Annotation $annotation, Request $request) { return $this->forward('Wallabag\Controller\AnnotationController::putAnnotationAction', [ @@ -170,11 +167,10 @@ class AnnotationRestController extends WallabagRestController * ) * ) * - * @Route("/api/annotations/{annotation}.{_format}", name="api_delete_annotation", methods={"DELETE"}, defaults={"_format": "json"}) - * @IsGranted("DELETE", subject="annotation") - * * @return Response */ + #[Route(path: '/api/annotations/{annotation}.{_format}', name: 'api_delete_annotation', methods: ['DELETE'], defaults: ['_format' => 'json'])] + #[IsGranted('DELETE', subject: 'annotation')] public function deleteAnnotationAction(Annotation $annotation) { return $this->forward('Wallabag\Controller\AnnotationController::deleteAnnotationAction', [ diff --git a/src/Controller/Api/ConfigRestController.php b/src/Controller/Api/ConfigRestController.php index 47659fc30..bdc23843f 100644 --- a/src/Controller/Api/ConfigRestController.php +++ b/src/Controller/Api/ConfigRestController.php @@ -23,10 +23,9 @@ class ConfigRestController extends WallabagRestController * ) * ) * - * @Route("/api/config.{_format}", name="api_get_config", methods={"GET"}, defaults={"_format": "json"}) - * * @return JsonResponse */ + #[Route(path: '/api/config.{_format}', name: 'api_get_config', methods: ['GET'], defaults: ['_format' => 'json'])] public function getConfigAction(SerializerInterface $serializer) { $this->validateAuthentication(); diff --git a/src/Controller/Api/DeveloperController.php b/src/Controller/Api/DeveloperController.php index a2097c211..1fd1da554 100644 --- a/src/Controller/Api/DeveloperController.php +++ b/src/Controller/Api/DeveloperController.php @@ -18,10 +18,9 @@ class DeveloperController extends AbstractController /** * List all clients and link to create a new one. * - * @Route("/developer", name="developer", methods={"GET"}) - * * @return Response */ + #[Route(path: '/developer', name: 'developer', methods: ['GET'])] public function indexAction(ClientRepository $repo) { $clients = $repo->findByUser($this->getUser()->getId()); @@ -34,10 +33,9 @@ class DeveloperController extends AbstractController /** * Create a client (an app). * - * @Route("/developer/client/create", name="developer_create_client", methods={"GET", "POST"}) - * * @return Response */ + #[Route(path: '/developer/client/create', name: 'developer_create_client', methods: ['GET', 'POST'])] public function createClientAction(Request $request, EntityManagerInterface $entityManager, TranslatorInterface $translator) { $client = new Client($this->getUser()); @@ -69,10 +67,9 @@ class DeveloperController extends AbstractController /** * Remove a client. * - * @Route("/developer/client/delete/{id}", name="developer_delete_client", methods={"POST"}, requirements={"id" = "\d+"}) - * * @return RedirectResponse */ + #[Route(path: '/developer/client/delete/{id}', name: 'developer_delete_client', methods: ['POST'], requirements: ['id' => '\d+'])] public function deleteClientAction(Request $request, Client $client, EntityManagerInterface $entityManager, TranslatorInterface $translator) { if (!$this->isCsrfTokenValid('delete-client', $request->request->get('token'))) { @@ -97,10 +94,9 @@ class DeveloperController extends AbstractController /** * Display developer how to use an existing app. * - * @Route("/developer/howto/first-app", name="developer_howto_firstapp", methods={"GET"}) - * * @return Response */ + #[Route(path: '/developer/howto/first-app', name: 'developer_howto_firstapp', methods: ['GET'])] public function howtoFirstAppAction() { return $this->render('Developer/howto_app.html.twig'); diff --git a/src/Controller/Api/EntryRestController.php b/src/Controller/Api/EntryRestController.php index 15b6d1c0e..a7dac9b07 100644 --- a/src/Controller/Api/EntryRestController.php +++ b/src/Controller/Api/EntryRestController.php @@ -85,11 +85,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/exists.{_format}", name="api_get_entries_exists", methods={"GET"}, defaults={"_format": "json"}) - * @IsGranted("LIST_ENTRIES") - * * @return JsonResponse */ + #[Route(path: '/api/entries/exists.{_format}', name: 'api_get_entries_exists', methods: ['GET'], defaults: ['_format' => 'json'])] + #[IsGranted('LIST_ENTRIES')] public function getEntriesExistsAction(Request $request, EntryRepository $entryRepository) { $returnId = (null === $request->query->get('return_id')) ? false : (bool) $request->query->get('return_id'); @@ -132,9 +131,7 @@ class EntryRestController extends WallabagRestController } if (false === $returnId) { - $results = array_map(function ($v) { - return null !== $v; - }, $results); + $results = array_map(fn ($v) => null !== $v, $results); } $results = $this->replaceUrlHashes($results, $urlHashMap); @@ -299,11 +296,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries.{_format}", name="api_get_entries", methods={"GET"}, defaults={"_format": "json"}) - * @IsGranted("LIST_ENTRIES") - * * @return JsonResponse */ + #[Route(path: '/api/entries.{_format}', name: 'api_get_entries', methods: ['GET'], defaults: ['_format' => 'json'])] + #[IsGranted('LIST_ENTRIES')] public function getEntriesAction(Request $request, EntryRepository $entryRepository) { $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive'); @@ -390,11 +386,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/{entry}.{_format}", name="api_get_entry", methods={"GET"}, defaults={"_format": "json"}) - * @IsGranted("VIEW", subject="entry") - * * @return JsonResponse */ + #[Route(path: '/api/entries/{entry}.{_format}', name: 'api_get_entry', methods: ['GET'], defaults: ['_format' => 'json'])] + #[IsGranted('VIEW', subject: 'entry')] public function getEntryAction(Entry $entry) { return $this->sendResponse($entry); @@ -432,11 +427,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/{entry}/export.{_format}", name="api_get_entry_export", methods={"GET"}, defaults={"_format": "json"}) - * @IsGranted("VIEW", subject="entry") - * * @return Response */ + #[Route(path: '/api/entries/{entry}/export.{_format}', name: 'api_get_entry_export', methods: ['GET'], defaults: ['_format' => 'json'])] + #[IsGranted('VIEW', subject: 'entry')] public function getEntryExportAction(Entry $entry, Request $request, EntriesExport $entriesExport) { return $entriesExport @@ -465,11 +459,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/list.{_format}", name="api_delete_entries_list", methods={"DELETE"}, defaults={"_format": "json"}) - * @IsGranted("DELETE_ENTRIES") - * * @return JsonResponse */ + #[Route(path: '/api/entries/list.{_format}', name: 'api_delete_entries_list', methods: ['DELETE'], defaults: ['_format' => 'json'])] + #[IsGranted('DELETE_ENTRIES')] public function deleteEntriesListAction(Request $request, EntryRepository $entryRepository, EventDispatcherInterface $eventDispatcher) { $urls = json_decode($request->query->get('urls', '[]')); @@ -522,13 +515,12 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/lists.{_format}", name="api_post_entries_list", methods={"POST"}, defaults={"_format": "json"}) - * @IsGranted("CREATE_ENTRIES") - * * @throws HttpException When limit is reached * * @return JsonResponse */ + #[Route(path: '/api/entries/lists.{_format}', name: 'api_post_entries_list', methods: ['POST'], defaults: ['_format' => 'json'])] + #[IsGranted('CREATE_ENTRIES')] public function postEntriesListAction(Request $request, EntryRepository $entryRepository, EventDispatcherInterface $eventDispatcher, ContentProxy $contentProxy) { $urls = json_decode($request->query->get('urls', '[]')); @@ -706,11 +698,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries.{_format}", name="api_post_entries", methods={"POST"}, defaults={"_format": "json"}) - * @IsGranted("CREATE_ENTRIES") - * * @return JsonResponse */ + #[Route(path: '/api/entries.{_format}', name: 'api_post_entries', methods: ['POST'], defaults: ['_format' => 'json'])] + #[IsGranted('CREATE_ENTRIES')] public function postEntriesAction( Request $request, EntryRepository $entryRepository, @@ -930,11 +921,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/{entry}.{_format}", name="api_patch_entries", methods={"PATCH"}, defaults={"_format": "json"}) - * @IsGranted("EDIT", subject="entry") - * * @return JsonResponse */ + #[Route(path: '/api/entries/{entry}.{_format}', name: 'api_patch_entries', methods: ['PATCH'], defaults: ['_format' => 'json'])] + #[IsGranted('EDIT', subject: 'entry')] public function patchEntriesAction(Entry $entry, Request $request, ContentProxy $contentProxy, LoggerInterface $logger, TagsAssigner $tagsAssigner, EventDispatcherInterface $eventDispatcher) { $data = $this->retrieveValueFromRequest($request); @@ -1045,11 +1035,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/{entry}/reload.{_format}", name="api_patch_entries_reload", methods={"PATCH"}, defaults={"_format": "json"}) - * @IsGranted("RELOAD", subject="entry") - * * @return JsonResponse */ + #[Route(path: '/api/entries/{entry}/reload.{_format}', name: 'api_patch_entries_reload', methods: ['PATCH'], defaults: ['_format' => 'json'])] + #[IsGranted('RELOAD', subject: 'entry')] public function patchEntriesReloadAction(Entry $entry, ContentProxy $contentProxy, LoggerInterface $logger, EventDispatcherInterface $eventDispatcher) { try { @@ -1100,11 +1089,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/{entry}.{_format}", name="api_delete_entries", methods={"DELETE"}, defaults={"_format": "json"}) - * @IsGranted("DELETE", subject="entry") - * * @return JsonResponse */ + #[Route(path: '/api/entries/{entry}.{_format}', name: 'api_delete_entries', methods: ['DELETE'], defaults: ['_format' => 'json'])] + #[IsGranted('DELETE', subject: 'entry')] public function deleteEntriesAction(Entry $entry, Request $request, EventDispatcherInterface $eventDispatcher) { $expect = $request->query->get('expect', 'entry'); @@ -1152,11 +1140,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/{entry}/tags.{_format}", name="api_get_entries_tags", methods={"GET"}, defaults={"_format": "json"}) - * @IsGranted("LIST_TAGS", subject="entry") - * * @return JsonResponse */ + #[Route(path: '/api/entries/{entry}/tags.{_format}', name: 'api_get_entries_tags', methods: ['GET'], defaults: ['_format' => 'json'])] + #[IsGranted('LIST_TAGS', subject: 'entry')] public function getEntriesTagsAction(Entry $entry) { return $this->sendResponse($entry->getTags()); @@ -1194,11 +1181,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/{entry}/tags.{_format}", name="api_post_entries_tags", methods={"POST"}, defaults={"_format": "json"}) - * @IsGranted("TAG", subject="entry") - * * @return JsonResponse */ + #[Route(path: '/api/entries/{entry}/tags.{_format}', name: 'api_post_entries_tags', methods: ['POST'], defaults: ['_format' => 'json'])] + #[IsGranted('TAG', subject: 'entry')] public function postEntriesTagsAction(Request $request, Entry $entry, TagsAssigner $tagsAssigner) { $tags = $request->request->get('tags', ''); @@ -1244,11 +1230,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/{entry}/tags/{tag}.{_format}", name="api_delete_entries_tags", methods={"DELETE"}, defaults={"_format": "json"}) - * @IsGranted("UNTAG", subject="entry") - * * @return JsonResponse */ + #[Route(path: '/api/entries/{entry}/tags/{tag}.{_format}', name: 'api_delete_entries_tags', methods: ['DELETE'], defaults: ['_format' => 'json'])] + #[IsGranted('UNTAG', subject: 'entry')] public function deleteEntriesTagsAction(Entry $entry, Tag $tag) { $entry->removeTag($tag); @@ -1278,11 +1263,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/tags/list.{_format}", name="api_delete_entries_tags_list", methods={"DELETE"}, defaults={"_format": "json"}) - * @IsGranted("DELETE_TAGS") - * * @return JsonResponse */ + #[Route(path: '/api/entries/tags/list.{_format}', name: 'api_delete_entries_tags_list', methods: ['DELETE'], defaults: ['_format' => 'json'])] + #[IsGranted('DELETE_TAGS')] public function deleteEntriesTagsListAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository) { $list = json_decode($request->query->get('list', '[]')); @@ -1344,11 +1328,10 @@ class EntryRestController extends WallabagRestController * ) * ) * - * @Route("/api/entries/tags/lists.{_format}", name="api_post_entries_tags_list", methods={"POST"}, defaults={"_format": "json"}) - * @IsGranted("CREATE_TAGS") - * * @return JsonResponse */ + #[Route(path: '/api/entries/tags/lists.{_format}', name: 'api_post_entries_tags_list', methods: ['POST'], defaults: ['_format' => 'json'])] + #[IsGranted('CREATE_TAGS')] public function postEntriesTagsListAction(Request $request, EntryRepository $entryRepository, TagsAssigner $tagsAssigner) { $list = json_decode($request->query->get('list', '[]')); diff --git a/src/Controller/Api/SearchRestController.php b/src/Controller/Api/SearchRestController.php index e00920c7b..98a3f6c81 100644 --- a/src/Controller/Api/SearchRestController.php +++ b/src/Controller/Api/SearchRestController.php @@ -55,11 +55,10 @@ class SearchRestController extends WallabagRestController * ) * ) * - * @Route("/api/search.{_format}", name="api_get_search", methods={"GET"}, defaults={"_format": "json"}) - * @IsGranted("LIST_ENTRIES") - * * @return JsonResponse */ + #[Route(path: '/api/search.{_format}', name: 'api_get_search', methods: ['GET'], defaults: ['_format' => 'json'])] + #[IsGranted('LIST_ENTRIES')] public function getSearchAction(Request $request, EntryRepository $entryRepository) { $term = $request->query->get('term'); diff --git a/src/Controller/Api/TagRestController.php b/src/Controller/Api/TagRestController.php index d8757cd92..1fac9f13f 100644 --- a/src/Controller/Api/TagRestController.php +++ b/src/Controller/Api/TagRestController.php @@ -26,10 +26,9 @@ class TagRestController extends WallabagRestController * ) * ) * - * @Route("/api/tags.{_format}", name="api_get_tags", methods={"GET"}, defaults={"_format": "json"}) - * * @return JsonResponse */ + #[Route(path: '/api/tags.{_format}', name: 'api_get_tags', methods: ['GET'], defaults: ['_format' => 'json'])] public function getTagsAction(TagRepository $tagRepository) { $this->validateAuthentication(); @@ -63,10 +62,9 @@ class TagRestController extends WallabagRestController * ) * ) * - * @Route("/api/tag/label.{_format}", name="api_delete_tag_label", methods={"DELETE"}, defaults={"_format": "json"}) - * * @return JsonResponse */ + #[Route(path: '/api/tag/label.{_format}', name: 'api_delete_tag_label', methods: ['DELETE'], defaults: ['_format' => 'json'])] public function deleteTagLabelAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository) { $this->validateAuthentication(); @@ -111,10 +109,9 @@ class TagRestController extends WallabagRestController * ) * ) * - * @Route("/api/tags/label.{_format}", name="api_delete_tags_label", methods={"DELETE"}, defaults={"_format": "json"}) - * * @return JsonResponse */ + #[Route(path: '/api/tags/label.{_format}', name: 'api_delete_tags_label', methods: ['DELETE'], defaults: ['_format' => 'json'])] public function deleteTagsLabelAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository) { $this->validateAuthentication(); @@ -158,10 +155,9 @@ class TagRestController extends WallabagRestController * ) * ) * - * @Route("/api/tags/{tag}.{_format}", name="api_delete_tag", methods={"DELETE"}, defaults={"_format": "json"}) - * * @return JsonResponse */ + #[Route(path: '/api/tags/{tag}.{_format}', name: 'api_delete_tag', methods: ['DELETE'], defaults: ['_format' => 'json'])] public function deleteTagAction(Tag $tag, TagRepository $tagRepository, EntryRepository $entryRepository) { $this->validateAuthentication(); diff --git a/src/Controller/Api/TaggingRuleRestController.php b/src/Controller/Api/TaggingRuleRestController.php index 6137da796..7f9f11d5f 100644 --- a/src/Controller/Api/TaggingRuleRestController.php +++ b/src/Controller/Api/TaggingRuleRestController.php @@ -23,10 +23,9 @@ class TaggingRuleRestController extends WallabagRestController * ) * ) * - * @Route("/api/taggingrule/export.{_format}", name="api_get_taggingrule_export", methods={"GET"}, defaults={"_format": "json"}) - * * @return Response */ + #[Route(path: '/api/taggingrule/export.{_format}', name: 'api_get_taggingrule_export', methods: ['GET'], defaults: ['_format' => 'json'])] public function getTaggingruleExportAction() { $this->validateAuthentication(); diff --git a/src/Controller/Api/WallabagRestController.php b/src/Controller/Api/WallabagRestController.php index 47987094e..fad611536 100644 --- a/src/Controller/Api/WallabagRestController.php +++ b/src/Controller/Api/WallabagRestController.php @@ -21,21 +21,14 @@ use Wallabag\Entity\User; class WallabagRestController extends AbstractFOSRestController { - protected EntityManagerInterface $entityManager; - protected SerializerInterface $serializer; - protected AuthorizationCheckerInterface $authorizationChecker; - protected TokenStorageInterface $tokenStorage; - protected TranslatorInterface $translator; - protected bool $registrationEnabled; - - public function __construct(EntityManagerInterface $entityManager, SerializerInterface $serializer, AuthorizationCheckerInterface $authorizationChecker, TokenStorageInterface $tokenStorage, TranslatorInterface $translator, bool $registrationEnabled) - { - $this->entityManager = $entityManager; - $this->serializer = $serializer; - $this->authorizationChecker = $authorizationChecker; - $this->tokenStorage = $tokenStorage; - $this->translator = $translator; - $this->registrationEnabled = $registrationEnabled; + public function __construct( + protected EntityManagerInterface $entityManager, + protected SerializerInterface $serializer, + protected AuthorizationCheckerInterface $authorizationChecker, + protected TokenStorageInterface $tokenStorage, + protected TranslatorInterface $translator, + protected bool $registrationEnabled, + ) { } /** @@ -57,10 +50,9 @@ class WallabagRestController extends AbstractFOSRestController * * @deprecated Should use info endpoint instead * - * @Route("/api/version.{_format}", name="api_get_version", methods={"GET"}, defaults={"_format": "json"}) - * * @return JsonResponse */ + #[Route(path: '/api/version.{_format}', name: 'api_get_version', methods: ['GET'], defaults: ['_format' => 'json'])] public function getVersionAction() { $version = $this->getParameter('wallabag.version'); @@ -80,10 +72,9 @@ class WallabagRestController extends AbstractFOSRestController * ) * ) * - * @Route("/api/info.{_format}", name="api_get_info", methods={"GET"}, defaults={"_format": "json"}) - * * @return JsonResponse */ + #[Route(path: '/api/info.{_format}', name: 'api_get_info', methods: ['GET'], defaults: ['_format' => 'json'])] public function getInfoAction(Config $craueConfig) { $info = new ApplicationInfo( diff --git a/src/Controller/ConfigController.php b/src/Controller/ConfigController.php index 792cc2494..017c84aa8 100644 --- a/src/Controller/ConfigController.php +++ b/src/Controller/ConfigController.php @@ -44,39 +44,20 @@ use Wallabag\Tools\Utils; class ConfigController extends AbstractController { - private EntityManagerInterface $entityManager; - private UserManagerInterface $userManager; - private EntryRepository $entryRepository; - private TagRepository $tagRepository; - private AnnotationRepository $annotationRepository; - private ConfigRepository $configRepository; - private EventDispatcherInterface $eventDispatcher; - private Redirect $redirectHelper; - public function __construct( - EntityManagerInterface $entityManager, - UserManagerInterface $userManager, - EntryRepository $entryRepository, - TagRepository $tagRepository, - AnnotationRepository $annotationRepository, - ConfigRepository $configRepository, - EventDispatcherInterface $eventDispatcher, - Redirect $redirectHelper, + private readonly EntityManagerInterface $entityManager, + private readonly UserManagerInterface $userManager, + private readonly EntryRepository $entryRepository, + private readonly TagRepository $tagRepository, + private readonly AnnotationRepository $annotationRepository, + private readonly ConfigRepository $configRepository, + private readonly EventDispatcherInterface $eventDispatcher, + private readonly Redirect $redirectHelper, ) { - $this->entityManager = $entityManager; - $this->userManager = $userManager; - $this->entryRepository = $entryRepository; - $this->tagRepository = $tagRepository; - $this->annotationRepository = $annotationRepository; - $this->configRepository = $configRepository; - $this->eventDispatcher = $eventDispatcher; - $this->redirectHelper = $redirectHelper; } - /** - * @Route("/config", name="config", methods={"GET", "POST"}) - * @IsGranted("EDIT_CONFIG") - */ + #[Route(path: '/config', name: 'config', methods: ['GET', 'POST'])] + #[IsGranted('EDIT_CONFIG')] public function indexAction(Request $request, Config $craueConfig, TaggingRuleRepository $taggingRuleRepository, IgnoreOriginUserRuleRepository $ignoreOriginUserRuleRepository, UserRepository $userRepository) { $config = $this->getConfig(); @@ -266,10 +247,9 @@ class ConfigController extends AbstractController /** * Disable 2FA using email. - * - * @Route("/config/otp/email/disable", name="disable_otp_email", methods={"POST"}) - * @IsGranted("EDIT_CONFIG") */ + #[Route(path: '/config/otp/email/disable', name: 'disable_otp_email', methods: ['POST'])] + #[IsGranted('EDIT_CONFIG')] public function disableOtpEmailAction(Request $request) { if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) { @@ -292,10 +272,9 @@ class ConfigController extends AbstractController /** * Enable 2FA using email. - * - * @Route("/config/otp/email", name="config_otp_email", methods={"POST"}) - * @IsGranted("EDIT_CONFIG") */ + #[Route(path: '/config/otp/email', name: 'config_otp_email', methods: ['POST'])] + #[IsGranted('EDIT_CONFIG')] public function otpEmailAction(Request $request) { if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) { @@ -321,10 +300,9 @@ class ConfigController extends AbstractController /** * Disable 2FA using OTP app. - * - * @Route("/config/otp/app/disable", name="disable_otp_app", methods={"POST"}) - * @IsGranted("EDIT_CONFIG") */ + #[Route(path: '/config/otp/app/disable', name: 'disable_otp_app', methods: ['POST'])] + #[IsGranted('EDIT_CONFIG')] public function disableOtpAppAction(Request $request) { if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) { @@ -349,10 +327,9 @@ class ConfigController extends AbstractController /** * Enable 2FA using OTP app, user will need to confirm the generated code from the app. - * - * @Route("/config/otp/app", name="config_otp_app", methods={"POST"}) - * @IsGranted("EDIT_CONFIG") */ + #[Route(path: '/config/otp/app', name: 'config_otp_app', methods: ['POST'])] + #[IsGranted('EDIT_CONFIG')] public function otpAppAction(Request $request, GoogleAuthenticatorInterface $googleAuthenticator) { if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) { @@ -367,9 +344,7 @@ class ConfigController extends AbstractController $backupCodes = (new BackupCodes())->toArray(); $backupCodesHashed = array_map( - function ($backupCode) { - return password_hash($backupCode, \PASSWORD_DEFAULT); - }, + fn ($backupCode) => password_hash((string) $backupCode, \PASSWORD_DEFAULT), $backupCodes ); @@ -411,10 +386,9 @@ class ConfigController extends AbstractController /** * Validate OTP code. - * - * @Route("/config/otp/app/check", name="config_otp_app_check", methods={"POST"}) - * @IsGranted("EDIT_CONFIG") */ + #[Route(path: '/config/otp/app/check', name: 'config_otp_app_check', methods: ['POST'])] + #[IsGranted('EDIT_CONFIG')] public function otpAppCheckAction(Request $request, GoogleAuthenticatorInterface $googleAuthenticator) { if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) { @@ -449,11 +423,10 @@ class ConfigController extends AbstractController } /** - * @Route("/generate-token", name="generate_token", methods={"GET"}) - * @IsGranted("EDIT_CONFIG") - * * @return RedirectResponse|JsonResponse */ + #[Route(path: '/generate-token', name: 'generate_token', methods: ['GET'])] + #[IsGranted('EDIT_CONFIG')] public function generateTokenAction(Request $request) { $config = $this->getConfig(); @@ -475,11 +448,10 @@ class ConfigController extends AbstractController } /** - * @Route("/revoke-token", name="revoke_token", methods={"GET"}) - * @IsGranted("EDIT_CONFIG") - * * @return RedirectResponse|JsonResponse */ + #[Route(path: '/revoke-token', name: 'revoke_token', methods: ['GET'])] + #[IsGranted('EDIT_CONFIG')] public function revokeTokenAction(Request $request) { $config = $this->getConfig(); @@ -503,11 +475,10 @@ class ConfigController extends AbstractController /** * Deletes a tagging rule and redirect to the config homepage. * - * @Route("/tagging-rule/delete/{taggingRule}", name="delete_tagging_rule", methods={"GET"}, requirements={"taggingRule" = "\d+"}) - * @IsGranted("DELETE", subject="taggingRule") - * * @return RedirectResponse */ + #[Route(path: '/tagging-rule/delete/{taggingRule}', name: 'delete_tagging_rule', methods: ['GET'], requirements: ['taggingRule' => '\d+'])] + #[IsGranted('DELETE', subject: 'taggingRule')] public function deleteTaggingRuleAction(TaggingRule $taggingRule) { $this->entityManager->remove($taggingRule); @@ -524,11 +495,10 @@ class ConfigController extends AbstractController /** * Edit a tagging rule. * - * @Route("/tagging-rule/edit/{taggingRule}", name="edit_tagging_rule", methods={"GET"}, requirements={"taggingRule" = "\d+"}) - * @IsGranted("EDIT", subject="taggingRule") - * * @return RedirectResponse */ + #[Route(path: '/tagging-rule/edit/{taggingRule}', name: 'edit_tagging_rule', methods: ['GET'], requirements: ['taggingRule' => '\d+'])] + #[IsGranted('EDIT', subject: 'taggingRule')] public function editTaggingRuleAction(TaggingRule $taggingRule) { return $this->redirect($this->generateUrl('config') . '?tagging-rule=' . $taggingRule->getId() . '#set5'); @@ -537,11 +507,10 @@ class ConfigController extends AbstractController /** * Deletes an ignore origin rule and redirect to the config homepage. * - * @Route("/ignore-origin-user-rule/delete/{ignoreOriginUserRule}", name="delete_ignore_origin_rule", methods={"GET"}, requirements={"ignoreOriginUserRule" = "\d+"}) - * @IsGranted("DELETE", subject="ignoreOriginUserRule") - * * @return RedirectResponse */ + #[Route(path: '/ignore-origin-user-rule/delete/{ignoreOriginUserRule}', name: 'delete_ignore_origin_rule', methods: ['GET'], requirements: ['ignoreOriginUserRule' => '\d+'])] + #[IsGranted('DELETE', subject: 'ignoreOriginUserRule')] public function deleteIgnoreOriginRuleAction(IgnoreOriginUserRule $ignoreOriginUserRule) { $this->entityManager->remove($ignoreOriginUserRule); @@ -558,11 +527,10 @@ class ConfigController extends AbstractController /** * Edit an ignore origin rule. * - * @Route("/ignore-origin-user-rule/edit/{ignoreOriginUserRule}", name="edit_ignore_origin_rule", methods={"GET"}, requirements={"ignoreOriginUserRule" = "\d+"}) - * @IsGranted("EDIT", subject="ignoreOriginUserRule") - * * @return RedirectResponse */ + #[Route(path: '/ignore-origin-user-rule/edit/{ignoreOriginUserRule}', name: 'edit_ignore_origin_rule', methods: ['GET'], requirements: ['ignoreOriginUserRule' => '\d+'])] + #[IsGranted('EDIT', subject: 'ignoreOriginUserRule')] public function editIgnoreOriginRuleAction(IgnoreOriginUserRule $ignoreOriginUserRule) { return $this->redirect($this->generateUrl('config') . '?ignore-origin-user-rule=' . $ignoreOriginUserRule->getId() . '#set6'); @@ -571,11 +539,10 @@ class ConfigController extends AbstractController /** * Remove all annotations OR tags OR entries for the current user. * - * @Route("/reset/{type}", name="config_reset", methods={"POST"}, requirements={"id" = "annotations|tags|entries|tagging_rules"}) - * @IsGranted("EDIT_CONFIG") - * * @return RedirectResponse */ + #[Route(path: '/reset/{type}', name: 'config_reset', methods: ['POST'], requirements: ['id' => 'annotations|tags|entries|tagging_rules'])] + #[IsGranted('EDIT_CONFIG')] public function resetAction(Request $request, string $type, AnnotationRepository $annotationRepository, EntryRepository $entryRepository, TaggingRuleRepository $taggingRuleRepository) { if (!$this->isCsrfTokenValid('reset-area', $request->request->get('token'))) { @@ -627,13 +594,11 @@ class ConfigController extends AbstractController /** * Delete account for current user. * - * @Route("/account/delete", name="delete_account", methods={"POST"}) - * @IsGranted("EDIT_CONFIG") - * * @throws AccessDeniedHttpException - * * @return RedirectResponse */ + #[Route(path: '/account/delete', name: 'delete_account', methods: ['POST'])] + #[IsGranted('EDIT_CONFIG')] public function deleteAccountAction(Request $request, UserRepository $userRepository, TokenStorageInterface $tokenStorage) { if (!$this->isCsrfTokenValid('delete-account', $request->request->get('token'))) { @@ -660,11 +625,10 @@ class ConfigController extends AbstractController /** * Switch view mode for current user. * - * @Route("/config/view-mode", name="switch_view_mode", methods={"GET"}) - * @IsGranted("EDIT_CONFIG") - * * @return RedirectResponse */ + #[Route(path: '/config/view-mode', name: 'switch_view_mode', methods: ['GET'])] + #[IsGranted('EDIT_CONFIG')] public function changeViewModeAction(Request $request) { $user = $this->getUser(); @@ -683,11 +647,10 @@ class ConfigController extends AbstractController * * @param string $language * - * @Route("/locale/{language}", name="changeLocale", methods={"GET"}) - * @IsGranted("PUBLIC_ACCESS") - * * @return RedirectResponse */ + #[Route(path: '/locale/{language}', name: 'changeLocale', methods: ['GET'])] + #[IsGranted('PUBLIC_ACCESS')] public function setLocaleAction(Request $request, ValidatorInterface $validator, $language = null) { $errors = $validator->validate($language, new LocaleConstraint(['canonicalize' => true])); @@ -702,11 +665,10 @@ class ConfigController extends AbstractController /** * Export tagging rules for the logged in user. * - * @Route("/tagging-rule/export", name="export_tagging_rule", methods={"GET"}) - * @IsGranted("EDIT_CONFIG") - * * @return Response */ + #[Route(path: '/tagging-rule/export', name: 'export_tagging_rule', methods: ['GET'])] + #[IsGranted('EDIT_CONFIG')] public function exportTaggingRulesAction() { $data = SerializerBuilder::create()->build()->serialize( diff --git a/src/Controller/EntryController.php b/src/Controller/EntryController.php index 7f184d2b5..ebfebe40b 100644 --- a/src/Controller/EntryController.php +++ b/src/Controller/EntryController.php @@ -33,33 +33,23 @@ use Wallabag\Repository\TagRepository; class EntryController extends AbstractController { - private EntityManagerInterface $entityManager; - private EventDispatcherInterface $eventDispatcher; - private EntryRepository $entryRepository; - private Redirect $redirectHelper; - private PreparePagerForEntries $preparePagerForEntriesHelper; - private FilterBuilderUpdaterInterface $filterBuilderUpdater; - private ContentProxy $contentProxy; - private Security $security; - - public function __construct(EntityManagerInterface $entityManager, EventDispatcherInterface $eventDispatcher, EntryRepository $entryRepository, Redirect $redirectHelper, PreparePagerForEntries $preparePagerForEntriesHelper, FilterBuilderUpdaterInterface $filterBuilderUpdater, ContentProxy $contentProxy, Security $security) - { - $this->entityManager = $entityManager; - $this->eventDispatcher = $eventDispatcher; - $this->entryRepository = $entryRepository; - $this->redirectHelper = $redirectHelper; - $this->preparePagerForEntriesHelper = $preparePagerForEntriesHelper; - $this->filterBuilderUpdater = $filterBuilderUpdater; - $this->contentProxy = $contentProxy; - $this->security = $security; + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly EventDispatcherInterface $eventDispatcher, + private readonly EntryRepository $entryRepository, + private readonly Redirect $redirectHelper, + private readonly PreparePagerForEntries $preparePagerForEntriesHelper, + private readonly FilterBuilderUpdaterInterface $filterBuilderUpdater, + private readonly ContentProxy $contentProxy, + private readonly Security $security, + ) { } /** - * @Route("/mass", name="mass_action", methods={"POST"}) - * @IsGranted("EDIT_ENTRIES") - * * @return Response */ + #[Route(path: '/mass', name: 'mass_action', methods: ['POST'])] + #[IsGranted('EDIT_ENTRIES')] public function massAction(Request $request, TagRepository $tagRepository) { $values = $request->request->all(); @@ -76,7 +66,7 @@ class EntryController extends AbstractController $action = 'tag'; if (isset($values['tags'])) { - $labels = array_filter(explode(',', $values['tags']), + $labels = array_filter(explode(',', (string) $values['tags']), function ($v) { $v = trim($v); @@ -141,14 +131,12 @@ class EntryController extends AbstractController /** * @param int $page * - * @Route("/search/{page}", name="search", methods={"GET", "POST"}, defaults={"page" = 1}) - * @IsGranted("LIST_ENTRIES") - * * Default parameter for page is hardcoded (in duplication of the defaults from the Route) * because this controller is also called inside the layout template without any page as argument - * * @return Response */ + #[Route(path: '/search/{page}', name: 'search', methods: ['GET', 'POST'], defaults: ['page' => 1])] + #[IsGranted('LIST_ENTRIES')] public function searchFormAction(Request $request, $page = 1, $currentRoute = null) { // fallback to retrieve currentRoute from query parameter instead of injected one (when using inside a template) @@ -171,11 +159,10 @@ class EntryController extends AbstractController } /** - * @Route("/new-entry", name="new_entry", methods={"GET", "POST"}) - * @IsGranted("CREATE_ENTRIES") - * * @return Response */ + #[Route(path: '/new-entry', name: 'new_entry', methods: ['GET', 'POST'])] + #[IsGranted('CREATE_ENTRIES')] public function addEntryFormAction(Request $request, TranslatorInterface $translator) { $entry = new Entry($this->getUser()); @@ -215,11 +202,10 @@ class EntryController extends AbstractController } /** - * @Route("/bookmarklet", name="bookmarklet", methods={"GET"}) - * @IsGranted("CREATE_ENTRIES") - * * @return Response */ + #[Route(path: '/bookmarklet', name: 'bookmarklet', methods: ['GET'])] + #[IsGranted('CREATE_ENTRIES')] public function addEntryViaBookmarkletAction(Request $request) { $entry = new Entry($this->getUser()); @@ -239,11 +225,10 @@ class EntryController extends AbstractController } /** - * @Route("/new", name="new", methods={"GET"}) - * @IsGranted("CREATE_ENTRIES") - * * @return Response */ + #[Route(path: '/new', name: 'new', methods: ['GET'])] + #[IsGranted('CREATE_ENTRIES')] public function addEntryAction() { return $this->render('Entry/new.html.twig'); @@ -252,11 +237,10 @@ class EntryController extends AbstractController /** * Edit an entry content. * - * @Route("/edit/{id}", name="edit", methods={"GET", "POST"}, requirements={"id" = "\d+"}) - * @IsGranted("EDIT", subject="entry") - * * @return Response */ + #[Route(path: '/edit/{id}', name: 'edit', methods: ['GET', 'POST'], requirements: ['id' => '\d+'])] + #[IsGranted('EDIT', subject: 'entry')] public function editEntryAction(Request $request, Entry $entry) { $form = $this->createForm(EditEntryType::class, $entry); @@ -285,11 +269,10 @@ class EntryController extends AbstractController * * @param int $page * - * @Route("/all/list/{page}", name="all", methods={"GET"}, defaults={"page" = "1"}) - * @IsGranted("LIST_ENTRIES") - * * @return Response */ + #[Route(path: '/all/list/{page}', name: 'all', methods: ['GET'], defaults: ['page' => '1'])] + #[IsGranted('LIST_ENTRIES')] public function showAllAction(Request $request, $page) { return $this->showEntries('all', $request, $page); @@ -300,11 +283,10 @@ class EntryController extends AbstractController * * @param int $page * - * @Route("/unread/list/{page}", name="unread", methods={"GET"}, defaults={"page" = "1"}) - * @IsGranted("LIST_ENTRIES") - * * @return Response */ + #[Route(path: '/unread/list/{page}', name: 'unread', methods: ['GET'], defaults: ['page' => '1'])] + #[IsGranted('LIST_ENTRIES')] public function showUnreadAction(Request $request, $page) { // load the quickstart if no entry in database @@ -320,11 +302,10 @@ class EntryController extends AbstractController * * @param int $page * - * @Route("/archive/list/{page}", name="archive", methods={"GET"}, defaults={"page" = "1"}) - * @IsGranted("LIST_ENTRIES") - * * @return Response */ + #[Route(path: '/archive/list/{page}', name: 'archive', methods: ['GET'], defaults: ['page' => '1'])] + #[IsGranted('LIST_ENTRIES')] public function showArchiveAction(Request $request, $page) { return $this->showEntries('archive', $request, $page); @@ -335,11 +316,10 @@ class EntryController extends AbstractController * * @param int $page * - * @Route("/starred/list/{page}", name="starred", methods={"GET"}, defaults={"page" = "1"}) - * @IsGranted("LIST_ENTRIES") - * * @return Response */ + #[Route(path: '/starred/list/{page}', name: 'starred', methods: ['GET'], defaults: ['page' => '1'])] + #[IsGranted('LIST_ENTRIES')] public function showStarredAction(Request $request, $page) { return $this->showEntries('starred', $request, $page); @@ -350,11 +330,10 @@ class EntryController extends AbstractController * * @param int $page * - * @Route("/untagged/list/{page}", name="untagged", methods={"GET"}, defaults={"page" = "1"}) - * @IsGranted("LIST_ENTRIES") - * * @return Response */ + #[Route(path: '/untagged/list/{page}', name: 'untagged', methods: ['GET'], defaults: ['page' => '1'])] + #[IsGranted('LIST_ENTRIES')] public function showUntaggedEntriesAction(Request $request, $page) { return $this->showEntries('untagged', $request, $page); @@ -365,11 +344,10 @@ class EntryController extends AbstractController * * @param int $page * - * @Route("/annotated/list/{page}", name="annotated", methods={"GET"}, defaults={"page" = "1"}) - * @IsGranted("LIST_ENTRIES") - * * @return Response */ + #[Route(path: '/annotated/list/{page}', name: 'annotated', methods: ['GET'], defaults: ['page' => '1'])] + #[IsGranted('LIST_ENTRIES')] public function showWithAnnotationsEntriesAction(Request $request, $page) { return $this->showEntries('annotated', $request, $page); @@ -378,17 +356,16 @@ class EntryController extends AbstractController /** * Shows random entry depending on the given type. * - * @Route("/{type}/random", name="random_entry", methods={"GET"}, requirements={"type": "unread|starred|archive|untagged|annotated|all"}) - * @IsGranted("LIST_ENTRIES") - * * @return RedirectResponse */ + #[Route(path: '/{type}/random', name: 'random_entry', methods: ['GET'], requirements: ['type' => 'unread|starred|archive|untagged|annotated|all'])] + #[IsGranted('LIST_ENTRIES')] public function redirectRandomEntryAction(string $type = 'all') { try { $entry = $this->entryRepository ->getRandomEntry($this->getUser()->getId(), $type); - } catch (NoResultException $e) { + } catch (NoResultException) { $this->addFlash('notice', 'flashes.entry.notice.no_random_entry'); return $this->redirect($this->generateUrl($type)); @@ -400,11 +377,10 @@ class EntryController extends AbstractController /** * Shows entry content. * - * @Route("/view/{id}", name="view", methods={"GET"}, requirements={"id" = "\d+"}) - * @IsGranted("VIEW", subject="entry") - * * @return Response */ + #[Route(path: '/view/{id}', name: 'view', methods: ['GET'], requirements: ['id' => '\d+'])] + #[IsGranted('VIEW', subject: 'entry')] public function viewAction(Entry $entry) { return $this->render( @@ -417,11 +393,10 @@ class EntryController extends AbstractController * Reload an entry. * Refetch content from the website and make it readable again. * - * @Route("/reload/{id}", name="reload_entry", methods={"GET"}, requirements={"id" = "\d+"}) - * @IsGranted("RELOAD", subject="entry") - * * @return RedirectResponse */ + #[Route(path: '/reload/{id}', name: 'reload_entry', methods: ['GET'], requirements: ['id' => '\d+'])] + #[IsGranted('RELOAD', subject: 'entry')] public function reloadAction(Entry $entry) { $this->updateEntry($entry, 'entry_reloaded'); @@ -445,11 +420,10 @@ class EntryController extends AbstractController /** * Changes read status for an entry. * - * @Route("/archive/{id}", name="archive_entry", methods={"GET"}, requirements={"id" = "\d+"}) - * @IsGranted("ARCHIVE", subject="entry") - * * @return RedirectResponse */ + #[Route(path: '/archive/{id}', name: 'archive_entry', methods: ['GET'], requirements: ['id' => '\d+'])] + #[IsGranted('ARCHIVE', subject: 'entry')] public function toggleArchiveAction(Request $request, Entry $entry) { $entry->toggleArchive(); @@ -473,11 +447,10 @@ class EntryController extends AbstractController /** * Changes starred status for an entry. * - * @Route("/star/{id}", name="star_entry", methods={"GET"}, requirements={"id" = "\d+"}) - * @IsGranted("STAR", subject="entry") - * * @return RedirectResponse */ + #[Route(path: '/star/{id}', name: 'star_entry', methods: ['GET'], requirements: ['id' => '\d+'])] + #[IsGranted('STAR', subject: 'entry')] public function toggleStarAction(Request $request, Entry $entry) { $entry->toggleStar(); @@ -502,11 +475,10 @@ class EntryController extends AbstractController /** * Deletes entry and redirect to the homepage or the last viewed page. * - * @Route("/delete/{id}", name="delete_entry", methods={"GET"}, requirements={"id" = "\d+"}) - * @IsGranted("DELETE", subject="entry") - * * @return RedirectResponse */ + #[Route(path: '/delete/{id}', name: 'delete_entry', methods: ['GET'], requirements: ['id' => '\d+'])] + #[IsGranted('DELETE', subject: 'entry')] public function deleteEntryAction(Request $request, Entry $entry) { // generates the view url for this entry to check for redirection later @@ -539,11 +511,10 @@ class EntryController extends AbstractController /** * Get public URL for entry (and generate it if necessary). * - * @Route("/share/{id}", name="share", methods={"GET"}, requirements={"id" = "\d+"}) - * @IsGranted("SHARE", subject="entry") - * * @return Response */ + #[Route(path: '/share/{id}', name: 'share', methods: ['GET'], requirements: ['id' => '\d+'])] + #[IsGranted('SHARE', subject: 'entry')] public function shareAction(Entry $entry) { if (null === $entry->getUid()) { @@ -561,11 +532,10 @@ class EntryController extends AbstractController /** * Disable public sharing for an entry. * - * @Route("/share/delete/{id}", name="delete_share", methods={"GET"}, requirements={"id" = "\d+"}) - * @IsGranted("UNSHARE", subject="entry") - * * @return Response */ + #[Route(path: '/share/delete/{id}', name: 'delete_share', methods: ['GET'], requirements: ['id' => '\d+'])] + #[IsGranted('UNSHARE', subject: 'entry')] public function deleteShareAction(Entry $entry) { $entry->cleanUid(); @@ -581,12 +551,11 @@ class EntryController extends AbstractController /** * Ability to view a content publicly. * - * @Route("/share/{uid}", name="share_entry", methods={"GET"}, requirements={"uid" = ".+"}) - * @Cache(maxage="25200", smaxage="25200", public=true) - * @IsGranted("PUBLIC_ACCESS") - * * @return Response */ + #[Route(path: '/share/{uid}', name: 'share_entry', methods: ['GET'], requirements: ['uid' => '.+'])] + #[Cache(maxage: 25200, smaxage: 25200, public: true)] + #[IsGranted('PUBLIC_ACCESS')] public function shareEntryAction(Entry $entry, Config $craueConfig) { if (!$craueConfig->get('share_public')) { @@ -604,11 +573,10 @@ class EntryController extends AbstractController * * @param int $page * - * @Route("/domain/{id}/{page}", name="same_domain", methods={"GET"}, requirements={"id" = "\d+"}, defaults={"page" = 1}) - * @IsGranted("LIST_ENTRIES") - * * @return Response */ + #[Route(path: '/domain/{id}/{page}', name: 'same_domain', methods: ['GET'], requirements: ['id' => '\d+'], defaults: ['page' => 1])] + #[IsGranted('LIST_ENTRIES')] public function getSameDomainEntries(Request $request, $page = 1) { return $this->showEntries('same-domain', $request, $page); @@ -625,8 +593,8 @@ class EntryController extends AbstractController */ private function showEntries($type, Request $request, $page) { - $searchTerm = (isset($request->query->all('search_entry')['term']) ? trim($request->query->all('search_entry')['term']) : ''); - $currentRoute = (null !== $request->query->get('currentRoute') ? $request->query->get('currentRoute') : ''); + $searchTerm = (isset($request->query->all('search_entry')['term']) ? trim((string) $request->query->all('search_entry')['term']) : ''); + $currentRoute = $request->query->get('currentRoute') ?? ''; $currentEntryId = $request->attributes->getInt('id'); $formOptions = []; @@ -679,7 +647,7 @@ class EntryController extends AbstractController try { $entries->setCurrentPage($page); - } catch (OutOfRangeCurrentPageException $e) { + } catch (OutOfRangeCurrentPageException) { if ($page > 1) { return $this->redirect($this->generateUrl($type, ['page' => $entries->getNbPages()]), 302); } @@ -708,7 +676,7 @@ class EntryController extends AbstractController try { $this->contentProxy->updateEntry($entry, $entry->getUrl()); - } catch (\Exception $e) { + } catch (\Exception) { // $this->logger->error('Error while saving an entry', [ // 'exception' => $e, // 'entry' => $entry, diff --git a/src/Controller/ExportController.php b/src/Controller/ExportController.php index ce622a956..af4f813f8 100644 --- a/src/Controller/ExportController.php +++ b/src/Controller/ExportController.php @@ -21,14 +21,10 @@ class ExportController extends AbstractController /** * Gets one entry content. * - * @Route("/export/{entry}.{format}", name="export_entry", methods={"GET"}, requirements={ - * "format": "epub|pdf|json|xml|txt|csv|md", - * "entry": "\d+" - * }) - * @IsGranted("EXPORT", subject="entry") - * * @return Response */ + #[Route(path: '/export/{entry}.{format}', name: 'export_entry', methods: ['GET'], requirements: ['format' => 'epub|pdf|json|xml|txt|csv|md', 'entry' => '\d+'])] + #[IsGranted('EXPORT', subject: 'entry')] public function downloadEntryAction(Request $request, EntryRepository $entryRepository, EntriesExport $entriesExport, string $format, Entry $entry) { try { @@ -45,14 +41,10 @@ class ExportController extends AbstractController /** * Export all entries for current user. * - * @Route("/export/{category}.{format}", name="export_entries", methods={"GET"}, requirements={ - * "format": "epub|pdf|json|xml|txt|csv|md", - * "category": "all|unread|starred|archive|tag_entries|untagged|search|annotated|same_domain" - * }) - * @IsGranted("EXPORT_ENTRIES") - * * @return Response */ + #[Route(path: '/export/{category}.{format}', name: 'export_entries', methods: ['GET'], requirements: ['format' => 'epub|pdf|json|xml|txt|csv|md', 'category' => 'all|unread|starred|archive|tag_entries|untagged|search|annotated|same_domain'])] + #[IsGranted('EXPORT_ENTRIES')] public function downloadEntriesAction(Request $request, EntryRepository $entryRepository, TagRepository $tagRepository, EntriesExport $entriesExport, string $format, string $category, int $entry = 0) { $method = ucfirst($category); @@ -77,8 +69,8 @@ class ExportController extends AbstractController $title = 'Tag ' . $tag->getLabel(); } elseif ('search' === $category) { - $searchTerm = (isset($request->query->all('search_entry')['term']) ? $request->query->all('search_entry')['term'] : ''); - $currentRoute = (null !== $request->query->get('currentRoute') ? $request->query->get('currentRoute') : ''); + $searchTerm = $request->query->all('search_entry')['term'] ?? ''; + $currentRoute = $request->query->get('currentRoute') ?? ''; $entries = $entryRepository->getBuilderForSearchByUser( $this->getUser()->getId(), diff --git a/src/Controller/FeedController.php b/src/Controller/FeedController.php index f650274f3..cd5adf24f 100644 --- a/src/Controller/FeedController.php +++ b/src/Controller/FeedController.php @@ -20,23 +20,19 @@ use Wallabag\Repository\EntryRepository; class FeedController extends AbstractController { - private EntryRepository $entryRepository; - - public function __construct(EntryRepository $entryRepository) - { - $this->entryRepository = $entryRepository; + public function __construct( + private readonly EntryRepository $entryRepository, + ) { } /** * Shows unread entries for current user. * - * @Route("/feed/{username}/{token}/unread/{page}", name="unread_feed", methods={"GET"}, defaults={"page"=1, "_format"="xml"}) - * @IsGranted("PUBLIC_ACCESS") - * - * @ParamConverter("user", class="Wallabag\Entity\User", converter="username_feed_token_converter") - * * @return Response */ + #[Route(path: '/feed/{username}/{token}/unread/{page}', name: 'unread_feed', methods: ['GET'], defaults: ['page' => 1, '_format' => 'xml'])] + #[IsGranted('PUBLIC_ACCESS')] + #[ParamConverter('user', class: User::class, converter: 'username_feed_token_converter')] public function showUnreadFeedAction(User $user, $page) { return $this->showEntries('unread', $user, $page); @@ -45,13 +41,11 @@ class FeedController extends AbstractController /** * Shows read entries for current user. * - * @Route("/feed/{username}/{token}/archive/{page}", name="archive_feed", methods={"GET"}, defaults={"page"=1, "_format"="xml"}) - * @IsGranted("PUBLIC_ACCESS") - * - * @ParamConverter("user", class="Wallabag\Entity\User", converter="username_feed_token_converter") - * * @return Response */ + #[Route(path: '/feed/{username}/{token}/archive/{page}', name: 'archive_feed', methods: ['GET'], defaults: ['page' => 1, '_format' => 'xml'])] + #[IsGranted('PUBLIC_ACCESS')] + #[ParamConverter('user', class: User::class, converter: 'username_feed_token_converter')] public function showArchiveFeedAction(User $user, $page) { return $this->showEntries('archive', $user, $page); @@ -60,13 +54,11 @@ class FeedController extends AbstractController /** * Shows starred entries for current user. * - * @Route("/feed/{username}/{token}/starred/{page}", name="starred_feed", methods={"GET"}, defaults={"page"=1, "_format"="xml"}) - * @IsGranted("PUBLIC_ACCESS") - * - * @ParamConverter("user", class="Wallabag\Entity\User", converter="username_feed_token_converter") - * * @return Response */ + #[Route(path: '/feed/{username}/{token}/starred/{page}', name: 'starred_feed', methods: ['GET'], defaults: ['page' => 1, '_format' => 'xml'])] + #[IsGranted('PUBLIC_ACCESS')] + #[ParamConverter('user', class: User::class, converter: 'username_feed_token_converter')] public function showStarredFeedAction(User $user, $page) { return $this->showEntries('starred', $user, $page); @@ -75,13 +67,11 @@ class FeedController extends AbstractController /** * Shows all entries for current user. * - * @Route("/feed/{username}/{token}/all/{page}", name="all_feed", methods={"GET"}, defaults={"page"=1, "_format"="xml"}) - * @IsGranted("PUBLIC_ACCESS") - * - * @ParamConverter("user", class="Wallabag\Entity\User", converter="username_feed_token_converter") - * * @return Response */ + #[Route(path: '/feed/{username}/{token}/all/{page}', name: 'all_feed', methods: ['GET'], defaults: ['page' => 1, '_format' => 'xml'])] + #[IsGranted('PUBLIC_ACCESS')] + #[ParamConverter('user', class: User::class, converter: 'username_feed_token_converter')] public function showAllFeedAction(User $user, $page) { return $this->showEntries('all', $user, $page); @@ -90,14 +80,12 @@ class FeedController extends AbstractController /** * Shows entries associated to a tag for current user. * - * @Route("/feed/{username}/{token}/tags/{slug}/{page}", name="tag_feed", methods={"GET"}, defaults={"page"=1, "_format"="xml"}) - * @IsGranted("PUBLIC_ACCESS") - * - * @ParamConverter("user", class="Wallabag\Entity\User", converter="username_feed_token_converter") - * @ParamConverter("tag", options={"mapping": {"slug": "slug"}}) - * * @return Response */ + #[Route(path: '/feed/{username}/{token}/tags/{slug}/{page}', name: 'tag_feed', methods: ['GET'], defaults: ['page' => 1, '_format' => 'xml'])] + #[IsGranted('PUBLIC_ACCESS')] + #[ParamConverter('user', class: User::class, converter: 'username_feed_token_converter')] + #[ParamConverter('tag', options: ['mapping' => ['slug' => 'slug']])] public function showTagsFeedAction(Request $request, User $user, Tag $tag, PreparePagerForEntries $preparePagerForEntries, $page) { $sort = $request->query->get('sort', 'created'); @@ -143,7 +131,7 @@ class FeedController extends AbstractController try { $entries->setCurrentPage($page); - } catch (OutOfRangeCurrentPageException $e) { + } catch (OutOfRangeCurrentPageException) { if ($page > 1) { return $this->redirect($url . '?page=' . $entries->getNbPages(), 302); } @@ -191,22 +179,13 @@ class FeedController extends AbstractController */ private function showEntries(string $type, User $user, $page = 1) { - switch ($type) { - case 'starred': - $qb = $this->entryRepository->getBuilderForStarredByUser($user->getId()); - break; - case 'archive': - $qb = $this->entryRepository->getBuilderForArchiveByUser($user->getId()); - break; - case 'unread': - $qb = $this->entryRepository->getBuilderForUnreadByUser($user->getId()); - break; - case 'all': - $qb = $this->entryRepository->getBuilderForAllByUser($user->getId()); - break; - default: - throw new \InvalidArgumentException(\sprintf('Type "%s" is not implemented.', $type)); - } + $qb = match ($type) { + 'starred' => $this->entryRepository->getBuilderForStarredByUser($user->getId()), + 'archive' => $this->entryRepository->getBuilderForArchiveByUser($user->getId()), + 'unread' => $this->entryRepository->getBuilderForUnreadByUser($user->getId()), + 'all' => $this->entryRepository->getBuilderForAllByUser($user->getId()), + default => throw new \InvalidArgumentException(\sprintf('Type "%s" is not implemented.', $type)), + }; $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); $entries = new Pagerfanta($pagerAdapter); @@ -225,7 +204,7 @@ class FeedController extends AbstractController try { $entries->setCurrentPage((int) $page); - } catch (OutOfRangeCurrentPageException $e) { + } catch (OutOfRangeCurrentPageException) { if ($page > 1) { return $this->redirect($url . '/' . $entries->getNbPages()); } diff --git a/src/Controller/IgnoreOriginInstanceRuleController.php b/src/Controller/IgnoreOriginInstanceRuleController.php index 12a3782c4..996d7c49f 100644 --- a/src/Controller/IgnoreOriginInstanceRuleController.php +++ b/src/Controller/IgnoreOriginInstanceRuleController.php @@ -20,21 +20,17 @@ use Wallabag\Repository\IgnoreOriginInstanceRuleRepository; */ class IgnoreOriginInstanceRuleController extends AbstractController { - private EntityManagerInterface $entityManager; - private TranslatorInterface $translator; - - public function __construct(EntityManagerInterface $entityManager, TranslatorInterface $translator) - { - $this->entityManager = $entityManager; - $this->translator = $translator; + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly TranslatorInterface $translator, + ) { } /** * Lists all IgnoreOriginInstanceRule entities. - * - * @Route("/ignore-origin-instance-rules", name="ignore_origin_instance_rules_index", methods={"GET"}) - * @IsGranted("LIST_IGNORE_ORIGIN_INSTANCE_RULES") */ + #[Route(path: '/ignore-origin-instance-rules', name: 'ignore_origin_instance_rules_index', methods: ['GET'])] + #[IsGranted('LIST_IGNORE_ORIGIN_INSTANCE_RULES')] public function indexAction(IgnoreOriginInstanceRuleRepository $repository) { $rules = $repository->findAll(); @@ -47,11 +43,10 @@ class IgnoreOriginInstanceRuleController extends AbstractController /** * Creates a new ignore origin instance rule entity. * - * @Route("/ignore-origin-instance-rules/new", name="ignore_origin_instance_rules_new", methods={"GET", "POST"}) - * @IsGranted("CREATE_IGNORE_ORIGIN_INSTANCE_RULES") - * * @return Response */ + #[Route(path: '/ignore-origin-instance-rules/new', name: 'ignore_origin_instance_rules_new', methods: ['GET', 'POST'])] + #[IsGranted('CREATE_IGNORE_ORIGIN_INSTANCE_RULES')] public function newAction(Request $request) { $ignoreOriginInstanceRule = new IgnoreOriginInstanceRule(); @@ -80,11 +75,10 @@ class IgnoreOriginInstanceRuleController extends AbstractController /** * Displays a form to edit an existing ignore origin instance rule entity. * - * @Route("/ignore-origin-instance-rules/{id}/edit", name="ignore_origin_instance_rules_edit", methods={"GET", "POST"}) - * @IsGranted("EDIT", subject="ignoreOriginInstanceRule") - * * @return Response */ + #[Route(path: '/ignore-origin-instance-rules/{id}/edit', name: 'ignore_origin_instance_rules_edit', methods: ['GET', 'POST'])] + #[IsGranted('EDIT', subject: 'ignoreOriginInstanceRule')] public function editAction(Request $request, IgnoreOriginInstanceRule $ignoreOriginInstanceRule) { $deleteForm = $this->createDeleteForm($ignoreOriginInstanceRule); @@ -113,11 +107,10 @@ class IgnoreOriginInstanceRuleController extends AbstractController /** * Deletes a site credential entity. * - * @Route("/ignore-origin-instance-rules/{id}", name="ignore_origin_instance_rules_delete", methods={"DELETE"}) - * @IsGranted("DELETE", subject="ignoreOriginInstanceRule") - * * @return RedirectResponse */ + #[Route(path: '/ignore-origin-instance-rules/{id}', name: 'ignore_origin_instance_rules_delete', methods: ['DELETE'])] + #[IsGranted('DELETE', subject: 'ignoreOriginInstanceRule')] public function deleteAction(Request $request, IgnoreOriginInstanceRule $ignoreOriginInstanceRule) { $form = $this->createDeleteForm($ignoreOriginInstanceRule); diff --git a/src/Controller/Import/BrowserController.php b/src/Controller/Import/BrowserController.php index 8cf1bd5ab..3b897248b 100644 --- a/src/Controller/Import/BrowserController.php +++ b/src/Controller/Import/BrowserController.php @@ -14,11 +14,10 @@ use Wallabag\Import\ImportInterface; abstract class BrowserController extends AbstractController { /** - * @Route("/import/browser", name="import_browser", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - * * @return Response */ + #[Route(path: '/import/browser', name: 'import_browser', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, TranslatorInterface $translator) { $form = $this->createForm(UploadImportType::class); diff --git a/src/Controller/Import/ChromeController.php b/src/Controller/Import/ChromeController.php index 79a769ca9..0283cdee4 100644 --- a/src/Controller/Import/ChromeController.php +++ b/src/Controller/Import/ChromeController.php @@ -13,23 +13,16 @@ use Wallabag\Redis\Producer as RedisProducer; class ChromeController extends BrowserController { - private ChromeImport $chromeImport; - private Config $craueConfig; - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(ChromeImport $chromeImport, Config $craueConfig, RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->chromeImport = $chromeImport; - $this->craueConfig = $craueConfig; - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly ChromeImport $chromeImport, + private readonly Config $craueConfig, + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/chrome", name="import_chrome", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/chrome', name: 'import_chrome', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, TranslatorInterface $translator) { return parent::indexAction($request, $translator); diff --git a/src/Controller/Import/DeliciousController.php b/src/Controller/Import/DeliciousController.php index f07011c80..2caa6bdc1 100644 --- a/src/Controller/Import/DeliciousController.php +++ b/src/Controller/Import/DeliciousController.php @@ -15,19 +15,14 @@ use Wallabag\Redis\Producer as RedisProducer; class DeliciousController extends AbstractController { - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/delicious", name="import_delicious", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/delicious', name: 'import_delicious', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, DeliciousImport $delicious, Config $craueConfig, TranslatorInterface $translator) { $form = $this->createForm(UploadImportType::class); diff --git a/src/Controller/Import/ElcuratorController.php b/src/Controller/Import/ElcuratorController.php index 429b07e3a..4132f01d4 100644 --- a/src/Controller/Import/ElcuratorController.php +++ b/src/Controller/Import/ElcuratorController.php @@ -13,23 +13,16 @@ use Wallabag\Redis\Producer as RedisProducer; class ElcuratorController extends WallabagController { - private ElcuratorImport $elcuratorImport; - private Config $craueConfig; - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(ElcuratorImport $elcuratorImport, Config $craueConfig, RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->elcuratorImport = $elcuratorImport; - $this->craueConfig = $craueConfig; - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly ElcuratorImport $elcuratorImport, + private readonly Config $craueConfig, + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/elcurator", name="import_elcurator", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/elcurator', name: 'import_elcurator', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, TranslatorInterface $translator) { return parent::indexAction($request, $translator); diff --git a/src/Controller/Import/FirefoxController.php b/src/Controller/Import/FirefoxController.php index 0e6656611..d3c6ad75d 100644 --- a/src/Controller/Import/FirefoxController.php +++ b/src/Controller/Import/FirefoxController.php @@ -13,23 +13,16 @@ use Wallabag\Redis\Producer as RedisProducer; class FirefoxController extends BrowserController { - private FirefoxImport $firefoxImport; - private Config $craueConfig; - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(FirefoxImport $firefoxImport, Config $craueConfig, RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->firefoxImport = $firefoxImport; - $this->craueConfig = $craueConfig; - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly FirefoxImport $firefoxImport, + private readonly Config $craueConfig, + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/firefox", name="import_firefox", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/firefox', name: 'import_firefox', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, TranslatorInterface $translator) { return parent::indexAction($request, $translator); diff --git a/src/Controller/Import/HtmlController.php b/src/Controller/Import/HtmlController.php index a8e24a892..c55e114e1 100644 --- a/src/Controller/Import/HtmlController.php +++ b/src/Controller/Import/HtmlController.php @@ -14,11 +14,10 @@ use Wallabag\Import\ImportInterface; abstract class HtmlController extends AbstractController { /** - * @Route("/import/html", name="import_html", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - * * @return Response */ + #[Route(path: '/import/html', name: 'import_html', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, TranslatorInterface $translator) { $form = $this->createForm(UploadImportType::class); diff --git a/src/Controller/Import/ImportController.php b/src/Controller/Import/ImportController.php index 5dc35418c..24ae654c0 100644 --- a/src/Controller/Import/ImportController.php +++ b/src/Controller/Import/ImportController.php @@ -13,19 +13,14 @@ use Wallabag\Import\ImportChain; class ImportController extends AbstractController { - private RabbitMQConsumerTotalProxy $rabbitMQConsumerTotalProxy; - private Client $redisClient; - - public function __construct(RabbitMQConsumerTotalProxy $rabbitMQConsumerTotalProxy, Client $redisClient) - { - $this->rabbitMQConsumerTotalProxy = $rabbitMQConsumerTotalProxy; - $this->redisClient = $redisClient; + public function __construct( + private readonly RabbitMQConsumerTotalProxy $rabbitMQConsumerTotalProxy, + private readonly Client $redisClient, + ) { } - /** - * @Route("/import/", name="import", methods={"GET"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/', name: 'import', methods: ['GET'])] + #[IsGranted('IMPORT_ENTRIES')] public function importAction(ImportChain $importChain) { return $this->render('Import/index.html.twig', [ @@ -65,7 +60,7 @@ class ImportController extends AbstractController + $this->rabbitMQConsumerTotalProxy->getTotalMessage('pocket_html') + $this->rabbitMQConsumerTotalProxy->getTotalMessage('omnivore') ; - } catch (\Exception $e) { + } catch (\Exception) { $rabbitNotInstalled = true; } } elseif ($craueConfig->get('import_with_redis')) { @@ -84,7 +79,7 @@ class ImportController extends AbstractController + $this->redisClient->llen('wallabag.import.pocket_html') + $this->redisClient->llen('wallabag.import.omnivore') ; - } catch (\Exception $e) { + } catch (\Exception) { $redisNotInstalled = true; } } diff --git a/src/Controller/Import/InstapaperController.php b/src/Controller/Import/InstapaperController.php index 90e1a943d..7edb4a9e7 100644 --- a/src/Controller/Import/InstapaperController.php +++ b/src/Controller/Import/InstapaperController.php @@ -15,19 +15,14 @@ use Wallabag\Redis\Producer as RedisProducer; class InstapaperController extends AbstractController { - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/instapaper", name="import_instapaper", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/instapaper', name: 'import_instapaper', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, InstapaperImport $instapaper, Config $craueConfig, TranslatorInterface $translator) { $form = $this->createForm(UploadImportType::class); diff --git a/src/Controller/Import/OmnivoreController.php b/src/Controller/Import/OmnivoreController.php index 33be27720..1796cb4ab 100644 --- a/src/Controller/Import/OmnivoreController.php +++ b/src/Controller/Import/OmnivoreController.php @@ -15,19 +15,14 @@ use Wallabag\Redis\Producer as RedisProducer; class OmnivoreController extends AbstractController { - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/omnivore", name="import_omnivore", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/omnivore', name: 'import_omnivore', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, OmnivoreImport $omnivore, Config $craueConfig, TranslatorInterface $translator) { $form = $this->createForm(UploadImportType::class); diff --git a/src/Controller/Import/PinboardController.php b/src/Controller/Import/PinboardController.php index b99d2e4d9..437faac83 100644 --- a/src/Controller/Import/PinboardController.php +++ b/src/Controller/Import/PinboardController.php @@ -15,19 +15,14 @@ use Wallabag\Redis\Producer as RedisProducer; class PinboardController extends AbstractController { - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/pinboard", name="import_pinboard", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/pinboard', name: 'import_pinboard', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, PinboardImport $pinboard, Config $craueConfig, TranslatorInterface $translator) { $form = $this->createForm(UploadImportType::class); diff --git a/src/Controller/Import/PocketController.php b/src/Controller/Import/PocketController.php index f2ad34c35..2970f5472 100644 --- a/src/Controller/Import/PocketController.php +++ b/src/Controller/Import/PocketController.php @@ -17,23 +17,16 @@ use Wallabag\Redis\Producer as RedisProducer; class PocketController extends AbstractController { - private Config $craueConfig; - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - private SessionInterface $session; - - public function __construct(Config $craueConfig, RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer, SessionInterface $session) - { - $this->craueConfig = $craueConfig; - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; - $this->session = $session; + public function __construct( + private readonly Config $craueConfig, + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + private readonly SessionInterface $session, + ) { } - /** - * @Route("/import/pocket", name="import_pocket", methods={"GET"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/pocket', name: 'import_pocket', methods: ['GET'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(PocketImport $pocketImport) { $pocket = $this->getPocketImportService($pocketImport); @@ -52,10 +45,8 @@ class PocketController extends AbstractController ]); } - /** - * @Route("/import/pocket/auth", name="import_pocket_auth", methods={"POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/pocket/auth', name: 'import_pocket_auth', methods: ['POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function authAction(Request $request, PocketImport $pocketImport) { $requestToken = $this->getPocketImportService($pocketImport) @@ -83,10 +74,8 @@ class PocketController extends AbstractController ); } - /** - * @Route("/import/pocket/callback", name="import_pocket_callback", methods={"GET"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/pocket/callback', name: 'import_pocket_callback', methods: ['GET'])] + #[IsGranted('IMPORT_ENTRIES')] public function callbackAction(PocketImport $pocketImport, TranslatorInterface $translator) { $message = 'flashes.import.notice.failed'; diff --git a/src/Controller/Import/PocketHtmlController.php b/src/Controller/Import/PocketHtmlController.php index ea3555ddd..00f6b7b7d 100644 --- a/src/Controller/Import/PocketHtmlController.php +++ b/src/Controller/Import/PocketHtmlController.php @@ -13,23 +13,16 @@ use Wallabag\Redis\Producer as RedisProducer; class PocketHtmlController extends HtmlController { - private PocketHtmlImport $pocketHtmlImport; - private Config $craueConfig; - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(PocketHtmlImport $pocketHtmlImport, Config $craueConfig, RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->pocketHtmlImport = $pocketHtmlImport; - $this->craueConfig = $craueConfig; - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly PocketHtmlImport $pocketHtmlImport, + private readonly Config $craueConfig, + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/pocket_html", name="import_pocket_html", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/pocket_html', name: 'import_pocket_html', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, TranslatorInterface $translator) { return parent::indexAction($request, $translator); diff --git a/src/Controller/Import/ReadabilityController.php b/src/Controller/Import/ReadabilityController.php index 584ffc67d..6409f5d05 100644 --- a/src/Controller/Import/ReadabilityController.php +++ b/src/Controller/Import/ReadabilityController.php @@ -15,19 +15,14 @@ use Wallabag\Redis\Producer as RedisProducer; class ReadabilityController extends AbstractController { - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/readability", name="import_readability", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/readability', name: 'import_readability', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, ReadabilityImport $readability, Config $craueConfig, TranslatorInterface $translator) { $form = $this->createForm(UploadImportType::class); diff --git a/src/Controller/Import/ShaarliController.php b/src/Controller/Import/ShaarliController.php index 91d6fd21b..8be50a180 100644 --- a/src/Controller/Import/ShaarliController.php +++ b/src/Controller/Import/ShaarliController.php @@ -13,23 +13,16 @@ use Wallabag\Redis\Producer as RedisProducer; class ShaarliController extends HtmlController { - private ShaarliImport $shaarliImport; - private Config $craueConfig; - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(ShaarliImport $shaarliImport, Config $craueConfig, RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->shaarliImport = $shaarliImport; - $this->craueConfig = $craueConfig; - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly ShaarliImport $shaarliImport, + private readonly Config $craueConfig, + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/shaarli", name="import_shaarli", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/shaarli', name: 'import_shaarli', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, TranslatorInterface $translator) { return parent::indexAction($request, $translator); diff --git a/src/Controller/Import/WallabagV1Controller.php b/src/Controller/Import/WallabagV1Controller.php index de7d1b9b5..7537db124 100644 --- a/src/Controller/Import/WallabagV1Controller.php +++ b/src/Controller/Import/WallabagV1Controller.php @@ -13,23 +13,16 @@ use Wallabag\Redis\Producer as RedisProducer; class WallabagV1Controller extends WallabagController { - private WallabagV1Import $wallabagImport; - private Config $craueConfig; - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(WallabagV1Import $wallabagImport, Config $craueConfig, RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->wallabagImport = $wallabagImport; - $this->craueConfig = $craueConfig; - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly WallabagV1Import $wallabagImport, + private readonly Config $craueConfig, + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/wallabag-v1", name="import_wallabag_v1", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/wallabag-v1', name: 'import_wallabag_v1', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, TranslatorInterface $translator) { return parent::indexAction($request, $translator); diff --git a/src/Controller/Import/WallabagV2Controller.php b/src/Controller/Import/WallabagV2Controller.php index bdfa7dfe6..dee455336 100644 --- a/src/Controller/Import/WallabagV2Controller.php +++ b/src/Controller/Import/WallabagV2Controller.php @@ -13,23 +13,16 @@ use Wallabag\Redis\Producer as RedisProducer; class WallabagV2Controller extends WallabagController { - private WallabagV2Import $wallabagImport; - private Config $craueConfig; - private RabbitMqProducer $rabbitMqProducer; - private RedisProducer $redisProducer; - - public function __construct(WallabagV2Import $wallabagImport, Config $craueConfig, RabbitMqProducer $rabbitMqProducer, RedisProducer $redisProducer) - { - $this->wallabagImport = $wallabagImport; - $this->craueConfig = $craueConfig; - $this->rabbitMqProducer = $rabbitMqProducer; - $this->redisProducer = $redisProducer; + public function __construct( + private readonly WallabagV2Import $wallabagImport, + private readonly Config $craueConfig, + private readonly RabbitMqProducer $rabbitMqProducer, + private readonly RedisProducer $redisProducer, + ) { } - /** - * @Route("/import/wallabag-v2", name="import_wallabag_v2", methods={"GET", "POST"}) - * @IsGranted("IMPORT_ENTRIES") - */ + #[Route(path: '/import/wallabag-v2', name: 'import_wallabag_v2', methods: ['GET', 'POST'])] + #[IsGranted('IMPORT_ENTRIES')] public function indexAction(Request $request, TranslatorInterface $translator) { return parent::indexAction($request, $translator); diff --git a/src/Controller/SiteCredentialController.php b/src/Controller/SiteCredentialController.php index 9e90899eb..70f9af98e 100644 --- a/src/Controller/SiteCredentialController.php +++ b/src/Controller/SiteCredentialController.php @@ -23,25 +23,19 @@ use Wallabag\Repository\SiteCredentialRepository; */ class SiteCredentialController extends AbstractController { - private EntityManagerInterface $entityManager; - private TranslatorInterface $translator; - private CryptoProxy $cryptoProxy; - private Config $craueConfig; - - public function __construct(EntityManagerInterface $entityManager, TranslatorInterface $translator, CryptoProxy $cryptoProxy, Config $craueConfig) - { - $this->entityManager = $entityManager; - $this->translator = $translator; - $this->cryptoProxy = $cryptoProxy; - $this->craueConfig = $craueConfig; + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly TranslatorInterface $translator, + private readonly CryptoProxy $cryptoProxy, + private readonly Config $craueConfig, + ) { } /** * Lists all User entities. - * - * @Route("/site-credentials", name="site_credentials_index", methods={"GET"}) - * @IsGranted("LIST_SITE_CREDENTIALS") */ + #[Route(path: '/site-credentials', name: 'site_credentials_index', methods: ['GET'])] + #[IsGranted('LIST_SITE_CREDENTIALS')] public function indexAction(SiteCredentialRepository $repository) { $this->isSiteCredentialsEnabled(); @@ -56,11 +50,10 @@ class SiteCredentialController extends AbstractController /** * Creates a new site credential entity. * - * @Route("/site-credentials/new", name="site_credentials_new", methods={"GET", "POST"}) - * @IsGranted("CREATE_SITE_CREDENTIALS") - * * @return Response */ + #[Route(path: '/site-credentials/new', name: 'site_credentials_new', methods: ['GET', 'POST'])] + #[IsGranted('CREATE_SITE_CREDENTIALS')] public function newAction(Request $request) { $this->isSiteCredentialsEnabled(); @@ -94,11 +87,10 @@ class SiteCredentialController extends AbstractController /** * Displays a form to edit an existing site credential entity. * - * @Route("/site-credentials/{id}/edit", name="site_credentials_edit", methods={"GET", "POST"}) - * @IsGranted("EDIT", subject="siteCredential") - * * @return Response */ + #[Route(path: '/site-credentials/{id}/edit', name: 'site_credentials_edit', methods: ['GET', 'POST'])] + #[IsGranted('EDIT', subject: 'siteCredential')] public function editAction(Request $request, SiteCredential $siteCredential) { $this->isSiteCredentialsEnabled(); @@ -132,11 +124,10 @@ class SiteCredentialController extends AbstractController /** * Deletes a site credential entity. * - * @Route("/site-credentials/{id}", name="site_credentials_delete", methods={"DELETE"}) - * @IsGranted("DELETE", subject="siteCredential") - * * @return RedirectResponse */ + #[Route(path: '/site-credentials/{id}', name: 'site_credentials_delete', methods: ['DELETE'])] + #[IsGranted('DELETE', subject: 'siteCredential')] public function deleteAction(Request $request, SiteCredential $siteCredential) { $this->isSiteCredentialsEnabled(); diff --git a/src/Controller/StaticController.php b/src/Controller/StaticController.php index 2411ef849..5c7bb06e3 100644 --- a/src/Controller/StaticController.php +++ b/src/Controller/StaticController.php @@ -7,10 +7,8 @@ use Symfony\Component\Routing\Annotation\Route; class StaticController extends AbstractController { - /** - * @Route("/howto", name="howto", methods={"GET"}) - * @IsGranted("IS_AUTHENTICATED_FULLY") - */ + #[Route(path: '/howto', name: 'howto', methods: ['GET'])] + #[IsGranted('IS_AUTHENTICATED_FULLY')] public function howtoAction() { $addonsUrl = $this->getParameter('addons_url'); @@ -23,10 +21,8 @@ class StaticController extends AbstractController ); } - /** - * @Route("/about", name="about", methods={"GET"}) - * @IsGranted("IS_AUTHENTICATED_FULLY") - */ + #[Route(path: '/about', name: 'about', methods: ['GET'])] + #[IsGranted('IS_AUTHENTICATED_FULLY')] public function aboutAction() { return $this->render( @@ -38,10 +34,8 @@ class StaticController extends AbstractController ); } - /** - * @Route("/quickstart", name="quickstart", methods={"GET"}) - * @IsGranted("IS_AUTHENTICATED_FULLY") - */ + #[Route(path: '/quickstart', name: 'quickstart', methods: ['GET'])] + #[IsGranted('IS_AUTHENTICATED_FULLY')] public function quickstartAction() { return $this->render( diff --git a/src/Controller/TagController.php b/src/Controller/TagController.php index 125cfdbba..38e9173ce 100644 --- a/src/Controller/TagController.php +++ b/src/Controller/TagController.php @@ -25,35 +25,29 @@ use Wallabag\Repository\TagRepository; class TagController extends AbstractController { - private EntityManagerInterface $entityManager; - private TagsAssigner $tagsAssigner; - private Redirect $redirectHelper; - private Security $security; - - public function __construct(EntityManagerInterface $entityManager, TagsAssigner $tagsAssigner, Redirect $redirectHelper, Security $security) - { - $this->entityManager = $entityManager; - $this->tagsAssigner = $tagsAssigner; - $this->redirectHelper = $redirectHelper; - $this->security = $security; + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly TagsAssigner $tagsAssigner, + private readonly Redirect $redirectHelper, + private readonly Security $security, + ) { } /** - * @Route("/new-tag/{entry}", name="new_tag", methods={"POST"}, requirements={"entry" = "\d+"}) - * @IsGranted("TAG", subject="entry") - * * @return Response */ + #[Route(path: '/new-tag/{entry}', name: 'new_tag', methods: ['POST'], requirements: ['entry' => '\d+'])] + #[IsGranted('TAG', subject: 'entry')] public function addTagFormAction(Request $request, Entry $entry, TranslatorInterface $translator) { $form = $this->createForm(NewTagType::class, new Tag()); $form->handleRequest($request); $tags = $form->get('label')->getData() ?? ''; - $tagsExploded = explode(',', $tags); + $tagsExploded = explode(',', (string) $tags); // avoid too much tag to be added - if (\count($tagsExploded) >= NewTagType::MAX_TAGS || \strlen($tags) >= NewTagType::MAX_LENGTH) { + if (\count($tagsExploded) >= NewTagType::MAX_TAGS || \strlen((string) $tags) >= NewTagType::MAX_LENGTH) { $message = $translator->trans('flashes.tag.notice.too_much_tags', [ '%tags%' => NewTagType::MAX_TAGS, '%characters%' => NewTagType::MAX_LENGTH, @@ -89,11 +83,10 @@ class TagController extends AbstractController /** * Removes tag from entry. * - * @Route("/remove-tag/{entry}/{tag}", name="remove_tag", methods={"GET"}, requirements={"entry" = "\d+", "tag" = "\d+"}) - * @IsGranted("UNTAG", subject="entry") - * * @return Response */ + #[Route(path: '/remove-tag/{entry}/{tag}', name: 'remove_tag', methods: ['GET'], requirements: ['entry' => '\d+', 'tag' => '\d+'])] + #[IsGranted('UNTAG', subject: 'entry')] public function removeTagFromEntry(Request $request, Entry $entry, Tag $tag) { $entry->removeTag($tag); @@ -113,11 +106,10 @@ class TagController extends AbstractController /** * Shows tags for current user. * - * @Route("/tag/list", name="tag", methods={"GET"}) - * @IsGranted("LIST_TAGS") - * * @return Response */ + #[Route(path: '/tag/list', name: 'tag', methods: ['GET'])] + #[IsGranted('LIST_TAGS')] public function showTagAction(TagRepository $tagRepository, EntryRepository $entryRepository) { $allTagsWithNbEntries = $tagRepository->findAllTagsWithNbEntries($this->getUser()->getId()); @@ -138,13 +130,12 @@ class TagController extends AbstractController /** * @param int $page * - * @Route("/tag/list/{slug}/{page}", name="tag_entries", methods={"GET"}, defaults={"page" = "1"}) - * @ParamConverter("tag", options={"mapping": {"slug": "slug"}}) - * @IsGranted("LIST_ENTRIES") - * @IsGranted("VIEW", subject="tag") - * * @return Response */ + #[Route(path: '/tag/list/{slug}/{page}', name: 'tag_entries', methods: ['GET'], defaults: ['page' => '1'])] + #[ParamConverter('tag', options: ['mapping' => ['slug' => 'slug']])] + #[IsGranted('LIST_ENTRIES')] + #[IsGranted('VIEW', subject: 'tag')] public function showEntriesForTagAction(Tag $tag, EntryRepository $entryRepository, PreparePagerForEntries $preparePagerForEntries, $page, Request $request) { $entriesByTag = $entryRepository->findAllByTagId( @@ -158,7 +149,7 @@ class TagController extends AbstractController try { $entries->setCurrentPage($page); - } catch (OutOfRangeCurrentPageException $e) { + } catch (OutOfRangeCurrentPageException) { if ($page > 1) { return $this->redirect($this->generateUrl($request->attributes->get('_route'), [ 'slug' => $tag->getSlug(), @@ -179,12 +170,11 @@ class TagController extends AbstractController * Rename a given tag with a new label * Create a new tag with the new name and drop the old one. * - * @Route("/tag/rename/{slug}", name="tag_rename", methods={"POST"}) - * @ParamConverter("tag", options={"mapping": {"slug": "slug"}}) - * @IsGranted("EDIT", subject="tag") - * * @return Response */ + #[Route(path: '/tag/rename/{slug}', name: 'tag_rename', methods: ['POST'])] + #[ParamConverter('tag', options: ['mapping' => ['slug' => 'slug']])] + #[IsGranted('EDIT', subject: 'tag')] public function renameTagAction(Tag $tag, Request $request, TagRepository $tagRepository, EntryRepository $entryRepository) { $form = $this->createForm(RenameTagType::class, new Tag()); @@ -233,11 +223,10 @@ class TagController extends AbstractController /** * Tag search results with the current search term. * - * @Route("/tag/search/{filter}", name="tag_this_search", methods={"GET"}) - * @IsGranted("CREATE_TAGS") - * * @return Response */ + #[Route(path: '/tag/search/{filter}', name: 'tag_this_search', methods: ['GET'])] + #[IsGranted('CREATE_TAGS')] public function tagThisSearchAction($filter, Request $request, EntryRepository $entryRepository) { $currentRoute = $request->query->has('currentRoute') ? $request->query->get('currentRoute') : ''; @@ -255,7 +244,7 @@ class TagController extends AbstractController // check to avoid duplicate tags creation foreach ($this->entityManager->getUnitOfWork()->getScheduledEntityInsertions() as $entity) { - if ($entity instanceof Tag && strtolower($entity->getLabel()) === strtolower($filter)) { + if ($entity instanceof Tag && strtolower($entity->getLabel()) === strtolower((string) $filter)) { continue 2; } $this->entityManager->persist($entry); @@ -269,12 +258,11 @@ class TagController extends AbstractController /** * Delete a given tag for the current user. * - * @Route("/tag/delete/{slug}", name="tag_delete", methods={"GET"}) - * @ParamConverter("tag", options={"mapping": {"slug": "slug"}}) - * @IsGranted("DELETE", subject="tag") - * * @return Response */ + #[Route(path: '/tag/delete/{slug}', name: 'tag_delete', methods: ['GET'])] + #[ParamConverter('tag', options: ['mapping' => ['slug' => 'slug']])] + #[IsGranted('DELETE', subject: 'tag')] public function removeTagAction(Tag $tag, Request $request, EntryRepository $entryRepository) { foreach ($tag->getEntriesByUserId($this->getUser()->getId()) as $entry) { diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 5be29a6cc..9f576b7dc 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -29,21 +29,17 @@ use Wallabag\Repository\UserRepository; */ class UserController extends AbstractController { - private EntityManagerInterface $entityManager; - private TranslatorInterface $translator; - - public function __construct(EntityManagerInterface $entityManager, TranslatorInterface $translator) - { - $this->entityManager = $entityManager; - $this->translator = $translator; + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly TranslatorInterface $translator, + ) { } /** * Creates a new User entity. - * - * @Route("/users/new", name="user_new", methods={"GET", "POST"}) - * @IsGranted("CREATE_USERS") */ + #[Route(path: '/users/new', name: 'user_new', methods: ['GET', 'POST'])] + #[IsGranted('CREATE_USERS')] public function newAction(Request $request, UserManagerInterface $userManager, EventDispatcherInterface $eventDispatcher) { $user = $userManager->createUser(); @@ -77,10 +73,9 @@ class UserController extends AbstractController /** * Displays a form to edit an existing User entity. - * - * @Route("/users/{id}/edit", name="user_edit", methods={"GET", "POST"}) - * @IsGranted("EDIT", subject="user") */ + #[Route(path: '/users/{id}/edit', name: 'user_edit', methods: ['GET', 'POST'])] + #[IsGranted('EDIT', subject: 'user')] public function editAction(Request $request, User $user, UserManagerInterface $userManager, GoogleAuthenticatorInterface $googleAuthenticator) { $deleteForm = $this->createDeleteForm($user); @@ -120,10 +115,9 @@ class UserController extends AbstractController /** * Deletes a User entity. - * - * @Route("/users/{id}", name="user_delete", methods={"DELETE"}) - * @IsGranted("DELETE", subject="user") */ + #[Route(path: '/users/{id}', name: 'user_delete', methods: ['DELETE'])] + #[IsGranted('DELETE', subject: 'user')] public function deleteAction(Request $request, User $user) { $form = $this->createDeleteForm($user); @@ -145,14 +139,10 @@ class UserController extends AbstractController /** * @param int $page * - * @Route("/users/list/{page}", name="user_index", methods={"GET"}, defaults={"page" = 1}) - * @IsGranted("LIST_USERS") - * - * Default parameter for page is hardcoded (in duplication of the defaults from the Route) - * because this controller is also called inside the layout template without any page as argument - * * @return Response */ + #[Route(path: '/users/list/{page}', name: 'user_index', methods: ['GET'], defaults: ['page' => 1])] + #[IsGranted('LIST_USERS')] // Default parameter for page is hardcoded (in duplication of the defaults from the Route) public function searchFormAction(Request $request, UserRepository $userRepository, $page = 1) { $qb = $userRepository->createQueryBuilder('u'); @@ -161,7 +151,7 @@ class UserController extends AbstractController $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $searchTerm = (isset($request->query->all('search_user')['term']) ? $request->query->all('search_user')['term'] : ''); + $searchTerm = $request->query->all('search_user')['term'] ?? ''; $qb = $userRepository->getQueryBuilderForSearch($searchTerm); } @@ -172,7 +162,7 @@ class UserController extends AbstractController try { $pagerFanta->setCurrentPage($page); - } catch (OutOfRangeCurrentPageException $e) { + } catch (OutOfRangeCurrentPageException) { if ($page > 1) { return $this->redirect($this->generateUrl('user_index', ['page' => $pagerFanta->getNbPages()]), 302); } diff --git a/src/Doctrine/JsonArrayType.php b/src/Doctrine/JsonArrayType.php index 8925c1201..0f2a80e58 100644 --- a/src/Doctrine/JsonArrayType.php +++ b/src/Doctrine/JsonArrayType.php @@ -22,7 +22,7 @@ class JsonArrayType extends JsonType $value = \is_resource($value) ? stream_get_contents($value) : $value; - return json_decode($value, true); + return json_decode((string) $value, true); } public function getName(): string diff --git a/src/Doctrine/MigrationFactoryDecorator.php b/src/Doctrine/MigrationFactoryDecorator.php index 2872159f2..b99f31af0 100644 --- a/src/Doctrine/MigrationFactoryDecorator.php +++ b/src/Doctrine/MigrationFactoryDecorator.php @@ -10,17 +10,12 @@ use Doctrine\Migrations\Version\MigrationFactory; */ class MigrationFactoryDecorator implements MigrationFactory { - private MigrationFactory $migrationFactory; - private string $tablePrefix; - private array $defaultIgnoreOriginInstanceRules; - private string $fetchingErrorMessage; - - public function __construct(MigrationFactory $migrationFactory, string $tablePrefix, array $defaultIgnoreOriginInstanceRules, string $fetchingErrorMessage) - { - $this->migrationFactory = $migrationFactory; - $this->tablePrefix = $tablePrefix; - $this->defaultIgnoreOriginInstanceRules = $defaultIgnoreOriginInstanceRules; - $this->fetchingErrorMessage = $fetchingErrorMessage; + public function __construct( + private readonly MigrationFactory $migrationFactory, + private readonly string $tablePrefix, + private readonly array $defaultIgnoreOriginInstanceRules, + private readonly string $fetchingErrorMessage, + ) { } public function createVersion(string $migrationClassName): AbstractMigration diff --git a/src/Doctrine/WallabagMigration.php b/src/Doctrine/WallabagMigration.php index 60d0a026c..4fcb445e6 100644 --- a/src/Doctrine/WallabagMigration.php +++ b/src/Doctrine/WallabagMigration.php @@ -89,9 +89,7 @@ abstract class WallabagMigration extends AbstractMigration */ protected function generateIdentifierName(array $columnNames, string $prefix = ''): string { - $hash = implode('', array_map(static function ($column): string { - return dechex(crc32($column)); - }, $columnNames)); + $hash = implode('', array_map(static fn ($column): string => dechex(crc32($column)), $columnNames)); return strtoupper(substr($prefix . '_' . $hash, 0, $this->platform->getMaxIdentifierLength())); } diff --git a/src/Entity/Annotation.php b/src/Entity/Annotation.php index d816aac46..9c265c4d6 100644 --- a/src/Entity/Annotation.php +++ b/src/Entity/Annotation.php @@ -14,12 +14,11 @@ use Wallabag\Repository\AnnotationRepository; /** * Annotation. - * - * @ExclusionPolicy("none") */ #[ORM\Table(name: 'annotation')] #[ORM\Entity(repositoryClass: AnnotationRepository::class)] #[ORM\HasLifecycleCallbacks] +#[ExclusionPolicy('none')] class Annotation { use EntityTimestampsTrait; @@ -34,10 +33,9 @@ class Annotation /** * @var string - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'text', type: 'text')] + #[Groups(['entries_for_user', 'export_all'])] private $text; /** @@ -54,36 +52,26 @@ class Annotation /** * @var string - * - * @Assert\Length( - * max = 10000, - * maxMessage = "validator.quote_length_too_high" - * ) - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'quote', type: 'text')] + #[Assert\Length(max: 10000, maxMessage: 'validator.quote_length_too_high')] + #[Groups(['entries_for_user', 'export_all'])] private $quote; /** * @var array - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'ranges', type: 'array')] + #[Groups(['entries_for_user', 'export_all'])] private $ranges; - /** - * @Exclude - */ #[ORM\ManyToOne(targetEntity: User::class)] + #[Exclude] private $user; - /** - * @Exclude - */ #[ORM\JoinColumn(name: 'entry_id', referencedColumnName: 'id', onDelete: 'cascade')] #[ORM\ManyToOne(targetEntity: Entry::class, inversedBy: 'annotations')] + #[Exclude] private $entry; /* @@ -220,10 +208,8 @@ class Annotation return $this->user; } - /** - * @VirtualProperty - * @SerializedName("user") - */ + #[VirtualProperty] + #[SerializedName('user')] public function getUserName() { return $this->user->getName(); @@ -254,10 +240,8 @@ class Annotation return $this->entry; } - /** - * @VirtualProperty - * @SerializedName("annotator_schema_version") - */ + #[VirtualProperty] + #[SerializedName('annotator_schema_version')] public function getVersion() { return 'v1.0'; diff --git a/src/Entity/Api/Client.php b/src/Entity/Api/Client.php index f01db50b9..af71be3fd 100644 --- a/src/Entity/Api/Client.php +++ b/src/Entity/Api/Client.php @@ -28,9 +28,9 @@ class Client extends BaseClient * type="string", * example="Default Client", * ) - * @Groups({"user_api_with_client"}) */ #[ORM\Column(name: 'name', type: 'text', nullable: false)] + #[Groups(['user_api_with_client'])] protected $name; #[ORM\OneToMany(targetEntity: RefreshToken::class, mappedBy: 'client', cascade: ['remove'])] @@ -47,10 +47,9 @@ class Client extends BaseClient * type="string", * example="2lmubx2m9vy80ss8c4wwcsg8ok44s88ocwcc8wo0w884oc8440", * ) - * - * @SerializedName("client_secret") - * @Groups({"user_api_with_client"}) */ + #[SerializedName('client_secret')] + #[Groups(['user_api_with_client'])] protected $secret; #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'clients')] @@ -95,17 +94,15 @@ class Client extends BaseClient } /** - * @VirtualProperty - * * @OA\Property( * description="Client secret used for authorization", * type="string", * example="3_1lpybsn0od40css4w4ko8gsc8cwwskggs8kgg448ko0owo4c84", * ) - * - * @SerializedName("client_id") - * @Groups({"user_api_with_client"}) */ + #[VirtualProperty] + #[SerializedName('client_id')] + #[Groups(['user_api_with_client'])] public function getClientId() { return $this->getId() . '_' . $this->getRandomId(); diff --git a/src/Entity/Config.php b/src/Entity/Config.php index 43d185a83..5733945af 100644 --- a/src/Entity/Config.php +++ b/src/Entity/Config.php @@ -21,66 +21,50 @@ class Config /** * @var int - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'id', type: 'integer')] #[ORM\Id] #[ORM\GeneratedValue(strategy: 'AUTO')] + #[Groups(['config_api'])] private $id; /** * @var int - * - * @Assert\NotBlank() - * @Assert\Range( - * min = 1, - * max = 100000, - * maxMessage = "validator.item_per_page_too_high" - * ) - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'items_per_page', type: 'integer', nullable: false)] + #[Assert\NotBlank] + #[Assert\Range(min: 1, max: 100000, maxMessage: 'validator.item_per_page_too_high')] + #[Groups(['config_api'])] private $itemsPerPage; /** * @var string - * - * @Assert\NotBlank() - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'language', type: 'string', nullable: false)] + #[Assert\NotBlank] + #[Groups(['config_api'])] private $language; /** * @var string|null - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'feed_token', type: 'string', nullable: true)] + #[Groups(['config_api'])] private $feedToken; /** * @var int|null - * - * @Assert\Range( - * min = 1, - * max = 100000, - * maxMessage = "validator.feed_limit_too_high" - * ) - * @Groups({"config_api"}) */ #[ORM\Column(name: 'feed_limit', type: 'integer', nullable: true)] + #[Assert\Range(min: 1, max: 100000, maxMessage: 'validator.feed_limit_too_high')] + #[Groups(['config_api'])] private $feedLimit; /** * @var float|null - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'reading_speed', type: 'float', nullable: true)] + #[Groups(['config_api'])] private $readingSpeed; /** @@ -91,58 +75,51 @@ class Config /** * @var int|null - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'action_mark_as_read', type: 'integer', nullable: true, options: ['default' => 0])] + #[Groups(['config_api'])] private $actionMarkAsRead; /** * @var int|null - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'list_mode', type: 'integer', nullable: true)] + #[Groups(['config_api'])] private $listMode; /** * @var int|null - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'display_thumbnails', type: 'integer', nullable: true, options: ['default' => 1])] + #[Groups(['config_api'])] private $displayThumbnails; /** * @var string|null - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'font', type: 'text', nullable: true)] + #[Groups(['config_api'])] private $font; /** * @var float|null - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'fontsize', type: 'float', nullable: true)] + #[Groups(['config_api'])] private $fontsize; /** * @var float|null - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'line_height', type: 'float', nullable: true)] + #[Groups(['config_api'])] private $lineHeight; /** * @var float|null - * - * @Groups({"config_api"}) */ #[ORM\Column(name: 'max_width', type: 'float', nullable: true)] + #[Groups(['config_api'])] private $maxWidth; /** diff --git a/src/Entity/Entry.php b/src/Entity/Entry.php index fa348df93..187fb1f24 100644 --- a/src/Entity/Entry.php +++ b/src/Entity/Entry.php @@ -18,7 +18,6 @@ use Wallabag\Repository\EntryRepository; /** * Entry. * - * @XmlRoot("entry") * @Hateoas\Relation("self", href = "expr('/api/entries/' ~ object.getId())") */ #[ORM\Table(name: '`entry`')] @@ -32,6 +31,7 @@ use Wallabag\Repository\EntryRepository; #[ORM\Index(columns: ['user_id', 'is_starred', 'starred_at'])] #[ORM\Entity(repositoryClass: EntryRepository::class)] #[ORM\HasLifecycleCallbacks] +#[XmlRoot('entry')] class Entry { use EntityTimestampsTrait; @@ -39,43 +39,36 @@ class Entry /** @Serializer\XmlAttribute */ /** * @var int - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'id', type: 'integer')] #[ORM\Id] #[ORM\GeneratedValue(strategy: 'AUTO')] + #[Groups(['entries_for_user', 'export_all'])] private $id; /** * @var string|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'uid', type: 'string', length: 23, nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $uid; /** * @var string|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'title', type: 'text', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $title; /** * Define the url fetched by wallabag (the final url after potential redirections). * * @var string|null - * - * @Assert\NotBlank() - * @Assert\Url( - * message = "The url '{{ value }}' is not a valid url", - * ) - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'url', type: 'text', nullable: true)] + #[Assert\NotBlank] + #[Assert\Url(message: "The url '{{ value }}' is not a valid url")] + #[Groups(['entries_for_user', 'export_all'])] private $url; /** @@ -88,20 +81,18 @@ class Entry * From where user retrieved/found the url (an other article, a twitter, or the given_url if non are provided). * * @var string|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'origin_url', type: 'text', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $originUrl; /** * Define the url entered by the user (without redirections). * * @var string|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'given_url', type: 'text', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $givenUrl; /** @@ -112,159 +103,134 @@ class Entry /** * @var bool - * - * @Exclude - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'is_archived', type: 'boolean')] + #[Exclude] + #[Groups(['entries_for_user', 'export_all'])] private $isArchived = false; /** * @var \DateTimeInterface|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'archived_at', type: 'datetime', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $archivedAt; /** * @var bool - * - * @Exclude - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'is_starred', type: 'boolean')] + #[Exclude] + #[Groups(['entries_for_user', 'export_all'])] private $isStarred = false; /** * @var string|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'content', type: 'text', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $content; /** * @var \DateTimeInterface - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'created_at', type: 'datetime')] + #[Groups(['entries_for_user', 'export_all'])] private $createdAt; /** * @var \DateTimeInterface - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'updated_at', type: 'datetime')] + #[Groups(['entries_for_user', 'export_all'])] private $updatedAt; /** * @var \DateTimeInterface|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'published_at', type: 'datetime', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $publishedAt; /** * @var array|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'published_by', type: 'array', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $publishedBy; /** * @var \DateTimeInterface|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'starred_at', type: 'datetime', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $starredAt; - /** - * @Groups({"entries_for_user", "export_all"}) - */ #[ORM\JoinTable] #[ORM\OneToMany(targetEntity: Annotation::class, mappedBy: 'entry', cascade: ['persist', 'remove'])] + #[Groups(['entries_for_user', 'export_all'])] private $annotations; /** * @var string|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'mimetype', type: 'text', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $mimetype; /** * @var string|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'language', type: 'string', length: 20, nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $language; /** * @var int - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'reading_time', type: 'integer', nullable: false)] + #[Groups(['entries_for_user', 'export_all'])] private $readingTime = 0; /** * @var string|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'domain_name', type: 'text', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $domainName; /** * @var string|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'preview_picture', type: 'text', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $previewPicture; /** * @var string|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'http_status', type: 'string', length: 3, nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $httpStatus; /** * @var array|null - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'headers', type: 'array', nullable: true)] + #[Groups(['entries_for_user', 'export_all'])] private $headers; /** * @var bool - * - * @Exclude - * - * @Groups({"entries_for_user", "export_all"}) */ #[ORM\Column(name: 'is_not_parsed', type: 'boolean', options: ['default' => false])] + #[Exclude] + #[Groups(['entries_for_user', 'export_all'])] private $isNotParsed = false; - /** - * @Exclude - * - * @Groups({"export_all"}) - */ #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'entries')] + #[Exclude] + #[Groups(['export_all'])] private $user; #[ORM\JoinTable(name: 'entry_tag')] @@ -403,11 +369,9 @@ class Entry return $this->isArchived; } - /** - * @VirtualProperty - * @SerializedName("is_archived") - * @Groups({"entries_for_user", "export_all"}) - */ + #[VirtualProperty] + #[SerializedName('is_archived')] + #[Groups(['entries_for_user', 'export_all'])] public function is_Archived() { return (int) $this->isArchived(); @@ -444,11 +408,9 @@ class Entry return $this->isStarred; } - /** - * @VirtualProperty - * @SerializedName("is_starred") - * @Groups({"entries_for_user", "export_all"}) - */ + #[VirtualProperty] + #[SerializedName('is_starred')] + #[Groups(['entries_for_user', 'export_all'])] public function is_Starred() { return (int) $this->isStarred(); @@ -493,28 +455,22 @@ class Entry return $this->user; } - /** - * @VirtualProperty - * @SerializedName("user_name") - */ + #[VirtualProperty] + #[SerializedName('user_name')] public function getUserName() { return $this->user->getUserName(); } - /** - * @VirtualProperty - * @SerializedName("user_email") - */ + #[VirtualProperty] + #[SerializedName('user_email')] public function getUserEmail() { return $this->user->getEmail(); } - /** - * @VirtualProperty - * @SerializedName("user_id") - */ + #[VirtualProperty] + #[SerializedName('user_id')] public function getUserId() { return $this->user->getId(); @@ -669,11 +625,9 @@ class Entry return $tags; } - /** - * @VirtualProperty - * @SerializedName("tags") - * @Groups({"entries_for_user", "export_all"}) - */ + #[VirtualProperty] + #[SerializedName('tags')] + #[Groups(['entries_for_user', 'export_all'])] public function getSerializedTags() { $data = []; @@ -823,12 +777,11 @@ class Entry * Used in the entries filter so it's more explicit for the end user than the uid. * Also used in the API. * - * @VirtualProperty - * @SerializedName("is_public") - * @Groups({"entries_for_user"}) - * * @return bool */ + #[VirtualProperty] + #[SerializedName('is_public')] + #[Groups(['entries_for_user'])] public function isPublic() { return null !== $this->uid; diff --git a/src/Entity/IgnoreOriginInstanceRule.php b/src/Entity/IgnoreOriginInstanceRule.php index 68cd8eab6..d0c1cce31 100644 --- a/src/Entity/IgnoreOriginInstanceRule.php +++ b/src/Entity/IgnoreOriginInstanceRule.php @@ -25,14 +25,14 @@ class IgnoreOriginInstanceRule implements IgnoreOriginRuleInterface, RuleInterfa /** * @var string * - * @Assert\NotBlank() - * @Assert\Length(max=255) * @RulerZAssert\ValidRule( * allowed_variables={"host","_all"}, * allowed_operators={"=","~"} * ) */ #[ORM\Column(name: 'rule', type: 'string', nullable: false)] + #[Assert\NotBlank] + #[Assert\Length(max: 255)] private $rule; /** diff --git a/src/Entity/IgnoreOriginUserRule.php b/src/Entity/IgnoreOriginUserRule.php index 2202c48c8..58af49d82 100644 --- a/src/Entity/IgnoreOriginUserRule.php +++ b/src/Entity/IgnoreOriginUserRule.php @@ -25,14 +25,14 @@ class IgnoreOriginUserRule implements IgnoreOriginRuleInterface, RuleInterface /** * @var string * - * @Assert\NotBlank() - * @Assert\Length(max=255) * @RulerZAssert\ValidRule( * allowed_variables={"host","_all"}, * allowed_operators={"=","~"} * ) */ #[ORM\Column(name: 'rule', type: 'string', nullable: false)] + #[Assert\NotBlank] + #[Assert\Length(max: 255)] private $rule; #[ORM\JoinColumn(nullable: false)] diff --git a/src/Entity/SiteCredential.php b/src/Entity/SiteCredential.php index 2a125181c..4ea007844 100644 --- a/src/Entity/SiteCredential.php +++ b/src/Entity/SiteCredential.php @@ -27,27 +27,24 @@ class SiteCredential /** * @var string - * - * @Assert\NotBlank() - * @Assert\Length(max=255) */ #[ORM\Column(name: 'host', type: 'string', length: 255)] + #[Assert\NotBlank] + #[Assert\Length(max: 255)] private $host; /** * @var string - * - * @Assert\NotBlank() */ #[ORM\Column(name: 'username', type: 'text')] + #[Assert\NotBlank] private $username; /** * @var string - * - * @Assert\NotBlank() */ #[ORM\Column(name: 'password', type: 'text')] + #[Assert\NotBlank] private $password; /** diff --git a/src/Entity/Tag.php b/src/Entity/Tag.php index 47102f3ab..2de5381b1 100644 --- a/src/Entity/Tag.php +++ b/src/Entity/Tag.php @@ -12,38 +12,33 @@ use Wallabag\Repository\TagRepository; /** * Tag. - * - * @XmlRoot("tag") - * @ExclusionPolicy("all") */ #[ORM\Table(name: '`tag`')] #[ORM\Index(columns: ['label'])] #[ORM\Entity(repositoryClass: TagRepository::class)] -class Tag +#[XmlRoot('tag')] +#[ExclusionPolicy('all')] +class Tag implements \Stringable { /** * @var int - * - * @Expose */ #[ORM\Column(name: 'id', type: 'integer')] #[ORM\Id] #[ORM\GeneratedValue(strategy: 'AUTO')] + #[Expose] private $id; /** * @var string - * - * @Expose */ #[ORM\Column(name: 'label', type: 'text')] + #[Expose] private $label; - /** - * @Expose - * @Gedmo\Slug(fields={"label"}, prefix="t:") - */ #[ORM\Column(length: 128, unique: true)] + #[Gedmo\Slug(fields: ['label'], prefix: 't:')] + #[Expose] private $slug; #[ORM\ManyToMany(targetEntity: Entry::class, mappedBy: 'tags', cascade: ['persist'])] @@ -54,7 +49,7 @@ class Tag $this->entries = new ArrayCollection(); } - public function __toString() + public function __toString(): string { return $this->label; } diff --git a/src/Entity/TaggingRule.php b/src/Entity/TaggingRule.php index f9d07d66b..c7729398b 100644 --- a/src/Entity/TaggingRule.php +++ b/src/Entity/TaggingRule.php @@ -12,11 +12,10 @@ use Wallabag\Repository\TaggingRuleRepository; /** * Tagging rule. - * - * @XmlRoot("tagging_rule") */ #[ORM\Table(name: '`tagging_rule`')] #[ORM\Entity(repositoryClass: TaggingRuleRepository::class)] +#[XmlRoot('tagging_rule')] class TaggingRule implements RuleInterface { /** @@ -30,32 +29,27 @@ class TaggingRule implements RuleInterface /** * @var string * - * @Assert\NotBlank() - * @Assert\Length(max=255) * @RulerZAssert\ValidRule( * allowed_variables={"title", "url", "isArchived", "isStarred", "content", "language", "mimetype", "readingTime", "domainName"}, * allowed_operators={">", "<", ">=", "<=", "=", "is", "!=", "and", "not", "or", "matches", "notmatches"} * ) - * - * @Groups({"export_tagging_rule"}) */ #[ORM\Column(name: 'rule', type: 'string', nullable: false)] + #[Assert\NotBlank] + #[Assert\Length(max: 255)] + #[Groups(['export_tagging_rule'])] private $rule; /** * @var array - * - * @Assert\NotBlank() - * - * @Groups({"export_tagging_rule"}) */ #[ORM\Column(name: 'tags', type: 'simple_array', nullable: false)] + #[Assert\NotBlank] + #[Groups(['export_tagging_rule'])] private $tags = []; - /** - * @Exclude - */ #[ORM\ManyToOne(targetEntity: Config::class, inversedBy: 'taggingRules')] + #[Exclude] private $config; /** diff --git a/src/Entity/User.php b/src/Entity/User.php index 5146b47dc..50fde090a 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -20,15 +20,13 @@ use Wallabag\Repository\UserRepository; /** * User. - * - * @XmlRoot("user") - * - * @UniqueEntity("email") - * @UniqueEntity("username") */ #[ORM\Table(name: '`user`')] #[ORM\Entity(repositoryClass: UserRepository::class)] #[ORM\HasLifecycleCallbacks] +#[UniqueEntity('email')] +#[UniqueEntity('username')] +#[XmlRoot('user')] class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorInterface, BackupCodeInterface { use EntityTimestampsTrait; @@ -42,12 +40,11 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI * type="int", * example=12, * ) - * - * @Groups({"user_api", "user_api_with_client"}) */ #[ORM\Column(name: 'id', type: 'integer')] #[ORM\Id] #[ORM\GeneratedValue(strategy: 'AUTO')] + #[Groups(['user_api', 'user_api_with_client'])] protected $id; /** @@ -58,9 +55,9 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI * type="string", * example="Walla Baggger", * ) - * @Groups({"user_api", "user_api_with_client"}) */ #[ORM\Column(name: 'name', type: 'text', nullable: true)] + #[Groups(['user_api', 'user_api_with_client'])] protected $name; /** @@ -71,9 +68,8 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI * type="string", * example="wallabag", * ) - * - * @Groups({"user_api", "user_api_with_client"}) */ + #[Groups(['user_api', 'user_api_with_client'])] protected $username; /** @@ -84,9 +80,8 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI * type="string", * example="wallabag@wallabag.io", * ) - * - * @Groups({"user_api", "user_api_with_client"}) */ + #[Groups(['user_api', 'user_api_with_client'])] protected $email; /** @@ -97,9 +92,9 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI * type="string", * example="2023-06-27T19:25:44+0000", * ) - * @Groups({"user_api", "user_api_with_client"}) */ #[ORM\Column(name: 'created_at', type: 'datetime')] + #[Groups(['user_api', 'user_api_with_client'])] protected $createdAt; /** @@ -110,9 +105,9 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI * type="string", * example="2023-06-27T19:37:30+0000", * ) - * @Groups({"user_api", "user_api_with_client"}) */ #[ORM\Column(name: 'updated_at', type: 'datetime')] + #[Groups(['user_api', 'user_api_with_client'])] protected $updatedAt; #[ORM\OneToMany(targetEntity: Entry::class, mappedBy: 'user', cascade: ['remove'])] @@ -140,10 +135,9 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI * description="Default client created during user registration. Used for further authorization", * ref=@Model(type=Client::class, groups={"user_api_with_client"}) * ) - * - * @Groups({"user_api_with_client"}) - * @Accessor(getter="getFirstClient") */ + #[Groups(['user_api_with_client'])] + #[Accessor(getter: 'getFirstClient')] protected $default_client; #[ORM\Column(type: 'integer', nullable: true)] @@ -383,7 +377,7 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI foreach ($this->backupCodes as $key => $backupCode) { // backup code are hashed using `password_hash` // see ConfigController->otpAppAction - if (password_verify($code, $backupCode)) { + if (password_verify($code, (string) $backupCode)) { return $key; } } diff --git a/src/Event/ConfigUpdatedEvent.php b/src/Event/ConfigUpdatedEvent.php index d1806a57f..455789137 100644 --- a/src/Event/ConfigUpdatedEvent.php +++ b/src/Event/ConfigUpdatedEvent.php @@ -12,11 +12,9 @@ class ConfigUpdatedEvent extends Event { public const NAME = 'config.updated'; - protected $config; - - public function __construct(Config $entry) - { - $this->config = $entry; + public function __construct( + protected Config $config, + ) { } public function getConfig(): Config diff --git a/src/Event/EntryDeletedEvent.php b/src/Event/EntryDeletedEvent.php index c81bf711e..b95806c80 100644 --- a/src/Event/EntryDeletedEvent.php +++ b/src/Event/EntryDeletedEvent.php @@ -12,11 +12,9 @@ class EntryDeletedEvent extends Event { public const NAME = 'entry.deleted'; - protected $entry; - - public function __construct(Entry $entry) - { - $this->entry = $entry; + public function __construct( + protected Entry $entry, + ) { } public function getEntry(): Entry diff --git a/src/Event/EntrySavedEvent.php b/src/Event/EntrySavedEvent.php index ec3bdfa93..c1deaedbe 100644 --- a/src/Event/EntrySavedEvent.php +++ b/src/Event/EntrySavedEvent.php @@ -12,11 +12,9 @@ class EntrySavedEvent extends Event { public const NAME = 'entry.saved'; - protected $entry; - - public function __construct(Entry $entry) - { - $this->entry = $entry; + public function __construct( + protected Entry $entry, + ) { } public function getEntry(): Entry diff --git a/src/Event/Listener/AuthenticationFailureListener.php b/src/Event/Listener/AuthenticationFailureListener.php index e1e2acc2e..077eeec80 100644 --- a/src/Event/Listener/AuthenticationFailureListener.php +++ b/src/Event/Listener/AuthenticationFailureListener.php @@ -9,13 +9,10 @@ use Symfony\Component\Security\Http\Event\LoginFailureEvent; class AuthenticationFailureListener implements EventSubscriberInterface { - private $requestStack; - private $logger; - - public function __construct(RequestStack $requestStack, LoggerInterface $logger) - { - $this->requestStack = $requestStack; - $this->logger = $logger; + public function __construct( + private readonly RequestStack $requestStack, + private readonly LoggerInterface $logger, + ) { } public static function getSubscribedEvents(): array diff --git a/src/Event/Listener/CreateConfigListener.php b/src/Event/Listener/CreateConfigListener.php index 9cc000e63..e7af5a15b 100644 --- a/src/Event/Listener/CreateConfigListener.php +++ b/src/Event/Listener/CreateConfigListener.php @@ -15,27 +15,17 @@ use Wallabag\Entity\Config; */ class CreateConfigListener implements EventSubscriberInterface { - private $em; - private $itemsOnPage; - private $feedLimit; - private $language; - private $readingSpeed; - private $actionMarkAsRead; - private $listMode; - private $requestStack; - private $displayThumbnails; - - public function __construct(EntityManagerInterface $em, $itemsOnPage, $feedLimit, $language, $readingSpeed, $actionMarkAsRead, $listMode, $displayThumbnails, RequestStack $requestStack) - { - $this->em = $em; - $this->itemsOnPage = $itemsOnPage; - $this->feedLimit = $feedLimit; - $this->language = $language; - $this->readingSpeed = $readingSpeed; - $this->actionMarkAsRead = $actionMarkAsRead; - $this->listMode = $listMode; - $this->requestStack = $requestStack; - $this->displayThumbnails = $displayThumbnails; + public function __construct( + private readonly EntityManagerInterface $em, + private $itemsOnPage, + private $feedLimit, + private $language, + private $readingSpeed, + private $actionMarkAsRead, + private $listMode, + private $displayThumbnails, + private readonly RequestStack $requestStack, + ) { } public static function getSubscribedEvents(): array diff --git a/src/Event/Listener/LocaleListener.php b/src/Event/Listener/LocaleListener.php index b14b8aa98..cd48551ec 100644 --- a/src/Event/Listener/LocaleListener.php +++ b/src/Event/Listener/LocaleListener.php @@ -11,11 +11,9 @@ use Symfony\Component\HttpKernel\KernelEvents; */ class LocaleListener implements EventSubscriberInterface { - private $defaultLocale; - - public function __construct($defaultLocale = 'en') - { - $this->defaultLocale = $defaultLocale; + public function __construct( + private $defaultLocale = 'en', + ) { } public function onKernelRequest(RequestEvent $event) diff --git a/src/Event/Listener/PasswordResettingListener.php b/src/Event/Listener/PasswordResettingListener.php index 6b47ffd09..b34522167 100644 --- a/src/Event/Listener/PasswordResettingListener.php +++ b/src/Event/Listener/PasswordResettingListener.php @@ -15,11 +15,9 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; */ class PasswordResettingListener implements EventSubscriberInterface { - private $router; - - public function __construct(UrlGeneratorInterface $router) - { - $this->router = $router; + public function __construct( + private readonly UrlGeneratorInterface $router, + ) { } public static function getSubscribedEvents(): array diff --git a/src/Event/Listener/RegistrationListener.php b/src/Event/Listener/RegistrationListener.php index 33a03c9d1..eaeef75f5 100644 --- a/src/Event/Listener/RegistrationListener.php +++ b/src/Event/Listener/RegistrationListener.php @@ -11,19 +11,12 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class RegistrationListener implements EventSubscriberInterface { /** - * @var bool + * @param bool $registrationEnabled */ - private $registrationEnabled; - - /** - * @var UrlGeneratorInterface - */ - private $urlGenerator; - - public function __construct($registrationEnabled, UrlGeneratorInterface $urlGenerator) - { - $this->registrationEnabled = $registrationEnabled; - $this->urlGenerator = $urlGenerator; + public function __construct( + private $registrationEnabled, + private readonly UrlGeneratorInterface $urlGenerator, + ) { } public static function getSubscribedEvents(): array diff --git a/src/Event/Listener/UserLocaleListener.php b/src/Event/Listener/UserLocaleListener.php index df195a2b0..5c9403376 100644 --- a/src/Event/Listener/UserLocaleListener.php +++ b/src/Event/Listener/UserLocaleListener.php @@ -16,11 +16,9 @@ use Wallabag\Entity\User; */ class UserLocaleListener { - private SessionInterface $session; - - public function __construct(SessionInterface $session) - { - $this->session = $session; + public function __construct( + private readonly SessionInterface $session, + ) { } public function onInteractiveLogin(InteractiveLoginEvent $event) diff --git a/src/Event/Subscriber/DownloadImagesSubscriber.php b/src/Event/Subscriber/DownloadImagesSubscriber.php index 069018b24..5324f449c 100644 --- a/src/Event/Subscriber/DownloadImagesSubscriber.php +++ b/src/Event/Subscriber/DownloadImagesSubscriber.php @@ -12,17 +12,12 @@ use Wallabag\Helper\DownloadImages; class DownloadImagesSubscriber implements EventSubscriberInterface { - private $em; - private $downloadImages; - private $enabled; - private $logger; - - public function __construct(EntityManagerInterface $em, DownloadImages $downloadImages, $enabled, LoggerInterface $logger) - { - $this->em = $em; - $this->downloadImages = $downloadImages; - $this->enabled = $enabled; - $this->logger = $logger; + public function __construct( + private readonly EntityManagerInterface $em, + private readonly DownloadImages $downloadImages, + private $enabled, + private readonly LoggerInterface $logger, + ) { } public static function getSubscribedEvents(): array diff --git a/src/Event/Subscriber/GenerateCustomCSSSubscriber.php b/src/Event/Subscriber/GenerateCustomCSSSubscriber.php index 78d9081a5..06dfbdbd5 100644 --- a/src/Event/Subscriber/GenerateCustomCSSSubscriber.php +++ b/src/Event/Subscriber/GenerateCustomCSSSubscriber.php @@ -9,13 +9,10 @@ use Wallabag\Event\ConfigUpdatedEvent; class GenerateCustomCSSSubscriber implements EventSubscriberInterface { - private $em; - private $compiler; - - public function __construct(EntityManagerInterface $em, Compiler $compiler) - { - $this->em = $em; - $this->compiler = $compiler; + public function __construct( + private readonly EntityManagerInterface $em, + private readonly Compiler $compiler, + ) { } public static function getSubscribedEvents(): array diff --git a/src/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php b/src/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php index 08ae02f1d..5e3e2ea68 100644 --- a/src/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php +++ b/src/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php @@ -17,11 +17,9 @@ use Wallabag\Entity\Entry; */ class SQLiteCascadeDeleteSubscriber implements EventSubscriber { - private $doctrine; - - public function __construct(ManagerRegistry $doctrine) - { - $this->doctrine = $doctrine; + public function __construct( + private readonly ManagerRegistry $doctrine, + ) { } /** diff --git a/src/Event/Subscriber/SchemaAdapterSubscriber.php b/src/Event/Subscriber/SchemaAdapterSubscriber.php index fb3cb15f6..ae02181dd 100644 --- a/src/Event/Subscriber/SchemaAdapterSubscriber.php +++ b/src/Event/Subscriber/SchemaAdapterSubscriber.php @@ -8,11 +8,9 @@ use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; class SchemaAdapterSubscriber implements EventSubscriber { - private string $databaseTablePrefix; - - public function __construct(string $databaseTablePrefix) - { - $this->databaseTablePrefix = $databaseTablePrefix; + public function __construct( + private readonly string $databaseTablePrefix, + ) { } public function getSubscribedEvents(): array diff --git a/src/ExpressionLanguage/AuthenticatorProvider.php b/src/ExpressionLanguage/AuthenticatorProvider.php index 25c748d3e..c98db51fd 100644 --- a/src/ExpressionLanguage/AuthenticatorProvider.php +++ b/src/ExpressionLanguage/AuthenticatorProvider.php @@ -9,11 +9,9 @@ use Symfony\Contracts\HttpClient\HttpClientInterface; class AuthenticatorProvider implements ExpressionFunctionProviderInterface { - private HttpClientInterface $requestHtmlFunctionClient; - - public function __construct(HttpClientInterface $requestHtmlFunctionClient) - { - $this->requestHtmlFunctionClient = $requestHtmlFunctionClient; + public function __construct( + private readonly HttpClientInterface $requestHtmlFunctionClient, + ) { } public function getFunctions(): array @@ -31,12 +29,10 @@ class AuthenticatorProvider implements ExpressionFunctionProviderInterface { return new ExpressionFunction( 'request_html', - function () { + function (): void { throw new \Exception('Not supported'); }, - function (array $arguments, $uri) { - return $this->requestHtmlFunctionClient->request('GET', $uri)->getContent(); - } + fn (array $arguments, $uri) => $this->requestHtmlFunctionClient->request('GET', $uri)->getContent() ); } @@ -44,7 +40,7 @@ class AuthenticatorProvider implements ExpressionFunctionProviderInterface { return new ExpressionFunction( 'preg_match', - function () { + function (): void { throw new \Exception('Not supported'); }, function (array $arguments, $pattern, $html) { @@ -63,7 +59,7 @@ class AuthenticatorProvider implements ExpressionFunctionProviderInterface { return new ExpressionFunction( 'xpath', - function () { + function (): void { throw new \Exception('Not supported'); }, function (array $arguments, $xpathQuery, $html) { @@ -71,7 +67,7 @@ class AuthenticatorProvider implements ExpressionFunctionProviderInterface $crawler = new Crawler((string) $html); $crawler = $crawler->filterXPath($xpathQuery); - } catch (\Throwable $e) { + } catch (\Throwable) { return ''; } diff --git a/src/Form/DataTransformer/StringToListTransformer.php b/src/Form/DataTransformer/StringToListTransformer.php index 97e012a16..32867d76a 100644 --- a/src/Form/DataTransformer/StringToListTransformer.php +++ b/src/Form/DataTransformer/StringToListTransformer.php @@ -10,17 +10,12 @@ use Symfony\Component\Form\DataTransformerInterface; */ class StringToListTransformer implements DataTransformerInterface { - /** - * @var string - */ - private $separator; - /** * @param string $separator The separator used in the list */ - public function __construct($separator = ',') - { - $this->separator = $separator; + public function __construct( + private $separator = ',', + ) { } /** diff --git a/src/Form/Type/Api/ClientType.php b/src/Form/Type/Api/ClientType.php index 8986a04ff..accb8ee2d 100644 --- a/src/Form/Type/Api/ClientType.php +++ b/src/Form/Type/Api/ClientType.php @@ -28,12 +28,8 @@ class ClientType extends AbstractType $builder->get('redirect_uris') ->addModelTransformer(new CallbackTransformer( - function ($originalUri) { - return $originalUri; - }, - function ($submittedUri) { - return [$submittedUri]; - } + fn ($originalUri) => $originalUri, + fn ($submittedUri) => [$submittedUri] )) ; } diff --git a/src/Form/Type/ConfigType.php b/src/Form/Type/ConfigType.php index fc72ebe75..2a4ee9a47 100644 --- a/src/Form/Type/ConfigType.php +++ b/src/Form/Type/ConfigType.php @@ -14,17 +14,14 @@ use Wallabag\Entity\Config; class ConfigType extends AbstractType { - private $languages = []; - private $fonts = []; - /** * @param array $languages Languages come from configuration, array just code language as key and label as value * @param array $fonts Fonts come from configuration, array just font name as key / value */ - public function __construct($languages, $fonts) - { - $this->languages = $languages; - $this->fonts = $fonts; + public function __construct( + private $languages, + private $fonts, + ) { } public function buildForm(FormBuilderInterface $builder, array $options) diff --git a/src/Form/Type/EntryFilterType.php b/src/Form/Type/EntryFilterType.php index 039fea6de..f4e9b76f0 100644 --- a/src/Form/Type/EntryFilterType.php +++ b/src/Form/Type/EntryFilterType.php @@ -21,16 +21,13 @@ use Wallabag\Repository\EntryRepository; class EntryFilterType extends AbstractType { - private $repository; - private $tokenStorage; - /** * Repository & user are used to get a list of language entries for this user. */ - public function __construct(EntryRepository $entryRepository, TokenStorageInterface $tokenStorage) - { - $this->repository = $entryRepository; - $this->tokenStorage = $tokenStorage; + public function __construct( + private readonly EntryRepository $repository, + private readonly TokenStorageInterface $tokenStorage, + ) { } public function buildForm(FormBuilderInterface $builder, array $options) diff --git a/src/Helper/ContentProxy.php b/src/Helper/ContentProxy.php index bfdc9f163..af66abf7f 100644 --- a/src/Helper/ContentProxy.php +++ b/src/Helper/ContentProxy.php @@ -17,26 +17,19 @@ use Wallabag\Tools\Utils; */ class ContentProxy { - protected $graby; - protected $tagger; - protected $ignoreOriginProcessor; - protected $validator; - protected $logger; protected $mimeTypes; - protected $fetchingErrorMessage; protected $eventDispatcher; - protected $storeArticleHeaders; - public function __construct(Graby $graby, RuleBasedTagger $tagger, RuleBasedIgnoreOriginProcessor $ignoreOriginProcessor, ValidatorInterface $validator, LoggerInterface $logger, $fetchingErrorMessage, $storeArticleHeaders = false) - { - $this->graby = $graby; - $this->tagger = $tagger; - $this->ignoreOriginProcessor = $ignoreOriginProcessor; - $this->validator = $validator; - $this->logger = $logger; + public function __construct( + protected Graby $graby, + protected RuleBasedTagger $tagger, + protected RuleBasedIgnoreOriginProcessor $ignoreOriginProcessor, + protected ValidatorInterface $validator, + protected LoggerInterface $logger, + protected $fetchingErrorMessage, + protected $storeArticleHeaders = false, + ) { $this->mimeTypes = new MimeTypes(); - $this->fetchingErrorMessage = $fetchingErrorMessage; - $this->storeArticleHeaders = $storeArticleHeaders; } /** @@ -59,7 +52,7 @@ class ContentProxy $fetchedContent['title'] = $this->sanitizeContentTitle( $fetchedContent['title'], - isset($fetchedContent['headers']['content-type']) ? $fetchedContent['headers']['content-type'] : '' + $fetchedContent['headers']['content-type'] ?? '' ); // when content is imported, we have information in $content @@ -107,7 +100,9 @@ class ContentProxy return; } - $this->logger->warning('Language validation failed. ' . (string) $errors); + foreach ($errors as $error) { + $this->logger->warning('Language validation failed. ' . $error->getMessage()); + } } /** @@ -128,7 +123,9 @@ class ContentProxy return; } - $this->logger->warning('PreviewPicture validation failed. ' . (string) $errors); + foreach ($errors as $error) { + $this->logger->warning('PreviewPicture validation failed. ' . $error->getMessage()); + } } /** diff --git a/src/Helper/CryptoProxy.php b/src/Helper/CryptoProxy.php index cfc365eb3..fc1814109 100644 --- a/src/Helper/CryptoProxy.php +++ b/src/Helper/CryptoProxy.php @@ -13,13 +13,12 @@ use Psr\Log\LoggerInterface; */ class CryptoProxy { - private $logger; private $encryptionKey; - public function __construct($encryptionKeyPath, LoggerInterface $logger) - { - $this->logger = $logger; - + public function __construct( + $encryptionKeyPath, + private readonly LoggerInterface $logger, + ) { if (!file_exists($encryptionKeyPath)) { $key = Key::createNewRandomKey(); diff --git a/src/Helper/DownloadImages.php b/src/Helper/DownloadImages.php index d7423d364..156100dc4 100644 --- a/src/Helper/DownloadImages.php +++ b/src/Helper/DownloadImages.php @@ -16,19 +16,16 @@ use Symfony\Contracts\HttpClient\ResponseInterface; class DownloadImages { public const REGENERATE_PICTURES_QUALITY = 80; - - private $client; - private $baseFolder; - private $logger; private $mimeTypes; private $wallabagUrl; - public function __construct(HttpClientInterface $downloadImagesClient, $baseFolder, $wallabagUrl, LoggerInterface $logger) - { - $this->client = $downloadImagesClient; - $this->baseFolder = $baseFolder; - $this->wallabagUrl = rtrim($wallabagUrl, '/'); - $this->logger = $logger; + public function __construct( + private readonly HttpClientInterface $client, + private $baseFolder, + $wallabagUrl, + private readonly LoggerInterface $logger, + ) { + $this->wallabagUrl = rtrim((string) $wallabagUrl, '/'); $this->mimeTypes = new MimeTypes(); $this->setFolder(); @@ -174,7 +171,7 @@ class DownloadImages try { $im = imagecreatefromstring($res->getContent()); - } catch (\Exception $e) { + } catch (\Exception) { $im = false; } @@ -193,7 +190,7 @@ class DownloadImages $imagick->readImageBlob($res->getContent()); $imagick->setImageFormat('gif'); $imagick->writeImages($localPath, true); - } catch (\Exception $e) { + } catch (\Exception) { // if Imagick fail, fallback to the default solution imagegif($im, $localPath); } @@ -294,9 +291,7 @@ class DownloadImages preg_match_all($pattern, $srcsetAttribute, $matches); $srcset = \call_user_func_array('array_merge', $matches); - $srcsetUrls = array_map(function ($src) { - return trim(explode(' ', $src, 2)[0]); - }, $srcset); + $srcsetUrls = array_map(fn ($src) => trim(explode(' ', (string) $src, 2)[0]), $srcset); $urls = array_merge($srcsetUrls, $urls); } diff --git a/src/Helper/EntriesExport.php b/src/Helper/EntriesExport.php index 6a8c45952..64360c3e2 100644 --- a/src/Helper/EntriesExport.php +++ b/src/Helper/EntriesExport.php @@ -19,10 +19,6 @@ use Wallabag\Entity\User; */ class EntriesExport { - private $wallabagUrl; - private $logoPath; - private $translator; - private $tokenStorage; private $title = ''; private $entries = []; private $author = 'wallabag'; @@ -34,12 +30,12 @@ class EntriesExport * @param string $logoPath Path to the logo FROM THE BUNDLE SCOPE * @param TokenStorageInterface $tokenStorage Needed to retrieve the current user */ - public function __construct(TranslatorInterface $translator, $wallabagUrl, $logoPath, TokenStorageInterface $tokenStorage) - { - $this->translator = $translator; - $this->wallabagUrl = $wallabagUrl; - $this->logoPath = $logoPath; - $this->tokenStorage = $tokenStorage; + public function __construct( + private readonly TranslatorInterface $translator, + private $wallabagUrl, + private $logoPath, + private readonly TokenStorageInterface $tokenStorage, + ) { } /** diff --git a/src/Helper/PreparePagerForEntries.php b/src/Helper/PreparePagerForEntries.php index 2a7564f0e..fe0446e6a 100644 --- a/src/Helper/PreparePagerForEntries.php +++ b/src/Helper/PreparePagerForEntries.php @@ -10,11 +10,9 @@ use Wallabag\Entity\User; class PreparePagerForEntries { - private $tokenStorage; - - public function __construct(TokenStorageInterface $tokenStorage) - { - $this->tokenStorage = $tokenStorage; + public function __construct( + private readonly TokenStorageInterface $tokenStorage, + ) { } /** diff --git a/src/Helper/Redirect.php b/src/Helper/Redirect.php index 777951ac9..77aec7ab4 100644 --- a/src/Helper/Redirect.php +++ b/src/Helper/Redirect.php @@ -13,13 +13,10 @@ use Wallabag\Entity\User; */ class Redirect { - private $router; - private $tokenStorage; - - public function __construct(UrlGeneratorInterface $router, TokenStorageInterface $tokenStorage) - { - $this->router = $router; - $this->tokenStorage = $tokenStorage; + public function __construct( + private readonly UrlGeneratorInterface $router, + private readonly TokenStorageInterface $tokenStorage, + ) { } /** diff --git a/src/Helper/RuleBasedIgnoreOriginProcessor.php b/src/Helper/RuleBasedIgnoreOriginProcessor.php index a44390406..dc6ac5654 100644 --- a/src/Helper/RuleBasedIgnoreOriginProcessor.php +++ b/src/Helper/RuleBasedIgnoreOriginProcessor.php @@ -9,15 +9,11 @@ use Wallabag\Repository\IgnoreOriginInstanceRuleRepository; class RuleBasedIgnoreOriginProcessor { - protected $rulerz; - protected $logger; - protected $ignoreOriginInstanceRuleRepository; - - public function __construct(RulerZ $rulerz, LoggerInterface $logger, IgnoreOriginInstanceRuleRepository $ignoreOriginInstanceRuleRepository) - { - $this->rulerz = $rulerz; - $this->logger = $logger; - $this->ignoreOriginInstanceRuleRepository = $ignoreOriginInstanceRuleRepository; + public function __construct( + protected RulerZ $rulerz, + protected LoggerInterface $logger, + protected IgnoreOriginInstanceRuleRepository $ignoreOriginInstanceRuleRepository, + ) { } /** diff --git a/src/Helper/RuleBasedTagger.php b/src/Helper/RuleBasedTagger.php index 355394579..d40604d50 100644 --- a/src/Helper/RuleBasedTagger.php +++ b/src/Helper/RuleBasedTagger.php @@ -14,17 +14,12 @@ use Wallabag\Repository\TagRepository; class RuleBasedTagger { - private $rulerz; - private $tagRepository; - private $entryRepository; - private $logger; - - public function __construct(RulerZ $rulerz, TagRepository $tagRepository, EntryRepository $entryRepository, LoggerInterface $logger) - { - $this->rulerz = $rulerz; - $this->tagRepository = $tagRepository; - $this->entryRepository = $entryRepository; - $this->logger = $logger; + public function __construct( + private readonly RulerZ $rulerz, + private readonly TagRepository $tagRepository, + private readonly EntryRepository $entryRepository, + private readonly LoggerInterface $logger, + ) { } /** diff --git a/src/Helper/TagsAssigner.php b/src/Helper/TagsAssigner.php index d39683e30..470c53b86 100644 --- a/src/Helper/TagsAssigner.php +++ b/src/Helper/TagsAssigner.php @@ -8,14 +8,9 @@ use Wallabag\Repository\TagRepository; class TagsAssigner { - /** - * @var TagRepository - */ - protected $tagRepository; - - public function __construct(TagRepository $tagRepository) - { - $this->tagRepository = $tagRepository; + public function __construct( + protected TagRepository $tagRepository, + ) { } /** @@ -44,7 +39,7 @@ class TagsAssigner } foreach ($tags as $label) { - $label = trim(mb_convert_case($label, \MB_CASE_LOWER)); + $label = trim(mb_convert_case((string) $label, \MB_CASE_LOWER)); // avoid empty tag if ('' === $label) { diff --git a/src/HttpClient/Authenticator.php b/src/HttpClient/Authenticator.php index 47a7a17aa..40028e5ec 100644 --- a/src/HttpClient/Authenticator.php +++ b/src/HttpClient/Authenticator.php @@ -14,19 +14,13 @@ use Wallabag\SiteConfig\SiteConfigBuilder; class Authenticator implements LoggerAwareInterface { - /** @var SiteConfigBuilder */ - private $configBuilder; - - /** @var LoginFormAuthenticator */ - private $authenticator; - /** @var LoggerInterface */ private $logger; - public function __construct(SiteConfigBuilder $configBuilder, LoginFormAuthenticator $authenticator) - { - $this->configBuilder = $configBuilder; - $this->authenticator = $authenticator; + public function __construct( + private readonly SiteConfigBuilder $configBuilder, + private readonly LoginFormAuthenticator $authenticator, + ) { $this->logger = new NullLogger(); } diff --git a/src/HttpClient/WallabagClient.php b/src/HttpClient/WallabagClient.php index 8b3f294bb..0bf9947ae 100644 --- a/src/HttpClient/WallabagClient.php +++ b/src/HttpClient/WallabagClient.php @@ -11,19 +11,14 @@ use Symfony\Contracts\HttpClient\ResponseStreamInterface; class WallabagClient implements HttpClientInterface { - private $restrictedAccess; - private HttpClientInterface $httpClient; - private HttpBrowser $browser; - private Authenticator $authenticator; - private LoggerInterface $logger; - - public function __construct($restrictedAccess, HttpBrowser $browser, Authenticator $authenticator, LoggerInterface $logger) - { - $this->restrictedAccess = $restrictedAccess; - $this->browser = $browser; - $this->authenticator = $authenticator; - $this->logger = $logger; + private readonly HttpClientInterface $httpClient; + public function __construct( + private $restrictedAccess, + private readonly HttpBrowser $browser, + private readonly Authenticator $authenticator, + private readonly LoggerInterface $logger, + ) { $this->httpClient = HttpClient::create([ 'timeout' => 10, ]); diff --git a/src/Import/AbstractImport.php b/src/Import/AbstractImport.php index c9ddee2b7..09d551028 100644 --- a/src/Import/AbstractImport.php +++ b/src/Import/AbstractImport.php @@ -7,7 +7,6 @@ use OldSound\RabbitMqBundle\RabbitMq\ProducerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Wallabag\Entity\Entry; -use Wallabag\Entity\Tag; use Wallabag\Entity\User; use Wallabag\Event\EntrySavedEvent; use Wallabag\Helper\ContentProxy; @@ -15,11 +14,6 @@ use Wallabag\Helper\TagsAssigner; abstract class AbstractImport implements ImportInterface { - protected $em; - protected $logger; - protected $contentProxy; - protected $tagsAssigner; - protected $eventDispatcher; protected $producer; protected $user; protected $markAsRead; @@ -28,13 +22,13 @@ abstract class AbstractImport implements ImportInterface protected $importedEntries = 0; protected $queuedEntries = 0; - public function __construct(EntityManagerInterface $em, ContentProxy $contentProxy, TagsAssigner $tagsAssigner, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger) - { - $this->em = $em; - $this->logger = $logger; - $this->contentProxy = $contentProxy; - $this->tagsAssigner = $tagsAssigner; - $this->eventDispatcher = $eventDispatcher; + public function __construct( + protected EntityManagerInterface $em, + protected ContentProxy $contentProxy, + protected TagsAssigner $tagsAssigner, + protected EventDispatcherInterface $eventDispatcher, + protected LoggerInterface $logger, + ) { } public function setLogger(LoggerInterface $logger): void @@ -178,9 +172,7 @@ abstract class AbstractImport implements ImportInterface $entryToBeFlushed = []; - // clear only affected entities - $this->em->clear(Entry::class); - $this->em->clear(Tag::class); + $this->em->clear(); } ++$i; } diff --git a/src/Import/ChromeImport.php b/src/Import/ChromeImport.php index 27ae96221..20333c269 100644 --- a/src/Import/ChromeImport.php +++ b/src/Import/ChromeImport.php @@ -39,7 +39,7 @@ class ChromeImport extends BrowserImport 'is_archived' => (int) $this->markAsRead, 'is_starred' => false, 'tags' => '', - 'created_at' => substr($entry['date_added'], 0, 10), + 'created_at' => substr((string) $entry['date_added'], 0, 10), ]; if (\array_key_exists('tags', $entry) && '' !== $entry['tags']) { diff --git a/src/Import/FirefoxImport.php b/src/Import/FirefoxImport.php index 2dba50d6a..efd9d2052 100644 --- a/src/Import/FirefoxImport.php +++ b/src/Import/FirefoxImport.php @@ -39,7 +39,7 @@ class FirefoxImport extends BrowserImport 'is_archived' => (int) $this->markAsRead, 'is_starred' => false, 'tags' => '', - 'created_at' => substr($entry['dateAdded'], 0, 10), + 'created_at' => substr((string) $entry['dateAdded'], 0, 10), ]; if (\array_key_exists('tags', $entry) && '' !== $entry['tags']) { diff --git a/src/Import/HtmlImport.php b/src/Import/HtmlImport.php index f54941ec2..607fd5da9 100644 --- a/src/Import/HtmlImport.php +++ b/src/Import/HtmlImport.php @@ -40,13 +40,11 @@ abstract class HtmlImport extends AbstractImport return false; } - $entries = $hrefs->each(function (Crawler $node) { - return [ - 'url' => $node->attr('href'), - 'tags' => $node->attr('tags'), - 'created_at' => $node->attr('add_date'), - ]; - }); + $entries = $hrefs->each(fn (Crawler $node) => [ + 'url' => $node->attr('href'), + 'tags' => $node->attr('tags'), + 'created_at' => $node->attr('add_date'), + ]); if ($this->producer) { $this->parseEntriesForProducer($entries); diff --git a/src/Import/PinboardImport.php b/src/Import/PinboardImport.php index f5da3f768..fa0bcfe3d 100644 --- a/src/Import/PinboardImport.php +++ b/src/Import/PinboardImport.php @@ -95,7 +95,7 @@ class PinboardImport extends AbstractImport 'is_archived' => ('no' === $importedEntry['toread']) || $this->markAsRead, 'is_starred' => false, 'created_at' => $importedEntry['time'], - 'tags' => explode(' ', $importedEntry['tags']), + 'tags' => explode(' ', (string) $importedEntry['tags']), ]; $entry = new Entry($this->user); diff --git a/src/Import/PocketHtmlImport.php b/src/Import/PocketHtmlImport.php index b1c7e3edb..08c8da1e2 100644 --- a/src/Import/PocketHtmlImport.php +++ b/src/Import/PocketHtmlImport.php @@ -56,13 +56,11 @@ class PocketHtmlImport extends HtmlImport return false; } - $entries = $hrefs->each(function (Crawler $node) { - return [ - 'url' => $node->attr('href'), - 'tags' => $node->attr('tags'), - 'created_at' => $node->attr('time_added'), - ]; - }); + $entries = $hrefs->each(fn (Crawler $node) => [ + 'url' => $node->attr('href'), + 'tags' => $node->attr('tags'), + 'created_at' => $node->attr('time_added'), + ]); if ($this->producer) { $this->parseEntriesForProducer($entries); diff --git a/src/Import/WallabagV1Import.php b/src/Import/WallabagV1Import.php index 9463d4b95..2dfd7f404 100644 --- a/src/Import/WallabagV1Import.php +++ b/src/Import/WallabagV1Import.php @@ -10,14 +10,15 @@ use Wallabag\Helper\TagsAssigner; class WallabagV1Import extends WallabagImport { - protected $fetchingErrorMessage; - protected $fetchingErrorMessageTitle; - - public function __construct(EntityManagerInterface $em, ContentProxy $contentProxy, TagsAssigner $tagsAssigner, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger, $fetchingErrorMessageTitle, $fetchingErrorMessage) - { - $this->fetchingErrorMessageTitle = $fetchingErrorMessageTitle; - $this->fetchingErrorMessage = $fetchingErrorMessage; - + public function __construct( + EntityManagerInterface $em, + ContentProxy $contentProxy, + TagsAssigner $tagsAssigner, + EventDispatcherInterface $eventDispatcher, + LoggerInterface $logger, + protected $fetchingErrorMessageTitle, + protected $fetchingErrorMessage, + ) { parent::__construct($em, $contentProxy, $tagsAssigner, $eventDispatcher, $logger); } diff --git a/src/Mailer/AuthCodeMailer.php b/src/Mailer/AuthCodeMailer.php index 8707b178b..858ba547f 100644 --- a/src/Mailer/AuthCodeMailer.php +++ b/src/Mailer/AuthCodeMailer.php @@ -17,52 +17,17 @@ use Wallabag\Entity\User; class AuthCodeMailer implements AuthCodeMailerInterface { /** - * Mailer. - * - * @var MailerInterface + * @param string $senderEmail sender email address + * @param string $senderName sender name + * @param string $supportUrl support URL to report any bugs */ - private $mailer; - - /** - * Twig to render the html's email. - * - * @var Environment - */ - private $twig; - - /** - * Sender email address. - * - * @var string - */ - private $senderEmail; - - /** - * Sender name. - * - * @var string - */ - private $senderName; - - /** - * Support URL to report any bugs. - * - * @var string - */ - private $supportUrl; - - /** - * @param string $senderEmail - * @param string $senderName - * @param string $supportUrl wallabag support url - */ - public function __construct(MailerInterface $mailer, Environment $twig, $senderEmail, $senderName, $supportUrl) - { - $this->mailer = $mailer; - $this->twig = $twig; - $this->senderEmail = $senderEmail; - $this->senderName = $senderName; - $this->supportUrl = $supportUrl; + public function __construct( + private readonly MailerInterface $mailer, + private readonly Environment $twig, + private $senderEmail, + private $senderName, + private $supportUrl, + ) { } /** diff --git a/src/Operator/PHP/Matches.php b/src/Operator/PHP/Matches.php index 7d727bcae..c1c57b95f 100644 --- a/src/Operator/PHP/Matches.php +++ b/src/Operator/PHP/Matches.php @@ -20,6 +20,6 @@ class Matches return false; } - return false !== stripos($subject, $pattern); + return false !== stripos((string) $subject, (string) $pattern); } } diff --git a/src/Operator/PHP/NotMatches.php b/src/Operator/PHP/NotMatches.php index 9942a985f..ba36247f8 100644 --- a/src/Operator/PHP/NotMatches.php +++ b/src/Operator/PHP/NotMatches.php @@ -20,6 +20,6 @@ class NotMatches return true; } - return false === stripos($subject, $pattern); + return false === stripos((string) $subject, (string) $pattern); } } diff --git a/src/Operator/PHP/PatternMatches.php b/src/Operator/PHP/PatternMatches.php index 9c2aede3a..9321286e5 100644 --- a/src/Operator/PHP/PatternMatches.php +++ b/src/Operator/PHP/PatternMatches.php @@ -16,7 +16,7 @@ class PatternMatches { public function __invoke($subject, $pattern) { - $count = preg_match("`$pattern`i", $subject); + $count = preg_match("`$pattern`i", (string) $subject); return \is_int($count) && $count > 0; } diff --git a/src/ParamConverter/UsernameFeedTokenConverter.php b/src/ParamConverter/UsernameFeedTokenConverter.php index 67807efb9..8e54e874c 100644 --- a/src/ParamConverter/UsernameFeedTokenConverter.php +++ b/src/ParamConverter/UsernameFeedTokenConverter.php @@ -18,14 +18,12 @@ use Wallabag\Repository\UserRepository; */ class UsernameFeedTokenConverter implements ParamConverterInterface { - private $registry; - /** * @param ManagerRegistry $registry Manager registry */ - public function __construct(?ManagerRegistry $registry = null) - { - $this->registry = $registry; + public function __construct( + private readonly ?ManagerRegistry $registry = null, + ) { } /** @@ -50,7 +48,7 @@ class UsernameFeedTokenConverter implements ParamConverterInterface $em = $this->registry->getManagerForClass($configuration->getClass()); // Check, if class name is what we need - if (null !== $em && 'Wallabag\Entity\User' !== $em->getClassMetadata($configuration->getClass())->getName()) { + if (null !== $em && User::class !== $em->getClassMetadata($configuration->getClass())->getName()) { return false; } diff --git a/src/Redis/Producer.php b/src/Redis/Producer.php index 9cc64aae3..1e8c487d1 100644 --- a/src/Redis/Producer.php +++ b/src/Redis/Producer.php @@ -15,11 +15,9 @@ use Simpleue\Queue\RedisQueue; */ class Producer implements ProducerInterface { - private $queue; - - public function __construct(RedisQueue $queue) - { - $this->queue = $queue; + public function __construct( + private readonly RedisQueue $queue, + ) { } /** diff --git a/src/Repository/EntryRepository.php b/src/Repository/EntryRepository.php index 83b3c77a4..ded1e2d44 100644 --- a/src/Repository/EntryRepository.php +++ b/src/Repository/EntryRepository.php @@ -289,9 +289,7 @@ class EntryRepository extends ServiceEntityRepository if ('metadata' === $detail) { $fieldNames = $this->getClassMetadata()->getFieldNames(); - $fields = array_filter($fieldNames, function ($k) { - return 'content' !== $k; - }); + $fields = array_filter($fieldNames, fn ($k) => 'content' !== $k); $qb->select(\sprintf('partial e.{%s}', implode(',', $fields))); } diff --git a/src/Repository/SiteCredentialRepository.php b/src/Repository/SiteCredentialRepository.php index 086c23b2d..3e1d1a357 100644 --- a/src/Repository/SiteCredentialRepository.php +++ b/src/Repository/SiteCredentialRepository.php @@ -14,13 +14,11 @@ use Wallabag\Helper\CryptoProxy; */ class SiteCredentialRepository extends ServiceEntityRepository { - private $cryptoProxy; - - public function __construct(ManagerRegistry $registry, CryptoProxy $cryptoProxy) - { + public function __construct( + ManagerRegistry $registry, + private readonly CryptoProxy $cryptoProxy, + ) { parent::__construct($registry, SiteCredential::class); - - $this->cryptoProxy = $cryptoProxy; } /** diff --git a/src/Repository/TagRepository.php b/src/Repository/TagRepository.php index 3fe8a2e88..7440bf3c0 100644 --- a/src/Repository/TagRepository.php +++ b/src/Repository/TagRepository.php @@ -16,7 +16,7 @@ class TagRepository extends ServiceEntityRepository { public function __construct( ManagerRegistry $registry, - private string $tablePrefix, + private readonly string $tablePrefix, ) { parent::__construct($registry, Tag::class); } diff --git a/src/Security/Voter/AdminVoter.php b/src/Security/Voter/AdminVoter.php index f4d6dda68..4b96b75e7 100644 --- a/src/Security/Voter/AdminVoter.php +++ b/src/Security/Voter/AdminVoter.php @@ -14,11 +14,9 @@ class AdminVoter extends Voter public const LIST_IGNORE_ORIGIN_INSTANCE_RULES = 'LIST_IGNORE_ORIGIN_INSTANCE_RULES'; public const CREATE_IGNORE_ORIGIN_INSTANCE_RULES = 'CREATE_IGNORE_ORIGIN_INSTANCE_RULES'; - private Security $security; - - public function __construct(Security $security) - { - $this->security = $security; + public function __construct( + private readonly Security $security, + ) { } protected function supports(string $attribute, $subject): bool @@ -38,14 +36,9 @@ class AdminVoter extends Voter return false; } - switch ($attribute) { - case self::LIST_USERS: - case self::CREATE_USERS: - case self::LIST_IGNORE_ORIGIN_INSTANCE_RULES: - case self::CREATE_IGNORE_ORIGIN_INSTANCE_RULES: - return $this->security->isGranted('ROLE_SUPER_ADMIN'); - } - - return false; + return match ($attribute) { + self::LIST_USERS, self::CREATE_USERS, self::LIST_IGNORE_ORIGIN_INSTANCE_RULES, self::CREATE_IGNORE_ORIGIN_INSTANCE_RULES => $this->security->isGranted('ROLE_SUPER_ADMIN'), + default => false, + }; } } diff --git a/src/Security/Voter/AnnotationVoter.php b/src/Security/Voter/AnnotationVoter.php index 7bed72dbc..a4b021de6 100644 --- a/src/Security/Voter/AnnotationVoter.php +++ b/src/Security/Voter/AnnotationVoter.php @@ -35,12 +35,9 @@ class AnnotationVoter extends Voter return false; } - switch ($attribute) { - case self::EDIT: - case self::DELETE: - return $subject->getUser() === $user; - } - - return false; + return match ($attribute) { + self::EDIT, self::DELETE => $subject->getUser() === $user, + default => false, + }; } } diff --git a/src/Security/Voter/EntryVoter.php b/src/Security/Voter/EntryVoter.php index a9b354fea..202dacb8c 100644 --- a/src/Security/Voter/EntryVoter.php +++ b/src/Security/Voter/EntryVoter.php @@ -47,24 +47,9 @@ class EntryVoter extends Voter return false; } - switch ($attribute) { - case self::VIEW: - case self::EDIT: - case self::RELOAD: - case self::STAR: - case self::ARCHIVE: - case self::SHARE: - case self::UNSHARE: - case self::EXPORT: - case self::DELETE: - case self::LIST_ANNOTATIONS: - case self::CREATE_ANNOTATIONS: - case self::LIST_TAGS: - case self::TAG: - case self::UNTAG: - return $user === $subject->getUser(); - } - - return false; + return match ($attribute) { + self::VIEW, self::EDIT, self::RELOAD, self::STAR, self::ARCHIVE, self::SHARE, self::UNSHARE, self::EXPORT, self::DELETE, self::LIST_ANNOTATIONS, self::CREATE_ANNOTATIONS, self::LIST_TAGS, self::TAG, self::UNTAG => $user === $subject->getUser(), + default => false, + }; } } diff --git a/src/Security/Voter/IgnoreOriginInstanceRuleVoter.php b/src/Security/Voter/IgnoreOriginInstanceRuleVoter.php index d8ccf88e6..8035aed28 100644 --- a/src/Security/Voter/IgnoreOriginInstanceRuleVoter.php +++ b/src/Security/Voter/IgnoreOriginInstanceRuleVoter.php @@ -12,11 +12,9 @@ class IgnoreOriginInstanceRuleVoter extends Voter public const EDIT = 'EDIT'; public const DELETE = 'DELETE'; - private Security $security; - - public function __construct(Security $security) - { - $this->security = $security; + public function __construct( + private readonly Security $security, + ) { } protected function supports(string $attribute, $subject): bool @@ -34,12 +32,9 @@ class IgnoreOriginInstanceRuleVoter extends Voter protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool { - switch ($attribute) { - case self::EDIT: - case self::DELETE: - return $this->security->isGranted('ROLE_SUPER_ADMIN'); - } - - return false; + return match ($attribute) { + self::EDIT, self::DELETE => $this->security->isGranted('ROLE_SUPER_ADMIN'), + default => false, + }; } } diff --git a/src/Security/Voter/IgnoreOriginUserRuleVoter.php b/src/Security/Voter/IgnoreOriginUserRuleVoter.php index f7186f835..d6f9b15b6 100644 --- a/src/Security/Voter/IgnoreOriginUserRuleVoter.php +++ b/src/Security/Voter/IgnoreOriginUserRuleVoter.php @@ -35,12 +35,9 @@ class IgnoreOriginUserRuleVoter extends Voter return false; } - switch ($attribute) { - case self::EDIT: - case self::DELETE: - return $subject->getConfig()->getUser() === $user; - } - - return false; + return match ($attribute) { + self::EDIT, self::DELETE => $subject->getConfig()->getUser() === $user, + default => false, + }; } } diff --git a/src/Security/Voter/MainVoter.php b/src/Security/Voter/MainVoter.php index b1f918ece..478a08099 100644 --- a/src/Security/Voter/MainVoter.php +++ b/src/Security/Voter/MainVoter.php @@ -21,11 +21,9 @@ class MainVoter extends Voter public const CREATE_SITE_CREDENTIALS = 'CREATE_SITE_CREDENTIALS'; public const EDIT_CONFIG = 'EDIT_CONFIG'; - private Security $security; - - public function __construct(Security $security) - { - $this->security = $security; + public function __construct( + private readonly Security $security, + ) { } protected function supports(string $attribute, $subject): bool @@ -43,22 +41,9 @@ class MainVoter extends Voter protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool { - switch ($attribute) { - case self::LIST_ENTRIES: - case self::CREATE_ENTRIES: - case self::EDIT_ENTRIES: - case self::EXPORT_ENTRIES: - case self::IMPORT_ENTRIES: - case self::DELETE_ENTRIES: - case self::LIST_TAGS: - case self::CREATE_TAGS: - case self::DELETE_TAGS: - case self::LIST_SITE_CREDENTIALS: - case self::CREATE_SITE_CREDENTIALS: - case self::EDIT_CONFIG: - return $this->security->isGranted('ROLE_USER'); - } - - return false; + return match ($attribute) { + self::LIST_ENTRIES, self::CREATE_ENTRIES, self::EDIT_ENTRIES, self::EXPORT_ENTRIES, self::IMPORT_ENTRIES, self::DELETE_ENTRIES, self::LIST_TAGS, self::CREATE_TAGS, self::DELETE_TAGS, self::LIST_SITE_CREDENTIALS, self::CREATE_SITE_CREDENTIALS, self::EDIT_CONFIG => $this->security->isGranted('ROLE_USER'), + default => false, + }; } } diff --git a/src/Security/Voter/SiteCredentialVoter.php b/src/Security/Voter/SiteCredentialVoter.php index 35ab28484..89c6982d4 100644 --- a/src/Security/Voter/SiteCredentialVoter.php +++ b/src/Security/Voter/SiteCredentialVoter.php @@ -35,12 +35,9 @@ class SiteCredentialVoter extends Voter return false; } - switch ($attribute) { - case self::EDIT: - case self::DELETE: - return $user === $subject->getUser(); - } - - return false; + return match ($attribute) { + self::EDIT, self::DELETE => $user === $subject->getUser(), + default => false, + }; } } diff --git a/src/Security/Voter/TagVoter.php b/src/Security/Voter/TagVoter.php index e81b1944d..dccdde979 100644 --- a/src/Security/Voter/TagVoter.php +++ b/src/Security/Voter/TagVoter.php @@ -15,7 +15,7 @@ class TagVoter extends Voter public const DELETE = 'DELETE'; public function __construct( - private Security $security, + private readonly Security $security, ) { } @@ -42,13 +42,9 @@ class TagVoter extends Voter return false; } - switch ($attribute) { - case self::VIEW: - case self::EDIT: - case self::DELETE: - return $this->security->isGranted('ROLE_USER'); - } - - return false; + return match ($attribute) { + self::VIEW, self::EDIT, self::DELETE => $this->security->isGranted('ROLE_USER'), + default => false, + }; } } diff --git a/src/Security/Voter/TaggingRuleVoter.php b/src/Security/Voter/TaggingRuleVoter.php index 01113957d..fc98ac66b 100644 --- a/src/Security/Voter/TaggingRuleVoter.php +++ b/src/Security/Voter/TaggingRuleVoter.php @@ -35,12 +35,9 @@ class TaggingRuleVoter extends Voter return false; } - switch ($attribute) { - case self::EDIT: - case self::DELETE: - return $subject->getConfig()->getUser() === $user; - } - - return false; + return match ($attribute) { + self::EDIT, self::DELETE => $subject->getConfig()->getUser() === $user, + default => false, + }; } } diff --git a/src/Security/Voter/UserVoter.php b/src/Security/Voter/UserVoter.php index 876f29aff..8d111eeea 100644 --- a/src/Security/Voter/UserVoter.php +++ b/src/Security/Voter/UserVoter.php @@ -12,11 +12,9 @@ class UserVoter extends Voter public const EDIT = 'EDIT'; public const DELETE = 'DELETE'; - private Security $security; - - public function __construct(Security $security) - { - $this->security = $security; + public function __construct( + private readonly Security $security, + ) { } protected function supports(string $attribute, $subject): bool diff --git a/src/SiteConfig/ArraySiteConfigBuilder.php b/src/SiteConfig/ArraySiteConfigBuilder.php index d150650c4..c6d20a501 100644 --- a/src/SiteConfig/ArraySiteConfigBuilder.php +++ b/src/SiteConfig/ArraySiteConfigBuilder.php @@ -21,14 +21,10 @@ class ArraySiteConfigBuilder implements SiteConfigBuilder { $host = strtolower($host); - if ('www.' === substr($host, 0, 4)) { + if (str_starts_with($host, 'www.')) { $host = substr($host, 4); } - if (isset($this->configs[$host])) { - return $this->configs[$host]; - } - - return false; + return $this->configs[$host] ?? false; } } diff --git a/src/SiteConfig/GrabySiteConfigBuilder.php b/src/SiteConfig/GrabySiteConfigBuilder.php index dfe433408..91b143402 100644 --- a/src/SiteConfig/GrabySiteConfigBuilder.php +++ b/src/SiteConfig/GrabySiteConfigBuilder.php @@ -9,35 +9,15 @@ use Wallabag\Repository\SiteCredentialRepository; class GrabySiteConfigBuilder implements SiteConfigBuilder { - /** - * @var ConfigBuilder - */ - private $grabyConfigBuilder; - - /** - * @var SiteCredentialRepository - */ - private $credentialRepository; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @var TokenStorageInterface - */ - private $token; - /** * GrabySiteConfigBuilder constructor. */ - public function __construct(ConfigBuilder $grabyConfigBuilder, TokenStorageInterface $token, SiteCredentialRepository $credentialRepository, LoggerInterface $logger) - { - $this->grabyConfigBuilder = $grabyConfigBuilder; - $this->credentialRepository = $credentialRepository; - $this->logger = $logger; - $this->token = $token; + public function __construct( + private readonly ConfigBuilder $grabyConfigBuilder, + private readonly TokenStorageInterface $token, + private readonly SiteCredentialRepository $credentialRepository, + private readonly LoggerInterface $logger, + ) { } public function buildForHost($host) @@ -46,7 +26,7 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder // required by credentials below $host = strtolower($host); - if ('www.' === substr($host, 0, 4)) { + if (str_starts_with($host, 'www.')) { $host = substr($host, 4); } @@ -115,11 +95,11 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder $extraFields = []; foreach ($extraFieldsStrings as $extraField) { - if (!str_contains($extraField, '=')) { + if (!str_contains((string) $extraField, '=')) { continue; } - list($fieldName, $fieldValue) = explode('=', $extraField, 2); + [$fieldName, $fieldValue] = explode('=', (string) $extraField, 2); $extraFields[$fieldName] = $fieldValue; } diff --git a/src/SiteConfig/LoginFormAuthenticator.php b/src/SiteConfig/LoginFormAuthenticator.php index 6a6eff8f1..5afd89648 100644 --- a/src/SiteConfig/LoginFormAuthenticator.php +++ b/src/SiteConfig/LoginFormAuthenticator.php @@ -9,12 +9,12 @@ use Wallabag\ExpressionLanguage\AuthenticatorProvider; class LoginFormAuthenticator { - private HttpBrowser $browser; - private ExpressionLanguage $expressionLanguage; + private readonly ExpressionLanguage $expressionLanguage; - public function __construct(HttpBrowser $browser, AuthenticatorProvider $authenticatorProvider) - { - $this->browser = $browser; + public function __construct( + private readonly HttpBrowser $browser, + AuthenticatorProvider $authenticatorProvider, + ) { $this->expressionLanguage = new ExpressionLanguage(null, [$authenticatorProvider]); } @@ -66,7 +66,7 @@ class LoginFormAuthenticator $crawler = new Crawler((string) $html); $loggedIn = $crawler->evaluate((string) $siteConfig->getNotLoggedInXpath()); - } catch (\Throwable $e) { + } catch (\Throwable) { return false; } @@ -98,9 +98,9 @@ class LoginFormAuthenticator $extraFields = []; foreach ($siteConfig->getExtraFields() as $fieldName => $fieldValue) { - if ('@=' === substr($fieldValue, 0, 2)) { + if (str_starts_with((string) $fieldValue, '@=')) { $fieldValue = $this->expressionLanguage->evaluate( - substr($fieldValue, 2), + substr((string) $fieldValue, 2), [ 'config' => $siteConfig, ] diff --git a/src/Twig/WallabagExtension.php b/src/Twig/WallabagExtension.php index f21187414..604b5c526 100644 --- a/src/Twig/WallabagExtension.php +++ b/src/Twig/WallabagExtension.php @@ -15,23 +15,15 @@ use Wallabag\Repository\TagRepository; class WallabagExtension extends AbstractExtension implements GlobalsInterface { - private $tokenStorage; - private $entryRepository; - private $annotationRepository; - private $tagRepository; - private $lifeTime; - private $translator; - private $projectDir; - - public function __construct(EntryRepository $entryRepository, AnnotationRepository $annotationRepository, TagRepository $tagRepository, TokenStorageInterface $tokenStorage, $lifeTime, TranslatorInterface $translator, string $projectDir) - { - $this->entryRepository = $entryRepository; - $this->annotationRepository = $annotationRepository; - $this->tagRepository = $tagRepository; - $this->tokenStorage = $tokenStorage; - $this->lifeTime = $lifeTime; - $this->translator = $translator; - $this->projectDir = $projectDir; + public function __construct( + private readonly EntryRepository $entryRepository, + private readonly AnnotationRepository $annotationRepository, + private readonly TagRepository $tagRepository, + private readonly TokenStorageInterface $tokenStorage, + private $lifeTime, + private readonly TranslatorInterface $translator, + private readonly string $projectDir, + ) { } public function getGlobals(): array @@ -42,20 +34,20 @@ class WallabagExtension extends AbstractExtension implements GlobalsInterface public function getFilters(): array { return [ - new TwigFilter('removeWww', [$this, 'removeWww']), - new TwigFilter('removeScheme', [$this, 'removeScheme']), - new TwigFilter('removeSchemeAndWww', [$this, 'removeSchemeAndWww']), + new TwigFilter('removeWww', $this->removeWww(...)), + new TwigFilter('removeScheme', $this->removeScheme(...)), + new TwigFilter('removeSchemeAndWww', $this->removeSchemeAndWww(...)), ]; } public function getFunctions(): array { return [ - new TwigFunction('count_entries', [$this, 'countEntries']), - new TwigFunction('count_tags', [$this, 'countTags']), - new TwigFunction('display_stats', [$this, 'displayStats']), - new TwigFunction('asset_file_exists', [$this, 'assetFileExists']), - new TwigFunction('theme_class', [$this, 'themeClass']), + new TwigFunction('count_entries', $this->countEntries(...)), + new TwigFunction('count_tags', $this->countTags(...)), + new TwigFunction('display_stats', $this->displayStats(...)), + new TwigFunction('asset_file_exists', $this->assetFileExists(...)), + new TwigFunction('theme_class', $this->themeClass(...)), ]; } @@ -97,25 +89,14 @@ class WallabagExtension extends AbstractExtension implements GlobalsInterface return 0; } - switch ($type) { - case 'starred': - $qb = $this->entryRepository->getCountBuilderForStarredByUser($user->getId())->select('COUNT(e.id)'); - break; - case 'archive': - $qb = $this->entryRepository->getCountBuilderForArchiveByUser($user->getId())->select('COUNT(e.id)'); - break; - case 'unread': - $qb = $this->entryRepository->getCountBuilderForUnreadByUser($user->getId())->select('COUNT(e.id)'); - break; - case 'annotated': - $qb = $this->annotationRepository->getCountBuilderByUser($user->getId())->select('COUNT(DISTINCT e.entry)'); - break; - case 'all': - $qb = $this->entryRepository->getCountBuilderForAllByUser($user->getId())->select('COUNT(e.id)'); - break; - default: - throw new \InvalidArgumentException(\sprintf('Type "%s" is not implemented.', $type)); - } + $qb = match ($type) { + 'starred' => $this->entryRepository->getCountBuilderForStarredByUser($user->getId())->select('COUNT(e.id)'), + 'archive' => $this->entryRepository->getCountBuilderForArchiveByUser($user->getId())->select('COUNT(e.id)'), + 'unread' => $this->entryRepository->getCountBuilderForUnreadByUser($user->getId())->select('COUNT(e.id)'), + 'annotated' => $this->annotationRepository->getCountBuilderByUser($user->getId())->select('COUNT(DISTINCT e.entry)'), + 'all' => $this->entryRepository->getCountBuilderForAllByUser($user->getId())->select('COUNT(e.id)'), + default => throw new \InvalidArgumentException(\sprintf('Type "%s" is not implemented.', $type)), + }; $query = $qb->getQuery(); $query->useQueryCache(true); diff --git a/tests/Consumer/AMQPEntryConsumerTest.php b/tests/Consumer/AMQPEntryConsumerTest.php index b12aa0f6b..c0940298c 100644 --- a/tests/Consumer/AMQPEntryConsumerTest.php +++ b/tests/Consumer/AMQPEntryConsumerTest.php @@ -25,7 +25,7 @@ class AMQPEntryConsumerTest extends TestCase ->method('flush'); $em - ->expects($this->exactly(2)) + ->expects($this->once()) ->method('clear'); $body = <<<'JSON' diff --git a/tests/Consumer/RedisEntryConsumerTest.php b/tests/Consumer/RedisEntryConsumerTest.php index 6aa749f7d..0d4c6b758 100644 --- a/tests/Consumer/RedisEntryConsumerTest.php +++ b/tests/Consumer/RedisEntryConsumerTest.php @@ -24,7 +24,7 @@ class RedisEntryConsumerTest extends TestCase ->method('flush'); $em - ->expects($this->exactly(2)) + ->expects($this->once()) ->method('clear'); $body = <<<'JSON' diff --git a/tests/Controller/Api/DeveloperControllerTest.php b/tests/Controller/Api/DeveloperControllerTest.php index f37923121..ab0b62d7d 100644 --- a/tests/Controller/Api/DeveloperControllerTest.php +++ b/tests/Controller/Api/DeveloperControllerTest.php @@ -50,7 +50,7 @@ class DeveloperControllerTest extends WallabagTestCase $this->assertSame(200, $client->getResponse()->getStatusCode()); - $data = json_decode($client->getResponse()->getContent(), true); + $data = json_decode((string) $client->getResponse()->getContent(), true); $this->assertArrayHasKey('access_token', $data); $this->assertArrayHasKey('expires_in', $data); $this->assertArrayHasKey('token_type', $data); diff --git a/tests/Controller/Api/TagRestControllerTest.php b/tests/Controller/Api/TagRestControllerTest.php index 71115f4a3..927a2a236 100644 --- a/tests/Controller/Api/TagRestControllerTest.php +++ b/tests/Controller/Api/TagRestControllerTest.php @@ -23,9 +23,7 @@ class TagRestControllerTest extends WallabagApiTestCase $this->assertArrayHasKey('label', $content[0]); $this->assertArrayHasKey('nbEntries', $content[0]); - $tagLabels = array_map(function ($i) { - return $i['label']; - }, $content); + $tagLabels = array_map(fn ($i) => $i['label'], $content); $this->assertNotContains($this->otherUserTagLabel, $tagLabels, 'There is a possible tag leak'); } diff --git a/tests/Controller/ConfigControllerTest.php b/tests/Controller/ConfigControllerTest.php index 3e097994c..301ece136 100644 --- a/tests/Controller/ConfigControllerTest.php +++ b/tests/Controller/ConfigControllerTest.php @@ -351,7 +351,7 @@ class ConfigControllerTest extends WallabagTestCase ); $this->assertSame(200, $client->getResponse()->getStatusCode()); - $content = json_decode($client->getResponse()->getContent(), true); + $content = json_decode((string) $client->getResponse()->getContent(), true); $this->assertArrayHasKey('token', $content); } @@ -1296,7 +1296,7 @@ class ConfigControllerTest extends WallabagTestCase $this->assertSame('attachment; filename="tagging_rules_admin.json"', $headers->get('content-disposition')); $this->assertSame('UTF-8', $headers->get('content-transfer-encoding')); - $content = json_decode($client->getResponse()->getContent(), true); + $content = json_decode((string) $client->getResponse()->getContent(), true); $this->assertCount(4, $content); $this->assertSame('content matches "spurs"', $content[0]['rule']); diff --git a/tests/Controller/EntryControllerTest.php b/tests/Controller/EntryControllerTest.php index dd1a33c3f..b7d020a80 100644 --- a/tests/Controller/EntryControllerTest.php +++ b/tests/Controller/EntryControllerTest.php @@ -1283,7 +1283,7 @@ class EntryControllerTest extends WallabagTestCase $this->assertSame($url, $entry->getUrl()); $this->assertStringContainsString('Comment Hidalgo', $entry->getTitle()); // instead of checking for the filename (which might change) check that the image is now local - $this->assertStringContainsString(rtrim($client->getContainer()->getParameter('domain_name'), '/') . '/assets/images/', $entry->getContent()); + $this->assertStringContainsString(rtrim((string) $client->getContainer()->getParameter('domain_name'), '/') . '/assets/images/', $entry->getContent()); $client->getContainer()->get(Config::class)->set('download_images_enabled', 0); } diff --git a/tests/Controller/ExportControllerTest.php b/tests/Controller/ExportControllerTest.php index bb8e6995f..0a5c56c2e 100644 --- a/tests/Controller/ExportControllerTest.php +++ b/tests/Controller/ExportControllerTest.php @@ -177,7 +177,7 @@ class ExportControllerTest extends WallabagTestCase $this->assertSame('attachment; filename="Archive articles.csv"', $headers->get('content-disposition')); $this->assertSame('UTF-8', $headers->get('content-transfer-encoding')); - $csv = str_getcsv($client->getResponse()->getContent(), "\n"); + $csv = str_getcsv((string) $client->getResponse()->getContent(), "\n"); $this->assertGreaterThan(1, $csv); // +1 for title line @@ -216,7 +216,7 @@ class ExportControllerTest extends WallabagTestCase $this->assertSame('attachment; filename="' . $this->getSanitizedFilename($contentInDB->getTitle()) . '.json"', $headers->get('content-disposition')); $this->assertSame('UTF-8', $headers->get('content-transfer-encoding')); - $content = json_decode($client->getResponse()->getContent(), true); + $content = json_decode((string) $client->getResponse()->getContent(), true); $this->assertArrayHasKey('id', $content[0]); $this->assertArrayHasKey('title', $content[0]); $this->assertArrayHasKey('url', $content[0]); @@ -262,7 +262,7 @@ class ExportControllerTest extends WallabagTestCase $this->assertSame('attachment; filename="Search entry search articles.json"', $headers->get('content-disposition')); $this->assertSame('UTF-8', $headers->get('content-transfer-encoding')); - $content = json_decode($client->getResponse()->getContent(), true); + $content = json_decode((string) $client->getResponse()->getContent(), true); $this->assertCount(1, $content); $this->tearDownForJsonExportFromSearch(); @@ -339,7 +339,7 @@ class ExportControllerTest extends WallabagTestCase $this->assertSame('attachment; filename="Same domain articles.json"', $headers->get('content-disposition')); $this->assertSame('UTF-8', $headers->get('content-transfer-encoding')); - $content = json_decode($client->getResponse()->getContent(), true); + $content = json_decode((string) $client->getResponse()->getContent(), true); $this->assertCount(4, $content); } diff --git a/tests/Controller/FeedControllerTest.php b/tests/Controller/FeedControllerTest.php index 80cdeabb4..0359e8888 100644 --- a/tests/Controller/FeedControllerTest.php +++ b/tests/Controller/FeedControllerTest.php @@ -36,7 +36,7 @@ class FeedControllerTest extends WallabagTestCase $this->assertSame('admin', $xpath->query('/a:feed/a:author/a:name')->item(0)->nodeValue); $this->assertSame(1, $xpath->query('/a:feed/a:subtitle')->length); - if (null !== $tagValue && str_starts_with($type, 'tag')) { + if (null !== $tagValue && str_starts_with((string) $type, 'tag')) { $this->assertSame('wallabag — ' . $type . ' ' . $tagValue . ' feed', $xpath->query('/a:feed/a:title')->item(0)->nodeValue); $this->assertSame('Atom feed for entries tagged with ' . $tagValue, $xpath->query('/a:feed/a:subtitle')->item(0)->nodeValue); } else { diff --git a/tests/Event/Subscriber/TablePrefixSubscriberTest.php b/tests/Event/Subscriber/TablePrefixSubscriberTest.php index fa0c37e38..2872fb23f 100644 --- a/tests/Event/Subscriber/TablePrefixSubscriberTest.php +++ b/tests/Event/Subscriber/TablePrefixSubscriberTest.php @@ -11,6 +11,7 @@ use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\DefaultQuoteStrategy; use PHPUnit\Framework\TestCase; +use Wallabag\Entity\Entry; use Wallabag\Entity\User; use Wallabag\Event\Subscriber\TablePrefixSubscriber; @@ -94,7 +95,7 @@ class TablePrefixSubscriberTest extends TestCase $subscriber = new TablePrefixSubscriber('yo_'); - $metaClass = new ClassMetadata('Wallabag\Entity\Entry'); + $metaClass = new ClassMetadata(Entry::class); $metaClass->setPrimaryTable(['name' => 'entry']); $metaClass->mapManyToMany([ 'fieldName' => 'tags', diff --git a/tests/Helper/ContentProxyTest.php b/tests/Helper/ContentProxyTest.php index 18e349135..075c66cf7 100644 --- a/tests/Helper/ContentProxyTest.php +++ b/tests/Helper/ContentProxyTest.php @@ -1074,7 +1074,7 @@ class ContentProxyTest extends TestCase private function strToHex($string) { $hex = ''; - for ($i = 0; $i < \strlen($string); ++$i) { + for ($i = 0; $i < \strlen((string) $string); ++$i) { $ord = \ord($string[$i]); $hexCode = dechex($ord); $hex .= substr('0' . $hexCode, -2); @@ -1093,7 +1093,7 @@ class ContentProxyTest extends TestCase private function hexToStr($hex) { $string = ''; - for ($i = 0; $i < \strlen($hex) - 1; $i += 2) { + for ($i = 0; $i < \strlen((string) $hex) - 1; $i += 2) { $string .= \chr(hexdec($hex[$i] . $hex[$i + 1])); } diff --git a/tests/Import/ChromeImportTest.php b/tests/Import/ChromeImportTest.php index 35ab0aa67..558bfdec9 100644 --- a/tests/Import/ChromeImportTest.php +++ b/tests/Import/ChromeImportTest.php @@ -95,9 +95,7 @@ class ChromeImportTest extends TestCase $this->em ->expects($this->any()) ->method('persist') - ->with($this->callback(function ($persistedEntry) { - return (bool) $persistedEntry->isArchived(); - })); + ->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived())); $res = $chromeImport->setMarkAsRead(true)->import(); diff --git a/tests/Import/FirefoxImportTest.php b/tests/Import/FirefoxImportTest.php index 7250c412b..5ed6cb550 100644 --- a/tests/Import/FirefoxImportTest.php +++ b/tests/Import/FirefoxImportTest.php @@ -95,9 +95,7 @@ class FirefoxImportTest extends TestCase $this->em ->expects($this->any()) ->method('persist') - ->with($this->callback(function ($persistedEntry) { - return (bool) $persistedEntry->isArchived(); - })); + ->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived())); $res = $firefoxImport->setMarkAsRead(true)->import(); diff --git a/tests/Import/InstapaperImportTest.php b/tests/Import/InstapaperImportTest.php index 17a7b4e21..aaba729e4 100644 --- a/tests/Import/InstapaperImportTest.php +++ b/tests/Import/InstapaperImportTest.php @@ -97,9 +97,7 @@ class InstapaperImportTest extends TestCase $this->em ->expects($this->once()) ->method('persist') - ->with($this->callback(function ($persistedEntry) { - return (bool) $persistedEntry->isArchived(); - })); + ->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived())); $res = $instapaperImport->setMarkAsRead(true)->import(); diff --git a/tests/Import/PocketHtmlImportTest.php b/tests/Import/PocketHtmlImportTest.php index 0f97a50c0..6bea2b98c 100644 --- a/tests/Import/PocketHtmlImportTest.php +++ b/tests/Import/PocketHtmlImportTest.php @@ -95,9 +95,7 @@ class PocketHtmlImportTest extends TestCase $this->em ->expects($this->any()) ->method('persist') - ->with($this->callback(function ($persistedEntry) { - return (bool) $persistedEntry->isArchived(); - })); + ->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived())); $res = $pocketHtmlImport ->setMarkAsRead(true) diff --git a/tests/Import/PocketImportTest.php b/tests/Import/PocketImportTest.php index dc0880360..1b8828382 100644 --- a/tests/Import/PocketImportTest.php +++ b/tests/Import/PocketImportTest.php @@ -207,9 +207,7 @@ JSON $this->em ->expects($this->any()) ->method('persist') - ->with($this->callback(function ($persistedEntry) { - return (bool) $persistedEntry->isArchived() && (bool) $persistedEntry->isStarred(); - })); + ->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived() && (bool) $persistedEntry->isStarred())); $entry = new Entry($this->user); @@ -299,9 +297,7 @@ JSON $this->em ->expects($this->any()) ->method('persist') - ->with($this->callback(function ($persistedEntry) { - return (bool) $persistedEntry->isArchived(); - })); + ->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived())); $entry = new Entry($this->user); diff --git a/tests/Import/ReadabilityImportTest.php b/tests/Import/ReadabilityImportTest.php index 851130bf9..cc7b7d828 100644 --- a/tests/Import/ReadabilityImportTest.php +++ b/tests/Import/ReadabilityImportTest.php @@ -95,9 +95,7 @@ class ReadabilityImportTest extends TestCase $this->em ->expects($this->any()) ->method('persist') - ->with($this->callback(function ($persistedEntry) { - return (bool) $persistedEntry->isArchived(); - })); + ->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived())); $res = $readabilityImport->setMarkAsRead(true)->import(); diff --git a/tests/Import/ShaarliImportTest.php b/tests/Import/ShaarliImportTest.php index f041e3005..7510a28e6 100644 --- a/tests/Import/ShaarliImportTest.php +++ b/tests/Import/ShaarliImportTest.php @@ -95,9 +95,7 @@ class ShaarliImportTest extends TestCase $this->em ->expects($this->any()) ->method('persist') - ->with($this->callback(function ($persistedEntry) { - return (bool) $persistedEntry->isArchived(); - })); + ->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived())); $res = $shaarliImport ->setMarkAsRead(true) diff --git a/tests/Import/WallabagV1ImportTest.php b/tests/Import/WallabagV1ImportTest.php index f51a39edf..7b9cbe558 100644 --- a/tests/Import/WallabagV1ImportTest.php +++ b/tests/Import/WallabagV1ImportTest.php @@ -99,9 +99,7 @@ class WallabagV1ImportTest extends TestCase $this->em ->expects($this->any()) ->method('persist') - ->with($this->callback(function ($persistedEntry) { - return (bool) $persistedEntry->isArchived(); - })); + ->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived())); $res = $wallabagV1Import->setMarkAsRead(true)->import(); diff --git a/tests/Import/WallabagV2ImportTest.php b/tests/Import/WallabagV2ImportTest.php index cfe8e95de..04a772f40 100644 --- a/tests/Import/WallabagV2ImportTest.php +++ b/tests/Import/WallabagV2ImportTest.php @@ -93,9 +93,7 @@ class WallabagV2ImportTest extends TestCase $this->em ->expects($this->any()) ->method('persist') - ->with($this->callback(function ($persistedEntry) { - return (bool) $persistedEntry->isArchived(); - })); + ->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived())); $res = $wallabagV2Import->setMarkAsRead(true)->import(); diff --git a/tests/WallabagTestCase.php b/tests/WallabagTestCase.php index 8f70a115e..9b31f8029 100644 --- a/tests/WallabagTestCase.php +++ b/tests/WallabagTestCase.php @@ -3,6 +3,7 @@ namespace Tests\Wallabag; use Doctrine\ORM\EntityManagerInterface; +use Predis\Client; use Symfony\Bundle\FrameworkBundle\KernelBrowser; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; @@ -118,8 +119,8 @@ abstract class WallabagTestCase extends WebTestCase protected function checkRedis() { try { - $this->client->getContainer()->get(\Predis\Client::class)->connect(); - } catch (\Exception $e) { + $this->client->getContainer()->get(Client::class)->connect(); + } catch (\Exception) { $this->markTestSkipped('Redis is not installed/activated'); } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index fad77b3bb..370282e93 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -15,7 +15,7 @@ if (!isPartialRun()) { '--force', '--env=test', '--no-debug', - ]))->run(function ($type, $buffer) { + ]))->run(function ($type, $buffer): void { echo $buffer; }); @@ -25,7 +25,7 @@ if (!isPartialRun()) { 'doctrine:database:create', '--env=test', '--no-debug', - ]))->mustRun(function ($type, $buffer) { + ]))->mustRun(function ($type, $buffer): void { echo $buffer; }); @@ -37,7 +37,7 @@ if (!isPartialRun()) { '--env=test', '--no-debug', '-vv', - ]))->mustRun(function ($type, $buffer) { + ]))->mustRun(function ($type, $buffer): void { echo $buffer; }); @@ -48,7 +48,7 @@ if (!isPartialRun()) { '--no-interaction', '--env=test', '-v', - ]))->mustRun(function ($type, $buffer) { + ]))->mustRun(function ($type, $buffer): void { echo $buffer; }); } @@ -60,6 +60,6 @@ if (!isPartialRun()) { '--no-interaction', '--env=test', '--no-debug', -]))->mustRun(function ($type, $buffer) { +]))->mustRun(function ($type, $buffer): void { echo $buffer; }); diff --git a/tests/functions.php b/tests/functions.php index a9b8881a7..02ab70fe7 100644 --- a/tests/functions.php +++ b/tests/functions.php @@ -11,19 +11,19 @@ function isPartialRun(): bool { foreach ($_SERVER['argv'] as $arg) { - if (str_starts_with($arg, '--filter')) { + if (str_starts_with((string) $arg, '--filter')) { return true; } - if (str_starts_with($arg, '--testsuite')) { + if (str_starts_with((string) $arg, '--testsuite')) { return true; } - if (str_starts_with($arg, '--group')) { + if (str_starts_with((string) $arg, '--group')) { return true; } - if (str_starts_with($arg, '--exclude-group')) { + if (str_starts_with((string) $arg, '--exclude-group')) { return true; } }