From 9980288a2aadbc2ba4f15ee82ee9be79a9cd01f4 Mon Sep 17 00:00:00 2001 From: Alexey Skobkin Date: Fri, 8 Jul 2022 04:46:36 +0300 Subject: [PATCH] PHP code modernization work. Not finished. --- config/packages/doctrine.yaml | 4 +- config/packages/security.yaml | 5 +- .../V1/Controller/AbstractApiController.php | 1 + src/Api/V1/Controller/RssController.php | 1 + src/Api/V1/Controller/SecurityController.php | 1 + src/Api/V1/Controller/TorrentController.php | 1 + src/Api/V1/DTO/ApiResponse.php | 38 +++---- src/Api/V1/DTO/ListPage.php | 43 +++----- src/Command/AddInvitesCommand.php | 29 ++---- src/Command/AddUserCommand.php | 32 ++---- src/Controller/AccountController.php | 7 +- src/Controller/MagnetRedirectController.php | 1 + src/Controller/MainController.php | 1 + src/Controller/SecurityController.php | 1 + src/Controller/TorrentController.php | 1 + src/Controller/UserController.php | 1 + src/Doctrine/ORM/AST/BaseFunction.php | 10 +- src/Doctrine/ORM/AST/Ilike.php | 1 - src/Entity/ApiToken.php | 41 +++----- src/Entity/Invite.php | 52 ++++------ src/Entity/PasswordResetToken.php | 36 +++---- src/Entity/User.php | 98 ++++++++----------- src/Feed/RssGenerator.php | 16 +-- src/Form/Data/PasswordResetData.php | 13 +-- src/Form/Data/PasswordResetRequestData.php | 19 ++-- src/Form/Data/RegisterData.php | 41 +++----- src/Form/LoginType.php | 5 +- src/Form/PasswordResetRequestType.php | 1 + src/Form/PasswordResetType.php | 3 +- src/Form/RegisterType.php | 1 + ...lder.php => BsTreeviewFileTreeBuilder.php} | 5 +- src/Helper/FileSizeHumanizer.php | 6 +- src/Kernel.php | 1 + src/Magnet/MagnetGenerator.php | 3 +- src/Magnetico/Entity/File.php | 53 ++++------ src/Magnetico/Entity/Torrent.php | 85 ++++++---------- .../Repository/TorrentRepository.php | 3 +- .../View/TwitterBootstrap4PagelessView.php | 14 ++- src/Repository/ApiTokenRepository.php | 3 +- src/Repository/InviteRepository.php | 3 +- .../PasswordResetTokenRepository.php | 1 + src/Repository/UserRepository.php | 3 +- src/Search/TorrentSearcher.php | 13 +-- src/Twig/FileSizeHumanizerExtension.php | 3 +- src/Twig/FileTreeExtension.php | 9 +- src/Twig/MagnetExtension.php | 13 ++- src/User/Exception/InvalidInviteException.php | 3 +- src/User/Exception/UserNotFoundException.php | 1 + src/User/InviteManager.php | 18 ++-- src/User/PasswordResetManager.php | 39 ++------ src/User/UserManager.php | 29 ++---- src/Validator/Constraints/ValidInvite.php | 9 +- .../Constraints/ValidInviteValidator.php | 14 ++- src/View/Torrent/FileTreeNode.php | 15 +-- 54 files changed, 309 insertions(+), 541 deletions(-) rename src/Helper/{BstreeviewFileTreeBuilder.php => BsTreeviewFileTreeBuilder.php} (96%) diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml index 7b61471..b24bd9e 100644 --- a/config/packages/doctrine.yaml +++ b/config/packages/doctrine.yaml @@ -30,7 +30,7 @@ doctrine: mappings: App: is_bundle: false - type: annotation + type: attribute dir: '%kernel.project_dir%/src/Entity' prefix: 'App\Entity' alias: App @@ -39,7 +39,7 @@ doctrine: mappings: Magnetico: is_bundle: false - type: annotation + type: attribute dir: '%kernel.project_dir%/src/Magnetico/Entity' prefix: 'App\Magnetico' alias: Magnetico diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 7c1819f..915e43b 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -6,10 +6,9 @@ security: class: App\Entity\User property: username manager_name: default - encoders: + password_hashers: App\Entity\User: - # https://symfony.com/blog/new-in-symfony-4-3-native-password-encoder - algorithm: 'auto' + algorithm: sodium firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ diff --git a/src/Api/V1/Controller/AbstractApiController.php b/src/Api/V1/Controller/AbstractApiController.php index 9ae216d..c6a91d2 100644 --- a/src/Api/V1/Controller/AbstractApiController.php +++ b/src/Api/V1/Controller/AbstractApiController.php @@ -1,4 +1,5 @@ em = $em; - $this->userRepo = $userRepo; - $this->inviteManager = $inviteManager; } protected function configure() @@ -38,15 +29,15 @@ class AddInvitesCommand extends Command ; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $username = $input->getArgument('username'); - $number = $input->getArgument('number'); + $number = (int) $input->getArgument('number'); if (null === $user = $this->userRepo->findOneBy(['username' => $username])) { $output->writeln('User not found.'); - return 1; + return Command::FAILURE; } $this->inviteManager->createInvitesForUser($user, $number); @@ -55,6 +46,6 @@ class AddInvitesCommand extends Command $output->writeln(sprintf('%d invites added to \'%s\'.', $number, $user->getUsername())); - return 0; + return Command::SUCCESS; } } diff --git a/src/Command/AddUserCommand.php b/src/Command/AddUserCommand.php index 7609362..8f4da3c 100644 --- a/src/Command/AddUserCommand.php +++ b/src/Command/AddUserCommand.php @@ -1,4 +1,5 @@ em = $em; - $this->userManager = $userManager; - $this->userRepo = $userRepo; - $this->inviteManager = $inviteManager; } protected function configure() @@ -47,7 +35,7 @@ class AddUserCommand extends Command ; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $username = $input->getArgument('username'); $email = $input->getArgument('email'); @@ -68,7 +56,7 @@ class AddUserCommand extends Command if (!$password) { $output->writeln('User password cannot be empty.'); - return 1; + return Command::FAILURE; } if ($roles) { @@ -88,7 +76,7 @@ class AddUserCommand extends Command $output->writeln(sprintf('User \'%s\' registered, %d invites added.', $user->getUsername(), $invites)); - return 0; + return Command::SUCCESS; } } \ No newline at end of file diff --git a/src/Controller/AccountController.php b/src/Controller/AccountController.php index 3ee3608..5792131 100644 --- a/src/Controller/AccountController.php +++ b/src/Controller/AccountController.php @@ -1,11 +1,10 @@ functionPrototype, $dispatched); } -} \ No newline at end of file +} diff --git a/src/Doctrine/ORM/AST/Ilike.php b/src/Doctrine/ORM/AST/Ilike.php index b9c374c..da9fc65 100644 --- a/src/Doctrine/ORM/AST/Ilike.php +++ b/src/Doctrine/ORM/AST/Ilike.php @@ -1,5 +1,4 @@ createdAt; } -} \ No newline at end of file +} diff --git a/src/Entity/Invite.php b/src/Entity/Invite.php index 00f3838..ce77b06 100644 --- a/src/Entity/Invite.php +++ b/src/Entity/Invite.php @@ -1,51 +1,35 @@ user = $forUser; - $this->code = md5(random_bytes(100)); + $this->code = md5(\random_bytes(100)); } public function getId(): int @@ -81,4 +65,4 @@ class Invite $this->usedBy = $user; } -} \ No newline at end of file +} diff --git a/src/Entity/PasswordResetToken.php b/src/Entity/PasswordResetToken.php index c5645c6..6bfdbb3 100644 --- a/src/Entity/PasswordResetToken.php +++ b/src/Entity/PasswordResetToken.php @@ -1,38 +1,24 @@ username = $username; - $this->password = $encoder->encodePassword($rawPassword, null); + $this->password = $hasher->hash($rawPassword); $this->email = $email; $this->roles = $roles ?: ['ROLE_USER']; $this->createdAt = new \DateTime(); @@ -78,22 +51,29 @@ class User implements UserInterface, \Serializable return $this->id; } - public function getUsername() + public function getUserIdentifier(): string { return $this->username; } - public function getPassword() + /** @deprecated since Symfony 5.3, use getUserIdentifier() instead */ + public function getUsername(): string + { + return $this->username; + } + + public function getPassword(): string { return $this->password; } - public function changePassword(PasswordEncoderInterface $encoder, string $rawPassword): void + public function changePassword(PasswordHasherInterface $hasher, string $rawPassword): void { - $this->password = $encoder->encodePassword($rawPassword, null); + $this->password = $hasher->hash($rawPassword); } - public function getSalt() + /** @deprecated since Symfony 5.3 */ + public function getSalt(): ?string { // Salt is not needed when using Argon2i // @see https://symfony.com/doc/current/reference/configuration/security.html#using-the-argon2i-password-encoder @@ -132,7 +112,7 @@ class User implements UserInterface, \Serializable } /** @see \Serializable::serialize() */ - public function serialize() + public function serialize(): string { return serialize([ $this->id, @@ -142,7 +122,7 @@ class User implements UserInterface, \Serializable } /** @see \Serializable::unserialize() */ - public function unserialize($serialized) + public function unserialize($serialized): void { [ $this->id, diff --git a/src/Feed/RssGenerator.php b/src/Feed/RssGenerator.php index 4bfd38a..34365d1 100644 --- a/src/Feed/RssGenerator.php +++ b/src/Feed/RssGenerator.php @@ -1,7 +1,6 @@ repo = $repo; - $this->router = $router; - $this->magnetGenerator = $magnetGenerator; } public function generateLast(int $page): string @@ -43,8 +39,6 @@ class RssGenerator /** * @param Torrent[] $torrents - * - * @return Feed */ private function createFeedFromTorrents(array $torrents): Feed { diff --git a/src/Form/Data/PasswordResetData.php b/src/Form/Data/PasswordResetData.php index 8ad6564..c170517 100644 --- a/src/Form/Data/PasswordResetData.php +++ b/src/Form/Data/PasswordResetData.php @@ -1,4 +1,5 @@ = $factor) { - $suffixIndex = $factor; - } else { - $suffixIndex = $maxSuffixIndex; - } + $suffixIndex = min($maxSuffixIndex, $factor); $suffix = self::SIZE_SUFFIXES[$suffixIndex]; diff --git a/src/Kernel.php b/src/Kernel.php index 779cd1f..7cc297a 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -1,4 +1,5 @@ pagerfanta = $pagerfanta; $this->currentPage = $pagerfanta->getCurrentPage(); } - private function configureTemplate($routeGenerator, $options) + private function configureTemplate($routeGenerator, $options): void { $this->template->setRouteGenerator($routeGenerator); $this->template->setOptions($options); } - private function generate() + private function generate(): array|string { $pages = $this->generatePages(); return $this->generateContainer($pages); } - private function generateContainer($pages) + private function generateContainer($pages): array|string { return str_replace('%pages%', $pages, $this->template->container()); } - private function generatePages() + private function generatePages(): string { return $this->previous().$this->currentPage().$this->next(); } diff --git a/src/Repository/ApiTokenRepository.php b/src/Repository/ApiTokenRepository.php index 6696bb4..9df98ee 100644 --- a/src/Repository/ApiTokenRepository.php +++ b/src/Repository/ApiTokenRepository.php @@ -1,4 +1,5 @@ getQuery()->getOneOrNullResult(); } -} \ No newline at end of file +} diff --git a/src/Repository/InviteRepository.php b/src/Repository/InviteRepository.php index 8661b45..5f4e14e 100644 --- a/src/Repository/InviteRepository.php +++ b/src/Repository/InviteRepository.php @@ -1,4 +1,5 @@ getQuery()->getResult(); } -} \ No newline at end of file +} diff --git a/src/Repository/PasswordResetTokenRepository.php b/src/Repository/PasswordResetTokenRepository.php index 4e2334d..ab8b2ba 100644 --- a/src/Repository/PasswordResetTokenRepository.php +++ b/src/Repository/PasswordResetTokenRepository.php @@ -1,4 +1,5 @@ getEntityManager()->persist($user); } -} \ No newline at end of file +} diff --git a/src/Search/TorrentSearcher.php b/src/Search/TorrentSearcher.php index 5aa7906..e05bc6e 100644 --- a/src/Search/TorrentSearcher.php +++ b/src/Search/TorrentSearcher.php @@ -13,16 +13,11 @@ class TorrentSearcher private const ORDER_DISABLED_FIELDS = ['infoHash']; - /** @var TorrentRepository */ - private $torrentRepo; + public function __construct( + private readonly TorrentRepository $torrentRepo, + private readonly ClassMetadata $classMetadata + ) { - /** @var ClassMetadata */ - private $classMetadata; - - public function __construct(TorrentRepository $torrentRepo, ClassMetadata $classMetadata) - { - $this->torrentRepo = $torrentRepo; - $this->classMetadata = $classMetadata; } public function createSearchQueryBuilder(string $query, string $orderBy = null, string $order = 'asc'): QueryBuilder diff --git a/src/Twig/FileSizeHumanizerExtension.php b/src/Twig/FileSizeHumanizerExtension.php index ca633e0..c86bd1a 100644 --- a/src/Twig/FileSizeHumanizerExtension.php +++ b/src/Twig/FileSizeHumanizerExtension.php @@ -1,4 +1,5 @@ humanizer, 'humanize']), ]; } -} \ No newline at end of file +} diff --git a/src/Twig/FileTreeExtension.php b/src/Twig/FileTreeExtension.php index 9a8ba89..c7577da 100644 --- a/src/Twig/FileTreeExtension.php +++ b/src/Twig/FileTreeExtension.php @@ -1,21 +1,22 @@ builder = $builder; } - public function getFilters() + public function getFilters(): array { return [ new TwigFilter('file_tree', [$this->builder, 'buildFileTreeDataArray']), diff --git a/src/Twig/MagnetExtension.php b/src/Twig/MagnetExtension.php index 2d7bff3..71252f0 100644 --- a/src/Twig/MagnetExtension.php +++ b/src/Twig/MagnetExtension.php @@ -1,4 +1,5 @@ magnetGenerator = $magnetGenerator; } public function getFunctions(): array @@ -23,10 +22,10 @@ class MagnetExtension extends AbstractExtension ]; } - public function getFilters() + public function getFilters(): array { return [ new TwigFilter('magnet', [$this->magnetGenerator, 'generate']), ]; } -} \ No newline at end of file +} diff --git a/src/User/Exception/InvalidInviteException.php b/src/User/Exception/InvalidInviteException.php index 827015a..fb80aed 100644 --- a/src/User/Exception/InvalidInviteException.php +++ b/src/User/Exception/InvalidInviteException.php @@ -1,8 +1,9 @@ inviteRepo = $inviteRepo; - $this->newUserInvites = $newUserInvites; } /** @@ -28,7 +24,7 @@ class InviteManager return []; } - $amount = (null !== $forceAmount) ? $forceAmount : $this->newUserInvites; + $amount = $forceAmount ?? $this->newUserInvites; $invites = []; @@ -40,4 +36,4 @@ class InviteManager return $invites; } -} \ No newline at end of file +} diff --git a/src/User/PasswordResetManager.php b/src/User/PasswordResetManager.php index ac94183..2a4e381 100644 --- a/src/User/PasswordResetManager.php +++ b/src/User/PasswordResetManager.php @@ -1,5 +1,5 @@ userRepo = $userRepo; - $this->tokenRepo = $tokenRepo; - $this->em = $em; - $this->mailer = $mailer; - $this->router = $router; - $this->fromAddress = $fromAddress; + } public function sendResetLink(string $address): void diff --git a/src/User/UserManager.php b/src/User/UserManager.php index a4b94ec..9fab5a5 100644 --- a/src/User/UserManager.php +++ b/src/User/UserManager.php @@ -1,37 +1,29 @@ userRepo = $userRepo; - $this->inviteRepo = $inviteRepo; - $this->encoderFactory = $encoderFactory; } public function createUser(string $username, string $password, string $email, array $roles = self::DEFAULT_ROLES): User { $user = new User( $username, - $this->encoderFactory->getEncoder(User::class), + $this->hasherFactory->getPasswordHasher(User::class), $password, $email, $roles @@ -44,10 +36,7 @@ class UserManager public function changePassword(User $user, string $rawPassword): void { - $user->changePassword( - $this->encoderFactory->getEncoder(User::class), - $rawPassword - ); + $user->changePassword($this->hasherFactory->getPasswordHasher(User::class), $rawPassword); } public function createUserByInvite(string $username, string $password, string $email, Invite $invite, array $roles = self::DEFAULT_ROLES): User diff --git a/src/Validator/Constraints/ValidInvite.php b/src/Validator/Constraints/ValidInvite.php index 1a0d455..8b67a87 100644 --- a/src/Validator/Constraints/ValidInvite.php +++ b/src/Validator/Constraints/ValidInvite.php @@ -1,12 +1,11 @@ inviteRepo = $inviteRepo; } /** - * @param mixed $value * @param ValidInvite $constraint */ - public function validate($value, Constraint $constraint) + public function validate(mixed $value, Constraint $constraint) { /** @var Invite $invite */ if (null === $invite = $this->inviteRepo->findOneBy(['code' => $value])) { @@ -39,4 +37,4 @@ class ValidInviteValidator extends ConstraintValidator ; } } -} \ No newline at end of file +} diff --git a/src/View/Torrent/FileTreeNode.php b/src/View/Torrent/FileTreeNode.php index 8b412a9..dc5371a 100644 --- a/src/View/Torrent/FileTreeNode.php +++ b/src/View/Torrent/FileTreeNode.php @@ -1,9 +1,9 @@ addChild($path, FileTreeNode::createFromFile($path, $file, $this)); + $this->addChild($path, self::createFromFile($path, $file, $this)); return; } @@ -89,12 +89,7 @@ class FileTreeNode return array_key_exists($name, $this->children); } - /** - * @param string $name - * - * @return FileTreeNode|File - */ - public function getChild(string $name) + public function getChild(string $name): File|FileTreeNode { if (!array_key_exists($name, $this->children)) { throw new \InvalidArgumentException(sprintf( @@ -119,7 +114,7 @@ class FileTreeNode $files = []; foreach ($this->children as $name => $child) { - if ($child instanceof FileTreeNode) { + if ($child instanceof self) { $dirs[$name] = $child; } elseif ($child instanceof File) { $files[] = $child;