diff --git a/rector.php b/rector.php index a70f0ba7..04ab0e5a 100644 --- a/rector.php +++ b/rector.php @@ -27,8 +27,8 @@ return static function (RectorConfig $rectorConfig): void { // define sets of rules $rectorConfig->sets([ //PHP rules - //SetList::CODE_QUALITY, - //LevelSetList::UP_TO_PHP_81, + SetList::CODE_QUALITY, + LevelSetList::UP_TO_PHP_81, //Symfony rules SymfonyLevelSetList::UP_TO_SYMFONY_62, diff --git a/src/Command/Attachments/CleanAttachmentsCommand.php b/src/Command/Attachments/CleanAttachmentsCommand.php index aa1750df..d0e37825 100644 --- a/src/Command/Attachments/CleanAttachmentsCommand.php +++ b/src/Command/Attachments/CleanAttachmentsCommand.php @@ -43,16 +43,10 @@ use const DIRECTORY_SEPARATOR; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:attachments:clean-unused|app:clean-attachments', 'Lists (and deletes if wanted) attachments files that are not used anymore (abandoned files).')] class CleanAttachmentsCommand extends Command { - protected AttachmentManager $attachment_helper; - protected AttachmentReverseSearch $reverseSearch; protected MimeTypes $mimeTypeGuesser; - protected AttachmentPathResolver $pathResolver; - public function __construct(AttachmentManager $attachmentHelper, AttachmentReverseSearch $reverseSearch, AttachmentPathResolver $pathResolver) + public function __construct(protected AttachmentManager $attachment_helper, protected AttachmentReverseSearch $reverseSearch, protected AttachmentPathResolver $pathResolver) { - $this->attachment_helper = $attachmentHelper; - $this->pathResolver = $pathResolver; - $this->reverseSearch = $reverseSearch; $this->mimeTypeGuesser = new MimeTypes(); parent::__construct(); } @@ -88,7 +82,7 @@ class CleanAttachmentsCommand extends Command foreach ($finder as $file) { //If not attachment object uses this file, print it - if (0 === count($this->reverseSearch->findAttachmentsByFile($file))) { + if ([] === $this->reverseSearch->findAttachmentsByFile($file)) { $file_list[] = $file; $table->addRow([ $fs->makePathRelative($file->getPathname(), $mediaPath), @@ -98,7 +92,7 @@ class CleanAttachmentsCommand extends Command } } - if (count($file_list) > 0) { + if ($file_list !== []) { $table->render(); $continue = $io->confirm(sprintf('Found %d abandoned files. Do you want to delete them? This can not be undone!', count($file_list)), false); diff --git a/src/Command/BackupCommand.php b/src/Command/BackupCommand.php index dc248126..ccc5763e 100644 --- a/src/Command/BackupCommand.php +++ b/src/Command/BackupCommand.php @@ -19,14 +19,8 @@ use Symfony\Component\Console\Style\SymfonyStyle; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:backup', 'Backup the files and the database of Part-DB')] class BackupCommand extends Command { - private string $project_dir; - private EntityManagerInterface $entityManager; - - public function __construct(string $project_dir, EntityManagerInterface $entityManager) + public function __construct(private readonly string $project_dir, private readonly EntityManagerInterface $entityManager) { - $this->project_dir = $project_dir; - $this->entityManager = $entityManager; - parent::__construct(); } @@ -69,13 +63,10 @@ class BackupCommand extends Command $io->info('Backup Part-DB to '.$output_filepath); //Check if the file already exists - if (file_exists($output_filepath)) { - //Then ask the user, if he wants to overwrite the file - if (!$io->confirm('The file '.realpath($output_filepath).' already exists. Do you want to overwrite it?', false)) { - $io->error('Backup aborted!'); - - return Command::FAILURE; - } + //Then ask the user, if he wants to overwrite the file + if (file_exists($output_filepath) && !$io->confirm('The file '.realpath($output_filepath).' already exists. Do you want to overwrite it?', false)) { + $io->error('Backup aborted!'); + return Command::FAILURE; } $io->note('Starting backup...'); @@ -113,8 +104,6 @@ class BackupCommand extends Command /** * Constructs the MySQL PDO DSN. * Taken from https://github.com/doctrine/dbal/blob/3.5.x/src/Driver/PDO/MySQL/Driver.php - * - * @param array $params */ private function configureDumper(array $params, DbDumper $dumper): void { diff --git a/src/Command/CheckRequirementsCommand.php b/src/Command/CheckRequirementsCommand.php index 3d7f3a72..38f599e3 100644 --- a/src/Command/CheckRequirementsCommand.php +++ b/src/Command/CheckRequirementsCommand.php @@ -30,11 +30,8 @@ use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:check-requirements', 'Checks if the requirements Part-DB needs or recommends are fulfilled.')] class CheckRequirementsCommand extends Command { - protected ContainerBagInterface $params; - - public function __construct(ContainerBagInterface $params) + public function __construct(protected ContainerBagInterface $params) { - $this->params = $params; parent::__construct(); } @@ -66,40 +63,48 @@ class CheckRequirementsCommand extends Command protected function checkPHP(SymfonyStyle $io, $only_issues = false): void { //Check PHP versions - $io->isVerbose() && $io->comment('Checking PHP version...'); + if ($io->isVerbose()) { + $io->comment('Checking PHP version...'); + } //We recommend PHP 8.2, but 8.1 is the minimum if (PHP_VERSION_ID < 80200) { $io->warning('You are using PHP '. PHP_VERSION .'. This will work, but a newer version is recommended.'); - } else { - !$only_issues && $io->success('PHP version is sufficient.'); + } elseif (!$only_issues) { + $io->success('PHP version is sufficient.'); } //Check if opcache is enabled - $io->isVerbose() && $io->comment('Checking Opcache...'); + if ($io->isVerbose()) { + $io->comment('Checking Opcache...'); + } $opcache_enabled = ini_get('opcache.enable') === '1'; if (!$opcache_enabled) { $io->warning('Opcache is not enabled. This will work, but performance will be better with opcache enabled. Set opcache.enable=1 in your php.ini to enable it'); - } else { - !$only_issues && $io->success('Opcache is enabled.'); + } elseif (!$only_issues) { + $io->success('Opcache is enabled.'); } //Check if opcache is configured correctly - $io->isVerbose() && $io->comment('Checking Opcache configuration...'); + if ($io->isVerbose()) { + $io->comment('Checking Opcache configuration...'); + } if ($opcache_enabled && (ini_get('opcache.memory_consumption') < 256 || ini_get('opcache.max_accelerated_files') < 20000)) { $io->warning('Opcache configuration can be improved. See https://symfony.com/doc/current/performance.html for more info.'); - } else { - !$only_issues && $io->success('Opcache configuration is already performance optimized.'); + } elseif (!$only_issues) { + $io->success('Opcache configuration is already performance optimized.'); } } protected function checkPartDBConfig(SymfonyStyle $io, $only_issues = false): void { //Check if APP_ENV is set to prod - $io->isVerbose() && $io->comment('Checking debug mode...'); - if($this->params->get('kernel.debug')) { + if ($io->isVerbose()) { + $io->comment('Checking debug mode...'); + } + if ($this->params->get('kernel.debug')) { $io->warning('You have activated debug mode, this is will leak informations in a production environment.'); - } else { - !$only_issues && $io->success('Debug mode disabled.'); + } elseif (!$only_issues) { + $io->success('Debug mode disabled.'); } } @@ -108,61 +113,71 @@ class CheckRequirementsCommand extends Command { //Get all installed PHP extensions $extensions = get_loaded_extensions(); - $io->isVerbose() && $io->comment('Your PHP installation has '. count($extensions) .' extensions installed: '. implode(', ', $extensions)); + if ($io->isVerbose()) { + $io->comment('Your PHP installation has '. count($extensions) .' extensions installed: '. implode(', ', $extensions)); + } $db_drivers_count = 0; if(!in_array('pdo_mysql', $extensions)) { $io->error('pdo_mysql is not installed. You will not be able to use MySQL databases.'); } else { - !$only_issues && $io->success('PHP extension pdo_mysql is installed.'); + if (!$only_issues) { + $io->success('PHP extension pdo_mysql is installed.'); + } $db_drivers_count++; } if(!in_array('pdo_sqlite', $extensions)) { $io->error('pdo_sqlite is not installed. You will not be able to use SQLite. databases'); } else { - !$only_issues && $io->success('PHP extension pdo_sqlite is installed.'); + if (!$only_issues) { + $io->success('PHP extension pdo_sqlite is installed.'); + } $db_drivers_count++; } - $io->isVerbose() && $io->comment('You have '. $db_drivers_count .' database drivers installed.'); + if ($io->isVerbose()) { + $io->comment('You have '. $db_drivers_count .' database drivers installed.'); + } if ($db_drivers_count === 0) { $io->error('You have no database drivers installed. You have to install at least one database driver!'); } - if(!in_array('curl', $extensions)) { + if (!in_array('curl', $extensions)) { $io->warning('curl extension is not installed. Install curl extension for better performance'); - } else { - !$only_issues && $io->success('PHP extension curl is installed.'); + } elseif (!$only_issues) { + $io->success('PHP extension curl is installed.'); } $gd_installed = in_array('gd', $extensions); - if(!$gd_installed) { + if (!$gd_installed) { $io->error('GD is not installed. GD is required for image processing.'); - } else { - !$only_issues && $io->success('PHP extension GD is installed.'); + } elseif (!$only_issues) { + $io->success('PHP extension GD is installed.'); } //Check if GD has jpeg support - $io->isVerbose() && $io->comment('Checking if GD has jpeg support...'); + if ($io->isVerbose()) { + $io->comment('Checking if GD has jpeg support...'); + } if ($gd_installed) { $gd_info = gd_info(); - if($gd_info['JPEG Support'] === false) { + if ($gd_info['JPEG Support'] === false) { $io->warning('Your GD does not have jpeg support. You will not be able to generate thumbnails of jpeg images.'); - } else { - !$only_issues && $io->success('GD has jpeg support.'); + } elseif (!$only_issues) { + $io->success('GD has jpeg support.'); } - if($gd_info['PNG Support'] === false) { + if ($gd_info['PNG Support'] === false) { $io->warning('Your GD does not have png support. You will not be able to generate thumbnails of png images.'); - } else { - !$only_issues && $io->success('GD has png support.'); + } elseif (!$only_issues) { + $io->success('GD has png support.'); } - if($gd_info['WebP Support'] === false) { + if ($gd_info['WebP Support'] === false) { $io->warning('Your GD does not have WebP support. You will not be able to generate thumbnails of WebP images.'); - } else { - !$only_issues && $io->success('GD has WebP support.'); + } elseif (!$only_issues) { + $io->success('GD has WebP support.'); } } diff --git a/src/Command/Currencies/UpdateExchangeRatesCommand.php b/src/Command/Currencies/UpdateExchangeRatesCommand.php index 13d2e2dc..4a6b88f1 100644 --- a/src/Command/Currencies/UpdateExchangeRatesCommand.php +++ b/src/Command/Currencies/UpdateExchangeRatesCommand.php @@ -38,18 +38,8 @@ use function strlen; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:currencies:update-exchange-rates|partdb:update-exchange-rates|app:update-exchange-rates', 'Updates the currency exchange rates.')] class UpdateExchangeRatesCommand extends Command { - protected string $base_current; - protected EntityManagerInterface $em; - protected ExchangeRateUpdater $exchangeRateUpdater; - - public function __construct(string $base_current, EntityManagerInterface $entityManager, ExchangeRateUpdater $exchangeRateUpdater) + public function __construct(protected string $base_current, protected EntityManagerInterface $em, protected ExchangeRateUpdater $exchangeRateUpdater) { - //$this->swap = $swap; - $this->base_current = $base_current; - - $this->em = $entityManager; - $this->exchangeRateUpdater = $exchangeRateUpdater; - parent::__construct(); } @@ -75,11 +65,7 @@ class UpdateExchangeRatesCommand extends Command $iso_code = $input->getArgument('iso_code'); $repo = $this->em->getRepository(Currency::class); - if (!empty($iso_code)) { - $candidates = $repo->findBy(['iso_code' => $iso_code]); - } else { - $candidates = $repo->findAll(); - } + $candidates = empty($iso_code) ? $repo->findAll() : $repo->findBy(['iso_code' => $iso_code]); $success_counter = 0; diff --git a/src/Command/Logs/ShowEventLogCommand.php b/src/Command/Logs/ShowEventLogCommand.php index cc02bfd1..0fc78d46 100644 --- a/src/Command/Logs/ShowEventLogCommand.php +++ b/src/Command/Logs/ShowEventLogCommand.php @@ -39,20 +39,11 @@ use Symfony\Contracts\Translation\TranslatorInterface; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:logs:show|app:show-logs', 'List the last event log entries.')] class ShowEventLogCommand extends Command { - protected EntityManagerInterface $entityManager; - protected TranslatorInterface $translator; - protected ElementTypeNameGenerator $elementTypeNameGenerator; protected LogEntryRepository $repo; - protected LogEntryExtraFormatter $formatter; - public function __construct(EntityManagerInterface $entityManager, - TranslatorInterface $translator, ElementTypeNameGenerator $elementTypeNameGenerator, LogEntryExtraFormatter $formatter) + public function __construct(protected EntityManagerInterface $entityManager, + protected TranslatorInterface $translator, protected ElementTypeNameGenerator $elementTypeNameGenerator, protected LogEntryExtraFormatter $formatter) { - $this->entityManager = $entityManager; - $this->translator = $translator; - $this->elementTypeNameGenerator = $elementTypeNameGenerator; - $this->formatter = $formatter; - $this->repo = $this->entityManager->getRepository(AbstractLogEntry::class); parent::__construct(); } @@ -145,14 +136,12 @@ class ShowEventLogCommand extends Command $target_class = $this->elementTypeNameGenerator->getLocalizedTypeLabel($entry->getTargetClass()); } - if ($entry->getUser()) { + if ($entry->getUser() instanceof \App\Entity\UserSystem\User) { $user = $entry->getUser()->getFullName(true); + } elseif ($entry->isCLIEntry()) { + $user = $entry->getCLIUsername() . ' [CLI]'; } else { - if ($entry->isCLIEntry()) { - $user = $entry->getCLIUsername() . ' [CLI]'; - } else { - $user = $entry->getUsername() . ' [deleted]'; - } + $user = $entry->getUsername() . ' [deleted]'; } $row = [ diff --git a/src/Command/Migrations/ConvertBBCodeCommand.php b/src/Command/Migrations/ConvertBBCodeCommand.php index f4565805..50e5b011 100644 --- a/src/Command/Migrations/ConvertBBCodeCommand.php +++ b/src/Command/Migrations/ConvertBBCodeCommand.php @@ -58,16 +58,10 @@ class ConvertBBCodeCommand extends Command * @var string The regex (performed in PHP) used to check if a property really contains BBCODE */ protected const BBCODE_REGEX = '/\\[.+\\].*\\[\\/.+\\]/'; - - protected EntityManagerInterface $em; - protected PropertyAccessorInterface $propertyAccessor; protected BBCodeToMarkdownConverter $converter; - public function __construct(EntityManagerInterface $entityManager, PropertyAccessorInterface $propertyAccessor) + public function __construct(protected EntityManagerInterface $em, protected PropertyAccessorInterface $propertyAccessor) { - $this->em = $entityManager; - $this->propertyAccessor = $propertyAccessor; - $this->converter = new BBCodeToMarkdownConverter(); parent::__construct(); @@ -126,25 +120,25 @@ class ConvertBBCodeCommand extends Command //Fetch resulting classes $results = $qb->getQuery()->getResult(); - $io->note(sprintf('Found %d entities, that need to be converted!', count($results))); + $io->note(sprintf('Found %d entities, that need to be converted!', is_countable($results) ? count($results) : 0)); //In verbose mode print the names of the entities foreach ($results as $result) { /** @var AbstractNamedDBElement $result */ $io->writeln( - 'Convert entity: '.$result->getName().' ('.get_class($result).': '.$result->getID().')', + 'Convert entity: '.$result->getName().' ('.$result::class.': '.$result->getID().')', OutputInterface::VERBOSITY_VERBOSE ); foreach ($properties as $property) { //Retrieve bbcode from entity $bbcode = $this->propertyAccessor->getValue($result, $property); //Check if the current property really contains BBCode - if (!preg_match(static::BBCODE_REGEX, $bbcode)) { + if (!preg_match(static::BBCODE_REGEX, (string) $bbcode)) { continue; } $io->writeln( 'BBCode (old): ' - .str_replace('\n', ' ', substr($bbcode, 0, 255)), + .str_replace('\n', ' ', substr((string) $bbcode, 0, 255)), OutputInterface::VERBOSITY_VERY_VERBOSE ); $markdown = $this->converter->convert($bbcode); diff --git a/src/Command/Migrations/ImportPartKeeprCommand.php b/src/Command/Migrations/ImportPartKeeprCommand.php index d2c015b9..1ba2e8db 100644 --- a/src/Command/Migrations/ImportPartKeeprCommand.php +++ b/src/Command/Migrations/ImportPartKeeprCommand.php @@ -37,24 +37,11 @@ use Symfony\Component\Console\Style\SymfonyStyle; class ImportPartKeeprCommand extends Command { - protected EntityManagerInterface $em; - protected MySQLDumpXMLConverter $xml_converter; - protected PKDatastructureImporter $datastructureImporter; - protected PKImportHelper $importHelper; - protected PKPartImporter $partImporter; - protected PKOptionalImporter $optionalImporter; - - public function __construct(EntityManagerInterface $em, MySQLDumpXMLConverter $xml_converter, - PKDatastructureImporter $datastructureImporter, PKPartImporter $partImporter, PKImportHelper $importHelper, - PKOptionalImporter $optionalImporter) + public function __construct(protected EntityManagerInterface $em, protected MySQLDumpXMLConverter $xml_converter, + protected PKDatastructureImporter $datastructureImporter, protected PKPartImporter $partImporter, protected PKImportHelper $importHelper, + protected PKOptionalImporter $optionalImporter) { parent::__construct(self::$defaultName); - $this->em = $em; - $this->datastructureImporter = $datastructureImporter; - $this->importHelper = $importHelper; - $this->partImporter = $partImporter; - $this->xml_converter = $xml_converter; - $this->optionalImporter = $optionalImporter; } protected function configure() diff --git a/src/Command/User/ConvertToSAMLUserCommand.php b/src/Command/User/ConvertToSAMLUserCommand.php index 635c9eb3..4461bb58 100644 --- a/src/Command/User/ConvertToSAMLUserCommand.php +++ b/src/Command/User/ConvertToSAMLUserCommand.php @@ -33,14 +33,9 @@ use Symfony\Component\Console\Style\SymfonyStyle; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:user:convert-to-saml-user|partdb:users:convert-to-saml-user', 'Converts a local user to a SAML user (and vice versa)')] class ConvertToSAMLUserCommand extends Command { - protected EntityManagerInterface $entityManager; - protected bool $saml_enabled; - - public function __construct(EntityManagerInterface $entityManager, bool $saml_enabled) + public function __construct(protected EntityManagerInterface $entityManager, protected bool $saml_enabled) { parent::__construct(); - $this->entityManager = $entityManager; - $this->saml_enabled = $saml_enabled; } protected function configure(): void diff --git a/src/Command/User/SetPasswordCommand.php b/src/Command/User/SetPasswordCommand.php index 4a7542e3..90f045b5 100644 --- a/src/Command/User/SetPasswordCommand.php +++ b/src/Command/User/SetPasswordCommand.php @@ -37,16 +37,8 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:users:set-password|app:set-password|users:set-password|partdb:user:set-password', 'Sets the password of a user')] class SetPasswordCommand extends Command { - protected EntityManagerInterface $entityManager; - protected UserPasswordHasherInterface $encoder; - protected EventDispatcherInterface $eventDispatcher; - - public function __construct(EntityManagerInterface $entityManager, UserPasswordHasherInterface $passwordEncoder, EventDispatcherInterface $eventDispatcher) + public function __construct(protected EntityManagerInterface $entityManager, protected UserPasswordHasherInterface $encoder, protected EventDispatcherInterface $eventDispatcher) { - $this->entityManager = $entityManager; - $this->encoder = $passwordEncoder; - $this->eventDispatcher = $eventDispatcher; - parent::__construct(); } @@ -64,7 +56,7 @@ class SetPasswordCommand extends Command $user = $this->entityManager->getRepository(User::class)->findByEmailOrName($user_name); - if (!$user) { + if (!$user instanceof \App\Entity\UserSystem\User) { $io->error(sprintf('No user with the given username %s found in the database!', $user_name)); return \Symfony\Component\Console\Command\Command::FAILURE; diff --git a/src/Command/User/UpgradePermissionsSchemaCommand.php b/src/Command/User/UpgradePermissionsSchemaCommand.php index 94d65c67..219ddb2f 100644 --- a/src/Command/User/UpgradePermissionsSchemaCommand.php +++ b/src/Command/User/UpgradePermissionsSchemaCommand.php @@ -34,17 +34,9 @@ use Symfony\Component\Console\Style\SymfonyStyle; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:users:upgrade-permissions-schema', '(Manually) upgrades the permissions schema of all users to the latest version.')] final class UpgradePermissionsSchemaCommand extends Command { - private PermissionSchemaUpdater $permissionSchemaUpdater; - private EntityManagerInterface $em; - private EventCommentHelper $eventCommentHelper; - - public function __construct(PermissionSchemaUpdater $permissionSchemaUpdater, EntityManagerInterface $entityManager, EventCommentHelper $eventCommentHelper) + public function __construct(private readonly PermissionSchemaUpdater $permissionSchemaUpdater, private readonly EntityManagerInterface $em, private readonly EventCommentHelper $eventCommentHelper) { parent::__construct(self::$defaultName); - - $this->permissionSchemaUpdater = $permissionSchemaUpdater; - $this->eventCommentHelper = $eventCommentHelper; - $this->em = $entityManager; } protected function configure(): void @@ -79,7 +71,7 @@ final class UpgradePermissionsSchemaCommand extends Command } $io->info('Found '. count($groups_to_upgrade) .' groups and '. count($users_to_upgrade) .' users that need an update.'); - if (empty($groups_to_upgrade) && empty($users_to_upgrade)) { + if ($groups_to_upgrade === [] && $users_to_upgrade === []) { $io->success('All users and group permissions schemas are up-to-date. No update needed.'); return \Symfony\Component\Console\Command\Command::SUCCESS; @@ -87,14 +79,10 @@ final class UpgradePermissionsSchemaCommand extends Command //List all users and groups that need an update $io->section('Groups that need an update:'); - $io->listing(array_map(static function (Group $group) { - return $group->getName() . ' (ID: '. $group->getID() .', Current version: ' . $group->getPermissions()->getSchemaVersion() . ')'; - }, $groups_to_upgrade)); + $io->listing(array_map(static fn(Group $group): string => $group->getName() . ' (ID: '. $group->getID() .', Current version: ' . $group->getPermissions()->getSchemaVersion() . ')', $groups_to_upgrade)); $io->section('Users that need an update:'); - $io->listing(array_map(static function (User $user) { - return $user->getUsername() . ' (ID: '. $user->getID() .', Current version: ' . $user->getPermissions()->getSchemaVersion() . ')'; - }, $users_to_upgrade)); + $io->listing(array_map(static fn(User $user): string => $user->getUsername() . ' (ID: '. $user->getID() .', Current version: ' . $user->getPermissions()->getSchemaVersion() . ')', $users_to_upgrade)); if(!$io->confirm('Continue with the update?', false)) { $io->warning('Update aborted.'); diff --git a/src/Command/User/UserEnableCommand.php b/src/Command/User/UserEnableCommand.php index 1a4063cd..ddb43513 100644 --- a/src/Command/User/UserEnableCommand.php +++ b/src/Command/User/UserEnableCommand.php @@ -32,12 +32,8 @@ use Symfony\Component\Console\Style\SymfonyStyle; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:users:enable|partdb:user:enable', 'Enables/Disable the login of one or more users')] class UserEnableCommand extends Command { - protected EntityManagerInterface $entityManager; - - public function __construct(EntityManagerInterface $entityManager, string $name = null) + public function __construct(protected EntityManagerInterface $entityManager, string $name = null) { - $this->entityManager = $entityManager; - parent::__construct($name); } @@ -70,7 +66,7 @@ class UserEnableCommand extends Command } else { //Otherwise, fetch the users from DB foreach ($usernames as $username) { $user = $repo->findByEmailOrName($username); - if ($user === null) { + if (!$user instanceof \App\Entity\UserSystem\User) { $io->error('No user found with username: '.$username); return self::FAILURE; } @@ -84,9 +80,7 @@ class UserEnableCommand extends Command $io->note('The following users will be enabled:'); } $io->table(['Username', 'Enabled/Disabled'], - array_map(static function(User $user) { - return [$user->getFullName(true), $user->isDisabled() ? 'Disabled' : 'Enabled']; - }, $users)); + array_map(static fn(User $user) => [$user->getFullName(true), $user->isDisabled() ? 'Disabled' : 'Enabled'], $users)); if(!$io->confirm('Do you want to continue?')) { $io->warning('Aborting!'); diff --git a/src/Command/User/UserListCommand.php b/src/Command/User/UserListCommand.php index 351c679d..8a2265fd 100644 --- a/src/Command/User/UserListCommand.php +++ b/src/Command/User/UserListCommand.php @@ -31,12 +31,8 @@ use Symfony\Component\Console\Style\SymfonyStyle; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:users:list|users:list', 'Lists all users')] class UserListCommand extends Command { - protected EntityManagerInterface $entityManager; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(protected EntityManagerInterface $entityManager) { - $this->entityManager = $entityManager; - parent::__construct(); } @@ -83,7 +79,7 @@ class UserListCommand extends Command $user->getUsername(), $user->getFullName(), $user->getEmail(), - $user->getGroup() !== null ? $user->getGroup()->getName() . ' (ID: ' . $user->getGroup()->getID() . ')' : 'No group', + $user->getGroup() instanceof \App\Entity\UserSystem\Group ? $user->getGroup()->getName() . ' (ID: ' . $user->getGroup()->getID() . ')' : 'No group', $user->isDisabled() ? 'Yes' : 'No', $user->isSAMLUser() ? 'SAML' : 'Local', ]); diff --git a/src/Command/User/UsersPermissionsCommand.php b/src/Command/User/UsersPermissionsCommand.php index f01bcedb..6be134ed 100644 --- a/src/Command/User/UsersPermissionsCommand.php +++ b/src/Command/User/UsersPermissionsCommand.php @@ -37,17 +37,11 @@ use Symfony\Contracts\Translation\TranslatorInterface; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:users:permissions|partdb:user:permissions', 'View and edit the permissions of a given user')] class UsersPermissionsCommand extends Command { - protected EntityManagerInterface $entityManager; protected UserRepository $userRepository; - protected PermissionManager $permissionResolver; - protected TranslatorInterface $translator; - public function __construct(EntityManagerInterface $entityManager, PermissionManager $permissionResolver, TranslatorInterface $translator) + public function __construct(protected EntityManagerInterface $entityManager, protected PermissionManager $permissionResolver, protected TranslatorInterface $translator) { - $this->entityManager = $entityManager; $this->userRepository = $entityManager->getRepository(User::class); - $this->permissionResolver = $permissionResolver; - $this->translator = $translator; parent::__construct(self::$defaultName); } @@ -71,7 +65,7 @@ class UsersPermissionsCommand extends Command //Find user $io->note('Finding user with username: ' . $username); $user = $this->userRepository->findByEmailOrName($username); - if ($user === null) { + if (!$user instanceof \App\Entity\UserSystem\User) { $io->error('No user found with username: ' . $username); return Command::FAILURE; } @@ -100,7 +94,7 @@ class UsersPermissionsCommand extends Command $new_value_str = $io->ask('Enter the new value for the permission (A = allow, D = disallow, I = inherit)'); - switch (strtolower($new_value_str)) { + switch (strtolower((string) $new_value_str)) { case 'a': case 'allow': $new_value = true; @@ -207,11 +201,11 @@ class UsersPermissionsCommand extends Command if ($permission_value === true) { return 'Allow'; - } else if ($permission_value === false) { + } elseif ($permission_value === false) { return 'Disallow'; - } else if ($permission_value === null && !$inherit) { + } elseif ($permission_value === null && !$inherit) { return 'Inherit'; - } else if ($permission_value === null && $inherit) { + } elseif ($permission_value === null && $inherit) { return 'Disallow (Inherited)'; } diff --git a/src/Command/VersionCommand.php b/src/Command/VersionCommand.php index d6a27ae2..feecc6ee 100644 --- a/src/Command/VersionCommand.php +++ b/src/Command/VersionCommand.php @@ -30,13 +30,8 @@ use Symfony\Component\Console\Style\SymfonyStyle; #[\Symfony\Component\Console\Attribute\AsCommand('partdb:version|app:version', 'Shows the currently installed version of Part-DB.')] class VersionCommand extends Command { - protected VersionManagerInterface $versionManager; - protected GitVersionInfo $gitVersionInfo; - - public function __construct(VersionManagerInterface $versionManager, GitVersionInfo $gitVersionInfo) + public function __construct(protected VersionManagerInterface $versionManager, protected GitVersionInfo $gitVersionInfo) { - $this->versionManager = $versionManager; - $this->gitVersionInfo = $gitVersionInfo; parent::__construct(); } diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php index 65a17668..8aaaf6f1 100644 --- a/src/Controller/AdminPages/BaseAdminController.php +++ b/src/Controller/AdminPages/BaseAdminController.php @@ -72,29 +72,16 @@ abstract class BaseAdminController extends AbstractController protected string $route_base = ''; protected string $attachment_class = ''; protected ?string $parameter_class = ''; - - protected UserPasswordHasherInterface $passwordEncoder; - protected TranslatorInterface $translator; - protected AttachmentSubmitHandler $attachmentSubmitHandler; - protected EventCommentHelper $commentHelper; - - protected HistoryHelper $historyHelper; - protected TimeTravel $timeTravel; - protected DataTableFactory $dataTableFactory; /** * @var EventDispatcher|EventDispatcherInterface */ protected $eventDispatcher; - protected LabelGenerator $labelGenerator; - protected LabelExampleElementsGenerator $barcodeExampleGenerator; - protected EntityManagerInterface $entityManager; - - public function __construct(TranslatorInterface $translator, UserPasswordHasherInterface $passwordEncoder, - AttachmentSubmitHandler $attachmentSubmitHandler, - EventCommentHelper $commentHelper, HistoryHelper $historyHelper, TimeTravel $timeTravel, - DataTableFactory $dataTableFactory, EventDispatcherInterface $eventDispatcher, LabelExampleElementsGenerator $barcodeExampleGenerator, - LabelGenerator $labelGenerator, EntityManagerInterface $entityManager) + public function __construct(protected TranslatorInterface $translator, protected UserPasswordHasherInterface $passwordEncoder, + protected AttachmentSubmitHandler $attachmentSubmitHandler, + protected EventCommentHelper $commentHelper, protected HistoryHelper $historyHelper, protected TimeTravel $timeTravel, + protected DataTableFactory $dataTableFactory, EventDispatcherInterface $eventDispatcher, protected LabelExampleElementsGenerator $barcodeExampleGenerator, + protected LabelGenerator $labelGenerator, protected EntityManagerInterface $entityManager) { if ('' === $this->entity_class || '' === $this->form_class || '' === $this->twig_template || '' === $this->route_base) { throw new InvalidArgumentException('You have to override the $entity_class, $form_class, $route_base and $twig_template value in your subclasss!'); @@ -107,18 +94,7 @@ abstract class BaseAdminController extends AbstractController if ('' === $this->parameter_class || ($this->parameter_class && !is_a($this->parameter_class, AbstractParameter::class, true))) { throw new InvalidArgumentException('You have to override the $parameter_class value with a valid Parameter class in your subclass!'); } - - $this->translator = $translator; - $this->passwordEncoder = $passwordEncoder; - $this->attachmentSubmitHandler = $attachmentSubmitHandler; - $this->commentHelper = $commentHelper; - $this->historyHelper = $historyHelper; - $this->timeTravel = $timeTravel; - $this->dataTableFactory = $dataTableFactory; $this->eventDispatcher = $eventDispatcher; - $this->barcodeExampleGenerator = $barcodeExampleGenerator; - $this->labelGenerator = $labelGenerator; - $this->entityManager = $entityManager; } protected function revertElementIfNeeded(AbstractDBElement $entity, ?string $timestamp): ?DateTime @@ -177,7 +153,7 @@ abstract class BaseAdminController extends AbstractController $form_options = [ 'attachment_class' => $this->attachment_class, 'parameter_class' => $this->parameter_class, - 'disabled' => null !== $timeTravel_timestamp, + 'disabled' => $timeTravel_timestamp instanceof \DateTime, ]; //Disable editing of options, if user is not allowed to use twig... @@ -269,13 +245,7 @@ abstract class BaseAdminController extends AbstractController protected function _new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?AbstractNamedDBElement $entity = null) { - if (null === $entity) { - /** @var AbstractStructuralDBElement|User $new_entity */ - $new_entity = new $this->entity_class(); - } else { - /** @var AbstractStructuralDBElement|User $new_entity */ - $new_entity = clone $entity; - } + $new_entity = $entity instanceof \App\Entity\Base\AbstractNamedDBElement ? clone $entity : new $this->entity_class(); $this->denyAccessUnlessGranted('read', $new_entity); @@ -287,42 +257,37 @@ abstract class BaseAdminController extends AbstractController $form->handleRequest($request); - if ($form->isSubmitted() && $form->isValid()) { - //Perform additional actions - if ($this->additionalActionNew($form, $new_entity)) { - //Upload passed files - $attachments = $form['attachments']; - foreach ($attachments as $attachment) { - /** @var FormInterface $attachment */ - $options = [ - 'secure_attachment' => $attachment['secureFile']->getData(), - 'download_url' => $attachment['downloadURL']->getData(), - ]; + //Perform additional actions + if ($form->isSubmitted() && $form->isValid() && $this->additionalActionNew($form, $new_entity)) { + //Upload passed files + $attachments = $form['attachments']; + foreach ($attachments as $attachment) { + /** @var FormInterface $attachment */ + $options = [ + 'secure_attachment' => $attachment['secureFile']->getData(), + 'download_url' => $attachment['downloadURL']->getData(), + ]; - try { - $this->attachmentSubmitHandler->handleFormSubmit( - $attachment->getData(), - $attachment['file']->getData(), - $options - ); - } catch (AttachmentDownloadException $attachmentDownloadException) { - $this->addFlash( - 'error', - $this->translator->trans( - 'attachment.download_failed' - ).' '.$attachmentDownloadException->getMessage() - ); - } + try { + $this->attachmentSubmitHandler->handleFormSubmit( + $attachment->getData(), + $attachment['file']->getData(), + $options + ); + } catch (AttachmentDownloadException $attachmentDownloadException) { + $this->addFlash( + 'error', + $this->translator->trans( + 'attachment.download_failed' + ).' '.$attachmentDownloadException->getMessage() + ); } - - $this->commentHelper->setMessage($form['log_comment']->getData()); - - $em->persist($new_entity); - $em->flush(); - $this->addFlash('success', 'entity.created_flash'); - - return $this->redirectToRoute($this->route_base.'_edit', ['id' => $new_entity->getID()]); } + $this->commentHelper->setMessage($form['log_comment']->getData()); + $em->persist($new_entity); + $em->flush(); + $this->addFlash('success', 'entity.created_flash'); + return $this->redirectToRoute($this->route_base.'_edit', ['id' => $new_entity->getID()]); } if ($form->isSubmitted() && !$form->isValid()) { @@ -369,7 +334,7 @@ abstract class BaseAdminController extends AbstractController } } } - catch (UnexpectedValueException $e) { + catch (UnexpectedValueException) { $this->addFlash('error', 'parts.import.flash.error.invalid_file'); } } diff --git a/src/Controller/AdminPages/CurrencyController.php b/src/Controller/AdminPages/CurrencyController.php index d607c792..18d449fd 100644 --- a/src/Controller/AdminPages/CurrencyController.php +++ b/src/Controller/AdminPages/CurrencyController.php @@ -64,8 +64,6 @@ class CurrencyController extends BaseAdminController protected string $attachment_class = CurrencyAttachment::class; protected ?string $parameter_class = CurrencyParameter::class; - protected ExchangeRateUpdater $exchangeRateUpdater; - public function __construct( TranslatorInterface $translator, UserPasswordHasherInterface $passwordEncoder, @@ -78,10 +76,8 @@ class CurrencyController extends BaseAdminController LabelExampleElementsGenerator $barcodeExampleGenerator, LabelGenerator $labelGenerator, EntityManagerInterface $entityManager, - ExchangeRateUpdater $exchangeRateUpdater + protected ExchangeRateUpdater $exchangeRateUpdater ) { - $this->exchangeRateUpdater = $exchangeRateUpdater; - parent::__construct( $translator, $passwordEncoder, diff --git a/src/Controller/AdminPages/ManufacturerController.php b/src/Controller/AdminPages/ManufacturerController.php index 09311e25..c6db73ee 100644 --- a/src/Controller/AdminPages/ManufacturerController.php +++ b/src/Controller/AdminPages/ManufacturerController.php @@ -45,9 +45,6 @@ class ManufacturerController extends BaseAdminController protected string $attachment_class = ManufacturerAttachment::class; protected ?string $parameter_class = ManufacturerParameter::class; - /** - * @return RedirectResponse - */ #[Route(path: '/{id}', name: 'manufacturer_delete', methods: ['DELETE'])] public function delete(Request $request, Manufacturer $entity, StructuralElementRecursionHelper $recursionHelper): RedirectResponse { diff --git a/src/Controller/HomepageController.php b/src/Controller/HomepageController.php index fe3025e9..45b80113 100644 --- a/src/Controller/HomepageController.php +++ b/src/Controller/HomepageController.php @@ -37,15 +37,8 @@ use Symfony\Contracts\Cache\CacheInterface; class HomepageController extends AbstractController { - protected CacheInterface $cache; - protected KernelInterface $kernel; - protected DataTableFactory $dataTable; - - public function __construct(CacheInterface $cache, KernelInterface $kernel, DataTableFactory $dataTable) + public function __construct(protected CacheInterface $cache, protected KernelInterface $kernel, protected DataTableFactory $dataTable) { - $this->cache = $cache; - $this->kernel = $kernel; - $this->dataTable = $dataTable; } public function getBanner(): string diff --git a/src/Controller/LabelController.php b/src/Controller/LabelController.php index 02b44112..d74376ec 100644 --- a/src/Controller/LabelController.php +++ b/src/Controller/LabelController.php @@ -62,20 +62,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; #[Route(path: '/label')] class LabelController extends AbstractController { - protected LabelGenerator $labelGenerator; - protected EntityManagerInterface $em; - protected ElementTypeNameGenerator $elementTypeNameGenerator; - protected RangeParser $rangeParser; - protected TranslatorInterface $translator; - - public function __construct(LabelGenerator $labelGenerator, EntityManagerInterface $em, ElementTypeNameGenerator $elementTypeNameGenerator, - RangeParser $rangeParser, TranslatorInterface $translator) + public function __construct(protected LabelGenerator $labelGenerator, protected EntityManagerInterface $em, protected ElementTypeNameGenerator $elementTypeNameGenerator, protected RangeParser $rangeParser, protected TranslatorInterface $translator) { - $this->labelGenerator = $labelGenerator; - $this->em = $em; - $this->elementTypeNameGenerator = $elementTypeNameGenerator; - $this->rangeParser = $rangeParser; - $this->translator = $translator; } #[Route(path: '/dialog', name: 'label_dialog')] @@ -85,15 +73,11 @@ class LabelController extends AbstractController $this->denyAccessUnlessGranted('@labels.create_labels'); //If we inherit a LabelProfile, the user need to have access to it... - if (null !== $profile) { + if ($profile instanceof \App\Entity\LabelSystem\LabelProfile) { $this->denyAccessUnlessGranted('read', $profile); } - if ($profile) { - $label_options = $profile->getOptions(); - } else { - $label_options = new LabelOptions(); - } + $label_options = $profile instanceof \App\Entity\LabelSystem\LabelProfile ? $profile->getOptions() : new LabelOptions(); //We have to disable the options, if twig mode is selected and user is not allowed to use it. $disable_options = 'twig' === $label_options->getLinesMode() && !$this->isGranted('@labels.use_twig'); @@ -107,7 +91,7 @@ class LabelController extends AbstractController $target_id = $request->query->get('target_id', null); $generate = $request->query->getBoolean('generate', false); - if (null === $profile && is_string($target_type)) { + if (!$profile instanceof \App\Entity\LabelSystem\LabelProfile && is_string($target_type)) { $label_options->setSupportedElement($target_type); } if (is_string($target_id)) { @@ -124,10 +108,10 @@ class LabelController extends AbstractController $filename = 'invalid.pdf'; //Generate PDF either when the form is submitted and valid, or the form was not submit yet, and generate is set - if (($form->isSubmitted() && $form->isValid()) || ($generate && !$form->isSubmitted() && null !== $profile)) { + if (($form->isSubmitted() && $form->isValid()) || ($generate && !$form->isSubmitted() && $profile instanceof \App\Entity\LabelSystem\LabelProfile)) { $target_id = (string) $form->get('target_id')->getData(); $targets = $this->findObjects($form_options->getSupportedElement(), $target_id); - if (!empty($targets)) { + if ($targets !== []) { try { $pdf_data = $this->labelGenerator->generateLabel($form_options, $targets); $filename = $this->getLabelName($targets[0], $profile); diff --git a/src/Controller/LogController.php b/src/Controller/LogController.php index 28d7cbac..2c6b6625 100644 --- a/src/Controller/LogController.php +++ b/src/Controller/LogController.php @@ -52,20 +52,13 @@ use Symfony\Component\Routing\Annotation\Route; #[Route(path: '/log')] class LogController extends AbstractController { - protected EntityManagerInterface $entityManager; - protected TimeTravel $timeTravel; protected DBElementRepository $dbRepository; - public function __construct(EntityManagerInterface $entityManager, TimeTravel $timeTravel) + public function __construct(protected EntityManagerInterface $entityManager, protected TimeTravel $timeTravel) { - $this->entityManager = $entityManager; - $this->timeTravel = $timeTravel; $this->dbRepository = $entityManager->getRepository(AbstractDBElement::class); } - /** - * @return Response - */ #[Route(path: '/', name: 'log_view')] public function showLogs(Request $request, DataTableFactory $dataTable): Response { @@ -96,8 +89,6 @@ class LogController extends AbstractController /** * @param Request $request - * @param AbstractLogEntry $logEntry - * @return Response */ #[Route(path: '/{id}/details', name: 'log_details')] public function logDetails(AbstractLogEntry $logEntry, LogEntryExtraFormatter $logEntryExtraFormatter, @@ -150,7 +141,7 @@ class LogController extends AbstractController } $log_element = $this->entityManager->find(AbstractLogEntry::class, $id); - if (null === $log_element) { + if (!$log_element instanceof \App\Entity\LogSystem\AbstractLogEntry) { throw new InvalidArgumentException('No log entry with the given ID is existing!'); } diff --git a/src/Controller/PartController.php b/src/Controller/PartController.php index 20a2006c..c10858ac 100644 --- a/src/Controller/PartController.php +++ b/src/Controller/PartController.php @@ -62,16 +62,8 @@ use function Symfony\Component\Translation\t; #[Route(path: '/part')] class PartController extends AbstractController { - protected PricedetailHelper $pricedetailHelper; - protected PartPreviewGenerator $partPreviewGenerator; - protected EventCommentHelper $commentHelper; - - public function __construct(PricedetailHelper $pricedetailHelper, - PartPreviewGenerator $partPreviewGenerator, EventCommentHelper $commentHelper) + public function __construct(protected PricedetailHelper $pricedetailHelper, protected PartPreviewGenerator $partPreviewGenerator, protected EventCommentHelper $commentHelper) { - $this->pricedetailHelper = $pricedetailHelper; - $this->partPreviewGenerator = $partPreviewGenerator; - $this->commentHelper = $commentHelper; } /** @@ -218,11 +210,13 @@ class PartController extends AbstractController ?Part $part = null, ?Project $project = null): Response { - if ($part) { //Clone part + if ($part instanceof \App\Entity\Parts\Part) { + //Clone part $new_part = clone $part; - } else if ($project) { //Initialize a new part for a build part from the given project + } elseif ($project instanceof \App\Entity\ProjectSystem\Project) { + //Initialize a new part for a build part from the given project //Ensure that the project has not already a build part - if ($project->getBuildPart() !== null) { + if ($project->getBuildPart() instanceof \App\Entity\Parts\Part) { $this->addFlash('error', 'part.new_build_part.error.build_part_already_exists'); return $this->redirectToRoute('part_edit', ['id' => $project->getBuildPart()->getID()]); } @@ -235,7 +229,7 @@ class PartController extends AbstractController $cid = $request->get('category', null); $category = $cid ? $em->find(Category::class, $cid) : null; - if (null !== $category && null === $new_part->getCategory()) { + if ($category instanceof \App\Entity\Parts\Category && !$new_part->getCategory() instanceof \App\Entity\Parts\Category) { $new_part->setCategory($category); $new_part->setDescription($category->getDefaultDescription()); $new_part->setComment($category->getDefaultComment()); @@ -243,19 +237,19 @@ class PartController extends AbstractController $fid = $request->get('footprint', null); $footprint = $fid ? $em->find(Footprint::class, $fid) : null; - if (null !== $footprint && null === $new_part->getFootprint()) { + if ($footprint instanceof \App\Entity\Parts\Footprint && !$new_part->getFootprint() instanceof \App\Entity\Parts\Footprint) { $new_part->setFootprint($footprint); } $mid = $request->get('manufacturer', null); $manufacturer = $mid ? $em->find(Manufacturer::class, $mid) : null; - if (null !== $manufacturer && null === $new_part->getManufacturer()) { + if ($manufacturer instanceof \App\Entity\Parts\Manufacturer && !$new_part->getManufacturer() instanceof \App\Entity\Parts\Manufacturer) { $new_part->setManufacturer($manufacturer); } $store_id = $request->get('storelocation', null); $storelocation = $store_id ? $em->find(Storelocation::class, $store_id) : null; - if (null !== $storelocation && $new_part->getPartLots()->isEmpty()) { + if ($storelocation instanceof \App\Entity\Parts\Storelocation && $new_part->getPartLots()->isEmpty()) { $partLot = new PartLot(); $partLot->setStorageLocation($storelocation); $partLot->setInstockUnknown(true); @@ -264,7 +258,7 @@ class PartController extends AbstractController $supplier_id = $request->get('supplier', null); $supplier = $supplier_id ? $em->find(Supplier::class, $supplier_id) : null; - if (null !== $supplier && $new_part->getOrderdetails()->isEmpty()) { + if ($supplier instanceof \App\Entity\Parts\Supplier && $new_part->getOrderdetails()->isEmpty()) { $orderdetail = new Orderdetail(); $orderdetail->setSupplier($supplier); $new_part->addOrderdetail($orderdetail); @@ -335,7 +329,7 @@ class PartController extends AbstractController if ($this->isCsrfTokenValid('part_withraw' . $part->getID(), $request->request->get('_csfr'))) { //Retrieve partlot from the request $partLot = $em->find(PartLot::class, $request->request->get('lot_id')); - if($partLot === null) { + if(!$partLot instanceof \App\Entity\Parts\PartLot) { throw new \RuntimeException('Part lot not found!'); } //Ensure that the partlot belongs to the part @@ -375,7 +369,7 @@ class PartController extends AbstractController default: throw new \RuntimeException("Unknown action!"); } - } catch (AccessDeniedException $exception) { + } catch (AccessDeniedException) { $this->addFlash('error', t('part.withdraw.access_denied')); goto err; } diff --git a/src/Controller/PartImportExportController.php b/src/Controller/PartImportExportController.php index fd37c045..b5d4c4e1 100644 --- a/src/Controller/PartImportExportController.php +++ b/src/Controller/PartImportExportController.php @@ -36,22 +36,10 @@ use UnexpectedValueException; class PartImportExportController extends AbstractController { - private PartsTableActionHandler $partsTableActionHandler; - private EntityImporter $entityImporter; - private EventCommentHelper $commentHelper; - - public function __construct(PartsTableActionHandler $partsTableActionHandler, - EntityImporter $entityImporter, EventCommentHelper $commentHelper) + public function __construct(private readonly PartsTableActionHandler $partsTableActionHandler, private readonly EntityImporter $entityImporter, private readonly EventCommentHelper $commentHelper) { - $this->partsTableActionHandler = $partsTableActionHandler; - $this->entityImporter = $entityImporter; - $this->commentHelper = $commentHelper; } - /** - * @param Request $request - * @return Response - */ #[Route(path: '/parts/import', name: 'parts_import')] public function importParts(Request $request): Response { @@ -116,16 +104,13 @@ class PartImportExportController extends AbstractController ]); } - /** - * @return Response - */ #[Route(path: '/parts/export', name: 'parts_export', methods: ['GET'])] public function exportParts(Request $request, EntityExporter $entityExporter): Response { $ids = $request->query->get('ids', ''); $parts = $this->partsTableActionHandler->idStringToArray($ids); - if (empty($parts)) { + if ($parts === []) { throw new \RuntimeException('No parts found!'); } diff --git a/src/Controller/PartListsController.php b/src/Controller/PartListsController.php index 271adb06..322d2ebf 100644 --- a/src/Controller/PartListsController.php +++ b/src/Controller/PartListsController.php @@ -48,18 +48,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class PartListsController extends AbstractController { - private EntityManagerInterface $entityManager; - private NodesListBuilder $nodesListBuilder; - private DataTableFactory $dataTableFactory; - - private TranslatorInterface $translator; - - public function __construct(EntityManagerInterface $entityManager, NodesListBuilder $nodesListBuilder, DataTableFactory $dataTableFactory, TranslatorInterface $translator) + public function __construct(private readonly EntityManagerInterface $entityManager, private readonly NodesListBuilder $nodesListBuilder, private readonly DataTableFactory $dataTableFactory, private readonly TranslatorInterface $translator) { - $this->entityManager = $entityManager; - $this->nodesListBuilder = $nodesListBuilder; - $this->dataTableFactory = $dataTableFactory; - $this->translator = $translator; } #[Route(path: '/table/action', name: 'table_action', methods: ['POST'])] @@ -100,8 +90,6 @@ class PartListsController extends AbstractController /** * Disable the given form interface after creation of the form by removing and reattaching the form. - * @param FormInterface $form - * @return void */ private function disableFormFieldAfterCreation(FormInterface $form, bool $disabled = true): void { @@ -109,12 +97,12 @@ class PartListsController extends AbstractController $attrs['disabled'] = $disabled; $parent = $form->getParent(); - if ($parent === null) { + if (!$parent instanceof \Symfony\Component\Form\FormInterface) { throw new \RuntimeException('This function can only be used on form fields that are children of another form!'); } $parent->remove($form->getName()); - $parent->add($form->getName(), get_class($form->getConfig()->getType()->getInnerType()), $attrs); + $parent->add($form->getName(), $form->getConfig()->getType()->getInnerType()::class, $attrs); } /** @@ -125,7 +113,6 @@ class PartListsController extends AbstractController * @param callable|null $form_changer A function that is called with the form object as parameter. This function can be used to customize the form * @param array $additonal_template_vars Any additional template variables that should be passed to the template * @param array $additional_table_vars Any additional variables that should be passed to the table creation - * @return Response */ protected function showListWithFilter(Request $request, string $template, ?callable $filter_changer = null, ?callable $form_changer = null, array $additonal_template_vars = [], array $additional_table_vars = []): Response { @@ -172,9 +159,6 @@ class PartListsController extends AbstractController ], $additonal_template_vars)); } - /** - * @return JsonResponse|Response - */ #[Route(path: '/category/{id}/parts', name: 'part_list_category')] public function showCategory(Category $category, Request $request): Response { @@ -193,9 +177,6 @@ class PartListsController extends AbstractController ); } - /** - * @return JsonResponse|Response - */ #[Route(path: '/footprint/{id}/parts', name: 'part_list_footprint')] public function showFootprint(Footprint $footprint, Request $request): Response { @@ -214,9 +195,6 @@ class PartListsController extends AbstractController ); } - /** - * @return JsonResponse|Response - */ #[Route(path: '/manufacturer/{id}/parts', name: 'part_list_manufacturer')] public function showManufacturer(Manufacturer $manufacturer, Request $request): Response { @@ -235,9 +213,6 @@ class PartListsController extends AbstractController ); } - /** - * @return JsonResponse|Response - */ #[Route(path: '/store_location/{id}/parts', name: 'part_list_store_location')] public function showStorelocation(Storelocation $storelocation, Request $request): Response { @@ -256,9 +231,6 @@ class PartListsController extends AbstractController ); } - /** - * @return JsonResponse|Response - */ #[Route(path: '/supplier/{id}/parts', name: 'part_list_supplier')] public function showSupplier(Supplier $supplier, Request $request): Response { @@ -277,9 +249,6 @@ class PartListsController extends AbstractController ); } - /** - * @return JsonResponse|Response - */ #[Route(path: '/parts/by_tag/{tag}', name: 'part_list_tags', requirements: ['tag' => '.*'])] public function showTag(string $tag, Request $request): Response { @@ -321,9 +290,6 @@ class PartListsController extends AbstractController return $filter; } - /** - * @return JsonResponse|Response - */ #[Route(path: '/parts/search', name: 'parts_search')] public function showSearch(Request $request, DataTableFactory $dataTable): Response { @@ -343,9 +309,6 @@ class PartListsController extends AbstractController ); } - /** - * @return Response - */ #[Route(path: '/parts', name: 'parts_show_all')] public function showAll(Request $request): Response { diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php index 2db1c1a7..a8fae5df 100644 --- a/src/Controller/ProjectController.php +++ b/src/Controller/ProjectController.php @@ -50,11 +50,8 @@ use function Symfony\Component\Translation\t; #[Route(path: '/project')] class ProjectController extends AbstractController { - private DataTableFactory $dataTableFactory; - - public function __construct(DataTableFactory $dataTableFactory) + public function __construct(private readonly DataTableFactory $dataTableFactory) { - $this->dataTableFactory = $dataTableFactory; } #[Route(path: '/{id}/info', name: 'project_info', requirements: ['id' => '\d+'])] @@ -180,9 +177,7 @@ class ProjectController extends AbstractController if (count ($errors) > 0) { $this->addFlash('error', t('project.bom_import.flash.invalid_entries')); } - } catch (\UnexpectedValueException $e) { - $this->addFlash('error', t('project.bom_import.flash.invalid_file', ['%message%' => $e->getMessage()])); - } catch (SyntaxError $e) { + } catch (\UnexpectedValueException|SyntaxError $e) { $this->addFlash('error', t('project.bom_import.flash.invalid_file', ['%message%' => $e->getMessage()])); } } @@ -194,15 +189,11 @@ class ProjectController extends AbstractController ]); } - /** - * @param Request $request - * @param Project|null $project - */ #[Route(path: '/add_parts', name: 'project_add_parts_no_id')] #[Route(path: '/{id}/add_parts', name: 'project_add_parts', requirements: ['id' => '\d+'])] public function addPart(Request $request, EntityManagerInterface $entityManager, ?Project $project): Response { - if($project) { + if($project instanceof \App\Entity\ProjectSystem\Project) { $this->denyAccessUnlessGranted('edit', $project); } else { $this->denyAccessUnlessGranted('@projects.edit'); @@ -212,7 +203,7 @@ class ProjectController extends AbstractController $builder->add('project', StructuralEntityType::class, [ 'class' => Project::class, 'required' => true, - 'disabled' => $project !== null, //If a project is given, disable the field + 'disabled' => $project instanceof \App\Entity\ProjectSystem\Project, //If a project is given, disable the field 'data' => $project, 'constraints' => [ new NotNull() @@ -224,7 +215,7 @@ class ProjectController extends AbstractController //Preset the BOM entries with the selected parts, when the form was not submitted yet $preset_data = new ArrayCollection(); - foreach (explode(',', $request->get('parts', '')) as $part_id) { + foreach (explode(',', (string) $request->get('parts', '')) as $part_id) { $part = $entityManager->getRepository(Part::class)->find($part_id); if (null !== $part) { //If there is already a BOM entry for this part, we use this one (we edit it then) diff --git a/src/Controller/RedirectController.php b/src/Controller/RedirectController.php index a6099ace..16bed9ea 100644 --- a/src/Controller/RedirectController.php +++ b/src/Controller/RedirectController.php @@ -32,15 +32,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class RedirectController extends AbstractController { - protected string $default_locale; - protected TranslatorInterface $translator; - protected bool $enforce_index_php; - - public function __construct(string $default_locale, TranslatorInterface $translator, bool $enforce_index_php) + public function __construct(protected string $default_locale, protected TranslatorInterface $translator, protected bool $enforce_index_php) { - $this->default_locale = $default_locale; - $this->translator = $translator; - $this->enforce_index_php = $enforce_index_php; } /** diff --git a/src/Controller/ScanController.php b/src/Controller/ScanController.php index 1c7a2670..41959d0a 100644 --- a/src/Controller/ScanController.php +++ b/src/Controller/ScanController.php @@ -54,13 +54,8 @@ use Symfony\Component\Routing\Annotation\Route; #[Route(path: '/scan')] class ScanController extends AbstractController { - protected BarcodeRedirector $barcodeParser; - protected BarcodeNormalizer $barcodeNormalizer; - - public function __construct(BarcodeRedirector $barcodeParser, BarcodeNormalizer $barcodeNormalizer) + public function __construct(protected BarcodeRedirector $barcodeParser, protected BarcodeNormalizer $barcodeNormalizer) { - $this->barcodeParser = $barcodeParser; - $this->barcodeNormalizer = $barcodeNormalizer; } #[Route(path: '', name: 'scan_dialog')] @@ -79,10 +74,10 @@ class ScanController extends AbstractController try { return $this->redirect($this->barcodeParser->getRedirectURL($type, $id)); - } catch (EntityNotFoundException $exception) { + } catch (EntityNotFoundException) { $this->addFlash('success', 'scan.qr_not_found'); } - } catch (InvalidArgumentException $exception) { + } catch (InvalidArgumentException) { $this->addFlash('error', 'scan.format_unknown'); } } @@ -101,7 +96,7 @@ class ScanController extends AbstractController $this->addFlash('success', 'scan.qr_success'); return $this->redirect($this->barcodeParser->getRedirectURL($type, $id)); - } catch (EntityNotFoundException $exception) { + } catch (EntityNotFoundException) { $this->addFlash('success', 'scan.qr_not_found'); return $this->redirectToRoute('homepage'); diff --git a/src/Controller/SecurityController.php b/src/Controller/SecurityController.php index bd696e1e..4ad6b772 100644 --- a/src/Controller/SecurityController.php +++ b/src/Controller/SecurityController.php @@ -48,13 +48,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class SecurityController extends AbstractController { - protected TranslatorInterface $translator; - protected bool $allow_email_pw_reset; - - public function __construct(TranslatorInterface $translator, bool $allow_email_pw_reset) + public function __construct(protected TranslatorInterface $translator, protected bool $allow_email_pw_reset) { - $this->translator = $translator; - $this->allow_email_pw_reset = $allow_email_pw_reset; } #[Route(path: '/login', name: 'login', methods: ['GET', 'POST'])] @@ -76,7 +71,7 @@ class SecurityController extends AbstractController * @return RedirectResponse|Response */ #[Route(path: '/pw_reset/request', name: 'pw_reset_request')] - public function requestPwReset(PasswordResetManager $passwordReset, Request $request) + public function requestPwReset(PasswordResetManager $passwordReset, Request $request): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response { if (!$this->allow_email_pw_reset) { throw new AccessDeniedHttpException('The password reset via email is disabled!'); @@ -119,7 +114,7 @@ class SecurityController extends AbstractController * @return RedirectResponse|Response */ #[Route(path: '/pw_reset/new_pw/{user}/{token}', name: 'pw_reset_new_pw')] - public function pwResetNewPw(PasswordResetManager $passwordReset, Request $request, EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher, ?string $user = null, ?string $token = null) + public function pwResetNewPw(PasswordResetManager $passwordReset, Request $request, EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher, ?string $user = null, ?string $token = null): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response { if (!$this->allow_email_pw_reset) { throw new AccessDeniedHttpException('The password reset via email is disabled!'); @@ -189,7 +184,7 @@ class SecurityController extends AbstractController } #[Route(path: '/logout', name: 'logout')] - public function logout(): void + public function logout(): never { throw new RuntimeException('Will be intercepted before getting here'); } diff --git a/src/Controller/SelectAPIController.php b/src/Controller/SelectAPIController.php index 7ea9a8bd..8691b967 100644 --- a/src/Controller/SelectAPIController.php +++ b/src/Controller/SelectAPIController.php @@ -42,15 +42,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; #[Route(path: '/select_api')] class SelectAPIController extends AbstractController { - private NodesListBuilder $nodesListBuilder; - private TranslatorInterface $translator; - private StructuralEntityChoiceHelper $choiceHelper; - - public function __construct(NodesListBuilder $nodesListBuilder, TranslatorInterface $translator, StructuralEntityChoiceHelper $choiceHelper) + public function __construct(private readonly NodesListBuilder $nodesListBuilder, private readonly TranslatorInterface $translator, private readonly StructuralEntityChoiceHelper $choiceHelper) { - $this->nodesListBuilder = $nodesListBuilder; - $this->translator = $translator; - $this->choiceHelper = $choiceHelper; } #[Route(path: '/category', name: 'select_category')] @@ -92,17 +85,12 @@ class SelectAPIController extends AbstractController 3 => $this->translator->trans('export.level.full'), ]; - return $this->json(array_map(static function ($key, $value) { - return [ - 'text' => $value, - 'value' => $key, - ]; - }, array_keys($entries), $entries)); + return $this->json(array_map(static fn($key, $value) => [ + 'text' => $value, + 'value' => $key, + ], array_keys($entries), $entries)); } - /** - * @return Response - */ #[Route(path: '/label_profiles', name: 'select_label_profiles')] public function labelProfiles(EntityManagerInterface $entityManager): Response { @@ -121,9 +109,6 @@ class SelectAPIController extends AbstractController return $this->json($nodes); } - /** - * @return Response - */ #[Route(path: '/label_profiles_lot', name: 'select_label_profiles_lot')] public function labelProfilesLot(EntityManagerInterface $entityManager): Response { diff --git a/src/Controller/ToolsController.php b/src/Controller/ToolsController.php index 56711d43..65321a19 100644 --- a/src/Controller/ToolsController.php +++ b/src/Controller/ToolsController.php @@ -77,7 +77,7 @@ class ToolsController extends AbstractController 'php_version' => PHP_VERSION, 'php_uname' => php_uname('a'), 'php_sapi' => PHP_SAPI, - 'php_extensions' => array_merge(get_loaded_extensions()), + 'php_extensions' => [...get_loaded_extensions()], 'php_opcache_enabled' => ini_get('opcache.enable'), 'php_upload_max_filesize' => ini_get('upload_max_filesize'), 'php_post_max_size' => ini_get('post_max_size'), @@ -91,32 +91,22 @@ class ToolsController extends AbstractController ]); } - /** - * @return Response - */ #[Route(path: '/builtin_footprints', name: 'tools_builtin_footprints_viewer')] public function builtInFootprintsViewer(BuiltinAttachmentsFinder $builtinAttachmentsFinder, AttachmentURLGenerator $urlGenerator): Response { $this->denyAccessUnlessGranted('@tools.builtin_footprints_viewer'); $grouped_footprints = $builtinAttachmentsFinder->getListOfFootprintsGroupedByFolder(); - $grouped_footprints = array_map(function($group) use ($urlGenerator) { - return array_map(function($placeholder_filepath) use ($urlGenerator) { - return [ - 'filename' => basename($placeholder_filepath), - 'assets_path' => $urlGenerator->placeholderPathToAssetPath($placeholder_filepath), - ]; - }, $group); - }, $grouped_footprints); + $grouped_footprints = array_map(fn($group) => array_map(fn($placeholder_filepath) => [ + 'filename' => basename((string) $placeholder_filepath), + 'assets_path' => $urlGenerator->placeholderPathToAssetPath($placeholder_filepath), + ], $group), $grouped_footprints); return $this->render('tools/builtin_footprints_viewer/builtin_footprints_viewer.html.twig', [ 'grouped_footprints' => $grouped_footprints, ]); } - /** - * @return Response - */ #[Route(path: '/ic_logos', name: 'tools_ic_logos')] public function icLogos(): Response { diff --git a/src/Controller/TreeController.php b/src/Controller/TreeController.php index 806dd4d2..3d8e9074 100644 --- a/src/Controller/TreeController.php +++ b/src/Controller/TreeController.php @@ -40,11 +40,8 @@ use Symfony\Component\Routing\Annotation\Route; #[Route(path: '/tree')] class TreeController extends AbstractController { - protected TreeViewGenerator $treeGenerator; - - public function __construct(TreeViewGenerator $treeGenerator) + public function __construct(protected TreeViewGenerator $treeGenerator) { - $this->treeGenerator = $treeGenerator; } #[Route(path: '/tools', name: 'tree_tools')] diff --git a/src/Controller/TypeaheadController.php b/src/Controller/TypeaheadController.php index 19385d0f..791cb793 100644 --- a/src/Controller/TypeaheadController.php +++ b/src/Controller/TypeaheadController.php @@ -55,13 +55,8 @@ use Symfony\Component\Serializer\Serializer; #[Route(path: '/typeahead')] class TypeaheadController extends AbstractController { - protected AttachmentURLGenerator $urlGenerator; - protected Packages $assets; - - public function __construct(AttachmentURLGenerator $URLGenerator, Packages $assets) + public function __construct(protected AttachmentURLGenerator $urlGenerator, protected Packages $assets) { - $this->urlGenerator = $URLGenerator; - $this->assets = $assets; } #[Route(path: '/builtInResources/search', name: 'typeahead_builtInRessources')] @@ -93,45 +88,26 @@ class TypeaheadController extends AbstractController /** * This function map the parameter type to the class, so we can access its repository - * @param string $type * @return class-string */ private function typeToParameterClass(string $type): string { - switch ($type) { - case 'category': - return CategoryParameter::class; - case 'part': - return PartParameter::class; - case 'device': - return ProjectParameter::class; - case 'footprint': - return FootprintParameter::class; - case 'manufacturer': - return ManufacturerParameter::class; - case 'storelocation': - return StorelocationParameter::class; - case 'supplier': - return SupplierParameter::class; - case 'attachment_type': - return AttachmentTypeParameter::class; - case 'group': - return GroupParameter::class; - case 'measurement_unit': - return MeasurementUnitParameter::class; - case 'currency': - return Currency::class; - - default: - throw new \InvalidArgumentException('Invalid parameter type: '.$type); - } + return match ($type) { + 'category' => CategoryParameter::class, + 'part' => PartParameter::class, + 'device' => ProjectParameter::class, + 'footprint' => FootprintParameter::class, + 'manufacturer' => ManufacturerParameter::class, + 'storelocation' => StorelocationParameter::class, + 'supplier' => SupplierParameter::class, + 'attachment_type' => AttachmentTypeParameter::class, + 'group' => GroupParameter::class, + 'measurement_unit' => MeasurementUnitParameter::class, + 'currency' => Currency::class, + default => throw new \InvalidArgumentException('Invalid parameter type: '.$type), + }; } - /** - * @param string $query - * @param EntityManagerInterface $entityManager - * @return JsonResponse - */ #[Route(path: '/parts/search/{query}', name: 'typeahead_parts')] public function parts(EntityManagerInterface $entityManager, PartPreviewGenerator $previewGenerator, AttachmentURLGenerator $attachmentURLGenerator, string $query = ""): JsonResponse @@ -146,7 +122,7 @@ class TypeaheadController extends AbstractController foreach ($parts as $part) { //Determine the picture to show: $preview_attachment = $previewGenerator->getTablePreviewAttachment($part); - if($preview_attachment !== null) { + if($preview_attachment instanceof \App\Entity\Attachments\Attachment) { $preview_url = $attachmentURLGenerator->getThumbnailURL($preview_attachment, 'thumbnail_sm'); } else { $preview_url = ''; @@ -156,8 +132,8 @@ class TypeaheadController extends AbstractController $data[] = [ 'id' => $part->getID(), 'name' => $part->getName(), - 'category' => $part->getCategory() ? $part->getCategory()->getName() : 'Unknown', - 'footprint' => $part->getFootprint() ? $part->getFootprint()->getName() : '', + 'category' => $part->getCategory() instanceof \App\Entity\Parts\Category ? $part->getCategory()->getName() : 'Unknown', + 'footprint' => $part->getFootprint() instanceof \App\Entity\Parts\Footprint ? $part->getFootprint()->getName() : '', 'description' => mb_strimwidth($part->getDescription(), 0, 127, '...'), 'image' => $preview_url, ]; @@ -166,10 +142,6 @@ class TypeaheadController extends AbstractController return new JsonResponse($data); } - /** - * @param string $query - * @return JsonResponse - */ #[Route(path: '/parameters/{type}/search/{query}', name: 'typeahead_parameters', requirements: ['type' => '.+'])] public function parameters(string $type, EntityManagerInterface $entityManager, string $query = ""): JsonResponse { diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 7d2b8160..ceb86802 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -180,7 +180,7 @@ class UserController extends AdminPages\BaseAdminController public function userInfo(?User $user, Packages $packages, Request $request, DataTableFactory $dataTableFactory): Response { //If no user id was passed, then we show info about the current user - if (null === $user) { + if (!$user instanceof \App\Entity\UserSystem\User) { $tmp = $this->getUser(); if (!$tmp instanceof User) { throw new InvalidArgumentException('Userinfo only works for database users!'); diff --git a/src/Controller/UserSettingsController.php b/src/Controller/UserSettingsController.php index 298b94d0..d21d0bbd 100644 --- a/src/Controller/UserSettingsController.php +++ b/src/Controller/UserSettingsController.php @@ -54,16 +54,13 @@ use Symfony\Component\Validator\Constraints\Length; #[Route(path: '/user')] class UserSettingsController extends AbstractController { - protected bool $demo_mode; - /** * @var EventDispatcher|EventDispatcherInterface */ protected $eventDispatcher; - public function __construct(bool $demo_mode, EventDispatcherInterface $eventDispatcher) + public function __construct(protected bool $demo_mode, EventDispatcherInterface $eventDispatcher) { - $this->demo_mode = $demo_mode; $this->eventDispatcher = $eventDispatcher; } @@ -121,49 +118,43 @@ class UserSettingsController extends AbstractController $key_repo = $entityManager->getRepository(U2FKey::class); /** @var U2FKey|null $u2f */ $u2f = $key_repo->find($key_id); - if (null === $u2f) { + if (!$u2f instanceof \App\Entity\UserSystem\U2FKey) { $this->addFlash('danger', 'tfa_u2f.u2f_delete.not_existing'); return $this->redirectToRoute('user_settings'); } - //User can only delete its own U2F keys if ($u2f->getUser() !== $user) { $this->addFlash('danger', 'tfa_u2f.u2f_delete.access_denied'); return $this->redirectToRoute('user_settings'); } - $backupCodeManager->disableBackupCodesIfUnused($user); $entityManager->remove($u2f); $entityManager->flush(); $this->addFlash('success', 'tfa.u2f.u2f_delete.success'); - $security_event = new SecurityEvent($user); $this->eventDispatcher->dispatch($security_event, SecurityEvents::U2F_REMOVED); - } else if ($request->request->has('webauthn_key_id')) { + } elseif ($request->request->has('webauthn_key_id')) { $key_id = $request->request->get('webauthn_key_id'); $key_repo = $entityManager->getRepository(WebauthnKey::class); /** @var WebauthnKey|null $key */ $key = $key_repo->find($key_id); - if (null === $key) { + if (!$key instanceof \App\Entity\UserSystem\WebauthnKey) { $this->addFlash('error', 'tfa_u2f.u2f_delete.not_existing'); return $this->redirectToRoute('user_settings'); } - //User can only delete its own U2F keys if ($key->getUser() !== $user) { $this->addFlash('error', 'tfa_u2f.u2f_delete.access_denied'); return $this->redirectToRoute('user_settings'); } - $backupCodeManager->disableBackupCodesIfUnused($user); $entityManager->remove($key); $entityManager->flush(); $this->addFlash('success', 'tfa.u2f.u2f_delete.success'); - $security_event = new SecurityEvent($user); $this->eventDispatcher->dispatch($security_event, SecurityEvents::U2F_REMOVED); } @@ -174,11 +165,8 @@ class UserSettingsController extends AbstractController return $this->redirectToRoute('user_settings'); } - /** - * @return RuntimeException|RedirectResponse - */ #[Route(path: '/invalidate_trustedDevices', name: 'tfa_trustedDevices_invalidate', methods: ['DELETE'])] - public function resetTrustedDevices(Request $request, EntityManagerInterface $entityManager) + public function resetTrustedDevices(Request $request, EntityManagerInterface $entityManager): \RuntimeException|\Symfony\Component\HttpFoundation\RedirectResponse { if ($this->demo_mode) { throw new RuntimeException('You can not do 2FA things in demo mode'); @@ -215,7 +203,7 @@ class UserSettingsController extends AbstractController * @return RedirectResponse|Response */ #[Route(path: '/settings', name: 'user_settings')] - public function userSettings(Request $request, EntityManagerInterface $em, UserPasswordHasherInterface $passwordEncoder, GoogleAuthenticator $googleAuthenticator, BackupCodeManager $backupCodeManager, FormFactoryInterface $formFactory, UserAvatarHelper $avatarHelper) + public function userSettings(Request $request, EntityManagerInterface $em, UserPasswordHasherInterface $passwordEncoder, GoogleAuthenticator $googleAuthenticator, BackupCodeManager $backupCodeManager, FormFactoryInterface $formFactory, UserAvatarHelper $avatarHelper): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response { /** @var User $user */ $user = $this->getUser(); @@ -254,13 +242,11 @@ class UserSettingsController extends AbstractController } /** @var Form $form We need a form implementation for the next calls */ - if ($form->getClickedButton() && 'remove_avatar' === $form->getClickedButton()->getName()) { - //Remove the avatar attachment from the user if requested - if ($user->getMasterPictureAttachment() !== null) { - $em->remove($user->getMasterPictureAttachment()); - $user->setMasterPictureAttachment(null); - $page_need_reload = true; - } + //Remove the avatar attachment from the user if requested + if ($form->getClickedButton() && 'remove_avatar' === $form->getClickedButton()->getName() && $user->getMasterPictureAttachment() instanceof \App\Entity\Attachments\Attachment) { + $em->remove($user->getMasterPictureAttachment()); + $user->setMasterPictureAttachment(null); + $page_need_reload = true; } $em->flush(); diff --git a/src/Controller/WebauthnKeyRegistrationController.php b/src/Controller/WebauthnKeyRegistrationController.php index ee39954a..cf273626 100644 --- a/src/Controller/WebauthnKeyRegistrationController.php +++ b/src/Controller/WebauthnKeyRegistrationController.php @@ -33,11 +33,8 @@ use function Symfony\Component\Translation\t; class WebauthnKeyRegistrationController extends AbstractController { - private bool $demo_mode; - - public function __construct(bool $demo_mode) + public function __construct(private readonly bool $demo_mode) { - $this->demo_mode = $demo_mode; } #[Route(path: '/webauthn/register', name: 'webauthn_register')] @@ -73,7 +70,7 @@ class WebauthnKeyRegistrationController extends AbstractController //Check the response try { $new_key = $registrationHelper->checkRegistrationResponse($webauthnResponse); - } catch (\Exception $exception) { + } catch (\Exception) { $this->addFlash('error', t('tfa_u2f.add_key.registration_error')); return $this->redirectToRoute('webauthn_register'); } diff --git a/src/DataFixtures/DataStructureFixtures.php b/src/DataFixtures/DataStructureFixtures.php index c7416abe..5abf6d6f 100644 --- a/src/DataFixtures/DataStructureFixtures.php +++ b/src/DataFixtures/DataStructureFixtures.php @@ -38,11 +38,8 @@ use InvalidArgumentException; class DataStructureFixtures extends Fixture { - protected EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(protected EntityManagerInterface $em) { - $this->em = $entityManager; } /** diff --git a/src/DataFixtures/GroupFixtures.php b/src/DataFixtures/GroupFixtures.php index 93e93b79..d8e54b9f 100644 --- a/src/DataFixtures/GroupFixtures.php +++ b/src/DataFixtures/GroupFixtures.php @@ -30,18 +30,12 @@ use Doctrine\Persistence\ObjectManager; class GroupFixtures extends Fixture { - public const ADMINS = 'group-admin'; - public const USERS = 'group-users'; - public const READONLY = 'group-readonly'; + final public const ADMINS = 'group-admin'; + final public const USERS = 'group-users'; + final public const READONLY = 'group-readonly'; - - private PermissionPresetsHelper $permission_presets; - private PermissionManager $permissionManager; - - public function __construct(PermissionPresetsHelper $permissionPresetsHelper, PermissionManager $permissionManager) + public function __construct(private readonly PermissionPresetsHelper $permission_presets, private readonly PermissionManager $permissionManager) { - $this->permission_presets = $permissionPresetsHelper; - $this->permissionManager = $permissionManager; } public function load(ObjectManager $manager): void diff --git a/src/DataFixtures/LabelProfileFixtures.php b/src/DataFixtures/LabelProfileFixtures.php index d2c23fad..77ebe791 100644 --- a/src/DataFixtures/LabelProfileFixtures.php +++ b/src/DataFixtures/LabelProfileFixtures.php @@ -49,11 +49,8 @@ use Doctrine\Persistence\ObjectManager; class LabelProfileFixtures extends Fixture { - protected EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(protected EntityManagerInterface $em) { - $this->em = $entityManager; } public function load(ObjectManager $manager): void diff --git a/src/DataFixtures/PartFixtures.php b/src/DataFixtures/PartFixtures.php index 45789dd9..6b765bc8 100644 --- a/src/DataFixtures/PartFixtures.php +++ b/src/DataFixtures/PartFixtures.php @@ -60,11 +60,8 @@ use Doctrine\Persistence\ObjectManager; class PartFixtures extends Fixture { - protected EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(protected EntityManagerInterface $em) { - $this->em = $entityManager; } public function load(ObjectManager $manager): void diff --git a/src/DataFixtures/UserFixtures.php b/src/DataFixtures/UserFixtures.php index f9e138b6..f329d1a2 100644 --- a/src/DataFixtures/UserFixtures.php +++ b/src/DataFixtures/UserFixtures.php @@ -30,13 +30,8 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; class UserFixtures extends Fixture { - protected UserPasswordHasherInterface $encoder; - protected EntityManagerInterface $em; - - public function __construct(UserPasswordHasherInterface $encoder, EntityManagerInterface $entityManager) + public function __construct(protected UserPasswordHasherInterface $encoder, protected EntityManagerInterface $em) { - $this->em = $entityManager; - $this->encoder = $encoder; } public function load(ObjectManager $manager): void diff --git a/src/DataTables/AttachmentDataTable.php b/src/DataTables/AttachmentDataTable.php index dd82f5a8..62a35049 100644 --- a/src/DataTables/AttachmentDataTable.php +++ b/src/DataTables/AttachmentDataTable.php @@ -42,27 +42,14 @@ use Symfony\Contracts\Translation\TranslatorInterface; final class AttachmentDataTable implements DataTableTypeInterface { - private TranslatorInterface $translator; - private EntityURLGenerator $entityURLGenerator; - private AttachmentManager $attachmentHelper; - private ElementTypeNameGenerator $elementTypeNameGenerator; - private AttachmentURLGenerator $attachmentURLGenerator; - - public function __construct(TranslatorInterface $translator, EntityURLGenerator $entityURLGenerator, - AttachmentManager $attachmentHelper, AttachmentURLGenerator $attachmentURLGenerator, - ElementTypeNameGenerator $elementTypeNameGenerator) + public function __construct(private readonly TranslatorInterface $translator, private readonly EntityURLGenerator $entityURLGenerator, private readonly AttachmentManager $attachmentHelper, private readonly AttachmentURLGenerator $attachmentURLGenerator, private readonly ElementTypeNameGenerator $elementTypeNameGenerator) { - $this->translator = $translator; - $this->entityURLGenerator = $entityURLGenerator; - $this->attachmentHelper = $attachmentHelper; - $this->elementTypeNameGenerator = $elementTypeNameGenerator; - $this->attachmentURLGenerator = $attachmentURLGenerator; } public function configure(DataTable $dataTable, array $options): void { $dataTable->add('dont_matter', RowClassColumn::class, [ - 'render' => function ($value, Attachment $context) { + 'render' => function ($value, Attachment $context): string { //Mark attachments with missing files yellow if(!$this->attachmentHelper->isFileExisting($context)){ return 'table-warning'; @@ -75,7 +62,7 @@ final class AttachmentDataTable implements DataTableTypeInterface $dataTable->add('picture', TextColumn::class, [ 'label' => '', 'className' => 'no-colvis', - 'render' => function ($value, Attachment $context) { + 'render' => function ($value, Attachment $context): string { if ($context->isPicture() && !$context->isExternal() && $this->attachmentHelper->isFileExisting($context)) { @@ -125,25 +112,21 @@ final class AttachmentDataTable implements DataTableTypeInterface $dataTable->add('attachment_type', TextColumn::class, [ 'label' => 'attachment.table.type', 'field' => 'attachment_type.name', - 'render' => function ($value, Attachment $context) { - return sprintf( - '%s', - $this->entityURLGenerator->editURL($context->getAttachmentType()), - htmlspecialchars($value) - ); - }, + 'render' => fn($value, Attachment $context): string => sprintf( + '%s', + $this->entityURLGenerator->editURL($context->getAttachmentType()), + htmlspecialchars((string) $value) + ), ]); $dataTable->add('element', TextColumn::class, [ 'label' => 'attachment.table.element', //'propertyPath' => 'element.name', - 'render' => function ($value, Attachment $context) { - return sprintf( - '%s', - $this->entityURLGenerator->infoURL($context->getElement()), - $this->elementTypeNameGenerator->getTypeNameCombination($context->getElement(), true) - ); - }, + 'render' => fn($value, Attachment $context): string => sprintf( + '%s', + $this->entityURLGenerator->infoURL($context->getElement()), + $this->elementTypeNameGenerator->getTypeNameCombination($context->getElement(), true) + ), ]); $dataTable->add('filename', TextColumn::class, [ diff --git a/src/DataTables/Column/EntityColumn.php b/src/DataTables/Column/EntityColumn.php index df3bf3d2..c14eabe9 100644 --- a/src/DataTables/Column/EntityColumn.php +++ b/src/DataTables/Column/EntityColumn.php @@ -31,13 +31,8 @@ use Symfony\Component\PropertyAccess\PropertyAccessorInterface; class EntityColumn extends AbstractColumn { - protected EntityURLGenerator $urlGenerator; - protected PropertyAccessorInterface $accessor; - - public function __construct(EntityURLGenerator $URLGenerator, PropertyAccessorInterface $accessor) + public function __construct(protected EntityURLGenerator $urlGenerator, protected PropertyAccessorInterface $accessor) { - $this->urlGenerator = $URLGenerator; - $this->accessor = $accessor; } /** @@ -58,34 +53,30 @@ class EntityColumn extends AbstractColumn $resolver->setRequired('property'); - $resolver->setDefault('field', static function (Options $option) { - return $option['property'].'.name'; - }); + $resolver->setDefault('field', static fn(Options $option): string => $option['property'].'.name'); - $resolver->setDefault('render', function (Options $options) { - return function ($value, $context) use ($options) { - if ($this->accessor->isReadable($context, $options['property'])) { - $entity = $this->accessor->getValue($context, $options['property']); - } else { - $entity = null; + $resolver->setDefault('render', fn(Options $options) => function ($value, $context) use ($options): string { + if ($this->accessor->isReadable($context, $options['property'])) { + $entity = $this->accessor->getValue($context, $options['property']); + } else { + $entity = null; + } + + /** @var AbstractNamedDBElement|null $entity */ + + if ($entity instanceof \App\Entity\Base\AbstractNamedDBElement) { + if (null !== $entity->getID()) { + return sprintf( + '%s', + $this->urlGenerator->listPartsURL($entity), + htmlspecialchars($entity->getName()) + ); } - /** @var AbstractNamedDBElement|null $entity */ + return sprintf('%s', $value); + } - if (null !== $entity) { - if (null !== $entity->getID()) { - return sprintf( - '%s', - $this->urlGenerator->listPartsURL($entity), - htmlspecialchars($entity->getName()) - ); - } - - return sprintf('%s', $value); - } - - return ''; - }; + return ''; }); return $this; diff --git a/src/DataTables/Column/LocaleDateTimeColumn.php b/src/DataTables/Column/LocaleDateTimeColumn.php index 733c0b6c..922f7eb3 100644 --- a/src/DataTables/Column/LocaleDateTimeColumn.php +++ b/src/DataTables/Column/LocaleDateTimeColumn.php @@ -38,7 +38,6 @@ class LocaleDateTimeColumn extends AbstractColumn { /** * @param $value - * @return string * @throws Exception */ public function normalize($value): string diff --git a/src/DataTables/Column/LogEntryExtraColumn.php b/src/DataTables/Column/LogEntryExtraColumn.php index da6b4865..7ac5ccd0 100644 --- a/src/DataTables/Column/LogEntryExtraColumn.php +++ b/src/DataTables/Column/LogEntryExtraColumn.php @@ -28,13 +28,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class LogEntryExtraColumn extends AbstractColumn { - protected TranslatorInterface $translator; - protected LogEntryExtraFormatter $formatter; - - public function __construct(TranslatorInterface $translator, LogEntryExtraFormatter $formatter) + public function __construct(protected TranslatorInterface $translator, protected LogEntryExtraFormatter $formatter) { - $this->translator = $translator; - $this->formatter = $formatter; } /** diff --git a/src/DataTables/Column/LogEntryTargetColumn.php b/src/DataTables/Column/LogEntryTargetColumn.php index 0f61d567..8a4e7fc5 100644 --- a/src/DataTables/Column/LogEntryTargetColumn.php +++ b/src/DataTables/Column/LogEntryTargetColumn.php @@ -44,11 +44,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class LogEntryTargetColumn extends AbstractColumn { - private LogTargetHelper $logTargetHelper; - - public function __construct(LogTargetHelper $logTargetHelper) + public function __construct(private readonly LogTargetHelper $logTargetHelper) { - $this->logTargetHelper = $logTargetHelper; } /** diff --git a/src/DataTables/Column/MarkdownColumn.php b/src/DataTables/Column/MarkdownColumn.php index 4e3dc9ff..23b89b49 100644 --- a/src/DataTables/Column/MarkdownColumn.php +++ b/src/DataTables/Column/MarkdownColumn.php @@ -27,11 +27,8 @@ use Omines\DataTablesBundle\Column\AbstractColumn; class MarkdownColumn extends AbstractColumn { - protected MarkdownParser $markdown; - - public function __construct(MarkdownParser $markdown) + public function __construct(protected MarkdownParser $markdown) { - $this->markdown = $markdown; } /** diff --git a/src/DataTables/Column/PartAttachmentsColumn.php b/src/DataTables/Column/PartAttachmentsColumn.php index 48ab3201..a5715d17 100644 --- a/src/DataTables/Column/PartAttachmentsColumn.php +++ b/src/DataTables/Column/PartAttachmentsColumn.php @@ -33,15 +33,8 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class PartAttachmentsColumn extends AbstractColumn { - protected FAIconGenerator $FAIconGenerator; - protected EntityURLGenerator $urlGenerator; - protected AttachmentManager $attachmentManager; - - public function __construct(FAIconGenerator $FAIconGenerator, EntityURLGenerator $urlGenerator, AttachmentManager $attachmentManager) + public function __construct(protected FAIconGenerator $FAIconGenerator, protected EntityURLGenerator $urlGenerator, protected AttachmentManager $attachmentManager) { - $this->FAIconGenerator = $FAIconGenerator; - $this->urlGenerator = $urlGenerator; - $this->attachmentManager = $attachmentManager; } /** @@ -61,9 +54,7 @@ class PartAttachmentsColumn extends AbstractColumn throw new RuntimeException('$context must be a Part object!'); } $tmp = ''; - $attachments = $context->getAttachments()->filter(function (Attachment $attachment) { - return $attachment->getShowInTable() && $this->attachmentManager->isFileExisting($attachment); - }); + $attachments = $context->getAttachments()->filter(fn(Attachment $attachment) => $attachment->getShowInTable() && $this->attachmentManager->isFileExisting($attachment)); $count = 5; foreach ($attachments as $attachment) { diff --git a/src/DataTables/Column/PrettyBoolColumn.php b/src/DataTables/Column/PrettyBoolColumn.php index a6f74c3c..ffddeac5 100644 --- a/src/DataTables/Column/PrettyBoolColumn.php +++ b/src/DataTables/Column/PrettyBoolColumn.php @@ -25,11 +25,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class PrettyBoolColumn extends AbstractColumn { - protected TranslatorInterface $translator; - - public function __construct(TranslatorInterface $translator) + public function __construct(protected TranslatorInterface $translator) { - $this->translator = $translator; } public function normalize($value): ?bool diff --git a/src/DataTables/Column/RevertLogColumn.php b/src/DataTables/Column/RevertLogColumn.php index 0215bd24..b61c0a87 100644 --- a/src/DataTables/Column/RevertLogColumn.php +++ b/src/DataTables/Column/RevertLogColumn.php @@ -51,13 +51,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class RevertLogColumn extends AbstractColumn { - protected TranslatorInterface $translator; - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(TranslatorInterface $translator, \Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(protected TranslatorInterface $translator, protected \Symfony\Bundle\SecurityBundle\Security $security) { - $this->translator = $translator; - $this->security = $security; } /** @@ -105,8 +100,6 @@ class RevertLogColumn extends AbstractColumn $this->translator->trans('log.undo.revert') ); - $tmp .= ''; - - return $tmp; + return $tmp . ''; } } diff --git a/src/DataTables/Column/SIUnitNumberColumn.php b/src/DataTables/Column/SIUnitNumberColumn.php index fa09e227..61e1999c 100644 --- a/src/DataTables/Column/SIUnitNumberColumn.php +++ b/src/DataTables/Column/SIUnitNumberColumn.php @@ -26,11 +26,8 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class SIUnitNumberColumn extends AbstractColumn { - protected SIFormatter $formatter; - - public function __construct(SIFormatter $formatter) + public function __construct(protected SIFormatter $formatter) { - $this->formatter = $formatter; } public function configureOptions(OptionsResolver $resolver): self diff --git a/src/DataTables/Column/TagsColumn.php b/src/DataTables/Column/TagsColumn.php index 4d0dee0a..9314e499 100644 --- a/src/DataTables/Column/TagsColumn.php +++ b/src/DataTables/Column/TagsColumn.php @@ -27,11 +27,8 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class TagsColumn extends AbstractColumn { - protected UrlGeneratorInterface $urlGenerator; - - public function __construct(UrlGeneratorInterface $urlGenerator) + public function __construct(protected UrlGeneratorInterface $urlGenerator) { - $this->urlGenerator = $urlGenerator; } /** @@ -46,7 +43,7 @@ class TagsColumn extends AbstractColumn return []; } - return explode(',', $value); + return explode(',', (string) $value); } public function render($tags, $context): string @@ -61,7 +58,7 @@ class TagsColumn extends AbstractColumn $html .= sprintf( '%s', $this->urlGenerator->generate('part_list_tags', ['tag' => $tag]), - htmlspecialchars($tag) + htmlspecialchars((string) $tag) ); } diff --git a/src/DataTables/ErrorDataTable.php b/src/DataTables/ErrorDataTable.php index 29888f17..6bb66841 100644 --- a/src/DataTables/ErrorDataTable.php +++ b/src/DataTables/ErrorDataTable.php @@ -54,16 +54,12 @@ class ErrorDataTable implements DataTableTypeInterface $dataTable ->add('dont_matter_we_only_set_color', RowClassColumn::class, [ - 'render' => function ($value, $context) { - return 'table-warning'; - }, + 'render' => fn($value, $context): string => 'table-warning', ]) ->add('error', TextColumn::class, [ 'label' => 'error_table.error', - 'render' => function ($value, $context) { - return ' ' . $value; - }, + 'render' => fn($value, $context): string => ' ' . $value, ]) ; diff --git a/src/DataTables/Filters/AttachmentFilter.php b/src/DataTables/Filters/AttachmentFilter.php index 9325bd60..5fc38296 100644 --- a/src/DataTables/Filters/AttachmentFilter.php +++ b/src/DataTables/Filters/AttachmentFilter.php @@ -60,59 +60,38 @@ class AttachmentFilter implements FilterInterface $this->applyAllChildFilters($queryBuilder); } - /** - * @return NumberConstraint - */ public function getDbId(): NumberConstraint { return $this->dbId; } - /** - * @return TextConstraint - */ public function getName(): TextConstraint { return $this->name; } - /** - * @return DateTimeConstraint - */ public function getLastModified(): DateTimeConstraint { return $this->lastModified; } - /** - * @return DateTimeConstraint - */ public function getAddedDate(): DateTimeConstraint { return $this->addedDate; } - /** - * @return BooleanConstraint - */ public function getShowInTable(): BooleanConstraint { return $this->showInTable; } - /** - * @return EntityConstraint - */ public function getAttachmentType(): EntityConstraint { return $this->attachmentType; } - /** - * @return InstanceOfConstraint - */ public function getTargetType(): InstanceOfConstraint { return $this->targetType; diff --git a/src/DataTables/Filters/CompoundFilterTrait.php b/src/DataTables/Filters/CompoundFilterTrait.php index ba778aac..24a9f46c 100644 --- a/src/DataTables/Filters/CompoundFilterTrait.php +++ b/src/DataTables/Filters/CompoundFilterTrait.php @@ -60,8 +60,6 @@ trait CompoundFilterTrait /** * Applies all children filters that are declared as property of this filter using reflection. - * @param QueryBuilder $queryBuilder - * @return void */ protected function applyAllChildFilters(QueryBuilder $queryBuilder): void { diff --git a/src/DataTables/Filters/Constraints/AbstractConstraint.php b/src/DataTables/Filters/Constraints/AbstractConstraint.php index d57b6add..2ef89c8e 100644 --- a/src/DataTables/Filters/Constraints/AbstractConstraint.php +++ b/src/DataTables/Filters/Constraints/AbstractConstraint.php @@ -26,11 +26,6 @@ abstract class AbstractConstraint implements FilterInterface { use FilterTrait; - /** - * @var string The property where this BooleanConstraint should apply to - */ - protected string $property; - /** * @var string */ @@ -43,9 +38,11 @@ abstract class AbstractConstraint implements FilterInterface */ abstract public function isEnabled(): bool; - public function __construct(string $property, string $identifier = null) + public function __construct(/** + * @var string The property where this BooleanConstraint should apply to + */ + protected string $property, string $identifier = null) { - $this->property = $property; $this->identifier = $identifier ?? $this->generateParameterIdentifier($property); } } \ No newline at end of file diff --git a/src/DataTables/Filters/Constraints/BooleanConstraint.php b/src/DataTables/Filters/Constraints/BooleanConstraint.php index ea3cfd6a..2810c26e 100644 --- a/src/DataTables/Filters/Constraints/BooleanConstraint.php +++ b/src/DataTables/Filters/Constraints/BooleanConstraint.php @@ -24,19 +24,14 @@ use Doctrine\ORM\QueryBuilder; class BooleanConstraint extends AbstractConstraint { - /** @var bool|null The value of our constraint */ - protected ?bool $value; - - - public function __construct(string $property, string $identifier = null, ?bool $default_value = null) + public function __construct(string $property, string $identifier = null, /** @var bool|null The value of our constraint */ + protected ?bool $value = null) { parent::__construct($property, $identifier); - $this->value = $default_value; } /** * Gets the value of this constraint. Null means "don't filter", true means "filter for true", false means "filter for false". - * @return bool|null */ public function getValue(): ?bool { @@ -45,7 +40,6 @@ class BooleanConstraint extends AbstractConstraint /** * Sets the value of this constraint. Null means "don't filter", true means "filter for true", false means "filter for false". - * @param bool|null $value */ public function setValue(?bool $value): void { diff --git a/src/DataTables/Filters/Constraints/ChoiceConstraint.php b/src/DataTables/Filters/Constraints/ChoiceConstraint.php index 52c0739f..9aa6ebbc 100644 --- a/src/DataTables/Filters/Constraints/ChoiceConstraint.php +++ b/src/DataTables/Filters/Constraints/ChoiceConstraint.php @@ -24,7 +24,7 @@ use Doctrine\ORM\QueryBuilder; class ChoiceConstraint extends AbstractConstraint { - public const ALLOWED_OPERATOR_VALUES = ['ANY', 'NONE']; + final public const ALLOWED_OPERATOR_VALUES = ['ANY', 'NONE']; /** * @var string[]|int[] The values to compare to @@ -46,7 +46,6 @@ class ChoiceConstraint extends AbstractConstraint /** * @param string[]|int[] $value - * @return ChoiceConstraint */ public function setValue(array $value): ChoiceConstraint { @@ -54,18 +53,11 @@ class ChoiceConstraint extends AbstractConstraint return $this; } - /** - * @return string - */ public function getOperator(): string { return $this->operator; } - /** - * @param string $operator - * @return ChoiceConstraint - */ public function setOperator(string $operator): ChoiceConstraint { $this->operator = $operator; diff --git a/src/DataTables/Filters/Constraints/EntityConstraint.php b/src/DataTables/Filters/Constraints/EntityConstraint.php index facbbfea..3fc002b3 100644 --- a/src/DataTables/Filters/Constraints/EntityConstraint.php +++ b/src/DataTables/Filters/Constraints/EntityConstraint.php @@ -33,26 +33,6 @@ class EntityConstraint extends AbstractConstraint private const ALLOWED_OPERATOR_VALUES_BASE = ['=', '!=']; private const ALLOWED_OPERATOR_VALUES_STRUCTURAL = ['INCLUDING_CHILDREN', 'EXCLUDING_CHILDREN']; - /** - * @var NodesListBuilder - */ - protected ?NodesListBuilder $nodesListBuilder; - - /** - * @var class-string The class to use for the comparison - */ - protected string $class; - - /** - * @var string|null The operator to use - */ - protected ?string $operator; - - /** - * @var T The value to compare to - */ - protected $value; - /** * @param NodesListBuilder|null $nodesListBuilder * @param class-string $class @@ -61,18 +41,13 @@ class EntityConstraint extends AbstractConstraint * @param null $value * @param string $operator */ - public function __construct(?NodesListBuilder $nodesListBuilder, string $class, string $property, string $identifier = null, $value = null, string $operator = '') + public function __construct(protected ?\App\Services\Trees\NodesListBuilder $nodesListBuilder, protected string $class, string $property, string $identifier = null, protected $value = null, protected ?string $operator = '') { - $this->nodesListBuilder = $nodesListBuilder; - $this->class = $class; - - if ($nodesListBuilder === null && $this->isStructural()) { + if (!$nodesListBuilder instanceof \App\Services\Trees\NodesListBuilder && $this->isStructural()) { throw new \InvalidArgumentException('NodesListBuilder must be provided for structural entities'); } parent::__construct($property, $identifier); - $this->value = $value; - $this->operator = $operator; } public function getClass(): string @@ -80,17 +55,11 @@ class EntityConstraint extends AbstractConstraint return $this->class; } - /** - * @return string|null - */ public function getOperator(): ?string { return $this->operator; } - /** - * @param string|null $operator - */ public function setOperator(?string $operator): self { $this->operator = $operator; @@ -119,7 +88,6 @@ class EntityConstraint extends AbstractConstraint /** * Checks whether the constraints apply to a structural type or not - * @return bool */ public function isStructural(): bool { @@ -136,7 +104,7 @@ class EntityConstraint extends AbstractConstraint $tmp = self::ALLOWED_OPERATOR_VALUES_BASE; if ($this->isStructural()) { - $tmp = array_merge($tmp, self::ALLOWED_OPERATOR_VALUES_STRUCTURAL); + $tmp = [...$tmp, ...self::ALLOWED_OPERATOR_VALUES_STRUCTURAL]; } return $tmp; @@ -160,7 +128,7 @@ class EntityConstraint extends AbstractConstraint } //We need to handle null values differently, as they can not be compared with == or != - if ($this->value === null) { + if (!$this->value instanceof \App\Entity\Base\AbstractDBElement) { if($this->operator === '=' || $this->operator === 'INCLUDING_CHILDREN') { $queryBuilder->andWhere(sprintf("%s IS NULL", $this->property)); return; diff --git a/src/DataTables/Filters/Constraints/FilterTrait.php b/src/DataTables/Filters/Constraints/FilterTrait.php index 733a2217..8244eac3 100644 --- a/src/DataTables/Filters/Constraints/FilterTrait.php +++ b/src/DataTables/Filters/Constraints/FilterTrait.php @@ -35,7 +35,6 @@ trait FilterTrait /** * Checks if the given input is an aggregateFunction like COUNT(part.partsLot) or so - * @return bool */ protected function isAggregateFunctionString(string $input): bool { @@ -44,8 +43,6 @@ trait FilterTrait /** * Generates a parameter identifier that can be used for the given property. It gives random results, to be unique, so you have to cache it. - * @param string $property - * @return string */ protected function generateParameterIdentifier(string $property): string { @@ -57,13 +54,8 @@ trait FilterTrait /** * Adds a simple constraint in the form of (property OPERATOR value) (e.g. "part.name = :name") to the given query builder. - * @param QueryBuilder $queryBuilder - * @param string $property - * @param string $comparison_operator - * @param mixed $value - * @return void */ - protected function addSimpleAndConstraint(QueryBuilder $queryBuilder, string $property, string $parameterIdentifier, string $comparison_operator, $value): void + protected function addSimpleAndConstraint(QueryBuilder $queryBuilder, string $property, string $parameterIdentifier, string $comparison_operator, mixed $value): void { if ($comparison_operator === 'IN' || $comparison_operator === 'NOT IN') { $expression = sprintf("%s %s (:%s)", $property, $comparison_operator, $parameterIdentifier); diff --git a/src/DataTables/Filters/Constraints/InstanceOfConstraint.php b/src/DataTables/Filters/Constraints/InstanceOfConstraint.php index e339ecc1..879e2321 100644 --- a/src/DataTables/Filters/Constraints/InstanceOfConstraint.php +++ b/src/DataTables/Filters/Constraints/InstanceOfConstraint.php @@ -27,7 +27,7 @@ use Doctrine\ORM\QueryBuilder; */ class InstanceOfConstraint extends AbstractConstraint { - public const ALLOWED_OPERATOR_VALUES = ['ANY', 'NONE']; + final public const ALLOWED_OPERATOR_VALUES = ['ANY', 'NONE']; /** * @var string[] The values to compare to (fully qualified class names) @@ -57,16 +57,12 @@ class InstanceOfConstraint extends AbstractConstraint return $this; } - /** - * @return string - */ public function getOperator(): string { return $this->operator; } /** - * @param string $operator * @return $this */ public function setOperator(string $operator): self diff --git a/src/DataTables/Filters/Constraints/NumberConstraint.php b/src/DataTables/Filters/Constraints/NumberConstraint.php index d5066f46..81ab26a6 100644 --- a/src/DataTables/Filters/Constraints/NumberConstraint.php +++ b/src/DataTables/Filters/Constraints/NumberConstraint.php @@ -25,61 +25,28 @@ use RuntimeException; class NumberConstraint extends AbstractConstraint { - public const ALLOWED_OPERATOR_VALUES = ['=', '!=', '<', '>', '<=', '>=', 'BETWEEN']; + final public const ALLOWED_OPERATOR_VALUES = ['=', '!=', '<', '>', '<=', '>=', 'BETWEEN']; - - /** - * The value1 used for comparison (this is the main one used for all mono-value comparisons) - * @var float|null|int|\DateTimeInterface - */ - protected $value1; - - /** - * The second value used when operator is RANGE; this is the upper bound of the range - * @var float|null|int|\DateTimeInterface - */ - protected $value2; - - /** - * @var string|null The operator to use - */ - protected ?string $operator; - - /** - * @return float|int|null|\DateTimeInterface - */ - public function getValue1() + public function getValue1(): float|int|null|\DateTimeInterface { return $this->value1; } - /** - * @param float|int|\DateTimeInterface|null $value1 - */ - public function setValue1($value1): void + public function setValue1(float|int|\DateTimeInterface|null $value1): void { $this->value1 = $value1; } - /** - * @return float|int|null - */ - public function getValue2() + public function getValue2(): float|int|null { return $this->value2; } - /** - * @param float|int|null $value2 - */ - public function setValue2($value2): void + public function setValue2(float|int|null $value2): void { $this->value2 = $value2; } - /** - * @return string - */ public function getOperator(): string { return $this->operator; @@ -94,12 +61,22 @@ class NumberConstraint extends AbstractConstraint } - public function __construct(string $property, string $identifier = null, $value1 = null, string $operator = null, $value2 = null) + /** + * @param float|null|int|\DateTimeInterface $value1 + * @param float|null|int|\DateTimeInterface $value2 + */ + public function __construct(string $property, string $identifier = null, /** + * The value1 used for comparison (this is the main one used for all mono-value comparisons) + */ + protected float|int|\DateTimeInterface|null $value1 = null, /** + * @var string|null The operator to use + */ + protected ?string $operator = null, /** + * The second value used when operator is RANGE; this is the upper bound of the range + */ + protected float|int|\DateTimeInterface|null $value2 = null) { parent::__construct($property, $identifier); - $this->value1 = $value1; - $this->value2 = $value2; - $this->operator = $operator; } public function isEnabled(): bool diff --git a/src/DataTables/Filters/Constraints/Part/ParameterConstraint.php b/src/DataTables/Filters/Constraints/Part/ParameterConstraint.php index ed29653b..2d431faf 100644 --- a/src/DataTables/Filters/Constraints/Part/ParameterConstraint.php +++ b/src/DataTables/Filters/Constraints/Part/ParameterConstraint.php @@ -103,71 +103,44 @@ class ParameterConstraint extends AbstractConstraint $queryBuilder->andWhere('(' . $subqb->getDQL() . ') > 0'); } - /** - * @return string - */ public function getName(): string { return $this->name; } - /** - * @param string $name - * @return ParameterConstraint - */ public function setName(string $name): ParameterConstraint { $this->name = $name; return $this; } - /** - * @return string - */ public function getSymbol(): string { return $this->symbol; } - /** - * @param string $symbol - * @return ParameterConstraint - */ public function setSymbol(string $symbol): ParameterConstraint { $this->symbol = $symbol; return $this; } - /** - * @return string - */ public function getUnit(): string { return $this->unit; } - /** - * @param string $unit - * @return ParameterConstraint - */ public function setUnit(string $unit): ParameterConstraint { $this->unit = $unit; return $this; } - /** - * @return TextConstraint - */ public function getValueText(): TextConstraint { return $this->value_text; } - /** - * @return ParameterValueConstraint - */ public function getValue(): ParameterValueConstraint { return $this->value; diff --git a/src/DataTables/Filters/Constraints/Part/ParameterValueConstraint.php b/src/DataTables/Filters/Constraints/Part/ParameterValueConstraint.php index 5da64098..0b4d5271 100644 --- a/src/DataTables/Filters/Constraints/Part/ParameterValueConstraint.php +++ b/src/DataTables/Filters/Constraints/Part/ParameterValueConstraint.php @@ -25,18 +25,14 @@ use Doctrine\ORM\QueryBuilder; class ParameterValueConstraint extends NumberConstraint { - protected string $alias; - - public const ALLOWED_OPERATOR_VALUES = ['=', '!=', '<', '>', '<=', '>=', 'BETWEEN', + final public const ALLOWED_OPERATOR_VALUES = ['=', '!=', '<', '>', '<=', '>=', 'BETWEEN', //Additional operators 'IN_RANGE', 'NOT_IN_RANGE', 'GREATER_THAN_RANGE', 'GREATER_EQUAL_RANGE', 'LESS_THAN_RANGE', 'LESS_EQUAL_RANGE', 'RANGE_IN_RANGE', 'RANGE_INTERSECT_RANGE']; /** * @param string $alias The alias which is used in the sub query of ParameterConstraint */ - public function __construct(string $alias) { - $this->alias = $alias; - + public function __construct(protected string $alias) { parent::__construct($alias . '.value_typical'); } diff --git a/src/DataTables/Filters/Constraints/Part/TagsConstraint.php b/src/DataTables/Filters/Constraints/Part/TagsConstraint.php index 92c78f6a..dfd15259 100644 --- a/src/DataTables/Filters/Constraints/Part/TagsConstraint.php +++ b/src/DataTables/Filters/Constraints/Part/TagsConstraint.php @@ -26,23 +26,20 @@ use Doctrine\ORM\QueryBuilder; class TagsConstraint extends AbstractConstraint { - public const ALLOWED_OPERATOR_VALUES = ['ANY', 'ALL', 'NONE']; + final public const ALLOWED_OPERATOR_VALUES = ['ANY', 'ALL', 'NONE']; /** - * @var string|null The operator to use + * @param string $value */ - protected ?string $operator; - - /** + public function __construct(string $property, string $identifier = null, /** * @var string The value to compare to */ - protected $value; - - public function __construct(string $property, string $identifier = null, $value = null, string $operator = '') + protected $value = null, /** + * @var string|null The operator to use + */ + protected ?string $operator = '') { parent::__construct($property, $identifier); - $this->value = $value; - $this->operator = $operator; } /** @@ -62,17 +59,11 @@ class TagsConstraint extends AbstractConstraint return $this; } - /** - * @return string - */ public function getValue(): string { return $this->value; } - /** - * @param string $value - */ public function setValue(string $value): self { $this->value = $value; @@ -96,9 +87,6 @@ class TagsConstraint extends AbstractConstraint /** * Builds an expression to query for a single tag - * @param QueryBuilder $queryBuilder - * @param string $tag - * @return Expr\Orx */ protected function getExpressionForTag(QueryBuilder $queryBuilder, string $tag): Expr\Orx { diff --git a/src/DataTables/Filters/Constraints/TextConstraint.php b/src/DataTables/Filters/Constraints/TextConstraint.php index 2b4ecea4..22e02fea 100644 --- a/src/DataTables/Filters/Constraints/TextConstraint.php +++ b/src/DataTables/Filters/Constraints/TextConstraint.php @@ -25,23 +25,20 @@ use Doctrine\ORM\QueryBuilder; class TextConstraint extends AbstractConstraint { - public const ALLOWED_OPERATOR_VALUES = ['=', '!=', 'STARTS', 'ENDS', 'CONTAINS', 'LIKE', 'REGEX']; + final public const ALLOWED_OPERATOR_VALUES = ['=', '!=', 'STARTS', 'ENDS', 'CONTAINS', 'LIKE', 'REGEX']; /** - * @var string|null The operator to use + * @param string $value */ - protected ?string $operator; - - /** + public function __construct(string $property, string $identifier = null, /** * @var string The value to compare to */ - protected $value; - - public function __construct(string $property, string $identifier = null, $value = null, string $operator = '') + protected $value = null, /** + * @var string|null The operator to use + */ + protected ?string $operator = '') { parent::__construct($property, $identifier); - $this->value = $value; - $this->operator = $operator; } /** @@ -61,17 +58,11 @@ class TextConstraint extends AbstractConstraint return $this; } - /** - * @return string - */ public function getValue(): string { return $this->value; } - /** - * @param string $value - */ public function setValue(string $value): self { $this->value = $value; @@ -105,11 +96,11 @@ class TextConstraint extends AbstractConstraint $like_value = null; if ($this->operator === 'LIKE') { $like_value = $this->value; - } else if ($this->operator === 'STARTS') { + } elseif ($this->operator === 'STARTS') { $like_value = $this->value . '%'; - } else if ($this->operator === 'ENDS') { + } elseif ($this->operator === 'ENDS') { $like_value = '%' . $this->value; - } else if ($this->operator === 'CONTAINS') { + } elseif ($this->operator === 'CONTAINS') { $like_value = '%' . $this->value . '%'; } diff --git a/src/DataTables/Filters/LogFilter.php b/src/DataTables/Filters/LogFilter.php index 86a600b0..1751d565 100644 --- a/src/DataTables/Filters/LogFilter.php +++ b/src/DataTables/Filters/LogFilter.php @@ -58,9 +58,6 @@ class LogFilter implements FilterInterface $this->applyAllChildFilters($queryBuilder); } - /** - * @return DateTimeConstraint - */ public function getTimestamp(): DateTimeConstraint { return $this->timestamp; @@ -69,38 +66,26 @@ class LogFilter implements FilterInterface /** * @return IntConstraint|NumberConstraint */ - public function getDbId() + public function getDbId(): \App\DataTables\Filters\Constraints\IntConstraint|\App\DataTables\Filters\Constraints\NumberConstraint { return $this->dbId; } - /** - * @return ChoiceConstraint - */ public function getLevel(): ChoiceConstraint { return $this->level; } - /** - * @return InstanceOfConstraint - */ public function getEventType(): InstanceOfConstraint { return $this->eventType; } - /** - * @return ChoiceConstraint - */ public function getTargetType(): ChoiceConstraint { return $this->targetType; } - /** - * @return IntConstraint - */ public function getTargetId(): IntConstraint { return $this->targetId; diff --git a/src/DataTables/Filters/PartFilter.php b/src/DataTables/Filters/PartFilter.php index 2e9bdeae..92032a28 100644 --- a/src/DataTables/Filters/PartFilter.php +++ b/src/DataTables/Filters/PartFilter.php @@ -145,17 +145,11 @@ class PartFilter implements FilterInterface } - /** - * @return BooleanConstraint - */ public function getFavorite(): BooleanConstraint { return $this->favorite; } - /** - * @return BooleanConstraint - */ public function getNeedsReview(): BooleanConstraint { return $this->needsReview; @@ -176,17 +170,11 @@ class PartFilter implements FilterInterface return $this->description; } - /** - * @return DateTimeConstraint - */ public function getLastModified(): DateTimeConstraint { return $this->lastModified; } - /** - * @return DateTimeConstraint - */ public function getAddedDate(): DateTimeConstraint { return $this->addedDate; @@ -197,49 +185,31 @@ class PartFilter implements FilterInterface return $this->category; } - /** - * @return EntityConstraint - */ public function getFootprint(): EntityConstraint { return $this->footprint; } - /** - * @return EntityConstraint - */ public function getManufacturer(): EntityConstraint { return $this->manufacturer; } - /** - * @return EntityConstraint - */ public function getSupplier(): EntityConstraint { return $this->supplier; } - /** - * @return EntityConstraint - */ public function getStorelocation(): EntityConstraint { return $this->storelocation; } - /** - * @return EntityConstraint - */ public function getMeasurementUnit(): EntityConstraint { return $this->measurementUnit; } - /** - * @return NumberConstraint - */ public function getDbId(): NumberConstraint { return $this->dbId; @@ -250,33 +220,21 @@ class PartFilter implements FilterInterface return $this->ipn; } - /** - * @return TextConstraint - */ public function getComment(): TextConstraint { return $this->comment; } - /** - * @return NumberConstraint - */ public function getMinAmount(): NumberConstraint { return $this->minAmount; } - /** - * @return TextConstraint - */ public function getManufacturerProductUrl(): TextConstraint { return $this->manufacturer_product_url; } - /** - * @return TextConstraint - */ public function getManufacturerProductNumber(): TextConstraint { return $this->manufacturer_product_number; @@ -287,73 +245,46 @@ class PartFilter implements FilterInterface return $this->lotCount; } - /** - * @return EntityConstraint - */ public function getLotOwner(): EntityConstraint { return $this->lotOwner; } - /** - * @return TagsConstraint - */ public function getTags(): TagsConstraint { return $this->tags; } - /** - * @return IntConstraint - */ public function getOrderdetailsCount(): IntConstraint { return $this->orderdetailsCount; } - /** - * @return IntConstraint - */ public function getAttachmentsCount(): IntConstraint { return $this->attachmentsCount; } - /** - * @return BooleanConstraint - */ public function getLotNeedsRefill(): BooleanConstraint { return $this->lotNeedsRefill; } - /** - * @return BooleanConstraint - */ public function getLotUnknownAmount(): BooleanConstraint { return $this->lotUnknownAmount; } - /** - * @return DateTimeConstraint - */ public function getLotExpirationDate(): DateTimeConstraint { return $this->lotExpirationDate; } - /** - * @return EntityConstraint - */ public function getAttachmentType(): EntityConstraint { return $this->attachmentType; } - /** - * @return TextConstraint - */ public function getAttachmentName(): TextConstraint { return $this->attachmentName; @@ -369,9 +300,6 @@ class PartFilter implements FilterInterface return $this->amountSum; } - /** - * @return ArrayCollection - */ public function getParameters(): ArrayCollection { return $this->parameters; @@ -382,25 +310,16 @@ class PartFilter implements FilterInterface return $this->parametersCount; } - /** - * @return TextConstraint - */ public function getLotDescription(): TextConstraint { return $this->lotDescription; } - /** - * @return BooleanConstraint - */ public function getObsolete(): BooleanConstraint { return $this->obsolete; } - /** - * @return LessThanDesiredConstraint - */ public function getLessThanDesired(): LessThanDesiredConstraint { return $this->lessThanDesired; diff --git a/src/DataTables/Filters/PartSearchFilter.php b/src/DataTables/Filters/PartSearchFilter.php index ccbb71fd..7ddaf86e 100644 --- a/src/DataTables/Filters/PartSearchFilter.php +++ b/src/DataTables/Filters/PartSearchFilter.php @@ -26,9 +26,6 @@ use Doctrine\ORM\QueryBuilder; class PartSearchFilter implements FilterInterface { - /** @var string The string to query for */ - protected string $keyword; - /** @var boolean Whether to use regex for searching */ protected bool $regex = false; @@ -68,9 +65,11 @@ class PartSearchFilter implements FilterInterface /** @var bool Use Internal Part number for searching */ protected bool $ipn = true; - public function __construct(string $query) + public function __construct( + /** @var string The string to query for */ + protected string $keyword + ) { - $this->keyword = $query; } protected function getFieldsToSearch(): array @@ -122,12 +121,12 @@ class PartSearchFilter implements FilterInterface $fields_to_search = $this->getFieldsToSearch(); //If we have nothing to search for, do nothing - if (empty($fields_to_search) || empty($this->keyword)) { + if ($fields_to_search === [] || empty($this->keyword)) { return; } //Convert the fields to search to a list of expressions - $expressions = array_map(function (string $field) { + $expressions = array_map(function (string $field): string { if ($this->regex) { return sprintf("REGEXP(%s, :search_query) = 1", $field); } @@ -148,162 +147,99 @@ class PartSearchFilter implements FilterInterface } } - /** - * @return string - */ public function getKeyword(): string { return $this->keyword; } - /** - * @param string $keyword - * @return PartSearchFilter - */ public function setKeyword(string $keyword): PartSearchFilter { $this->keyword = $keyword; return $this; } - /** - * @return bool - */ public function isRegex(): bool { return $this->regex; } - /** - * @param bool $regex - * @return PartSearchFilter - */ public function setRegex(bool $regex): PartSearchFilter { $this->regex = $regex; return $this; } - /** - * @return bool - */ public function isName(): bool { return $this->name; } - /** - * @param bool $name - * @return PartSearchFilter - */ public function setName(bool $name): PartSearchFilter { $this->name = $name; return $this; } - /** - * @return bool - */ public function isCategory(): bool { return $this->category; } - /** - * @param bool $category - * @return PartSearchFilter - */ public function setCategory(bool $category): PartSearchFilter { $this->category = $category; return $this; } - /** - * @return bool - */ public function isDescription(): bool { return $this->description; } - /** - * @param bool $description - * @return PartSearchFilter - */ public function setDescription(bool $description): PartSearchFilter { $this->description = $description; return $this; } - /** - * @return bool - */ public function isTags(): bool { return $this->tags; } - /** - * @param bool $tags - * @return PartSearchFilter - */ public function setTags(bool $tags): PartSearchFilter { $this->tags = $tags; return $this; } - /** - * @return bool - */ public function isStorelocation(): bool { return $this->storelocation; } - /** - * @param bool $storelocation - * @return PartSearchFilter - */ public function setStorelocation(bool $storelocation): PartSearchFilter { $this->storelocation = $storelocation; return $this; } - /** - * @return bool - */ public function isOrdernr(): bool { return $this->ordernr; } - /** - * @param bool $ordernr - * @return PartSearchFilter - */ public function setOrdernr(bool $ordernr): PartSearchFilter { $this->ordernr = $ordernr; return $this; } - /** - * @return bool - */ public function isMpn(): bool { return $this->mpn; } - /** - * @param bool $mpn - * @return PartSearchFilter - */ public function setMpn(bool $mpn): PartSearchFilter { $this->mpn = $mpn; @@ -321,72 +257,44 @@ class PartSearchFilter implements FilterInterface return $this; } - /** - * @return bool - */ public function isSupplier(): bool { return $this->supplier; } - /** - * @param bool $supplier - * @return PartSearchFilter - */ public function setSupplier(bool $supplier): PartSearchFilter { $this->supplier = $supplier; return $this; } - /** - * @return bool - */ public function isManufacturer(): bool { return $this->manufacturer; } - /** - * @param bool $manufacturer - * @return PartSearchFilter - */ public function setManufacturer(bool $manufacturer): PartSearchFilter { $this->manufacturer = $manufacturer; return $this; } - /** - * @return bool - */ public function isFootprint(): bool { return $this->footprint; } - /** - * @param bool $footprint - * @return PartSearchFilter - */ public function setFootprint(bool $footprint): PartSearchFilter { $this->footprint = $footprint; return $this; } - /** - * @return bool - */ public function isComment(): bool { return $this->comment; } - /** - * @param bool $comment - * @return PartSearchFilter - */ public function setComment(bool $comment): PartSearchFilter { $this->comment = $comment; diff --git a/src/DataTables/Helpers/PartDataTableHelper.php b/src/DataTables/Helpers/PartDataTableHelper.php index b13ee813..9e7c9686 100644 --- a/src/DataTables/Helpers/PartDataTableHelper.php +++ b/src/DataTables/Helpers/PartDataTableHelper.php @@ -31,19 +31,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class PartDataTableHelper { - private PartPreviewGenerator $previewGenerator; - private AttachmentURLGenerator $attachmentURLGenerator; - - private TranslatorInterface $translator; - private EntityURLGenerator $entityURLGenerator; - - public function __construct(PartPreviewGenerator $previewGenerator, AttachmentURLGenerator $attachmentURLGenerator, - EntityURLGenerator $entityURLGenerator, TranslatorInterface $translator) + public function __construct(private readonly PartPreviewGenerator $previewGenerator, private readonly AttachmentURLGenerator $attachmentURLGenerator, private readonly EntityURLGenerator $entityURLGenerator, private readonly TranslatorInterface $translator) { - $this->previewGenerator = $previewGenerator; - $this->attachmentURLGenerator = $attachmentURLGenerator; - $this->translator = $translator; - $this->entityURLGenerator = $entityURLGenerator; } public function renderName(Part $context): string @@ -57,7 +46,7 @@ class PartDataTableHelper if ($context->isNeedsReview()) { $icon = sprintf('', $this->translator->trans('part.needs_review.badge')); } - if ($context->getBuiltProject() !== null) { + if ($context->getBuiltProject() instanceof \App\Entity\ProjectSystem\Project) { $icon = sprintf('', $this->translator->trans('part.info.projectBuildPart.hint') . ': ' . $context->getBuiltProject()->getName()); } @@ -74,7 +63,7 @@ class PartDataTableHelper public function renderPicture(Part $context): string { $preview_attachment = $this->previewGenerator->getTablePreviewAttachment($context); - if (null === $preview_attachment) { + if (!$preview_attachment instanceof \App\Entity\Attachments\Attachment) { return ''; } diff --git a/src/DataTables/LogDataTable.php b/src/DataTables/LogDataTable.php index 424297e0..5bf3febc 100644 --- a/src/DataTables/LogDataTable.php +++ b/src/DataTables/LogDataTable.php @@ -61,27 +61,13 @@ use Symfony\Contracts\Translation\TranslatorInterface; class LogDataTable implements DataTableTypeInterface { - protected ElementTypeNameGenerator $elementTypeNameGenerator; - protected TranslatorInterface $translator; - protected UrlGeneratorInterface $urlGenerator; - protected EntityURLGenerator $entityURLGenerator; protected LogEntryRepository $logRepo; - protected \Symfony\Bundle\SecurityBundle\Security $security; - protected UserAvatarHelper $userAvatarHelper; - protected LogLevelHelper $logLevelHelper; - public function __construct(ElementTypeNameGenerator $elementTypeNameGenerator, TranslatorInterface $translator, - UrlGeneratorInterface $urlGenerator, EntityURLGenerator $entityURLGenerator, EntityManagerInterface $entityManager, - \Symfony\Bundle\SecurityBundle\Security $security, UserAvatarHelper $userAvatarHelper, LogLevelHelper $logLevelHelper) + public function __construct(protected ElementTypeNameGenerator $elementTypeNameGenerator, protected TranslatorInterface $translator, + protected UrlGeneratorInterface $urlGenerator, protected EntityURLGenerator $entityURLGenerator, EntityManagerInterface $entityManager, + protected \Symfony\Bundle\SecurityBundle\Security $security, protected UserAvatarHelper $userAvatarHelper, protected LogLevelHelper $logLevelHelper) { - $this->elementTypeNameGenerator = $elementTypeNameGenerator; - $this->translator = $translator; - $this->urlGenerator = $urlGenerator; - $this->entityURLGenerator = $entityURLGenerator; $this->logRepo = $entityManager->getRepository(AbstractLogEntry::class); - $this->security = $security; - $this->userAvatarHelper = $userAvatarHelper; - $this->logLevelHelper = $logLevelHelper; } public function configureOptions(OptionsResolver $optionsResolver): void @@ -115,21 +101,17 @@ class LogDataTable implements DataTableTypeInterface //This special $$rowClass column is used to set the row class depending on the log level. The class gets set by the frontend controller $dataTable->add('dont_matter', RowClassColumn::class, [ - 'render' => function ($value, AbstractLogEntry $context) { - return $this->logLevelHelper->logLevelToTableColorClass($context->getLevelString()); - }, + 'render' => fn($value, AbstractLogEntry $context) => $this->logLevelHelper->logLevelToTableColorClass($context->getLevelString()), ]); $dataTable->add('symbol', TextColumn::class, [ 'label' => '', 'className' => 'no-colvis', - 'render' => function ($value, AbstractLogEntry $context) { - return sprintf( - '', - $this->logLevelHelper->logLevelToIconClass($context->getLevelString()), - $context->getLevelString() - ); - }, + 'render' => fn($value, AbstractLogEntry $context): string => sprintf( + '', + $this->logLevelHelper->logLevelToIconClass($context->getLevelString()), + $context->getLevelString() + ), ]); $dataTable->add('id', TextColumn::class, [ @@ -140,12 +122,10 @@ class LogDataTable implements DataTableTypeInterface $dataTable->add('timestamp', LocaleDateTimeColumn::class, [ 'label' => 'log.timestamp', 'timeFormat' => 'medium', - 'render' => function (string $value, AbstractLogEntry $context) { - return sprintf('%s', - $this->urlGenerator->generate('log_details', ['id' => $context->getId()]), - $value - ); - } + 'render' => fn(string $value, AbstractLogEntry $context): string => sprintf('%s', + $this->urlGenerator->generate('log_details', ['id' => $context->getId()]), + $value + ) ]); $dataTable->add('type', TextColumn::class, [ @@ -169,18 +149,16 @@ class LogDataTable implements DataTableTypeInterface 'label' => 'log.level', 'visible' => 'system_log' === $options['mode'], 'propertyPath' => 'levelString', - 'render' => function (string $value, AbstractLogEntry $context) { - return $this->translator->trans('log.level.'.$value); - }, + 'render' => fn(string $value, AbstractLogEntry $context) => $this->translator->trans('log.level.'.$value), ]); $dataTable->add('user', TextColumn::class, [ 'label' => 'log.user', - 'render' => function ($value, AbstractLogEntry $context) { + 'render' => function ($value, AbstractLogEntry $context): string { $user = $context->getUser(); //If user was deleted, show the info from the username field - if ($user === null) { + if (!$user instanceof \App\Entity\UserSystem\User) { if ($context->isCLIEntry()) { return sprintf('%s [%s]', htmlentities($context->getCLIUsername()), @@ -241,19 +219,17 @@ class LogDataTable implements DataTableTypeInterface ) { try { $target = $this->logRepo->getTargetElement($context); - if (null !== $target) { + if ($target instanceof \App\Entity\Base\AbstractDBElement) { return $this->entityURLGenerator->timeTravelURL($target, $context->getTimestamp()); } - } catch (EntityNotSupportedException $exception) { + } catch (EntityNotSupportedException) { return null; } } return null; }, - 'disabled' => function ($value, AbstractLogEntry $context) { - return !$this->security->isGranted('show_history', $context->getTargetClass()); - }, + 'disabled' => fn($value, AbstractLogEntry $context) => !$this->security->isGranted('show_history', $context->getTargetClass()), ]); $dataTable->add('actionRevert', RevertLogColumn::class, [ @@ -310,7 +286,7 @@ class LogDataTable implements DataTableTypeInterface foreach ($options['filter_elements'] as $element) { /** @var AbstractDBElement $element */ - $target_type = AbstractLogEntry::targetTypeClassToID(get_class($element)); + $target_type = AbstractLogEntry::targetTypeClassToID($element::class); $target_id = $element->getID(); $builder->orWhere("log.target_type = ${target_type} AND log.target_id = ${target_id}"); } diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php index 8436cd89..c1f8296c 100644 --- a/src/DataTables/PartsDataTable.php +++ b/src/DataTables/PartsDataTable.php @@ -54,22 +54,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; final class PartsDataTable implements DataTableTypeInterface { - private TranslatorInterface $translator; - private AmountFormatter $amountFormatter; - private \Symfony\Bundle\SecurityBundle\Security $security; - - private PartDataTableHelper $partDataTableHelper; - - private EntityURLGenerator $urlGenerator; - - public function __construct(EntityURLGenerator $urlGenerator, TranslatorInterface $translator, - AmountFormatter $amountFormatter,PartDataTableHelper $partDataTableHelper, \Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(private readonly EntityURLGenerator $urlGenerator, private readonly TranslatorInterface $translator, private readonly AmountFormatter $amountFormatter, private readonly PartDataTableHelper $partDataTableHelper, private readonly \Symfony\Bundle\SecurityBundle\Security $security) { - $this->urlGenerator = $urlGenerator; - $this->translator = $translator; - $this->amountFormatter = $amountFormatter; - $this->security = $security; - $this->partDataTableHelper = $partDataTableHelper; } public function configureOptions(OptionsResolver $optionsResolver): void @@ -92,7 +78,7 @@ final class PartsDataTable implements DataTableTypeInterface $dataTable //Color the table rows depending on the review and favorite status ->add('dont_matter', RowClassColumn::class, [ - 'render' => function ($value, Part $context) { + 'render' => function ($value, Part $context): string { if ($context->isNeedsReview()) { return 'table-secondary'; } @@ -108,15 +94,11 @@ final class PartsDataTable implements DataTableTypeInterface ->add('picture', TextColumn::class, [ 'label' => '', 'className' => 'no-colvis', - 'render' => function ($value, Part $context) { - return $this->partDataTableHelper->renderPicture($context); - }, + 'render' => fn($value, Part $context) => $this->partDataTableHelper->renderPicture($context), ]) ->add('name', TextColumn::class, [ 'label' => $this->translator->trans('part.table.name'), - 'render' => function ($value, Part $context) { - return $this->partDataTableHelper->renderName($context); - }, + 'render' => fn($value, Part $context) => $this->partDataTableHelper->renderName($context), ]) ->add('id', TextColumn::class, [ 'label' => $this->translator->trans('part.table.id'), @@ -153,11 +135,11 @@ final class PartsDataTable implements DataTableTypeInterface $dataTable->add('storelocation', TextColumn::class, [ 'label' => $this->translator->trans('part.table.storeLocations'), 'orderField' => 'storelocations.name', - 'render' => function ($value, Part $context) { + 'render' => function ($value, Part $context): string { $tmp = []; foreach ($context->getPartLots() as $lot) { //Ignore lots without storelocation - if (null === $lot->getStorageLocation()) { + if (!$lot->getStorageLocation() instanceof \App\Entity\Parts\Storelocation) { continue; } $tmp[] = sprintf( @@ -216,9 +198,7 @@ final class PartsDataTable implements DataTableTypeInterface ->add('minamount', TextColumn::class, [ 'label' => $this->translator->trans('part.table.minamount'), 'visible' => false, - 'render' => function ($value, Part $context) { - return htmlspecialchars($this->amountFormatter->format($value, $context->getPartUnit())); - }, + 'render' => fn($value, Part $context): string => htmlspecialchars($this->amountFormatter->format($value, $context->getPartUnit())), ]); if ($this->security->isGranted('@footprints.read')) { @@ -278,12 +258,8 @@ final class PartsDataTable implements DataTableTypeInterface ->add('edit', IconLinkColumn::class, [ 'label' => $this->translator->trans('part.table.edit'), 'visible' => false, - 'href' => function ($value, Part $context) { - return $this->urlGenerator->editURL($context); - }, - 'disabled' => function ($value, Part $context) { - return !$this->security->isGranted('edit', $context); - }, + 'href' => fn($value, Part $context) => $this->urlGenerator->editURL($context), + 'disabled' => fn($value, Part $context) => !$this->security->isGranted('edit', $context), 'title' => $this->translator->trans('part.table.edit.title'), ]) diff --git a/src/DataTables/ProjectBomEntriesDataTable.php b/src/DataTables/ProjectBomEntriesDataTable.php index eac5ae5a..5c44caf1 100644 --- a/src/DataTables/ProjectBomEntriesDataTable.php +++ b/src/DataTables/ProjectBomEntriesDataTable.php @@ -40,18 +40,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class ProjectBomEntriesDataTable implements DataTableTypeInterface { - protected TranslatorInterface $translator; - protected PartDataTableHelper $partDataTableHelper; - protected EntityURLGenerator $entityURLGenerator; - protected AmountFormatter $amountFormatter; - - public function __construct(TranslatorInterface $translator, PartDataTableHelper $partDataTableHelper, - EntityURLGenerator $entityURLGenerator, AmountFormatter $amountFormatter) + public function __construct(protected TranslatorInterface $translator, protected PartDataTableHelper $partDataTableHelper, protected EntityURLGenerator $entityURLGenerator, protected AmountFormatter $amountFormatter) { - $this->translator = $translator; - $this->partDataTableHelper = $partDataTableHelper; - $this->entityURLGenerator = $entityURLGenerator; - $this->amountFormatter = $amountFormatter; } @@ -63,7 +53,7 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface 'label' => '', 'className' => 'no-colvis', 'render' => function ($value, ProjectBOMEntry $context) { - if($context->getPart() === null) { + if(!$context->getPart() instanceof \App\Entity\Parts\Part) { return ''; } return $this->partDataTableHelper->renderPicture($context->getPart()); @@ -79,9 +69,9 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface 'label' => $this->translator->trans('project.bom.quantity'), 'className' => 'text-center', 'orderField' => 'bom_entry.quantity', - 'render' => function ($value, ProjectBOMEntry $context) { + 'render' => function ($value, ProjectBOMEntry $context): float|string { //If we have a non-part entry, only show the rounded quantity - if ($context->getPart() === null) { + if (!$context->getPart() instanceof \App\Entity\Parts\Part) { return round($context->getQuantity()); } //Otherwise use the unit of the part to format the quantity @@ -93,10 +83,10 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface 'label' => $this->translator->trans('part.table.name'), 'orderField' => 'part.name', 'render' => function ($value, ProjectBOMEntry $context) { - if($context->getPart() === null) { + if(!$context->getPart() instanceof \App\Entity\Parts\Part) { return htmlspecialchars($context->getName()); } - if($context->getPart() !== null) { + if($context->getPart() instanceof \App\Entity\Parts\Part) { $tmp = $this->partDataTableHelper->renderName($context->getPart()); if(!empty($context->getName())) { $tmp .= '
'.htmlspecialchars($context->getName()).''; @@ -110,7 +100,7 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface ->add('description', MarkdownColumn::class, [ 'label' => $this->translator->trans('part.table.description'), 'data' => function (ProjectBOMEntry $context) { - if($context->getPart() !== null) { + if($context->getPart() instanceof \App\Entity\Parts\Part) { return $context->getPart()->getDescription(); } //For non-part BOM entries show the comment field diff --git a/src/Doctrine/Purger/ResetAutoIncrementORMPurger.php b/src/Doctrine/Purger/ResetAutoIncrementORMPurger.php index a3fdaf1e..4d3b9f6c 100644 --- a/src/Doctrine/Purger/ResetAutoIncrementORMPurger.php +++ b/src/Doctrine/Purger/ResetAutoIncrementORMPurger.php @@ -47,11 +47,8 @@ use function preg_match; */ class ResetAutoIncrementORMPurger implements PurgerInterface, ORMPurgerInterface { - public const PURGE_MODE_DELETE = 1; - public const PURGE_MODE_TRUNCATE = 2; - - /** @var EntityManagerInterface|null */ - private ?EntityManagerInterface $em; + final public const PURGE_MODE_DELETE = 1; + final public const PURGE_MODE_TRUNCATE = 2; /** * If the purge should be done through DELETE or TRUNCATE statements @@ -60,31 +57,26 @@ class ResetAutoIncrementORMPurger implements PurgerInterface, ORMPurgerInterface */ private int $purgeMode = self::PURGE_MODE_DELETE; - /** - * Table/view names to be excluded from purge - * - * @var string[] - */ - private array $excluded; - /** * Construct new purger instance. * * @param EntityManagerInterface|null $em EntityManagerInterface instance used for persistence. * @param string[] $excluded array of table/view names to be excluded from purge */ - public function __construct(?EntityManagerInterface $em = null, array $excluded = []) + public function __construct( + private ?\Doctrine\ORM\EntityManagerInterface $em = null, + /** + * Table/view names to be excluded from purge + */ + private readonly array $excluded = [] + ) { - $this->em = $em; - $this->excluded = $excluded; } /** * Set the purge mode * - * @param int $mode * - * @return void */ public function setPurgeMode(int $mode): void { @@ -93,8 +85,6 @@ class ResetAutoIncrementORMPurger implements PurgerInterface, ORMPurgerInterface /** * Get the purge mode - * - * @return int */ public function getPurgeMode(): int { @@ -123,7 +113,7 @@ class ResetAutoIncrementORMPurger implements PurgerInterface, ORMPurgerInterface $classes = []; foreach ($this->em->getMetadataFactory()->getAllMetadata() as $metadata) { - if ($metadata->isMappedSuperclass || (isset($metadata->isEmbeddedClass) && $metadata->isEmbeddedClass)) { + if ($metadata->isMappedSuperclass || ($metadata->isEmbeddedClass !== null && $metadata->isEmbeddedClass)) { continue; } @@ -143,7 +133,7 @@ class ResetAutoIncrementORMPurger implements PurgerInterface, ORMPurgerInterface $class = $commitOrder[$i]; if ( - (isset($class->isEmbeddedClass) && $class->isEmbeddedClass) || + ($class->isEmbeddedClass !== null && $class->isEmbeddedClass) || $class->isMappedSuperclass || ($class->isInheritanceTypeSingleTable() && $class->name !== $class->rootEntityName) ) { @@ -172,13 +162,13 @@ class ResetAutoIncrementORMPurger implements PurgerInterface, ORMPurgerInterface foreach ($orderedTables as $tbl) { // If we have a filter expression, check it and skip if necessary - if (! $emptyFilterExpression && ! preg_match($filterExpr, $tbl)) { + if (! $emptyFilterExpression && ! preg_match($filterExpr, (string) $tbl)) { continue; } // The table name might be quoted, we have to trim it // See https://github.com/Part-DB/Part-DB-server/issues/299 - $tbl = trim($tbl, '"'); + $tbl = trim((string) $tbl, '"'); $tbl = trim($tbl, '`'); // If the table is excluded, skip it as well @@ -276,11 +266,6 @@ class ResetAutoIncrementORMPurger implements PurgerInterface, ORMPurgerInterface return array_reverse($sorter->sort()); } - /** - * @param array $classes - * - * @return array - */ private function getAssociationTables(array $classes, AbstractPlatform $platform): array { $associationTables = []; @@ -310,9 +295,6 @@ class ResetAutoIncrementORMPurger implements PurgerInterface, ORMPurgerInterface return $this->em->getConfiguration()->getQuoteStrategy()->getTableName($class, $platform); } - /** - * @param array $assoc - */ private function getJoinTableName( array $assoc, ClassMetadata $class, diff --git a/src/Doctrine/SQLiteRegexExtension.php b/src/Doctrine/SQLiteRegexExtension.php index 0845ffb2..cc1ff5f8 100644 --- a/src/Doctrine/SQLiteRegexExtension.php +++ b/src/Doctrine/SQLiteRegexExtension.php @@ -45,7 +45,7 @@ class SQLiteRegexExtension implements EventSubscriberInterface if($native_connection instanceof \PDO && method_exists($native_connection, 'sqliteCreateFunction' )) { $native_connection->sqliteCreateFunction('REGEXP', function ($pattern, $value) { try { - return (false !== mb_ereg($pattern, $value)) ? 1 : 0; + return (mb_ereg($pattern, $value)) ? 1 : 0; } catch (\ErrorException $e) { throw InvalidRegexException::fromMBRegexError($e); } diff --git a/src/Doctrine/Types/BigDecimalType.php b/src/Doctrine/Types/BigDecimalType.php index f1522857..4dcabbb3 100644 --- a/src/Doctrine/Types/BigDecimalType.php +++ b/src/Doctrine/Types/BigDecimalType.php @@ -27,7 +27,7 @@ use Doctrine\DBAL\Types\Type; class BigDecimalType extends Type { - public const BIG_DECIMAL = 'big_decimal'; + final public const BIG_DECIMAL = 'big_decimal'; public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string { @@ -53,7 +53,7 @@ class BigDecimalType extends Type */ public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string { - if (null === $value) { + if (!$value instanceof \Brick\Math\BigDecimal) { return null; } diff --git a/src/Doctrine/Types/UTCDateTimeType.php b/src/Doctrine/Types/UTCDateTimeType.php index c9fe215b..462d4ae4 100644 --- a/src/Doctrine/Types/UTCDateTimeType.php +++ b/src/Doctrine/Types/UTCDateTimeType.php @@ -47,7 +47,7 @@ class UTCDateTimeType extends DateTimeType */ public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string { - if (!self::$utc_timezone) { + if (!self::$utc_timezone instanceof \DateTimeZone) { self::$utc_timezone = new DateTimeZone('UTC'); } @@ -60,7 +60,7 @@ class UTCDateTimeType extends DateTimeType public function convertToPHPValue($value, AbstractPlatform $platform): ?DateTime { - if (!self::$utc_timezone) { + if (!self::$utc_timezone instanceof \DateTimeZone) { self::$utc_timezone = new DateTimeZone('UTC'); } diff --git a/src/Entity/Attachments/Attachment.php b/src/Entity/Attachments/Attachment.php index bc3f52b8..5fd1de14 100644 --- a/src/Entity/Attachments/Attachment.php +++ b/src/Entity/Attachments/Attachment.php @@ -34,11 +34,11 @@ use LogicException; /** * Class Attachment. */ -#[ORM\Entity(repositoryClass: 'App\Repository\AttachmentRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\AttachmentRepository::class)] #[ORM\InheritanceType('SINGLE_TABLE')] #[ORM\DiscriminatorColumn(name: 'class_name', type: 'string')] #[ORM\DiscriminatorMap(['PartDB\Part' => 'PartAttachment', 'Part' => 'PartAttachment', 'PartDB\Device' => 'ProjectAttachment', 'Device' => 'ProjectAttachment', 'AttachmentType' => 'AttachmentTypeAttachment', 'Category' => 'CategoryAttachment', 'Footprint' => 'FootprintAttachment', 'Manufacturer' => 'ManufacturerAttachment', 'Currency' => 'CurrencyAttachment', 'Group' => 'GroupAttachment', 'MeasurementUnit' => 'MeasurementUnitAttachment', 'Storelocation' => 'StorelocationAttachment', 'Supplier' => 'SupplierAttachment', 'User' => 'UserAttachment', 'LabelProfile' => 'LabelAttachment'])] -#[ORM\EntityListeners(['App\EntityListeners\AttachmentDeleteListener'])] +#[ORM\EntityListeners([\App\EntityListeners\AttachmentDeleteListener::class])] #[ORM\Table(name: '`attachments`')] #[ORM\Index(name: 'attachments_idx_id_element_id_class_name', columns: ['id', 'element_id', 'class_name'])] #[ORM\Index(name: 'attachments_idx_class_name_id', columns: ['class_name', 'id'])] @@ -51,23 +51,23 @@ abstract class Attachment extends AbstractNamedDBElement * Based on: https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types * It will be used to determine if an attachment is a picture and therefore will be shown to user as preview. */ - public const PICTURE_EXTS = ['apng', 'bmp', 'gif', 'ico', 'cur', 'jpg', 'jpeg', 'jfif', 'pjpeg', 'pjp', 'png', + final public const PICTURE_EXTS = ['apng', 'bmp', 'gif', 'ico', 'cur', 'jpg', 'jpeg', 'jfif', 'pjpeg', 'pjp', 'png', 'svg', 'webp', ]; /** * A list of extensions that will be treated as a 3D Model that can be shown to user directly in Part-DB. */ - public const MODEL_EXTS = ['x3d']; + final public const MODEL_EXTS = ['x3d']; /** * When the path begins with one of the placeholders. */ - public const INTERNAL_PLACEHOLDER = ['%BASE%', '%MEDIA%', '%SECURE%']; + final public const INTERNAL_PLACEHOLDER = ['%BASE%', '%MEDIA%', '%SECURE%']; /** * @var array placeholders for attachments which using built in files */ - public const BUILTIN_PLACEHOLDER = ['%FOOTPRINTS%', '%FOOTPRINTS3D%']; + final public const BUILTIN_PLACEHOLDER = ['%FOOTPRINTS%', '%FOOTPRINTS3D%']; /** * @var string The class of the element that can be passed to this attachment. Must be overridden in subclasses. diff --git a/src/Entity/Attachments/AttachmentType.php b/src/Entity/Attachments/AttachmentType.php index e2614168..bac4ecc4 100644 --- a/src/Entity/Attachments/AttachmentType.php +++ b/src/Entity/Attachments/AttachmentType.php @@ -33,7 +33,7 @@ use Symfony\Component\Validator\Constraints as Assert; /** * Class AttachmentType. */ -#[ORM\Entity(repositoryClass: 'App\Repository\StructuralDBElementRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\StructuralDBElementRepository::class)] #[ORM\Table(name: '`attachment_types`')] #[ORM\Index(name: 'attachment_types_idx_name', columns: ['name'])] #[ORM\Index(name: 'attachment_types_idx_parent_name', columns: ['parent_id', 'name'])] @@ -45,7 +45,7 @@ class AttachmentType extends AbstractStructuralDBElement #[ORM\ManyToOne(targetEntity: 'AttachmentType', inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] - protected ?AbstractStructuralDBElement $parent; + protected ?AbstractStructuralDBElement $parent = null; /** * @var string @@ -57,14 +57,14 @@ class AttachmentType extends AbstractStructuralDBElement * @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\AttachmentTypeAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\AttachmentTypeAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; /** @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\AttachmentTypeParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\AttachmentTypeParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; diff --git a/src/Entity/Attachments/AttachmentTypeAttachment.php b/src/Entity/Attachments/AttachmentTypeAttachment.php index b6dab86f..a8e441c2 100644 --- a/src/Entity/Attachments/AttachmentTypeAttachment.php +++ b/src/Entity/Attachments/AttachmentTypeAttachment.php @@ -32,11 +32,11 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class AttachmentTypeAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = AttachmentType::class; + final public const ALLOWED_ELEMENT_CLASS = AttachmentType::class; /** * @var AttachmentContainingDBElement|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Attachments\AttachmentType', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Attachments\AttachmentType::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/CategoryAttachment.php b/src/Entity/Attachments/CategoryAttachment.php index e7a54fdd..854d628f 100644 --- a/src/Entity/Attachments/CategoryAttachment.php +++ b/src/Entity/Attachments/CategoryAttachment.php @@ -33,11 +33,11 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class CategoryAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = Category::class; + final public const ALLOWED_ELEMENT_CLASS = Category::class; /** * @var AttachmentContainingDBElement|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Category', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Category::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/CurrencyAttachment.php b/src/Entity/Attachments/CurrencyAttachment.php index 6671bdca..d3b06654 100644 --- a/src/Entity/Attachments/CurrencyAttachment.php +++ b/src/Entity/Attachments/CurrencyAttachment.php @@ -33,11 +33,11 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class CurrencyAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = Currency::class; + final public const ALLOWED_ELEMENT_CLASS = Currency::class; /** * @var Currency|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\PriceInformations\Currency', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\PriceInformations\Currency::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/FootprintAttachment.php b/src/Entity/Attachments/FootprintAttachment.php index 3fc3e2af..2cd60bfb 100644 --- a/src/Entity/Attachments/FootprintAttachment.php +++ b/src/Entity/Attachments/FootprintAttachment.php @@ -33,11 +33,11 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class FootprintAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = Footprint::class; + final public const ALLOWED_ELEMENT_CLASS = Footprint::class; /** * @var Footprint|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Footprint', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Footprint::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/GroupAttachment.php b/src/Entity/Attachments/GroupAttachment.php index a2d439bf..e10d17f6 100644 --- a/src/Entity/Attachments/GroupAttachment.php +++ b/src/Entity/Attachments/GroupAttachment.php @@ -33,12 +33,12 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class GroupAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = Group::class; + final public const ALLOWED_ELEMENT_CLASS = Group::class; /** * @var Group|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\UserSystem\Group', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\UserSystem\Group::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/LabelAttachment.php b/src/Entity/Attachments/LabelAttachment.php index 7ff1a191..ddb13283 100644 --- a/src/Entity/Attachments/LabelAttachment.php +++ b/src/Entity/Attachments/LabelAttachment.php @@ -52,12 +52,12 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class LabelAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = LabelProfile::class; + final public const ALLOWED_ELEMENT_CLASS = LabelProfile::class; /** * @var LabelProfile the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\LabelSystem\LabelProfile', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\LabelSystem\LabelProfile::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/ManufacturerAttachment.php b/src/Entity/Attachments/ManufacturerAttachment.php index 1d5709dd..620d5c58 100644 --- a/src/Entity/Attachments/ManufacturerAttachment.php +++ b/src/Entity/Attachments/ManufacturerAttachment.php @@ -33,12 +33,12 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class ManufacturerAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = Manufacturer::class; + final public const ALLOWED_ELEMENT_CLASS = Manufacturer::class; /** * @var Manufacturer|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Manufacturer', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Manufacturer::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/MeasurementUnitAttachment.php b/src/Entity/Attachments/MeasurementUnitAttachment.php index ad4fbbc9..0df01536 100644 --- a/src/Entity/Attachments/MeasurementUnitAttachment.php +++ b/src/Entity/Attachments/MeasurementUnitAttachment.php @@ -34,11 +34,11 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class MeasurementUnitAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = MeasurementUnit::class; + final public const ALLOWED_ELEMENT_CLASS = MeasurementUnit::class; /** * @var Manufacturer|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\MeasurementUnit', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\MeasurementUnit::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/PartAttachment.php b/src/Entity/Attachments/PartAttachment.php index 82db5c72..fbc7479c 100644 --- a/src/Entity/Attachments/PartAttachment.php +++ b/src/Entity/Attachments/PartAttachment.php @@ -33,11 +33,11 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class PartAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = Part::class; + final public const ALLOWED_ELEMENT_CLASS = Part::class; /** * @var Part the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Part', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Part::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/ProjectAttachment.php b/src/Entity/Attachments/ProjectAttachment.php index 052996c3..6dfa9dcd 100644 --- a/src/Entity/Attachments/ProjectAttachment.php +++ b/src/Entity/Attachments/ProjectAttachment.php @@ -33,11 +33,11 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class ProjectAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = Project::class; + final public const ALLOWED_ELEMENT_CLASS = Project::class; /** * @var Project|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\ProjectSystem\Project', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\ProjectSystem\Project::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/StorelocationAttachment.php b/src/Entity/Attachments/StorelocationAttachment.php index b0fc6cb6..f1ac9090 100644 --- a/src/Entity/Attachments/StorelocationAttachment.php +++ b/src/Entity/Attachments/StorelocationAttachment.php @@ -33,12 +33,12 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class StorelocationAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = Storelocation::class; + final public const ALLOWED_ELEMENT_CLASS = Storelocation::class; /** * @var Storelocation|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Storelocation', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Storelocation::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/SupplierAttachment.php b/src/Entity/Attachments/SupplierAttachment.php index 0f611d4c..241f401a 100644 --- a/src/Entity/Attachments/SupplierAttachment.php +++ b/src/Entity/Attachments/SupplierAttachment.php @@ -33,12 +33,12 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class SupplierAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = Supplier::class; + final public const ALLOWED_ELEMENT_CLASS = Supplier::class; /** * @var Supplier|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Supplier', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Supplier::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Attachments/UserAttachment.php b/src/Entity/Attachments/UserAttachment.php index 8fc9b9df..c08b38f8 100644 --- a/src/Entity/Attachments/UserAttachment.php +++ b/src/Entity/Attachments/UserAttachment.php @@ -33,12 +33,12 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity] class UserAttachment extends Attachment { - public const ALLOWED_ELEMENT_CLASS = User::class; + final public const ALLOWED_ELEMENT_CLASS = User::class; /** * @var User|null the element this attachment is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\UserSystem\User', inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: \App\Entity\UserSystem\User::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AttachmentContainingDBElement $element = null; } diff --git a/src/Entity/Base/AbstractDBElement.php b/src/Entity/Base/AbstractDBElement.php index ce55c700..101493fe 100644 --- a/src/Entity/Base/AbstractDBElement.php +++ b/src/Entity/Base/AbstractDBElement.php @@ -35,8 +35,8 @@ use Symfony\Component\Serializer\Annotation\Groups; * Every database table which are managed with this class (or a subclass of it) * must have the table row "id"!! The ID is the unique key to identify the elements. */ -#[DiscriminatorMap(typeProperty: 'type', mapping: ['attachment_type' => 'App\Entity\Attachments\AttachmentType', 'attachment' => 'App\Entity\Attachments\Attachment', 'attachment_type_attachment' => 'App\Entity\Attachments\AttachmentTypeAttachment', 'category_attachment' => 'App\Entity\Attachments\CategoryAttachment', 'currency_attachment' => 'App\Entity\Attachments\CurrencyAttachment', 'footprint_attachment' => 'App\Entity\Attachments\FootprintAttachment', 'group_attachment' => 'App\Entity\Attachments\GroupAttachment', 'label_attachment' => 'App\Entity\Attachments\LabelAttachment', 'manufacturer_attachment' => 'App\Entity\Attachments\ManufacturerAttachment', 'measurement_unit_attachment' => 'App\Entity\Attachments\MeasurementUnitAttachment', 'part_attachment' => 'App\Entity\Attachments\PartAttachment', 'project_attachment' => 'App\Entity\Attachments\ProjectAttachment', 'storelocation_attachment' => 'App\Entity\Attachments\StorelocationAttachment', 'supplier_attachment' => 'App\Entity\Attachments\SupplierAttachment', 'user_attachment' => 'App\Entity\Attachments\UserAttachment', 'category' => 'App\Entity\Parts\Category', 'project' => 'App\Entity\ProjectSystem\Project', 'project_bom_entry' => 'App\Entity\ProjectSystem\ProjectBOMEntry', 'footprint' => 'App\Entity\Parts\Footprint', 'group' => 'App\Entity\UserSystem\Group', 'manufacturer' => 'App\Entity\Parts\Manufacturer', 'orderdetail' => 'App\Entity\PriceInformations\Orderdetail', 'part' => 'App\Entity\Parts\Part', 'pricedetail' => 'App\Entity\PriceInformation\Pricedetail', 'storelocation' => 'App\Entity\Parts\Storelocation', 'part_lot' => 'App\Entity\Parts\PartLot', 'currency' => 'App\Entity\PriceInformations\Currency', 'measurement_unit' => 'App\Entity\Parts\MeasurementUnit', 'parameter' => 'App\Entity\Parts\AbstractParameter', 'supplier' => 'App\Entity\Parts\Supplier', 'user' => 'App\Entity\UserSystem\User'])] -#[ORM\MappedSuperclass(repositoryClass: 'App\Repository\DBElementRepository')] +#[DiscriminatorMap(typeProperty: 'type', mapping: ['attachment_type' => \App\Entity\Attachments\AttachmentType::class, 'attachment' => \App\Entity\Attachments\Attachment::class, 'attachment_type_attachment' => \App\Entity\Attachments\AttachmentTypeAttachment::class, 'category_attachment' => \App\Entity\Attachments\CategoryAttachment::class, 'currency_attachment' => \App\Entity\Attachments\CurrencyAttachment::class, 'footprint_attachment' => \App\Entity\Attachments\FootprintAttachment::class, 'group_attachment' => \App\Entity\Attachments\GroupAttachment::class, 'label_attachment' => \App\Entity\Attachments\LabelAttachment::class, 'manufacturer_attachment' => \App\Entity\Attachments\ManufacturerAttachment::class, 'measurement_unit_attachment' => \App\Entity\Attachments\MeasurementUnitAttachment::class, 'part_attachment' => \App\Entity\Attachments\PartAttachment::class, 'project_attachment' => \App\Entity\Attachments\ProjectAttachment::class, 'storelocation_attachment' => \App\Entity\Attachments\StorelocationAttachment::class, 'supplier_attachment' => \App\Entity\Attachments\SupplierAttachment::class, 'user_attachment' => \App\Entity\Attachments\UserAttachment::class, 'category' => \App\Entity\Parts\Category::class, 'project' => \App\Entity\ProjectSystem\Project::class, 'project_bom_entry' => \App\Entity\ProjectSystem\ProjectBOMEntry::class, 'footprint' => \App\Entity\Parts\Footprint::class, 'group' => \App\Entity\UserSystem\Group::class, 'manufacturer' => \App\Entity\Parts\Manufacturer::class, 'orderdetail' => \App\Entity\PriceInformations\Orderdetail::class, 'part' => \App\Entity\Parts\Part::class, 'pricedetail' => 'App\Entity\PriceInformation\Pricedetail', 'storelocation' => \App\Entity\Parts\Storelocation::class, 'part_lot' => \App\Entity\Parts\PartLot::class, 'currency' => \App\Entity\PriceInformations\Currency::class, 'measurement_unit' => \App\Entity\Parts\MeasurementUnit::class, 'parameter' => 'App\Entity\Parts\AbstractParameter', 'supplier' => \App\Entity\Parts\Supplier::class, 'user' => \App\Entity\UserSystem\User::class])] +#[ORM\MappedSuperclass(repositoryClass: \App\Repository\DBElementRepository::class)] abstract class AbstractDBElement implements JsonSerializable { /** @var int|null The Identification number for this part. This value is unique for the element in this table. diff --git a/src/Entity/Base/AbstractNamedDBElement.php b/src/Entity/Base/AbstractNamedDBElement.php index 4b2b9d9e..f286e6b8 100644 --- a/src/Entity/Base/AbstractNamedDBElement.php +++ b/src/Entity/Base/AbstractNamedDBElement.php @@ -33,7 +33,7 @@ use Symfony\Component\Validator\Constraints as Assert; */ #[ORM\MappedSuperclass(repositoryClass: 'App\Repository\NamedDBElement')] #[ORM\HasLifecycleCallbacks] -abstract class AbstractNamedDBElement extends AbstractDBElement implements NamedElementInterface, TimeStampableInterface +abstract class AbstractNamedDBElement extends AbstractDBElement implements NamedElementInterface, TimeStampableInterface, \Stringable { use TimestampTrait; @@ -51,7 +51,7 @@ abstract class AbstractNamedDBElement extends AbstractDBElement implements Named * ******************************************************************************/ - public function __toString() + public function __toString(): string { return $this->getName(); } diff --git a/src/Entity/Base/AbstractPartsContainingDBElement.php b/src/Entity/Base/AbstractPartsContainingDBElement.php index 7ccb74c3..1885bfb9 100644 --- a/src/Entity/Base/AbstractPartsContainingDBElement.php +++ b/src/Entity/Base/AbstractPartsContainingDBElement.php @@ -29,7 +29,7 @@ use Symfony\Component\Serializer\Annotation\Groups; /** * Class PartsContainingDBElement. */ -#[ORM\MappedSuperclass(repositoryClass: 'App\Repository\AbstractPartsContainingRepository')] +#[ORM\MappedSuperclass(repositoryClass: \App\Repository\AbstractPartsContainingRepository::class)] abstract class AbstractPartsContainingDBElement extends AbstractStructuralDBElement { #[Groups(['full'])] diff --git a/src/Entity/Base/AbstractStructuralDBElement.php b/src/Entity/Base/AbstractStructuralDBElement.php index 484fbaf6..847c5ff3 100644 --- a/src/Entity/Base/AbstractStructuralDBElement.php +++ b/src/Entity/Base/AbstractStructuralDBElement.php @@ -46,8 +46,8 @@ use Symfony\Component\Serializer\Annotation\Groups; * */ #[UniqueEntity(fields: ['name', 'parent'], ignoreNull: false, message: 'structural.entity.unique_name')] -#[ORM\MappedSuperclass(repositoryClass: 'App\Repository\StructuralDBElementRepository')] -#[ORM\EntityListeners(['App\EntityListeners\TreeCacheInvalidationListener'])] +#[ORM\MappedSuperclass(repositoryClass: \App\Repository\StructuralDBElementRepository::class)] +#[ORM\EntityListeners([\App\EntityListeners\TreeCacheInvalidationListener::class])] abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement { use ParametersTrait; @@ -105,7 +105,6 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement parent::__construct(); $this->children = new ArrayCollection(); $this->parameters = new ArrayCollection(); - $this->parent = null; } public function __clone() @@ -141,11 +140,11 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement //Check if both elements compared, are from the same type // (we have to check inheritance, or we get exceptions when using doctrine entities (they have a proxy type): - if (!is_a($another_element, $class_name) && !is_a($this, get_class($another_element))) { + if (!$another_element instanceof $class_name && !is_a($this, $another_element::class)) { throw new InvalidArgumentException('isChildOf() only works for objects of the same type!'); } - if (null === $this->getParent()) { // this is the root node + if (!$this->getParent() instanceof \App\Entity\Base\AbstractStructuralDBElement) { // this is the root node return false; } @@ -170,7 +169,7 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement */ public function isRoot(): bool { - return null === $this->parent; + return !$this->parent instanceof \App\Entity\Base\AbstractStructuralDBElement; } /****************************************************************************** @@ -213,9 +212,9 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement /* * Only check for nodes that have a parent. In the other cases zero is correct. */ - if (0 === $this->level && null !== $this->parent) { + if (0 === $this->level && $this->parent instanceof \App\Entity\Base\AbstractStructuralDBElement) { $element = $this->parent; - while (null !== $element) { + while ($element instanceof \App\Entity\Base\AbstractStructuralDBElement) { /** @var AbstractStructuralDBElement $element */ $element = $element->parent; ++$this->level; @@ -234,14 +233,14 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement */ public function getFullPath(string $delimiter = self::PATH_DELIMITER_ARROW): string { - if (empty($this->full_path_strings)) { + if ($this->full_path_strings === []) { $this->full_path_strings = []; $this->full_path_strings[] = $this->getName(); $element = $this; $overflow = 20; //We only allow 20 levels depth - while (null !== $element->parent && $overflow >= 0) { + while ($element->parent instanceof \App\Entity\Base\AbstractStructuralDBElement && $overflow >= 0) { $element = $element->parent; $this->full_path_strings[] = $element->getName(); //Decrement to prevent mem overflow. @@ -328,7 +327,7 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement $this->parent = $new_parent; //Add this element as child to the new parent - if (null !== $new_parent) { + if ($new_parent instanceof \App\Entity\Base\AbstractStructuralDBElement) { $new_parent->getChildren()->add($this); } diff --git a/src/Entity/Base/MasterAttachmentTrait.php b/src/Entity/Base/MasterAttachmentTrait.php index f1451e1c..e3801fb6 100644 --- a/src/Entity/Base/MasterAttachmentTrait.php +++ b/src/Entity/Base/MasterAttachmentTrait.php @@ -35,7 +35,7 @@ trait MasterAttachmentTrait * @var Attachment|null */ #[Assert\Expression('value == null or value.isPicture()', message: 'part.master_attachment.must_be_picture')] - #[ORM\ManyToOne(targetEntity: 'App\Entity\Attachments\Attachment')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Attachments\Attachment::class)] #[ORM\JoinColumn(name: 'id_preview_attachment', onDelete: 'SET NULL')] protected ?Attachment $master_picture_attachment = null; diff --git a/src/Entity/LabelSystem/LabelOptions.php b/src/Entity/LabelSystem/LabelOptions.php index 19360fb8..b50230e8 100644 --- a/src/Entity/LabelSystem/LabelOptions.php +++ b/src/Entity/LabelSystem/LabelOptions.php @@ -47,11 +47,11 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Embeddable] class LabelOptions { - public const BARCODE_TYPES = ['none', /*'ean8',*/ 'qr', 'code39', 'datamatrix', 'code93', 'code128']; - public const SUPPORTED_ELEMENTS = ['part', 'part_lot', 'storelocation']; - public const PICTURE_TYPES = ['none', 'element_picture', 'main_attachment']; + final public const BARCODE_TYPES = ['none', /*'ean8',*/ 'qr', 'code39', 'datamatrix', 'code93', 'code128']; + final public const SUPPORTED_ELEMENTS = ['part', 'part_lot', 'storelocation']; + final public const PICTURE_TYPES = ['none', 'element_picture', 'main_attachment']; - public const LINES_MODES = ['html', 'twig']; + final public const LINES_MODES = ['html', 'twig']; /** * @var float The page size of the label in mm @@ -111,9 +111,6 @@ class LabelOptions return $this->width; } - /** - * @return LabelOptions - */ public function setWidth(float $width): self { $this->width = $width; @@ -126,9 +123,6 @@ class LabelOptions return $this->height; } - /** - * @return LabelOptions - */ public function setHeight(float $height): self { $this->height = $height; @@ -141,9 +135,6 @@ class LabelOptions return $this->barcode_type; } - /** - * @return LabelOptions - */ public function setBarcodeType(string $barcode_type): self { $this->barcode_type = $barcode_type; @@ -156,9 +147,6 @@ class LabelOptions return $this->picture_type; } - /** - * @return LabelOptions - */ public function setPictureType(string $picture_type): self { $this->picture_type = $picture_type; @@ -171,9 +159,6 @@ class LabelOptions return $this->supported_element; } - /** - * @return LabelOptions - */ public function setSupportedElement(string $supported_element): self { $this->supported_element = $supported_element; @@ -186,9 +171,6 @@ class LabelOptions return $this->lines; } - /** - * @return LabelOptions - */ public function setLines(string $lines): self { $this->lines = $lines; @@ -204,9 +186,6 @@ class LabelOptions return $this->additional_css; } - /** - * @return LabelOptions - */ public function setAdditionalCss(string $additional_css): self { $this->additional_css = $additional_css; @@ -219,9 +198,6 @@ class LabelOptions return $this->lines_mode; } - /** - * @return LabelOptions - */ public function setLinesMode(string $lines_mode): self { $this->lines_mode = $lines_mode; diff --git a/src/Entity/LabelSystem/LabelProfile.php b/src/Entity/LabelSystem/LabelProfile.php index 8548104b..c7fd4a26 100644 --- a/src/Entity/LabelSystem/LabelProfile.php +++ b/src/Entity/LabelSystem/LabelProfile.php @@ -49,15 +49,15 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Validator\Constraints as Assert; #[UniqueEntity(['name', 'options.supported_element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\LabelProfileRepository')] -#[ORM\EntityListeners(['App\EntityListeners\TreeCacheInvalidationListener'])] +#[ORM\Entity(repositoryClass: \App\Repository\LabelProfileRepository::class)] +#[ORM\EntityListeners([\App\EntityListeners\TreeCacheInvalidationListener::class])] #[ORM\Table(name: 'label_profiles')] class LabelProfile extends AttachmentContainingDBElement { /** * @var Collection */ - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\LabelAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\LabelAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; @@ -126,8 +126,6 @@ class LabelProfile extends AttachmentContainingDBElement /** * Sets the show in dropdown menu. - * - * @return LabelProfile */ public function setShowInDropdown(bool $show_in_dropdown): self { diff --git a/src/Entity/LogSystem/AbstractLogEntry.php b/src/Entity/LogSystem/AbstractLogEntry.php index f2ca701c..fe94ec81 100644 --- a/src/Entity/LogSystem/AbstractLogEntry.php +++ b/src/Entity/LogSystem/AbstractLogEntry.php @@ -61,14 +61,14 @@ use App\Repository\LogEntryRepository; #[ORM\Index(columns: ['datetime'], name: 'log_idx_datetime')] abstract class AbstractLogEntry extends AbstractDBElement { - public const LEVEL_EMERGENCY = 0; - public const LEVEL_ALERT = 1; - public const LEVEL_CRITICAL = 2; - public const LEVEL_ERROR = 3; - public const LEVEL_WARNING = 4; - public const LEVEL_NOTICE = 5; - public const LEVEL_INFO = 6; - public const LEVEL_DEBUG = 7; + final public const LEVEL_EMERGENCY = 0; + final public const LEVEL_ALERT = 1; + final public const LEVEL_CRITICAL = 2; + final public const LEVEL_ERROR = 3; + final public const LEVEL_WARNING = 4; + final public const LEVEL_NOTICE = 5; + final public const LEVEL_INFO = 6; + final public const LEVEL_DEBUG = 7; protected const TARGET_TYPE_NONE = 0; protected const TARGET_TYPE_USER = 1; @@ -129,7 +129,7 @@ abstract class AbstractLogEntry extends AbstractDBElement /** @var User|null The user which has caused this log entry */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\UserSystem\User', fetch: 'EAGER')] + #[ORM\ManyToOne(targetEntity: \App\Entity\UserSystem\User::class, fetch: 'EAGER')] #[ORM\JoinColumn(name: 'id_user', onDelete: 'SET NULL')] protected ?User $user = null; @@ -147,7 +147,7 @@ abstract class AbstractLogEntry extends AbstractDBElement /** @var int The priority level of the associated level. 0 is highest, 7 lowest */ #[ORM\Column(type: 'tinyint', name: 'level')] - protected int $level; + protected int $level = self::LEVEL_WARNING; /** @var int The ID of the element targeted by this event */ @@ -173,7 +173,6 @@ abstract class AbstractLogEntry extends AbstractDBElement public function __construct() { $this->timestamp = new DateTime(); - $this->level = self::LEVEL_WARNING; } /** @@ -214,7 +213,6 @@ abstract class AbstractLogEntry extends AbstractDBElement * Marks this log entry as a CLI entry, and set the username of the CLI user. * This removes the association to a user object in database, as CLI users are not really related to logged in * Part-DB users. - * @param string $cli_username * @return $this */ public function setCLIUsername(string $cli_username): self @@ -372,14 +370,14 @@ abstract class AbstractLogEntry extends AbstractDBElement */ public function setTargetElement(?AbstractDBElement $element): self { - if (null === $element) { + if (!$element instanceof \App\Entity\Base\AbstractDBElement) { $this->target_id = 0; $this->target_type = self::TARGET_TYPE_NONE; return $this; } - $this->target_type = static::targetTypeClassToID(get_class($element)); + $this->target_type = static::targetTypeClassToID($element::class); $this->target_id = $element->getID(); return $this; diff --git a/src/Entity/LogSystem/CollectionElementDeleted.php b/src/Entity/LogSystem/CollectionElementDeleted.php index 15f23e7f..8e85dd10 100644 --- a/src/Entity/LogSystem/CollectionElementDeleted.php +++ b/src/Entity/LogSystem/CollectionElementDeleted.php @@ -93,11 +93,9 @@ class CollectionElementDeleted extends AbstractLogEntry implements LogWithEventU public function __construct(AbstractDBElement $changed_element, string $collection_name, AbstractDBElement $deletedElement) { parent::__construct(); - - $this->level = self::LEVEL_INFO; $this->setTargetElement($changed_element); $this->extra['n'] = $collection_name; - $this->extra['c'] = self::targetTypeClassToID(get_class($deletedElement)); + $this->extra['c'] = self::targetTypeClassToID($deletedElement::class); $this->extra['i'] = $deletedElement->getID(); if ($deletedElement instanceof NamedElementInterface) { $this->extra['o'] = $deletedElement->getName(); @@ -141,8 +139,6 @@ class CollectionElementDeleted extends AbstractLogEntry implements LogWithEventU /** * This functions maps an abstract class name derived from the extra c element to an instantiable class name (based on the target element of this log entry). * For example if the target element is a part and the extra c element is "App\Entity\Attachments\Attachment", this function will return "App\Entity\Attachments\PartAttachment". - * @param string $abstract_class - * @return string */ private function resolveAbstractClassToInstantiableClass(string $abstract_class): string { diff --git a/src/Entity/LogSystem/PartStockChangedLogEntry.php b/src/Entity/LogSystem/PartStockChangedLogEntry.php index 5fc755bf..22c7a9ee 100644 --- a/src/Entity/LogSystem/PartStockChangedLogEntry.php +++ b/src/Entity/LogSystem/PartStockChangedLogEntry.php @@ -26,9 +26,9 @@ use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] class PartStockChangedLogEntry extends AbstractLogEntry { - public const TYPE_ADD = "add"; - public const TYPE_WITHDRAW = "withdraw"; - public const TYPE_MOVE = "move"; + final public const TYPE_ADD = "add"; + final public const TYPE_WITHDRAW = "withdraw"; + final public const TYPE_MOVE = "move"; protected string $typeString = 'part_stock_changed'; @@ -68,7 +68,7 @@ class PartStockChangedLogEntry extends AbstractLogEntry $this->extra['c'] = mb_strimwidth($comment, 0, self::COMMENT_MAX_LENGTH, '...'); } - if ($move_to_target) { + if ($move_to_target instanceof \App\Entity\Parts\PartLot) { if ($type !== self::TYPE_MOVE) { throw new \InvalidArgumentException('The move_to_target parameter can only be set if the type is "move"!'); } @@ -130,7 +130,6 @@ class PartStockChangedLogEntry extends AbstractLogEntry /** * Returns the old stock of the lot. - * @return float */ public function getOldStock(): float { @@ -139,7 +138,6 @@ class PartStockChangedLogEntry extends AbstractLogEntry /** * Returns the new stock of the lot. - * @return float */ public function getNewStock(): float { @@ -148,7 +146,6 @@ class PartStockChangedLogEntry extends AbstractLogEntry /** * Returns the new total instock of the part. - * @return float */ public function getNewTotalPartInstock(): float { @@ -157,7 +154,6 @@ class PartStockChangedLogEntry extends AbstractLogEntry /** * Returns the comment associated with the change. - * @return string */ public function getComment(): string { @@ -166,7 +162,6 @@ class PartStockChangedLogEntry extends AbstractLogEntry /** * Gets the difference between the old and the new stock value of the lot as a positive number. - * @return float */ public function getChangeAmount(): float { @@ -175,7 +170,6 @@ class PartStockChangedLogEntry extends AbstractLogEntry /** * Returns the target lot ID (where the instock was moved to) if the type is TYPE_MOVE. - * @return int|null */ public function getMoveToTargetID(): ?int { @@ -184,39 +178,27 @@ class PartStockChangedLogEntry extends AbstractLogEntry /** * Converts the human-readable type (TYPE_* consts) to the version stored in DB - * @param string $type - * @return string */ protected function typeToShortType(string $type): string { - switch ($type) { - case self::TYPE_ADD: - return 'a'; - case self::TYPE_WITHDRAW: - return 'w'; - case self::TYPE_MOVE: - return 'm'; - default: - throw new \InvalidArgumentException('Invalid type: '.$type); - } + return match ($type) { + self::TYPE_ADD => 'a', + self::TYPE_WITHDRAW => 'w', + self::TYPE_MOVE => 'm', + default => throw new \InvalidArgumentException('Invalid type: '.$type), + }; } /** * Converts the short type stored in DB to the human-readable type (TYPE_* consts). - * @param string $short_type - * @return string */ protected function shortTypeToType(string $short_type): string { - switch ($short_type) { - case 'a': - return self::TYPE_ADD; - case 'w': - return self::TYPE_WITHDRAW; - case 'm': - return self::TYPE_MOVE; - default: - throw new \InvalidArgumentException('Invalid short type: '.$short_type); - } + return match ($short_type) { + 'a' => self::TYPE_ADD, + 'w' => self::TYPE_WITHDRAW, + 'm' => self::TYPE_MOVE, + default => throw new \InvalidArgumentException('Invalid short type: '.$short_type), + }; } } \ No newline at end of file diff --git a/src/Entity/LogSystem/SecurityEventLogEntry.php b/src/Entity/LogSystem/SecurityEventLogEntry.php index 2d74f5ea..0dafce92 100644 --- a/src/Entity/LogSystem/SecurityEventLogEntry.php +++ b/src/Entity/LogSystem/SecurityEventLogEntry.php @@ -54,7 +54,7 @@ use Symfony\Component\HttpFoundation\IpUtils; #[ORM\Entity] class SecurityEventLogEntry extends AbstractLogEntry { - public const SECURITY_TYPE_MAPPING = [ + final public const SECURITY_TYPE_MAPPING = [ 0 => SecurityEvents::PASSWORD_CHANGED, 1 => SecurityEvents::PASSWORD_RESET, 2 => SecurityEvents::BACKUP_KEYS_RESET, diff --git a/src/Entity/Parameters/AbstractParameter.php b/src/Entity/Parameters/AbstractParameter.php index be918d00..dd080d5a 100644 --- a/src/Entity/Parameters/AbstractParameter.php +++ b/src/Entity/Parameters/AbstractParameter.php @@ -51,7 +51,7 @@ use Symfony\Component\Validator\Constraints as Assert; use function sprintf; -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] #[ORM\InheritanceType('SINGLE_TABLE')] #[ORM\DiscriminatorColumn(name: 'type', type: 'smallint')] #[ORM\DiscriminatorMap([0 => 'CategoryParameter', 1 => 'CurrencyParameter', 2 => 'ProjectParameter', 3 => 'FootprintParameter', 4 => 'GroupParameter', 5 => 'ManufacturerParameter', 6 => 'MeasurementUnitParameter', 7 => 'PartParameter', 8 => 'StorelocationParameter', 9 => 'SupplierParameter', 10 => 'AttachmentTypeParameter'])] @@ -187,7 +187,7 @@ abstract class AbstractParameter extends AbstractNamedDBElement $str .= ')'; } - if ($this->value_text) { + if ($this->value_text !== '' && $this->value_text !== '0') { $str .= ' ['.$this->value_text.']'; } @@ -317,7 +317,6 @@ abstract class AbstractParameter extends AbstractNamedDBElement /** * Sets the typical value of this property. * - * @param float|null $value_typical * * @return $this */ diff --git a/src/Entity/Parameters/AttachmentTypeParameter.php b/src/Entity/Parameters/AttachmentTypeParameter.php index 28f53669..f06c26aa 100644 --- a/src/Entity/Parameters/AttachmentTypeParameter.php +++ b/src/Entity/Parameters/AttachmentTypeParameter.php @@ -47,14 +47,14 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class AttachmentTypeParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = AttachmentType::class; + final public const ALLOWED_ELEMENT_CLASS = AttachmentType::class; /** * @var AttachmentType the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Attachments\AttachmentType', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Attachments\AttachmentType::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parameters/CategoryParameter.php b/src/Entity/Parameters/CategoryParameter.php index ba71e46f..94004355 100644 --- a/src/Entity/Parameters/CategoryParameter.php +++ b/src/Entity/Parameters/CategoryParameter.php @@ -47,14 +47,14 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class CategoryParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = Category::class; + final public const ALLOWED_ELEMENT_CLASS = Category::class; /** * @var Category the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Category', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Category::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parameters/CurrencyParameter.php b/src/Entity/Parameters/CurrencyParameter.php index fc3d6726..3db70701 100644 --- a/src/Entity/Parameters/CurrencyParameter.php +++ b/src/Entity/Parameters/CurrencyParameter.php @@ -50,15 +50,15 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; * An attachment attached to a category element. */ #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class CurrencyParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = Currency::class; + final public const ALLOWED_ELEMENT_CLASS = Currency::class; /** * @var Currency the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\PriceInformations\Currency', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\PriceInformations\Currency::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parameters/FootprintParameter.php b/src/Entity/Parameters/FootprintParameter.php index 1f8f517b..ca632a8f 100644 --- a/src/Entity/Parameters/FootprintParameter.php +++ b/src/Entity/Parameters/FootprintParameter.php @@ -47,15 +47,15 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class FootprintParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = Footprint::class; + final public const ALLOWED_ELEMENT_CLASS = Footprint::class; /** * @var Footprint the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Footprint', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Footprint::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parameters/GroupParameter.php b/src/Entity/Parameters/GroupParameter.php index 0b181929..eb838e99 100644 --- a/src/Entity/Parameters/GroupParameter.php +++ b/src/Entity/Parameters/GroupParameter.php @@ -47,15 +47,15 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class GroupParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = Group::class; + final public const ALLOWED_ELEMENT_CLASS = Group::class; /** * @var Group the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\UserSystem\Group', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\UserSystem\Group::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parameters/ManufacturerParameter.php b/src/Entity/Parameters/ManufacturerParameter.php index 3fa585cf..d4a59793 100644 --- a/src/Entity/Parameters/ManufacturerParameter.php +++ b/src/Entity/Parameters/ManufacturerParameter.php @@ -47,15 +47,15 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class ManufacturerParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = Manufacturer::class; + final public const ALLOWED_ELEMENT_CLASS = Manufacturer::class; /** * @var Manufacturer the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Manufacturer', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Manufacturer::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parameters/MeasurementUnitParameter.php b/src/Entity/Parameters/MeasurementUnitParameter.php index 67d20f3f..a32910be 100644 --- a/src/Entity/Parameters/MeasurementUnitParameter.php +++ b/src/Entity/Parameters/MeasurementUnitParameter.php @@ -47,15 +47,15 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class MeasurementUnitParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = MeasurementUnit::class; + final public const ALLOWED_ELEMENT_CLASS = MeasurementUnit::class; /** * @var MeasurementUnit the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\MeasurementUnit', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\MeasurementUnit::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parameters/PartParameter.php b/src/Entity/Parameters/PartParameter.php index 97494abc..65aba267 100644 --- a/src/Entity/Parameters/PartParameter.php +++ b/src/Entity/Parameters/PartParameter.php @@ -47,15 +47,15 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class PartParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = Part::class; + final public const ALLOWED_ELEMENT_CLASS = Part::class; /** * @var Part the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Part', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Part::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parameters/ProjectParameter.php b/src/Entity/Parameters/ProjectParameter.php index bda1b59a..11462e38 100644 --- a/src/Entity/Parameters/ProjectParameter.php +++ b/src/Entity/Parameters/ProjectParameter.php @@ -47,15 +47,15 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class ProjectParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = Project::class; + final public const ALLOWED_ELEMENT_CLASS = Project::class; /** * @var Project the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\ProjectSystem\Project', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\ProjectSystem\Project::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parameters/StorelocationParameter.php b/src/Entity/Parameters/StorelocationParameter.php index f119f4a7..f6ed82e2 100644 --- a/src/Entity/Parameters/StorelocationParameter.php +++ b/src/Entity/Parameters/StorelocationParameter.php @@ -47,15 +47,15 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class StorelocationParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = Storelocation::class; + final public const ALLOWED_ELEMENT_CLASS = Storelocation::class; /** * @var Storelocation the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Storelocation', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Storelocation::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parameters/SupplierParameter.php b/src/Entity/Parameters/SupplierParameter.php index e3087c27..6ffcbcfa 100644 --- a/src/Entity/Parameters/SupplierParameter.php +++ b/src/Entity/Parameters/SupplierParameter.php @@ -47,15 +47,15 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[UniqueEntity(fields: ['name', 'group', 'element'])] -#[ORM\Entity(repositoryClass: 'App\Repository\ParameterRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\ParameterRepository::class)] class SupplierParameter extends AbstractParameter { - public const ALLOWED_ELEMENT_CLASS = Supplier::class; + final public const ALLOWED_ELEMENT_CLASS = Supplier::class; /** * @var Supplier the element this para is associated with */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Supplier', inversedBy: 'parameters')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Supplier::class, inversedBy: 'parameters')] #[ORM\JoinColumn(name: 'element_id', nullable: false, onDelete: 'CASCADE')] protected ?AbstractDBElement $element = null; } diff --git a/src/Entity/Parts/Category.php b/src/Entity/Parts/Category.php index 56450f11..ba5c5750 100644 --- a/src/Entity/Parts/Category.php +++ b/src/Entity/Parts/Category.php @@ -34,7 +34,7 @@ use Symfony\Component\Validator\Constraints as Assert; /** * Class AttachmentType. */ -#[ORM\Entity(repositoryClass: 'App\Repository\Parts\CategoryRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\Parts\CategoryRepository::class)] #[ORM\Table(name: '`categories`')] #[ORM\Index(name: 'category_idx_name', columns: ['name'])] #[ORM\Index(name: 'category_idx_parent_name', columns: ['parent_id', 'name'])] @@ -112,7 +112,7 @@ class Category extends AbstractPartsContainingDBElement */ #[Assert\Valid] #[Groups(['full'])] - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\CategoryAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\CategoryAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; @@ -120,7 +120,7 @@ class Category extends AbstractPartsContainingDBElement */ #[Assert\Valid] #[Groups(['full'])] - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\CategoryParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\CategoryParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; @@ -129,9 +129,6 @@ class Category extends AbstractPartsContainingDBElement return $this->partname_hint; } - /** - * @return Category - */ public function setPartnameHint(string $partname_hint): self { $this->partname_hint = $partname_hint; @@ -144,9 +141,6 @@ class Category extends AbstractPartsContainingDBElement return $this->partname_regex; } - /** - * @return Category - */ public function setPartnameRegex(string $partname_regex): self { $this->partname_regex = $partname_regex; @@ -159,9 +153,6 @@ class Category extends AbstractPartsContainingDBElement return $this->disable_footprints; } - /** - * @return Category - */ public function setDisableFootprints(bool $disable_footprints): self { $this->disable_footprints = $disable_footprints; @@ -174,9 +165,6 @@ class Category extends AbstractPartsContainingDBElement return $this->disable_manufacturers; } - /** - * @return Category - */ public function setDisableManufacturers(bool $disable_manufacturers): self { $this->disable_manufacturers = $disable_manufacturers; @@ -189,9 +177,6 @@ class Category extends AbstractPartsContainingDBElement return $this->disable_autodatasheets; } - /** - * @return Category - */ public function setDisableAutodatasheets(bool $disable_autodatasheets): self { $this->disable_autodatasheets = $disable_autodatasheets; @@ -204,9 +189,6 @@ class Category extends AbstractPartsContainingDBElement return $this->disable_properties; } - /** - * @return Category - */ public function setDisableProperties(bool $disable_properties): self { $this->disable_properties = $disable_properties; @@ -219,9 +201,6 @@ class Category extends AbstractPartsContainingDBElement return $this->default_description; } - /** - * @return Category - */ public function setDefaultDescription(string $default_description): self { $this->default_description = $default_description; @@ -234,9 +213,6 @@ class Category extends AbstractPartsContainingDBElement return $this->default_comment; } - /** - * @return Category - */ public function setDefaultComment(string $default_comment): self { $this->default_comment = $default_comment; diff --git a/src/Entity/Parts/Footprint.php b/src/Entity/Parts/Footprint.php index f7c56a79..b228141f 100644 --- a/src/Entity/Parts/Footprint.php +++ b/src/Entity/Parts/Footprint.php @@ -32,7 +32,7 @@ use Symfony\Component\Validator\Constraints as Assert; /** * Class Footprint. */ -#[ORM\Entity(repositoryClass: 'App\Repository\Parts\FootprintRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\Parts\FootprintRepository::class)] #[ORM\Table('`footprints`')] #[ORM\Index(name: 'footprint_idx_name', columns: ['name'])] #[ORM\Index(name: 'footprint_idx_parent_name', columns: ['parent_id', 'name'])] @@ -40,7 +40,7 @@ class Footprint extends AbstractPartsContainingDBElement { #[ORM\ManyToOne(targetEntity: 'Footprint', inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] - protected ?\App\Entity\Base\AbstractStructuralDBElement $parent; + protected ?\App\Entity\Base\AbstractStructuralDBElement $parent = null; /** * @var Collection @@ -53,21 +53,21 @@ class Footprint extends AbstractPartsContainingDBElement * @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\FootprintAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\FootprintAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; /** * @var FootprintAttachment|null */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Attachments\FootprintAttachment')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Attachments\FootprintAttachment::class)] #[ORM\JoinColumn(name: 'id_footprint_3d')] protected ?FootprintAttachment $footprint_3d = null; /** @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\FootprintParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\FootprintParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; @@ -88,13 +88,10 @@ class Footprint extends AbstractPartsContainingDBElement * Setters * *********************************************************************************/ - /** * Sets the 3D Model associated with this footprint. * * @param FootprintAttachment|null $new_attachment The new 3D Model - * - * @return Footprint */ public function setFootprint3d(?FootprintAttachment $new_attachment): self { diff --git a/src/Entity/Parts/Manufacturer.php b/src/Entity/Parts/Manufacturer.php index 1e56bcfb..0ff9d49c 100644 --- a/src/Entity/Parts/Manufacturer.php +++ b/src/Entity/Parts/Manufacturer.php @@ -32,7 +32,7 @@ use Symfony\Component\Validator\Constraints as Assert; /** * Class Manufacturer. */ -#[ORM\Entity(repositoryClass: 'App\Repository\Parts\ManufacturerRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\Parts\ManufacturerRepository::class)] #[ORM\Table('`manufacturers`')] #[ORM\Index(name: 'manufacturer_name', columns: ['name'])] #[ORM\Index(name: 'manufacturer_idx_parent_name', columns: ['parent_id', 'name'])] @@ -40,7 +40,7 @@ class Manufacturer extends AbstractCompany { #[ORM\ManyToOne(targetEntity: 'Manufacturer', inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] - protected ?\App\Entity\Base\AbstractStructuralDBElement $parent; + protected ?\App\Entity\Base\AbstractStructuralDBElement $parent = null; /** * @var Collection @@ -53,14 +53,14 @@ class Manufacturer extends AbstractCompany * @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\ManufacturerAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\ManufacturerAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; /** @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\ManufacturerParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\ManufacturerParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; public function __construct() diff --git a/src/Entity/Parts/MeasurementUnit.php b/src/Entity/Parts/MeasurementUnit.php index b36db648..1faac9e0 100644 --- a/src/Entity/Parts/MeasurementUnit.php +++ b/src/Entity/Parts/MeasurementUnit.php @@ -36,7 +36,7 @@ use Symfony\Component\Validator\Constraints as Assert; * This could be something like N, grams, meters, etc... */ #[UniqueEntity('unit')] -#[ORM\Entity(repositoryClass: 'App\Repository\Parts\MeasurementUnitRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\Parts\MeasurementUnitRepository::class)] #[ORM\Table(name: '`measurement_units`')] #[ORM\Index(name: 'unit_idx_name', columns: ['name'])] #[ORM\Index(name: 'unit_idx_parent_name', columns: ['parent_id', 'name'])] @@ -77,20 +77,20 @@ class MeasurementUnit extends AbstractPartsContainingDBElement #[ORM\ManyToOne(targetEntity: 'MeasurementUnit', inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] - protected ?\App\Entity\Base\AbstractStructuralDBElement $parent; + protected ?\App\Entity\Base\AbstractStructuralDBElement $parent = null; /** * @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\MeasurementUnitAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\MeasurementUnitAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; /** @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\MeasurementUnitParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\MeasurementUnitParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; @@ -102,11 +102,6 @@ class MeasurementUnit extends AbstractPartsContainingDBElement return $this->unit; } - /** - * @param string|null $unit - * - * @return MeasurementUnit - */ public function setUnit(?string $unit): self { $this->unit = $unit; @@ -119,9 +114,6 @@ class MeasurementUnit extends AbstractPartsContainingDBElement return $this->is_integer; } - /** - * @return MeasurementUnit - */ public function setIsInteger(bool $isInteger): self { $this->is_integer = $isInteger; @@ -134,9 +126,6 @@ class MeasurementUnit extends AbstractPartsContainingDBElement return $this->use_si_prefix; } - /** - * @return MeasurementUnit - */ public function setUseSIPrefix(bool $usesSIPrefixes): self { $this->use_si_prefix = $usesSIPrefixes; diff --git a/src/Entity/Parts/Part.php b/src/Entity/Parts/Part.php index df127d94..a77f10e5 100644 --- a/src/Entity/Parts/Part.php +++ b/src/Entity/Parts/Part.php @@ -49,7 +49,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; * Otherwise, this class would be too big, to be maintained. */ #[UniqueEntity(fields: ['ipn'], message: 'part.ipn.must_be_unique')] -#[ORM\Entity(repositoryClass: 'App\Repository\PartRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\PartRepository::class)] #[ORM\Table('`parts`')] #[ORM\Index(name: 'parts_idx_datet_name_last_id_needs', columns: ['datetime_added', 'name', 'last_modified', 'id', 'needs_review'])] #[ORM\Index(name: 'parts_idx_name', columns: ['name'])] @@ -69,7 +69,7 @@ class Part extends AttachmentContainingDBElement */ #[Assert\Valid] #[Groups(['full'])] - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\PartParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\PartParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; @@ -89,7 +89,7 @@ class Part extends AttachmentContainingDBElement */ #[Assert\Valid] #[Groups(['full'])] - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\PartAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\PartAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; @@ -97,7 +97,7 @@ class Part extends AttachmentContainingDBElement * @var Attachment|null */ #[Assert\Expression('value == null or value.isPicture()', message: 'part.master_attachment.must_be_picture')] - #[ORM\ManyToOne(targetEntity: 'App\Entity\Attachments\Attachment')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Attachments\Attachment::class)] #[ORM\JoinColumn(name: 'id_preview_attachment', onDelete: 'SET NULL')] protected ?Attachment $master_picture_attachment = null; @@ -142,15 +142,13 @@ class Part extends AttachmentContainingDBElement public function validate(ExecutionContextInterface $context, $payload) { //Ensure that the part name fullfills the regex of the category - if ($this->category) { + if ($this->category instanceof \App\Entity\Parts\Category) { $regex = $this->category->getPartnameRegex(); - if (!empty($regex)) { - if (!preg_match($regex, $this->name)) { - $context->buildViolation('part.name.must_match_category_regex') - ->atPath('name') - ->setParameter('%regex%', $regex) - ->addViolation(); - } + if (!empty($regex) && !preg_match($regex, $this->name)) { + $context->buildViolation('part.name.must_match_category_regex') + ->atPath('name') + ->setParameter('%regex%', $regex) + ->addViolation(); } } } diff --git a/src/Entity/Parts/PartLot.php b/src/Entity/Parts/PartLot.php index eb47581e..58b30726 100644 --- a/src/Entity/Parts/PartLot.php +++ b/src/Entity/Parts/PartLot.php @@ -115,7 +115,7 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named /** * @var User|null The owner of this part lot */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\UserSystem\User')] + #[ORM\ManyToOne(targetEntity: \App\Entity\UserSystem\User::class)] #[ORM\JoinColumn(name: 'id_owner', onDelete: 'SET NULL')] protected ?User $owner = null; @@ -137,7 +137,7 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named */ public function isExpired(): ?bool { - if (null === $this->expiration_date) { + if (!$this->expiration_date instanceof \DateTimeInterface) { return null; } @@ -155,8 +155,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named /** * Sets the description of the part lot. - * - * @return PartLot */ public function setDescription(string $description): self { @@ -175,8 +173,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named /** * Sets the comment for this part lot. - * - * @return PartLot */ public function setComment(string $comment): self { @@ -196,9 +192,7 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named /** * Sets the expiration date for the part lot. Set to null, if the part lot does not expire. * - * @param \DateTimeInterface|null $expiration_date * - * @return PartLot */ public function setExpirationDate(?\DateTimeInterface $expiration_date): self { @@ -219,8 +213,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named /** * Sets the storage location, where this part lot is stored. - * - * @return PartLot */ public function setStorageLocation(?Storelocation $storage_location): self { @@ -239,8 +231,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named /** * Sets the part that is stored in this part lot. - * - * @return PartLot */ public function setPart(Part $part): self { @@ -259,8 +249,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named /** * Set the unknown instock status of this part lot. - * - * @return PartLot */ public function setInstockUnknown(bool $instock_unknown): self { @@ -302,9 +290,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named return $this->needs_refill; } - /** - * @return PartLot - */ public function setNeedsRefill(bool $needs_refill): self { $this->needs_refill = $needs_refill; @@ -314,7 +299,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named /** * Returns the owner of this part lot. - * @return User|null */ public function getOwner(): ?User { @@ -323,8 +307,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named /** * Sets the owner of this part lot. - * @param User|null $owner - * @return PartLot */ public function setOwner(?User $owner): PartLot { @@ -349,14 +331,12 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named //When the storage location sets the owner must match, the part lot owner must match the storage location owner if ($this->getStorageLocation() && $this->getStorageLocation()->isPartOwnerMustMatch() - && $this->getStorageLocation()->getOwner() && $this->getOwner()) { - if ($this->getOwner() !== $this->getStorageLocation()->getOwner() - && $this->owner->getID() !== $this->getStorageLocation()->getOwner()->getID()) { - $context->buildViolation('validator.part_lot.owner_must_match_storage_location_owner') - ->setParameter('%owner_name%', $this->getStorageLocation()->getOwner()->getFullName(true)) - ->atPath('owner') - ->addViolation(); - } + && $this->getStorageLocation()->getOwner() && $this->getOwner() && ($this->getOwner() !== $this->getStorageLocation()->getOwner() + && $this->owner->getID() !== $this->getStorageLocation()->getOwner()->getID())) { + $context->buildViolation('validator.part_lot.owner_must_match_storage_location_owner') + ->setParameter('%owner_name%', $this->getStorageLocation()->getOwner()->getFullName(true)) + ->atPath('owner') + ->addViolation(); } } } diff --git a/src/Entity/Parts/PartTraits/AdvancedPropertyTrait.php b/src/Entity/Parts/PartTraits/AdvancedPropertyTrait.php index fe3db50b..9079c21d 100644 --- a/src/Entity/Parts/PartTraits/AdvancedPropertyTrait.php +++ b/src/Entity/Parts/PartTraits/AdvancedPropertyTrait.php @@ -142,7 +142,6 @@ trait AdvancedPropertyTrait /** * Sets the internal part number of the part * @param string $ipn The new IPN of the part - * @return Part */ public function setIpn(?string $ipn): Part { diff --git a/src/Entity/Parts/PartTraits/InstockTrait.php b/src/Entity/Parts/PartTraits/InstockTrait.php index 152ade10..9ae170ab 100644 --- a/src/Entity/Parts/PartTraits/InstockTrait.php +++ b/src/Entity/Parts/PartTraits/InstockTrait.php @@ -153,7 +153,6 @@ trait InstockTrait /** * Returns true, if the total instock amount of this part is less than the minimum amount. - * @return bool */ public function isNotEnoughInstock(): bool { @@ -204,7 +203,6 @@ trait InstockTrait /** * Returns the summed amount of all part lots that are expired. If no part lots are expired 0 is returned. - * @return float */ public function getExpiredAmountSum(): float { diff --git a/src/Entity/Parts/PartTraits/OrderTrait.php b/src/Entity/Parts/PartTraits/OrderTrait.php index b4e661a8..18b6698e 100644 --- a/src/Entity/Parts/PartTraits/OrderTrait.php +++ b/src/Entity/Parts/PartTraits/OrderTrait.php @@ -39,7 +39,7 @@ trait OrderTrait */ #[Assert\Valid] #[Groups(['extended', 'full', 'import'])] - #[ORM\OneToMany(targetEntity: 'App\Entity\PriceInformations\Orderdetail', mappedBy: 'part', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\PriceInformations\Orderdetail::class, mappedBy: 'part', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['supplierpartnr' => 'ASC'])] protected \Doctrine\Common\Collections\Collection $orderdetails; @@ -58,7 +58,7 @@ trait OrderTrait /** * @var Orderdetail|null */ - #[ORM\OneToOne(targetEntity: 'App\Entity\PriceInformations\Orderdetail')] + #[ORM\OneToOne(targetEntity: \App\Entity\PriceInformations\Orderdetail::class)] #[ORM\JoinColumn(name: 'order_orderdetails_id')] protected ?Orderdetail $order_orderdetail = null; @@ -105,9 +105,7 @@ trait OrderTrait { //If needed hide the obsolete entries if ($hide_obsolete) { - return $this->orderdetails->filter(function (Orderdetail $orderdetail) { - return ! $orderdetail->getObsolete(); - }); + return $this->orderdetails->filter(fn(Orderdetail $orderdetail) => ! $orderdetail->getObsolete()); } return $this->orderdetails; diff --git a/src/Entity/Parts/PartTraits/ProjectTrait.php b/src/Entity/Parts/PartTraits/ProjectTrait.php index a8a7162c..2a5cf6ed 100644 --- a/src/Entity/Parts/PartTraits/ProjectTrait.php +++ b/src/Entity/Parts/PartTraits/ProjectTrait.php @@ -13,13 +13,13 @@ trait ProjectTrait /** * @var \Doctrine\Common\Collections\Collection<\App\Entity\ProjectSystem\ProjectBOMEntry> $project_bom_entries */ - #[ORM\OneToMany(targetEntity: 'App\Entity\ProjectSystem\ProjectBOMEntry', mappedBy: 'part', cascade: ['remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\ProjectSystem\ProjectBOMEntry::class, mappedBy: 'part', cascade: ['remove'], orphanRemoval: true)] protected \Doctrine\Common\Collections\Collection $project_bom_entries; /** * @var Project|null If a project is set here, then this part is special and represents the builds of a project. */ - #[ORM\OneToOne(targetEntity: 'App\Entity\ProjectSystem\Project', inversedBy: 'build_part')] + #[ORM\OneToOne(targetEntity: \App\Entity\ProjectSystem\Project::class, inversedBy: 'build_part')] #[ORM\JoinColumn] protected ?Project $built_project = null; @@ -43,7 +43,6 @@ trait ProjectTrait /** * Returns the project that this part represents the builds of, or null if it doesn't - * @return Project|null */ public function getBuiltProject(): ?Project { diff --git a/src/Entity/Parts/Storelocation.php b/src/Entity/Parts/Storelocation.php index 2249fb00..71ea2669 100644 --- a/src/Entity/Parts/Storelocation.php +++ b/src/Entity/Parts/Storelocation.php @@ -35,7 +35,7 @@ use Symfony\Component\Validator\Constraints as Assert; /** * Class Store location. */ -#[ORM\Entity(repositoryClass: 'App\Repository\Parts\StorelocationRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\Parts\StorelocationRepository::class)] #[ORM\Table('`storelocations`')] #[ORM\Index(name: 'location_idx_name', columns: ['name'])] #[ORM\Index(name: 'location_idx_parent_name', columns: ['parent_id', 'name'])] @@ -50,7 +50,7 @@ class Storelocation extends AbstractPartsContainingDBElement #[ORM\ManyToOne(targetEntity: 'Storelocation', inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] - protected ?AbstractStructuralDBElement $parent; + protected ?AbstractStructuralDBElement $parent = null; /** * @var MeasurementUnit|null The measurement unit, which parts can be stored in here @@ -62,7 +62,7 @@ class Storelocation extends AbstractPartsContainingDBElement /** @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\StorelocationParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\StorelocationParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; @@ -91,7 +91,7 @@ class Storelocation extends AbstractPartsContainingDBElement * @var User|null The owner of this storage location */ #[Assert\Expression('this.getOwner() == null or this.getOwner().isAnonymousUser() === false', message: 'validator.part_lot.owner_must_not_be_anonymous')] - #[ORM\ManyToOne(targetEntity: 'App\Entity\UserSystem\User')] + #[ORM\ManyToOne(targetEntity: \App\Entity\UserSystem\User::class)] #[ORM\JoinColumn(name: 'id_owner', onDelete: 'SET NULL')] protected ?User $owner = null; @@ -105,7 +105,7 @@ class Storelocation extends AbstractPartsContainingDBElement * @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\StorelocationAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\StorelocationAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] protected Collection $attachments; /******************************************************************************** @@ -135,9 +135,6 @@ class Storelocation extends AbstractPartsContainingDBElement return $this->only_single_part; } - /** - * @return Storelocation - */ public function setOnlySinglePart(bool $only_single_part): self { $this->only_single_part = $only_single_part; @@ -153,9 +150,6 @@ class Storelocation extends AbstractPartsContainingDBElement return $this->limit_to_existing_parts; } - /** - * @return Storelocation - */ public function setLimitToExistingParts(bool $limit_to_existing_parts): self { $this->limit_to_existing_parts = $limit_to_existing_parts; @@ -168,9 +162,6 @@ class Storelocation extends AbstractPartsContainingDBElement return $this->storage_type; } - /** - * @return Storelocation - */ public function setStorageType(?MeasurementUnit $storage_type): self { $this->storage_type = $storage_type; @@ -180,7 +171,6 @@ class Storelocation extends AbstractPartsContainingDBElement /** * Returns the owner of this storage location - * @return User|null */ public function getOwner(): ?User { @@ -189,8 +179,6 @@ class Storelocation extends AbstractPartsContainingDBElement /** * Sets the owner of this storage location - * @param User|null $owner - * @return Storelocation */ public function setOwner(?User $owner): Storelocation { @@ -200,7 +188,6 @@ class Storelocation extends AbstractPartsContainingDBElement /** * If this is set to true, only parts lots, which are owned by the same user as the store location are allowed to be stored here. - * @return bool */ public function isPartOwnerMustMatch(): bool { @@ -209,8 +196,6 @@ class Storelocation extends AbstractPartsContainingDBElement /** * If this is set to true, only parts lots, which are owned by the same user as the store location are allowed to be stored here. - * @param bool $part_owner_must_match - * @return Storelocation */ public function setPartOwnerMustMatch(bool $part_owner_must_match): Storelocation { @@ -226,7 +211,6 @@ class Storelocation extends AbstractPartsContainingDBElement * Setters * *********************************************************************************/ - /** * Change the "is full" attribute of this store location. * @@ -235,8 +219,6 @@ class Storelocation extends AbstractPartsContainingDBElement * * @param bool $new_is_full * true means that the storelocation is full * * false means that the storelocation isn't full - * - * @return Storelocation */ public function setIsFull(bool $new_is_full): self { diff --git a/src/Entity/Parts/Supplier.php b/src/Entity/Parts/Supplier.php index 65b82fec..d0d4bd12 100644 --- a/src/Entity/Parts/Supplier.php +++ b/src/Entity/Parts/Supplier.php @@ -38,7 +38,7 @@ use Symfony\Component\Validator\Constraints as Assert; /** * Class Supplier. */ -#[ORM\Entity(repositoryClass: 'App\Repository\Parts\SupplierRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\Parts\SupplierRepository::class)] #[ORM\Table('`suppliers`')] #[ORM\Index(name: 'supplier_idx_name', columns: ['name'])] #[ORM\Index(name: 'supplier_idx_parent_name', columns: ['parent_id', 'name'])] @@ -53,12 +53,12 @@ class Supplier extends AbstractCompany #[ORM\ManyToOne(targetEntity: 'Supplier', inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] - protected ?AbstractStructuralDBElement $parent; + protected ?AbstractStructuralDBElement $parent = null; /** * @var \Doctrine\Common\Collections\Collection|\App\Entity\PriceInformations\Orderdetail[] */ - #[ORM\OneToMany(targetEntity: 'App\Entity\PriceInformations\Orderdetail', mappedBy: 'supplier')] + #[ORM\OneToMany(targetEntity: \App\Entity\PriceInformations\Orderdetail::class, mappedBy: 'supplier')] protected Collection $orderdetails; /** @@ -66,7 +66,7 @@ class Supplier extends AbstractCompany * Set to null, to use global base currency. * @Selectable() */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\PriceInformations\Currency')] + #[ORM\ManyToOne(targetEntity: \App\Entity\PriceInformations\Currency::class)] #[ORM\JoinColumn(name: 'default_currency_id')] protected ?Currency $default_currency = null; @@ -82,14 +82,14 @@ class Supplier extends AbstractCompany * @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\SupplierAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\SupplierAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; /** @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\SupplierParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\SupplierParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; @@ -103,8 +103,6 @@ class Supplier extends AbstractCompany /** * Sets the default currency. - * - * @return Supplier */ public function setDefaultCurrency(?Currency $default_currency): self { @@ -127,12 +125,10 @@ class Supplier extends AbstractCompany * Sets the shipping costs for an order with this supplier. * * @param BigDecimal|null $shipping_costs a BigDecimal with the shipping costs - * - * @return Supplier */ public function setShippingCosts(?BigDecimal $shipping_costs): self { - if (null === $shipping_costs) { + if (!$shipping_costs instanceof \Brick\Math\BigDecimal) { $this->shipping_costs = null; } diff --git a/src/Entity/PriceInformations/Currency.php b/src/Entity/PriceInformations/Currency.php index f434c1ff..106cb052 100644 --- a/src/Entity/PriceInformations/Currency.php +++ b/src/Entity/PriceInformations/Currency.php @@ -45,7 +45,7 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Index(name: 'currency_idx_parent_name', columns: ['parent_id', 'name'])] class Currency extends AbstractStructuralDBElement { - public const PRICE_SCALE = 5; + final public const PRICE_SCALE = 5; /** * @var BigDecimal|null The exchange rate between this currency and the base currency @@ -69,26 +69,26 @@ class Currency extends AbstractStructuralDBElement #[ORM\ManyToOne(targetEntity: 'Currency', inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] - protected ?AbstractStructuralDBElement $parent; + protected ?AbstractStructuralDBElement $parent = null; /** * @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\CurrencyAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\CurrencyAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; /** @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\CurrencyParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\CurrencyParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; /** @var Collection */ - #[ORM\OneToMany(targetEntity: 'App\Entity\PriceInformations\Pricedetail', mappedBy: 'currency')] + #[ORM\OneToMany(targetEntity: \App\Entity\PriceInformations\Pricedetail::class, mappedBy: 'currency')] protected Collection $pricedetails; public function __construct() @@ -115,11 +115,6 @@ class Currency extends AbstractStructuralDBElement return $this->iso_code; } - /** - * @param string|null $iso_code - * - * @return Currency - */ public function setIsoCode(?string $iso_code): self { $this->iso_code = $iso_code; @@ -134,7 +129,7 @@ class Currency extends AbstractStructuralDBElement { $tmp = $this->getExchangeRate(); - if (null === $tmp || $tmp->isZero()) { + if (!$tmp instanceof \Brick\Math\BigDecimal || $tmp->isZero()) { return null; } @@ -155,12 +150,10 @@ class Currency extends AbstractStructuralDBElement * * @param BigDecimal|null $exchange_rate The new exchange rate of the currency. * Set to null, if the exchange rate is unknown. - * - * @return Currency */ public function setExchangeRate(?BigDecimal $exchange_rate): self { - if (null === $exchange_rate) { + if (!$exchange_rate instanceof \Brick\Math\BigDecimal) { $this->exchange_rate = null; } $tmp = $exchange_rate->toScale(self::PRICE_SCALE, RoundingMode::HALF_UP); diff --git a/src/Entity/PriceInformations/Orderdetail.php b/src/Entity/PriceInformations/Orderdetail.php index 9fce1a5f..9feec023 100644 --- a/src/Entity/PriceInformations/Orderdetail.php +++ b/src/Entity/PriceInformations/Orderdetail.php @@ -81,7 +81,7 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N * @var Part|null */ #[Assert\NotNull] - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Part', inversedBy: 'orderdetails')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Part::class, inversedBy: 'orderdetails')] #[ORM\JoinColumn(name: 'part_id', nullable: false, onDelete: 'CASCADE')] protected ?Part $part = null; @@ -90,7 +90,7 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N */ #[Assert\NotNull(message: 'validator.orderdetail.supplier_must_not_be_null')] #[Groups(['extended', 'full', 'import'])] - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Supplier', inversedBy: 'orderdetails')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Supplier::class, inversedBy: 'orderdetails')] #[ORM\JoinColumn(name: 'id_supplier')] protected ?Supplier $supplier = null; @@ -121,7 +121,7 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N public function updateTimestamps(): void { $this->lastModified = new DateTime('now'); - if (null === $this->addedDate) { + if (!$this->addedDate instanceof \DateTimeInterface) { $this->addedDate = new DateTime('now'); } @@ -194,7 +194,7 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N return $this->supplier_product_url; } - if (null === $this->getSupplier()) { + if (!$this->getSupplier() instanceof \App\Entity\Parts\Supplier) { return ''; } @@ -216,8 +216,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N * Adds a price detail to this orderdetail. * * @param Pricedetail $pricedetail The pricedetail to add - * - * @return Orderdetail */ public function addPricedetail(Pricedetail $pricedetail): self { @@ -229,8 +227,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N /** * Removes a price detail from this orderdetail. - * - * @return Orderdetail */ public function removePricedetail(Pricedetail $pricedetail): self { @@ -273,11 +269,8 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N * Setters * *********************************************************************************/ - /** * Sets a new part with which this orderdetail is associated. - * - * @return Orderdetail */ public function setPart(Part $part): self { @@ -288,8 +281,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N /** * Sets the new supplier associated with this orderdetail. - * - * @return Orderdetail */ public function setSupplier(Supplier $new_supplier): self { @@ -302,9 +293,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N * Set the supplier part-nr. * * @param string $new_supplierpartnr the new supplier-part-nr - * - * @return Orderdetail - * @return Orderdetail */ public function setSupplierpartnr(string $new_supplierpartnr): self { @@ -317,9 +305,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N * Set if the part is obsolete at the supplier of that orderdetails. * * @param bool $new_obsolete true means that this part is obsolete - * - * @return Orderdetail - * @return Orderdetail */ public function setObsolete(bool $new_obsolete): self { @@ -333,8 +318,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N * Set this to "", if the function getSupplierProductURL should return the automatic generated URL. * * @param string $new_url The new URL for the supplier URL - * - * @return Orderdetail */ public function setSupplierProductUrl(string $new_url): self { diff --git a/src/Entity/PriceInformations/Pricedetail.php b/src/Entity/PriceInformations/Pricedetail.php index b9af1e5b..d0f97929 100644 --- a/src/Entity/PriceInformations/Pricedetail.php +++ b/src/Entity/PriceInformations/Pricedetail.php @@ -48,7 +48,7 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface { use TimestampTrait; - public const PRICE_PRECISION = 5; + final public const PRICE_PRECISION = 5; /** * @var BigDecimal The price related to the detail. (Given in the selected currency) @@ -119,7 +119,7 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface public function updateTimestamps(): void { $this->lastModified = new DateTime('now'); - if (null === $this->addedDate) { + if (!$this->addedDate instanceof \DateTimeInterface) { $this->addedDate = new DateTime('now'); } @@ -166,7 +166,7 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface * * @return BigDecimal the price as a bcmath string */ - public function getPricePerUnit($multiplier = 1.0): BigDecimal + public function getPricePerUnit(float|string|\Brick\Math\BigDecimal $multiplier = 1.0): BigDecimal { $tmp = BigDecimal::of($multiplier); $tmp = $tmp->multipliedBy($this->price); @@ -248,8 +248,6 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface /** * Sets the currency associated with the price information. * Set to null, to use the global base currency. - * - * @return Pricedetail */ public function setCurrency(?Currency $currency): self { diff --git a/src/Entity/ProjectSystem/Project.php b/src/Entity/ProjectSystem/Project.php index a539e6cf..a2b920ca 100644 --- a/src/Entity/ProjectSystem/Project.php +++ b/src/Entity/ProjectSystem/Project.php @@ -37,7 +37,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; /** * Class AttachmentType. */ -#[ORM\Entity(repositoryClass: 'App\Repository\Parts\DeviceRepository')] +#[ORM\Entity(repositoryClass: \App\Repository\Parts\DeviceRepository::class)] #[ORM\Table(name: 'projects')] class Project extends AbstractStructuralDBElement { @@ -50,7 +50,7 @@ class Project extends AbstractStructuralDBElement #[ORM\ManyToOne(targetEntity: 'Project', inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] - protected ?AbstractStructuralDBElement $parent; + protected ?AbstractStructuralDBElement $parent = null; #[Assert\Valid] #[Groups(['extended', 'full'])] @@ -72,7 +72,7 @@ class Project extends AbstractStructuralDBElement /** * @var Part|null The (optional) part that represents the builds of this project in the stock */ - #[ORM\OneToOne(targetEntity: 'App\Entity\Parts\Part', mappedBy: 'built_project', cascade: ['persist'], orphanRemoval: true)] + #[ORM\OneToOne(targetEntity: \App\Entity\Parts\Part::class, mappedBy: 'built_project', cascade: ['persist'], orphanRemoval: true)] protected ?Part $build_part = null; #[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)] @@ -85,13 +85,13 @@ class Project extends AbstractStructuralDBElement /** * @var Collection */ - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\ProjectAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\ProjectAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; /** @var Collection */ - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\ProjectParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\ProjectParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; @@ -174,8 +174,6 @@ class Project extends AbstractStructuralDBElement * Set the "order_only_missing_parts" attribute. * * @param bool $new_order_only_missing_parts the new "order_only_missing_parts" attribute - * - * @return Project */ public function setOrderOnlyMissingParts(bool $new_order_only_missing_parts): self { @@ -193,7 +191,6 @@ class Project extends AbstractStructuralDBElement } /** - * @param ProjectBOMEntry $entry * @return $this */ public function addBomEntry(ProjectBOMEntry $entry): self @@ -204,7 +201,6 @@ class Project extends AbstractStructuralDBElement } /** - * @param ProjectBOMEntry $entry * @return $this */ public function removeBomEntry(ProjectBOMEntry $entry): self @@ -213,18 +209,11 @@ class Project extends AbstractStructuralDBElement return $this; } - /** - * @return string - */ public function getDescription(): string { return $this->description; } - /** - * @param string $description - * @return Project - */ public function setDescription(string $description): Project { $this->description = $description; @@ -249,16 +238,14 @@ class Project extends AbstractStructuralDBElement /** * Checks if this project has an associated part representing the builds of this project in the stock. - * @return bool */ public function hasBuildPart(): bool { - return $this->build_part !== null; + return $this->build_part instanceof \App\Entity\Parts\Part; } /** * Gets the part representing the builds of this project in the stock, if it is existing - * @return Part|null */ public function getBuildPart(): ?Part { @@ -267,12 +254,11 @@ class Project extends AbstractStructuralDBElement /** * Sets the part representing the builds of this project in the stock. - * @param Part|null $build_part */ public function setBuildPart(?Part $build_part): void { $this->build_part = $build_part; - if ($build_part) { + if ($build_part instanceof \App\Entity\Parts\Part) { $build_part->setBuiltProject($this); } } @@ -283,7 +269,7 @@ class Project extends AbstractStructuralDBElement //If this project has subprojects, and these have builds part, they must be included in the BOM foreach ($this->getChildren() as $child) { /** @var $child Project */ - if ($child->getBuildPart() === null) { + if (!$child->getBuildPart() instanceof \App\Entity\Parts\Part) { continue; } //We have to search all bom entries for the build part diff --git a/src/Entity/ProjectSystem/ProjectBOMEntry.php b/src/Entity/ProjectSystem/ProjectBOMEntry.php index 04be2862..4d432f75 100644 --- a/src/Entity/ProjectSystem/ProjectBOMEntry.php +++ b/src/Entity/ProjectSystem/ProjectBOMEntry.php @@ -82,7 +82,7 @@ class ProjectBOMEntry extends AbstractDBElement /** * @var Part|null The part associated with this */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\Parts\Part', inversedBy: 'project_bom_entries')] + #[ORM\ManyToOne(targetEntity: \App\Entity\Parts\Part::class, inversedBy: 'project_bom_entries')] #[ORM\JoinColumn(name: 'id_part')] protected ?Part $part = null; @@ -91,52 +91,36 @@ class ProjectBOMEntry extends AbstractDBElement */ #[Assert\AtLeastOneOf([new BigDecimalPositive(), new Assert\IsNull()])] #[ORM\Column(type: 'big_decimal', precision: 11, scale: 5, nullable: true)] - protected ?BigDecimal $price; + protected ?BigDecimal $price = null; /** * @var ?Currency The currency for the price of this non-part BOM entry * @Selectable() */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\PriceInformations\Currency')] + #[ORM\ManyToOne(targetEntity: \App\Entity\PriceInformations\Currency::class)] #[ORM\JoinColumn] protected ?Currency $price_currency = null; public function __construct() { - //$this->price = BigDecimal::zero()->toScale(5); - $this->price = null; } - /** - * @return float - */ public function getQuantity(): float { return $this->quantity; } - /** - * @param float $quantity - * @return ProjectBOMEntry - */ public function setQuantity(float $quantity): ProjectBOMEntry { $this->quantity = $quantity; return $this; } - /** - * @return string - */ public function getMountnames(): string { return $this->mountnames; } - /** - * @param string $mountnames - * @return ProjectBOMEntry - */ public function setMountnames(string $mountnames): ProjectBOMEntry { $this->mountnames = $mountnames; @@ -153,7 +137,6 @@ class ProjectBOMEntry extends AbstractDBElement /** * @param string $name - * @return ProjectBOMEntry */ public function setName(?string $name): ProjectBOMEntry { @@ -161,36 +144,22 @@ class ProjectBOMEntry extends AbstractDBElement return $this; } - /** - * @return string - */ public function getComment(): string { return $this->comment; } - /** - * @param string $comment - * @return ProjectBOMEntry - */ public function setComment(string $comment): ProjectBOMEntry { $this->comment = $comment; return $this; } - /** - * @return Project|null - */ public function getProject(): ?Project { return $this->project; } - /** - * @param Project|null $project - * @return ProjectBOMEntry - */ public function setProject(?Project $project): ProjectBOMEntry { $this->project = $project; @@ -199,18 +168,11 @@ class ProjectBOMEntry extends AbstractDBElement - /** - * @return Part|null - */ public function getPart(): ?Part { return $this->part; } - /** - * @param Part|null $part - * @return ProjectBOMEntry - */ public function setPart(?Part $part): ProjectBOMEntry { $this->part = $part; @@ -220,7 +182,6 @@ class ProjectBOMEntry extends AbstractDBElement /** * Returns the price of this BOM entry, if existing. * Prices are only valid on non-Part BOM entries. - * @return BigDecimal|null */ public function getPrice(): ?BigDecimal { @@ -230,24 +191,17 @@ class ProjectBOMEntry extends AbstractDBElement /** * Sets the price of this BOM entry. * Prices are only valid on non-Part BOM entries. - * @param BigDecimal|null $price */ public function setPrice(?BigDecimal $price): void { $this->price = $price; } - /** - * @return Currency|null - */ public function getPriceCurrency(): ?Currency { return $this->price_currency; } - /** - * @param Currency|null $price_currency - */ public function setPriceCurrency(?Currency $price_currency): void { $this->price_currency = $price_currency; @@ -259,20 +213,18 @@ class ProjectBOMEntry extends AbstractDBElement */ public function isPartBomEntry(): bool { - return $this->part !== null; + return $this->part instanceof \App\Entity\Parts\Part; } #[Assert\Callback] public function validate(ExecutionContextInterface $context, $payload): void { //Round quantity to whole numbers, if the part is not a decimal part - if ($this->part) { - if (!$this->part->getPartUnit() || $this->part->getPartUnit()->isInteger()) { - $this->quantity = round($this->quantity); - } + if ($this->part instanceof \App\Entity\Parts\Part && (!$this->part->getPartUnit() || $this->part->getPartUnit()->isInteger())) { + $this->quantity = round($this->quantity); } //Non-Part BOM entries are rounded - if ($this->part === null) { + if (!$this->part instanceof \App\Entity\Parts\Part) { $this->quantity = round($this->quantity); } @@ -296,14 +248,14 @@ class ProjectBOMEntry extends AbstractDBElement } //Prices are only allowed on non-part BOM entries - if ($this->part !== null && $this->price !== null) { + if ($this->part instanceof \App\Entity\Parts\Part && $this->price instanceof \Brick\Math\BigDecimal) { $context->buildViolation('project.bom_entry.price_not_allowed_on_parts') ->atPath('price') ->addViolation(); } //Check that the part is not the build representation part of this device or one of its parents - if ($this->part && $this->part->getBuiltProject() !== null) { + if ($this->part && $this->part->getBuiltProject() instanceof \App\Entity\ProjectSystem\Project) { //Get the associated project $associated_project = $this->part->getBuiltProject(); //Check that it is not the same as the current project neither one of its parents diff --git a/src/Entity/UserSystem/Group.php b/src/Entity/UserSystem/Group.php index 663e9fed..6207e25c 100644 --- a/src/Entity/UserSystem/Group.php +++ b/src/Entity/UserSystem/Group.php @@ -51,7 +51,7 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa #[ORM\ManyToOne(targetEntity: 'Group', inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] - protected ?AbstractStructuralDBElement $parent; + protected ?AbstractStructuralDBElement $parent = null; /** * @var Collection @@ -69,7 +69,7 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa * @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\GroupAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\GroupAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; @@ -84,7 +84,7 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa /** @var Collection */ #[Assert\Valid] - #[ORM\OneToMany(targetEntity: 'App\Entity\Parameters\GroupParameter', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Parameters\GroupParameter::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['group' => 'ASC', 'name' => 'ASC'])] protected Collection $parameters; @@ -122,7 +122,7 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa public function getPermissions(): PermissionData { - if ($this->permissions === null) { + if (!$this->permissions instanceof \App\Entity\UserSystem\PermissionData) { $this->permissions = new PermissionData(); } diff --git a/src/Entity/UserSystem/PermissionData.php b/src/Entity/UserSystem/PermissionData.php index 9d6c4cf2..65101ee9 100644 --- a/src/Entity/UserSystem/PermissionData.php +++ b/src/Entity/UserSystem/PermissionData.php @@ -42,6 +42,10 @@ final class PermissionData implements \JsonSerializable public const CURRENT_SCHEMA_VERSION = 2; /** + * Creates a new Permission Data Instance using the given data. + * By default, an empty array is used, meaning + */ + public function __construct(/** * @var array|null This array contains the permission values for each permission * This array contains the permission values for each permission, in the form of: * permission => [ @@ -49,19 +53,8 @@ final class PermissionData implements \JsonSerializable * ] */ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON, name: 'data')] - protected ?array $data = [ - //$ prefixed entries are used for metadata - '$ver' => self::CURRENT_SCHEMA_VERSION, //The schema version of the permission data - ]; - - /** - * Creates a new Permission Data Instance using the given data. - * By default, an empty array is used, meaning - */ - public function __construct(array $data = []) + protected array $data = []) { - $this->data = $data; - //If the passed data did not contain a schema version, we set it to the current version if (!isset($this->data['$ver'])) { $this->data['$ver'] = self::CURRENT_SCHEMA_VERSION; @@ -70,8 +63,6 @@ final class PermissionData implements \JsonSerializable /** * Checks if any of the operations of the given permission is defined (meaning it is either ALLOW or DENY) - * @param string $permission - * @return bool */ public function isAnyOperationOfPermissionSet(string $permission): bool { @@ -80,7 +71,6 @@ final class PermissionData implements \JsonSerializable /** * Returns an associative array containing all defined (non-INHERIT) operations of the given permission. - * @param string $permission * @return array An array in the form ["operation" => value], returns an empty array if no operations are defined */ public function getAllDefinedOperationsOfPermission(string $permission): array @@ -95,8 +85,6 @@ final class PermissionData implements \JsonSerializable /** * Sets all operations of the given permission via the given array. * The data is an array in the form [$operation => $value], all existing values will be overwritten/deleted. - * @param string $permission - * @param array $data * @return $this */ public function setAllOperationsOfPermission(string $permission, array $data): self @@ -108,7 +96,6 @@ final class PermissionData implements \JsonSerializable /** * Removes a whole permission from the data including all operations (effectivly setting them to INHERIT) - * @param string $permission * @return $this */ public function removePermission(string $permission): self @@ -120,8 +107,6 @@ final class PermissionData implements \JsonSerializable /** * Check if a permission value is set for the given permission and operation (meaning there value is not inherit). - * @param string $permission - * @param string $operation * @return bool True if the permission value is set, false otherwise */ public function isPermissionSet(string $permission, string $operation): bool @@ -136,8 +121,6 @@ final class PermissionData implements \JsonSerializable /** * Returns the permission value for the given permission and operation. - * @param string $permission - * @param string $operation * @return bool|null True means allow, false means disallow, null means inherit */ public function getPermissionValue(string $permission, string $operation): ?bool @@ -152,9 +135,6 @@ final class PermissionData implements \JsonSerializable /** * Sets the permission value for the given permission and operation. - * @param string $permission - * @param string $operation - * @param bool|null $value * @return $this */ public function setPermissionValue(string $permission, string $operation, ?bool $value): self @@ -185,8 +165,6 @@ final class PermissionData implements \JsonSerializable /** * Creates a new Permission Data Instance using the given JSON encoded data - * @param string $json - * @return static * @throws \JsonException */ public static function fromJSON(string $json): self @@ -202,7 +180,6 @@ final class PermissionData implements \JsonSerializable /** * Returns an JSON encodable representation of this object. - * @return array */ public function jsonSerialize(): array { @@ -215,9 +192,7 @@ final class PermissionData implements \JsonSerializable continue; } - $ret[$permission] = array_filter($operations, static function ($value) { - return $value !== null; - }); + $ret[$permission] = array_filter($operations, static fn($value) => $value !== null); //If the permission has no operations, unset it if (empty($ret[$permission])) { @@ -239,7 +214,6 @@ final class PermissionData implements \JsonSerializable /** * Sets the schema version of this permission data - * @param int $new_version * @return $this */ public function setSchemaVersion(int $new_version): self diff --git a/src/Entity/UserSystem/U2FKey.php b/src/Entity/UserSystem/U2FKey.php index 8bc86705..fefbbe20 100644 --- a/src/Entity/UserSystem/U2FKey.php +++ b/src/Entity/UserSystem/U2FKey.php @@ -73,7 +73,7 @@ class U2FKey implements LegacyU2FKeyInterface #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING)] protected string $name; - #[ORM\ManyToOne(targetEntity: 'App\Entity\UserSystem\User', inversedBy: 'u2fKeys')] + #[ORM\ManyToOne(targetEntity: \App\Entity\UserSystem\User::class, inversedBy: 'u2fKeys')] protected ?User $user = null; public function getKeyHandle(): string diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php index a2fa7b11..b7badde3 100644 --- a/src/Entity/UserSystem/User.php +++ b/src/Entity/UserSystem/User.php @@ -56,8 +56,8 @@ use Jbtronics\TFAWebauthn\Model\TwoFactorInterface as WebauthnTwoFactorInterface * Also, this entity is able to save some information about the user, like the names, email-address and other info. */ #[UniqueEntity('name', message: 'validator.user.username_already_used')] -#[ORM\Entity(repositoryClass: 'App\Repository\UserRepository')] -#[ORM\EntityListeners(['App\EntityListeners\TreeCacheInvalidationListener'])] +#[ORM\Entity(repositoryClass: \App\Repository\UserRepository::class)] +#[ORM\EntityListeners([\App\EntityListeners\TreeCacheInvalidationListener::class])] #[ORM\Table('`users`')] #[ORM\Index(name: 'user_idx_username', columns: ['name'])] class User extends AttachmentContainingDBElement implements UserInterface, HasPermissionsInterface, TwoFactorInterface, @@ -68,7 +68,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * The User id of the anonymous user. */ - public const ID_ANONYMOUS = 1; + final public const ID_ANONYMOUS = 1; /** * @var bool Determines if the user is disabled (user can not log in) @@ -214,7 +214,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * @var Collection */ - #[ORM\OneToMany(targetEntity: 'App\Entity\Attachments\UserAttachment', mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\Attachments\UserAttachment::class, mappedBy: 'element', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $attachments; @@ -226,13 +226,13 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** @var Collection */ - #[ORM\OneToMany(targetEntity: 'App\Entity\UserSystem\U2FKey', mappedBy: 'user', cascade: ['REMOVE'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\UserSystem\U2FKey::class, mappedBy: 'user', cascade: ['REMOVE'], orphanRemoval: true)] protected Collection $u2fKeys; /** * @var Collection */ - #[ORM\OneToMany(targetEntity: 'App\Entity\UserSystem\WebauthnKey', mappedBy: 'user', cascade: ['REMOVE'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: \App\Entity\UserSystem\WebauthnKey::class, mappedBy: 'user', cascade: ['REMOVE'], orphanRemoval: true)] protected Collection $webauthn_keys; /** @@ -243,9 +243,9 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe * @Selectable() */ #[Groups(['extended', 'full', 'import'])] - #[ORM\ManyToOne(targetEntity: 'App\Entity\PriceInformations\Currency')] + #[ORM\ManyToOne(targetEntity: \App\Entity\PriceInformations\Currency::class)] #[ORM\JoinColumn(name: 'currency_id')] - protected ?Currency $currency; + protected ?Currency $currency = null; /** * @var PermissionData|null @@ -259,7 +259,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe * @var \DateTimeInterface|null the time until the password reset token is valid */ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_MUTABLE, nullable: true)] - protected ?\DateTimeInterface $pw_reset_expires; + protected ?\DateTimeInterface $pw_reset_expires = null; /** * @var bool True if the user was created by a SAML provider (and therefore cannot change its password) @@ -350,8 +350,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Sets the password hash for this user. - * - * @return User */ public function setPassword(string $password): self { @@ -389,8 +387,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Sets the currency the users prefers to see prices in. - * - * @return User */ public function setCurrency(?Currency $currency): self { @@ -413,8 +409,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe * Sets the status if a user is disabled. * * @param bool $disabled true if the user should be disabled - * - * @return User */ public function setDisabled(bool $disabled): self { @@ -425,7 +419,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe public function getPermissions(): PermissionData { - if ($this->permissions === null) { + if (!$this->permissions instanceof \App\Entity\UserSystem\PermissionData) { $this->permissions = new PermissionData(); } @@ -442,8 +436,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Set the status, if the user needs a password change. - * - * @return User */ public function setNeedPwChange(bool $need_pw_change): self { @@ -462,8 +454,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Sets the encrypted password reset token. - * - * @return User */ public function setPwResetToken(?string $pw_reset_token): self { @@ -482,8 +472,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Sets the datetime when the password reset token expires. - * - * @return User */ public function setPwResetExpires(\DateTimeInterface $pw_reset_expires): self { @@ -595,8 +583,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe * Change the department of the user. * * @param string|null $department The new department - * - * @return User */ public function setDepartment(?string $department): self { @@ -631,7 +617,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Gets whether the email address of the user is shown on the public profile page. - * @return bool */ public function isShowEmailOnProfile(): bool { @@ -640,8 +625,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Sets whether the email address of the user is shown on the public profile page. - * @param bool $show_email_on_profile - * @return User */ public function setShowEmailOnProfile(bool $show_email_on_profile): User { @@ -653,7 +636,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Returns the about me text of the user. - * @return string */ public function getAboutMe(): string { @@ -662,8 +644,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Change the about me text of the user. - * @param string $aboutMe - * @return User */ public function setAboutMe(string $aboutMe): User { @@ -689,8 +669,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe * * @param string|null $language The new language as 2-letter ISO code (e.g. 'en' or 'de'). * Set to null, to use the system-wide language. - * - * @return User */ public function setLanguage(?string $language): self { @@ -855,11 +833,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe public function setBackupCodes(array $codes): self { $this->backupCodes = $codes; - if (empty($codes)) { - $this->backupCodesGenerationDate = null; - } else { - $this->backupCodesGenerationDate = new DateTime(); - } + $this->backupCodesGenerationDate = $codes === [] ? null : new DateTime(); return $this; } @@ -938,7 +912,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Returns true, if the user was created by the SAML authentication. - * @return bool */ public function isSamlUser(): bool { @@ -947,8 +920,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * Sets the saml_user flag. - * @param bool $saml_user - * @return User */ public function setSamlUser(bool $saml_user): User { diff --git a/src/Entity/UserSystem/WebauthnKey.php b/src/Entity/UserSystem/WebauthnKey.php index fd43ad33..82a0a5fe 100644 --- a/src/Entity/UserSystem/WebauthnKey.php +++ b/src/Entity/UserSystem/WebauthnKey.php @@ -39,48 +39,31 @@ class WebauthnKey extends BasePublicKeyCredentialSource #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING)] protected string $name; - #[ORM\ManyToOne(targetEntity: 'App\Entity\UserSystem\User', inversedBy: 'webauthn_keys')] + #[ORM\ManyToOne(targetEntity: \App\Entity\UserSystem\User::class, inversedBy: 'webauthn_keys')] protected ?User $user = null; - /** - * @return string - */ public function getName(): string { return $this->name; } - /** - * @param string $name - * @return WebauthnKey - */ public function setName(string $name): WebauthnKey { $this->name = $name; return $this; } - /** - * @return User|null - */ public function getUser(): ?User { return $this->user; } - /** - * @param User|null $user - * @return WebauthnKey - */ public function setUser(?User $user): WebauthnKey { $this->user = $user; return $this; } - /** - * @return int - */ public function getId(): int { return $this->id; diff --git a/src/EntityListeners/AttachmentDeleteListener.php b/src/EntityListeners/AttachmentDeleteListener.php index 430740cb..11ddd794 100644 --- a/src/EntityListeners/AttachmentDeleteListener.php +++ b/src/EntityListeners/AttachmentDeleteListener.php @@ -41,15 +41,8 @@ use SplFileInfo; */ class AttachmentDeleteListener { - protected AttachmentReverseSearch $attachmentReverseSearch; - protected AttachmentManager $attachmentHelper; - protected AttachmentPathResolver $pathResolver; - - public function __construct(AttachmentReverseSearch $attachmentReverseSearch, AttachmentManager $attachmentHelper, AttachmentPathResolver $pathResolver) + public function __construct(protected AttachmentReverseSearch $attachmentReverseSearch, protected AttachmentManager $attachmentHelper, protected AttachmentPathResolver $pathResolver) { - $this->attachmentReverseSearch = $attachmentReverseSearch; - $this->attachmentHelper = $attachmentHelper; - $this->pathResolver = $pathResolver; } /** @@ -87,7 +80,7 @@ class AttachmentDeleteListener //Ensure that the attachment that will be deleted, is not used as preview picture anymore... $attachment_holder = $attachment->getElement(); - if (null === $attachment_holder) { + if (!$attachment_holder instanceof \App\Entity\Attachments\AttachmentContainingDBElement) { return; } @@ -100,7 +93,7 @@ class AttachmentDeleteListener if (!$em instanceof EntityManagerInterface) { throw new \RuntimeException('Invalid EntityManagerInterface!'); } - $classMetadata = $em->getClassMetadata(get_class($attachment_holder)); + $classMetadata = $em->getClassMetadata($attachment_holder::class); $em->getUnitOfWork()->computeChangeSet($classMetadata, $attachment_holder); } } @@ -118,7 +111,7 @@ class AttachmentDeleteListener $file = $this->attachmentHelper->attachmentToFile($attachment); //Only delete if the attachment has a valid file. - if (null !== $file) { + if ($file instanceof \SplFileInfo) { /* The original file has already been removed, so we have to decrease the threshold to zero, as any remaining attachment depends on this attachment, and we must not delete this file! */ $this->attachmentReverseSearch->deleteIfNotUsed($file, 0); diff --git a/src/EntityListeners/TreeCacheInvalidationListener.php b/src/EntityListeners/TreeCacheInvalidationListener.php index 6e17fe3f..4cbcf8f8 100644 --- a/src/EntityListeners/TreeCacheInvalidationListener.php +++ b/src/EntityListeners/TreeCacheInvalidationListener.php @@ -35,13 +35,8 @@ use Symfony\Contracts\Cache\TagAwareCacheInterface; class TreeCacheInvalidationListener { - protected TagAwareCacheInterface $cache; - protected UserCacheKeyGenerator $keyGenerator; - - public function __construct(TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator) + public function __construct(protected TagAwareCacheInterface $cache, protected UserCacheKeyGenerator $keyGenerator) { - $this->cache = $treeCache; - $this->keyGenerator = $keyGenerator; } #[ORM\PostUpdate] @@ -51,7 +46,7 @@ class TreeCacheInvalidationListener { //If an element was changed, then invalidate all cached trees with this element class if ($element instanceof AbstractStructuralDBElement || $element instanceof LabelProfile) { - $secure_class_name = str_replace('\\', '_', get_class($element)); + $secure_class_name = str_replace('\\', '_', $element::class); $this->cache->invalidateTags([$secure_class_name]); //Trigger a sidebar reload for all users (see SidebarTreeUpdater service) @@ -62,7 +57,7 @@ class TreeCacheInvalidationListener //If a user change, then invalidate all cached trees for him if ($element instanceof User) { - $secure_class_name = str_replace('\\', '_', get_class($element)); + $secure_class_name = str_replace('\\', '_', $element::class); $tag = $this->keyGenerator->generateKey($element); $this->cache->invalidateTags([$tag, $secure_class_name]); } diff --git a/src/EventSubscriber/LogSystem/EventLoggerSubscriber.php b/src/EventSubscriber/LogSystem/EventLoggerSubscriber.php index eed5953d..f66a96e5 100644 --- a/src/EventSubscriber/LogSystem/EventLoggerSubscriber.php +++ b/src/EventSubscriber/LogSystem/EventLoggerSubscriber.php @@ -70,30 +70,12 @@ class EventLoggerSubscriber implements EventSubscriber ]; protected const MAX_STRING_LENGTH = 2000; - - protected EventLogger $logger; - protected SerializerInterface $serializer; - protected EventCommentHelper $eventCommentHelper; - protected EventUndoHelper $eventUndoHelper; - protected bool $save_changed_fields; - protected bool $save_changed_data; - protected bool $save_removed_data; protected bool $save_new_data; - protected PropertyAccessorInterface $propertyAccessor; - public function __construct(EventLogger $logger, SerializerInterface $serializer, EventCommentHelper $commentHelper, - bool $save_changed_fields, bool $save_changed_data, bool $save_removed_data, bool $save_new_data, - PropertyAccessorInterface $propertyAccessor, EventUndoHelper $eventUndoHelper) + public function __construct(protected EventLogger $logger, protected SerializerInterface $serializer, protected EventCommentHelper $eventCommentHelper, + protected bool $save_changed_fields, protected bool $save_changed_data, protected bool $save_removed_data, bool $save_new_data, + protected PropertyAccessorInterface $propertyAccessor, protected EventUndoHelper $eventUndoHelper) { - $this->logger = $logger; - $this->serializer = $serializer; - $this->eventCommentHelper = $commentHelper; - $this->propertyAccessor = $propertyAccessor; - $this->eventUndoHelper = $eventUndoHelper; - - $this->save_changed_fields = $save_changed_fields; - $this->save_changed_data = $save_changed_data; - $this->save_removed_data = $save_removed_data; //This option only makes sense if save_changed_data is true $this->save_new_data = $save_new_data && $save_changed_data; } @@ -181,7 +163,7 @@ class EventLoggerSubscriber implements EventSubscriber public function hasFieldRestrictions(AbstractDBElement $element): bool { foreach (array_keys(static::FIELD_BLACKLIST) as $class) { - if (is_a($element, $class)) { + if ($element instanceof $class) { return true; } } @@ -195,7 +177,7 @@ class EventLoggerSubscriber implements EventSubscriber public function shouldFieldBeSaved(AbstractDBElement $element, string $field_name): bool { foreach (static::FIELD_BLACKLIST as $class => $blacklist) { - if (is_a($element, $class) && in_array($field_name, $blacklist, true)) { + if ($element instanceof $class && in_array($field_name, $blacklist, true)) { return false; } } @@ -231,11 +213,11 @@ class EventLoggerSubscriber implements EventSubscriber //Check if we have to log CollectionElementDeleted entries if ($this->save_changed_data) { - $metadata = $em->getClassMetadata(get_class($entity)); + $metadata = $em->getClassMetadata($entity::class); $mappings = $metadata->getAssociationMappings(); //Check if class is whitelisted for CollectionElementDeleted entry foreach (static::TRIGGER_ASSOCIATION_LOG_WHITELIST as $class => $whitelist) { - if (is_a($entity, $class)) { + if ($entity instanceof $class) { //Check names foreach ($mappings as $field => $mapping) { if (in_array($field, $whitelist, true)) { @@ -308,8 +290,6 @@ class EventLoggerSubscriber implements EventSubscriber /** * Restrict the length of every string in the given array to MAX_STRING_LENGTH, to save memory in the case of very * long strings (e.g. images in notes) - * @param array $fields - * @return array */ protected function fieldLengthRestrict(array $fields): array { @@ -325,6 +305,7 @@ class EventLoggerSubscriber implements EventSubscriber protected function saveChangeSet(AbstractDBElement $entity, AbstractLogEntry $logEntry, EntityManagerInterface $em, bool $element_deleted = false): void { + $new_data = null; $uow = $em->getUnitOfWork(); if (!$logEntry instanceof ElementEditedLogEntry && !$logEntry instanceof ElementDeletedLogEntry) { @@ -348,7 +329,7 @@ class EventLoggerSubscriber implements EventSubscriber $logEntry->setOldData($old_data); - if (!empty($new_data)) { + if ($new_data !== []) { $new_data = $this->filterFieldRestrictions($entity, $new_data); $new_data = $this->fieldLengthRestrict($new_data); diff --git a/src/EventSubscriber/LogSystem/LogAccessDeniedSubscriber.php b/src/EventSubscriber/LogSystem/LogAccessDeniedSubscriber.php index 45dbe61b..abe2f9ba 100644 --- a/src/EventSubscriber/LogSystem/LogAccessDeniedSubscriber.php +++ b/src/EventSubscriber/LogSystem/LogAccessDeniedSubscriber.php @@ -53,11 +53,8 @@ use Symfony\Component\Security\Core\Exception\AccessDeniedException; */ class LogAccessDeniedSubscriber implements EventSubscriberInterface { - private EventLogger $logger; - - public function __construct(EventLogger $logger) + public function __construct(private readonly EventLogger $logger) { - $this->logger = $logger; } public function onKernelException(ExceptionEvent $event): void diff --git a/src/EventSubscriber/LogSystem/LogDBMigrationSubscriber.php b/src/EventSubscriber/LogSystem/LogDBMigrationSubscriber.php index 610c0b5e..8e3af891 100644 --- a/src/EventSubscriber/LogSystem/LogDBMigrationSubscriber.php +++ b/src/EventSubscriber/LogSystem/LogDBMigrationSubscriber.php @@ -37,13 +37,8 @@ class LogDBMigrationSubscriber implements EventSubscriber protected ?string $old_version = null; protected ?string $new_version = null; - protected EventLogger $eventLogger; - protected DependencyFactory $dependencyFactory; - - public function __construct(EventLogger $eventLogger, DependencyFactory $dependencyFactory) + public function __construct(protected EventLogger $eventLogger, protected DependencyFactory $dependencyFactory) { - $this->eventLogger = $eventLogger; - $this->dependencyFactory = $dependencyFactory; } public function onMigrationsMigrated(MigrationsEventArgs $args): void @@ -66,7 +61,7 @@ class LogDBMigrationSubscriber implements EventSubscriber try { $log = new DatabaseUpdatedLogEntry($this->old_version, $this->new_version); $this->eventLogger->logAndFlush($log); - } catch (\Throwable $exception) { + } catch (\Throwable) { //Ignore any exception occuring here... } } diff --git a/src/EventSubscriber/LogSystem/LogLogoutEventListener.php b/src/EventSubscriber/LogSystem/LogLogoutEventListener.php index f9586c76..80dfb98f 100644 --- a/src/EventSubscriber/LogSystem/LogLogoutEventListener.php +++ b/src/EventSubscriber/LogSystem/LogLogoutEventListener.php @@ -32,15 +32,10 @@ use Symfony\Component\Security\Http\Event\LogoutEvent; * This handler logs to event log, if a user logs out. */ #[AsEventListener] -final class LogLogoutEventListener +final class LogLogoutEventEventSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface { - protected EventLogger $logger; - protected bool $gpdr_compliance; - - public function __construct(EventLogger $logger, bool $gpdr_compliance) + public function __construct(protected EventLogger $logger, protected bool $gpdr_compliance) { - $this->logger = $logger; - $this->gpdr_compliance = $gpdr_compliance; } public function __invoke(LogoutEvent $event): void @@ -48,7 +43,7 @@ final class LogLogoutEventListener $request = $event->getRequest(); $token = $event->getToken(); - if (null === $token) { + if (!$token instanceof \Symfony\Component\Security\Core\Authentication\Token\TokenInterface) { return; } @@ -60,4 +55,11 @@ final class LogLogoutEventListener $this->logger->logAndFlush($log); } + /** + * @return array + */ + public static function getSubscribedEvents(): array + { + return ['' => '']; + } } diff --git a/src/EventSubscriber/LogSystem/SecurityEventLoggerSubscriber.php b/src/EventSubscriber/LogSystem/SecurityEventLoggerSubscriber.php index 88eeef2c..66fb9fde 100644 --- a/src/EventSubscriber/LogSystem/SecurityEventLoggerSubscriber.php +++ b/src/EventSubscriber/LogSystem/SecurityEventLoggerSubscriber.php @@ -53,15 +53,8 @@ use Symfony\Component\HttpFoundation\RequestStack; */ final class SecurityEventLoggerSubscriber implements EventSubscriberInterface { - private RequestStack $requestStack; - private bool $gpdr_compliant; - private EventLogger $eventLogger; - - public function __construct(RequestStack $requestStack, EventLogger $eventLogger, bool $gpdr_compliance) + public function __construct(private readonly RequestStack $requestStack, private readonly EventLogger $eventLogger, private readonly bool $gpdr_compliant) { - $this->requestStack = $requestStack; - $this->gpdr_compliant = $gpdr_compliance; - $this->eventLogger = $eventLogger; } public static function getSubscribedEvents(): array @@ -129,7 +122,7 @@ final class SecurityEventLoggerSubscriber implements EventSubscriberInterface $anonymize = $this->gpdr_compliant; $request = $this->requestStack->getCurrentRequest(); - if (null !== $request) { + if ($request instanceof \Symfony\Component\HttpFoundation\Request) { $ip = $request->getClientIp() ?? 'unknown'; } else { $ip = 'Console'; diff --git a/src/EventSubscriber/SetMailFromSubscriber.php b/src/EventSubscriber/SetMailFromSubscriber.php index 6c9f563c..3675c487 100644 --- a/src/EventSubscriber/SetMailFromSubscriber.php +++ b/src/EventSubscriber/SetMailFromSubscriber.php @@ -32,13 +32,8 @@ use Symfony\Component\Mime\Email; */ final class SetMailFromSubscriber implements EventSubscriberInterface { - private string $email; - private string $name; - - public function __construct(string $email, string $name) + public function __construct(private readonly string $email, private readonly string $name) { - $this->email = $email; - $this->name = $name; } public function onMessage(MessageEvent $event): void diff --git a/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php b/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php index d2aab142..c404ffc0 100644 --- a/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php +++ b/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php @@ -30,11 +30,8 @@ use Symfony\Component\HttpKernel\Event\ResponseEvent; */ final class SymfonyDebugToolbarSubscriber implements EventSubscriberInterface { - private bool $kernel_debug; - - public function __construct(bool $kernel_debug) + public function __construct(private readonly bool $kernel_debug) { - $this->kernel_debug = $kernel_debug; } /** diff --git a/src/EventSubscriber/UserSystem/LoginSuccessSubscriber.php b/src/EventSubscriber/UserSystem/LoginSuccessSubscriber.php index cce88d82..e1cdfd84 100644 --- a/src/EventSubscriber/UserSystem/LoginSuccessSubscriber.php +++ b/src/EventSubscriber/UserSystem/LoginSuccessSubscriber.php @@ -37,17 +37,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ final class LoginSuccessSubscriber implements EventSubscriberInterface { - private TranslatorInterface $translator; - private RequestStack $requestStack; - private EventLogger $eventLogger; - private bool $gpdr_compliance; - - public function __construct(TranslatorInterface $translator, RequestStack $requestStack, EventLogger $eventLogger, bool $gpdr_compliance) + public function __construct(private readonly TranslatorInterface $translator, private readonly RequestStack $requestStack, private readonly EventLogger $eventLogger, private readonly bool $gpdr_compliance) { - $this->translator = $translator; - $this->requestStack = $requestStack; - $this->eventLogger = $eventLogger; - $this->gpdr_compliance = $gpdr_compliance; } public function onLogin(InteractiveLoginEvent $event): void diff --git a/src/EventSubscriber/UserSystem/LogoutDisabledUserSubscriber.php b/src/EventSubscriber/UserSystem/LogoutDisabledUserSubscriber.php index 73708566..da8d3b94 100644 --- a/src/EventSubscriber/UserSystem/LogoutDisabledUserSubscriber.php +++ b/src/EventSubscriber/UserSystem/LogoutDisabledUserSubscriber.php @@ -36,14 +36,8 @@ use Symfony\Component\Security\Core\Security; */ final class LogoutDisabledUserSubscriber implements EventSubscriberInterface { - private \Symfony\Bundle\SecurityBundle\Security $security; - private UrlGeneratorInterface $urlGenerator; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, UrlGeneratorInterface $urlGenerator) + public function __construct(private readonly \Symfony\Bundle\SecurityBundle\Security $security, private readonly UrlGeneratorInterface $urlGenerator) { - $this->security = $security; - - $this->urlGenerator = $urlGenerator; } public function onRequest(RequestEvent $event): void diff --git a/src/EventSubscriber/UserSystem/PasswordChangeNeededSubscriber.php b/src/EventSubscriber/UserSystem/PasswordChangeNeededSubscriber.php index 6c7e61f5..db8b6575 100644 --- a/src/EventSubscriber/UserSystem/PasswordChangeNeededSubscriber.php +++ b/src/EventSubscriber/UserSystem/PasswordChangeNeededSubscriber.php @@ -55,13 +55,9 @@ final class PasswordChangeNeededSubscriber implements EventSubscriberInterface * @var string The route the user will redirected to, if he needs to change this password */ public const REDIRECT_TARGET = 'user_settings'; - private \Symfony\Bundle\SecurityBundle\Security $security; - private HttpUtils $httpUtils; - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, HttpUtils $httpUtils) + public function __construct(private readonly \Symfony\Bundle\SecurityBundle\Security $security, private readonly HttpUtils $httpUtils) { - $this->security = $security; - $this->httpUtils = $httpUtils; } /** @@ -129,7 +125,7 @@ final class PasswordChangeNeededSubscriber implements EventSubscriberInterface { $tfa_enabled = $user->isWebAuthnAuthenticatorEnabled() || $user->isGoogleAuthenticatorEnabled(); - return null !== $user->getGroup() && $user->getGroup()->isEnforce2FA() && !$tfa_enabled; + return $user->getGroup() instanceof \App\Entity\UserSystem\Group && $user->getGroup()->isEnforce2FA() && !$tfa_enabled; } public static function getSubscribedEvents(): array diff --git a/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php b/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php index a6347c26..cf1206c1 100644 --- a/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php +++ b/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php @@ -33,13 +33,8 @@ use Symfony\Component\Security\Core\Security; */ final class SetUserTimezoneSubscriber implements EventSubscriberInterface { - private string $default_timezone; - private \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(string $timezone, \Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(private readonly string $default_timezone, private readonly \Symfony\Bundle\SecurityBundle\Security $security) { - $this->default_timezone = $timezone; - $this->security = $security; } public function setTimeZone(ControllerEvent $event): void diff --git a/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php b/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php index 551bb8b6..b2f30b01 100644 --- a/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php +++ b/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php @@ -35,17 +35,8 @@ use Symfony\Component\Security\Core\Security; */ class UpgradePermissionsSchemaSubscriber implements EventSubscriberInterface { - private \Symfony\Bundle\SecurityBundle\Security $security; - private PermissionSchemaUpdater $permissionSchemaUpdater; - private EntityManagerInterface $entityManager; - private EventCommentHelper $eventCommentHelper; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, PermissionSchemaUpdater $permissionSchemaUpdater, EntityManagerInterface $entityManager, EventCommentHelper $eventCommentHelper) + public function __construct(private readonly \Symfony\Bundle\SecurityBundle\Security $security, private readonly PermissionSchemaUpdater $permissionSchemaUpdater, private readonly EntityManagerInterface $entityManager, private readonly EventCommentHelper $eventCommentHelper) { - $this->security = $security; - $this->permissionSchemaUpdater = $permissionSchemaUpdater; - $this->entityManager = $entityManager; - $this->eventCommentHelper = $eventCommentHelper; } public function onRequest(RequestEvent $event): void @@ -55,7 +46,7 @@ class UpgradePermissionsSchemaSubscriber implements EventSubscriberInterface } $user = $this->security->getUser(); - if (null === $user) { + if (!$user instanceof \Symfony\Component\Security\Core\User\UserInterface) { //Retrieve anonymous user $user = $this->entityManager->getRepository(User::class)->getAnonymousUser(); } diff --git a/src/Events/SecurityEvent.php b/src/Events/SecurityEvent.php index 68f277c5..883460a7 100644 --- a/src/Events/SecurityEvent.php +++ b/src/Events/SecurityEvent.php @@ -50,11 +50,8 @@ use Symfony\Contracts\EventDispatcher\Event; */ class SecurityEvent extends Event { - protected User $targetUser; - - public function __construct(User $targetUser) + public function __construct(protected User $targetUser) { - $this->targetUser = $targetUser; } /** diff --git a/src/Events/SecurityEvents.php b/src/Events/SecurityEvents.php index 6ac1f882..c7c43882 100644 --- a/src/Events/SecurityEvents.php +++ b/src/Events/SecurityEvents.php @@ -43,13 +43,13 @@ namespace App\Events; class SecurityEvents { - public const PASSWORD_CHANGED = 'security.password_changed'; - public const PASSWORD_RESET = 'security.password_reset'; - public const BACKUP_KEYS_RESET = 'security.backup_keys_reset'; - public const U2F_ADDED = 'security.u2f_added'; - public const U2F_REMOVED = 'security.u2f_removed'; - public const GOOGLE_ENABLED = 'security.google_enabled'; - public const GOOGLE_DISABLED = 'security.google_disabled'; - public const TRUSTED_DEVICE_RESET = 'security.trusted_device_reset'; - public const TFA_ADMIN_RESET = 'security.2fa_admin_reset'; + final public const PASSWORD_CHANGED = 'security.password_changed'; + final public const PASSWORD_RESET = 'security.password_reset'; + final public const BACKUP_KEYS_RESET = 'security.backup_keys_reset'; + final public const U2F_ADDED = 'security.u2f_added'; + final public const U2F_REMOVED = 'security.u2f_removed'; + final public const GOOGLE_ENABLED = 'security.google_enabled'; + final public const GOOGLE_DISABLED = 'security.google_disabled'; + final public const TRUSTED_DEVICE_RESET = 'security.trusted_device_reset'; + final public const TFA_ADMIN_RESET = 'security.2fa_admin_reset'; } diff --git a/src/Exceptions/InvalidRegexException.php b/src/Exceptions/InvalidRegexException.php index a94201d0..e2dcd68e 100644 --- a/src/Exceptions/InvalidRegexException.php +++ b/src/Exceptions/InvalidRegexException.php @@ -25,17 +25,13 @@ use ErrorException; class InvalidRegexException extends \RuntimeException { - private ?string $reason; - - public function __construct(string $reason = null) + public function __construct(private readonly ?string $reason = null) { - $this->reason = $reason; parent::__construct('Invalid regular expression'); } /** * Returns the reason for the exception (what the regex driver deemed invalid) - * @return string|null */ public function getReason(): ?string { @@ -44,8 +40,6 @@ class InvalidRegexException extends \RuntimeException /** * Creates a new exception from a driver exception happening, when MySQL encounters an invalid regex - * @param DriverException $exception - * @return self */ public static function fromDriverException(DriverException $exception): self { @@ -62,13 +56,11 @@ class InvalidRegexException extends \RuntimeException /** * Creates a new exception from the errorException thrown by mb_ereg - * @param ErrorException $ex - * @return self */ public static function fromMBRegexError(ErrorException $ex): self { //Ensure that the error is really a mb_ereg error - if ($ex->getSeverity() !== E_WARNING || !strpos($ex->getMessage(), 'mb_ereg()') !== false) { + if ($ex->getSeverity() !== E_WARNING || !strpos($ex->getMessage(), 'mb_ereg()')) { throw new \InvalidArgumentException('The given exception is not a mb_ereg error', 0, $ex); } diff --git a/src/Form/AdminPages/AttachmentTypeAdminForm.php b/src/Form/AdminPages/AttachmentTypeAdminForm.php index 475eb66e..c2ea1c00 100644 --- a/src/Form/AdminPages/AttachmentTypeAdminForm.php +++ b/src/Form/AdminPages/AttachmentTypeAdminForm.php @@ -32,11 +32,8 @@ use Symfony\Component\Security\Core\Security; class AttachmentTypeAdminForm extends BaseEntityAdminForm { - protected FileTypeFilterTools $filterTools; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, FileTypeFilterTools $filterTools, EventCommentNeededHelper $eventCommentNeededHelper) + public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, protected FileTypeFilterTools $filterTools, EventCommentNeededHelper $eventCommentNeededHelper) { - $this->filterTools = $filterTools; parent::__construct($security, $eventCommentNeededHelper); } @@ -58,12 +55,8 @@ class AttachmentTypeAdminForm extends BaseEntityAdminForm //Normalize data before writing it to database $builder->get('filetype_filter')->addViewTransformer(new CallbackTransformer( - static function ($value) { - return $value; - }, - function ($value) { - return $this->filterTools->normalizeFilterString($value); - } + static fn($value) => $value, + fn($value) => $this->filterTools->normalizeFilterString($value) )); } } diff --git a/src/Form/AdminPages/BaseEntityAdminForm.php b/src/Form/AdminPages/BaseEntityAdminForm.php index 4e49c784..464e32ad 100644 --- a/src/Form/AdminPages/BaseEntityAdminForm.php +++ b/src/Form/AdminPages/BaseEntityAdminForm.php @@ -44,13 +44,8 @@ use Symfony\Component\Security\Core\Security; class BaseEntityAdminForm extends AbstractType { - protected \Symfony\Bundle\SecurityBundle\Security $security; - protected EventCommentNeededHelper $eventCommentNeededHelper; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, EventCommentNeededHelper $eventCommentNeededHelper) + public function __construct(protected \Symfony\Bundle\SecurityBundle\Security $security, protected EventCommentNeededHelper $eventCommentNeededHelper) { - $this->security = $security; - $this->eventCommentNeededHelper = $eventCommentNeededHelper; } public function configureOptions(OptionsResolver $resolver): void @@ -82,7 +77,7 @@ class BaseEntityAdminForm extends AbstractType 'parent', StructuralEntityType::class, [ - 'class' => get_class($entity), + 'class' => $entity::class, 'required' => false, 'label' => 'parent.label', 'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity), diff --git a/src/Form/AdminPages/CurrencyAdminForm.php b/src/Form/AdminPages/CurrencyAdminForm.php index 0ba85c49..7ebe08bb 100644 --- a/src/Form/AdminPages/CurrencyAdminForm.php +++ b/src/Form/AdminPages/CurrencyAdminForm.php @@ -32,12 +32,9 @@ use Symfony\Component\Security\Core\Security; class CurrencyAdminForm extends BaseEntityAdminForm { - private string $default_currency; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, EventCommentNeededHelper $eventCommentNeededHelper, string $default_currency) + public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, EventCommentNeededHelper $eventCommentNeededHelper, private readonly string $default_currency) { parent::__construct($security, $eventCommentNeededHelper); - $this->default_currency = $default_currency; } protected function additionalFormElements(FormBuilderInterface $builder, array $options, AbstractNamedDBElement $entity): void diff --git a/src/Form/AdminPages/ImportType.php b/src/Form/AdminPages/ImportType.php index bc481a82..ceaa0c0c 100644 --- a/src/Form/AdminPages/ImportType.php +++ b/src/Form/AdminPages/ImportType.php @@ -37,11 +37,8 @@ use Symfony\Component\Security\Core\Security; class ImportType extends AbstractType { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(protected \Symfony\Bundle\SecurityBundle\Security $security) { - $this->security = $security; } public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Form/AdminPages/MassCreationForm.php b/src/Form/AdminPages/MassCreationForm.php index 6eb23785..dbf3fbcb 100644 --- a/src/Form/AdminPages/MassCreationForm.php +++ b/src/Form/AdminPages/MassCreationForm.php @@ -32,11 +32,8 @@ use Symfony\Component\Security\Core\Security; class MassCreationForm extends AbstractType { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(protected \Symfony\Bundle\SecurityBundle\Security $security) { - $this->security = $security; } public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Form/AdminPages/SupplierForm.php b/src/Form/AdminPages/SupplierForm.php index ea158484..d5253c1a 100644 --- a/src/Form/AdminPages/SupplierForm.php +++ b/src/Form/AdminPages/SupplierForm.php @@ -32,12 +32,9 @@ use Symfony\Component\Security\Core\Security; class SupplierForm extends CompanyForm { - protected string $default_currency; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, EventCommentNeededHelper $eventCommentNeededHelper, string $default_currency) + public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, EventCommentNeededHelper $eventCommentNeededHelper, protected string $default_currency) { parent::__construct($security, $eventCommentNeededHelper); - $this->default_currency = $default_currency; } protected function additionalFormElements(FormBuilderInterface $builder, array $options, AbstractNamedDBElement $entity): void diff --git a/src/Form/AttachmentFormType.php b/src/Form/AttachmentFormType.php index 72098dc4..88d4d3d1 100644 --- a/src/Form/AttachmentFormType.php +++ b/src/Form/AttachmentFormType.php @@ -48,25 +48,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class AttachmentFormType extends AbstractType { - protected AttachmentManager $attachment_helper; - protected UrlGeneratorInterface $urlGenerator; - protected bool $allow_attachments_download; - protected string $max_file_size; - protected \Symfony\Bundle\SecurityBundle\Security $security; - protected AttachmentSubmitHandler $submitHandler; - protected TranslatorInterface $translator; - - public function __construct(AttachmentManager $attachmentHelper, UrlGeneratorInterface $urlGenerator, - \Symfony\Bundle\SecurityBundle\Security $security, AttachmentSubmitHandler $submitHandler, TranslatorInterface $translator, - bool $allow_attachments_downloads, string $max_file_size) + public function __construct(protected AttachmentManager $attachment_helper, protected UrlGeneratorInterface $urlGenerator, protected \Symfony\Bundle\SecurityBundle\Security $security, protected AttachmentSubmitHandler $submitHandler, protected TranslatorInterface $translator, protected bool $allow_attachments_download, protected string $max_file_size) { - $this->attachment_helper = $attachmentHelper; - $this->urlGenerator = $urlGenerator; - $this->allow_attachments_download = $allow_attachments_downloads; - $this->security = $security; - $this->submitHandler = $submitHandler; - $this->translator = $translator; - $this->max_file_size = $max_file_size; } public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Form/CollectionTypeExtension.php b/src/Form/CollectionTypeExtension.php index 1c0c8d63..a70576fd 100644 --- a/src/Form/CollectionTypeExtension.php +++ b/src/Form/CollectionTypeExtension.php @@ -67,11 +67,8 @@ use Symfony\Component\PropertyAccess\PropertyAccessorInterface; */ class CollectionTypeExtension extends AbstractTypeExtension { - protected PropertyAccessorInterface $propertyAccess; - - public function __construct(PropertyAccessorInterface $propertyAccess) + public function __construct(protected PropertyAccessorInterface $propertyAccess) { - $this->propertyAccess = $propertyAccess; } public static function getExtendedTypes(): iterable @@ -93,9 +90,7 @@ class CollectionTypeExtension extends AbstractTypeExtension //Set a unique prototype name, so that we can use nested collections $resolver->setDefaults([ - 'prototype_name' => function (Options $options) { - return '__name_'.uniqid("", false) . '__'; - }, + 'prototype_name' => fn(Options $options): string => '__name_'.uniqid("", false) . '__', ]); $resolver->setAllowedTypes('reindex_enable', 'bool'); @@ -156,7 +151,7 @@ class CollectionTypeExtension extends AbstractTypeExtension //The validator uses the number of the element as index, so we have to map the errors to the correct index $error_mapping = []; $n = 0; - foreach ($data as $key => $item) { + foreach (array_keys($data) as $key) { $error_mapping['['.$n.']'] = $key; $n++; } diff --git a/src/Form/Filters/Constraints/InstanceOfConstraintType.php b/src/Form/Filters/Constraints/InstanceOfConstraintType.php index 4a776cd6..b88fa50f 100644 --- a/src/Form/Filters/Constraints/InstanceOfConstraintType.php +++ b/src/Form/Filters/Constraints/InstanceOfConstraintType.php @@ -27,11 +27,8 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class InstanceOfConstraintType extends AbstractType { - protected EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(protected EntityManagerInterface $em) { - $this->em = $entityManager; } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Form/Filters/Constraints/TagsConstraintType.php b/src/Form/Filters/Constraints/TagsConstraintType.php index e6134a65..5fbf348c 100644 --- a/src/Form/Filters/Constraints/TagsConstraintType.php +++ b/src/Form/Filters/Constraints/TagsConstraintType.php @@ -30,11 +30,8 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class TagsConstraintType extends AbstractType { - protected UrlGeneratorInterface $urlGenerator; - - public function __construct(UrlGeneratorInterface $urlGenerator) + public function __construct(protected UrlGeneratorInterface $urlGenerator) { - $this->urlGenerator = $urlGenerator; } public function configureOptions(OptionsResolver $resolver): void diff --git a/src/Form/LabelOptionsType.php b/src/Form/LabelOptionsType.php index 78546702..25c3c646 100644 --- a/src/Form/LabelOptionsType.php +++ b/src/Form/LabelOptionsType.php @@ -53,11 +53,8 @@ use Symfony\Component\Security\Core\Security; class LabelOptionsType extends AbstractType { - private \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(private readonly \Symfony\Bundle\SecurityBundle\Security $security) { - $this->security = $security; } public function buildForm(FormBuilderInterface $builder, array $options): void @@ -101,7 +98,7 @@ class LabelOptionsType extends AbstractType 'label_options.barcode_type.code93' => 'code93', 'label_options.barcode_type.datamatrix' => 'datamatrix', ], - 'group_by' => static function ($choice, $key, $value) { + 'group_by' => static function ($choice, $key, $value): ?string { if (in_array($choice, ['qr', 'datamatrix'], true)) { return 'label_options.barcode_type.2D'; } diff --git a/src/Form/LabelSystem/LabelDialogType.php b/src/Form/LabelSystem/LabelDialogType.php index 4427fab1..faf12adb 100644 --- a/src/Form/LabelSystem/LabelDialogType.php +++ b/src/Form/LabelSystem/LabelDialogType.php @@ -52,11 +52,8 @@ use Symfony\Component\Security\Core\Security; class LabelDialogType extends AbstractType { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(protected \Symfony\Bundle\SecurityBundle\Security $security) { - $this->security = $security; } public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Form/Part/OrderdetailType.php b/src/Form/Part/OrderdetailType.php index b904e582..67d2aa82 100644 --- a/src/Form/Part/OrderdetailType.php +++ b/src/Form/Part/OrderdetailType.php @@ -40,11 +40,8 @@ use Symfony\Component\Security\Core\Security; class OrderdetailType extends AbstractType { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(protected \Symfony\Bundle\SecurityBundle\Security $security) { - $this->security = $security; } public function buildForm(FormBuilderInterface $builder, array $options): void @@ -82,7 +79,7 @@ class OrderdetailType extends AbstractType $orderdetail = $event->getData(); $dummy_pricedetail = new Pricedetail(); - if (null !== $orderdetail && null !== $orderdetail->getSupplier()) { + if ($orderdetail instanceof \App\Entity\PriceInformations\Orderdetail && $orderdetail->getSupplier() instanceof \App\Entity\Parts\Supplier) { $dummy_pricedetail->setCurrency($orderdetail->getSupplier()->getDefaultCurrency()); } diff --git a/src/Form/Part/PartBaseType.php b/src/Form/Part/PartBaseType.php index f00458d2..53205e1f 100644 --- a/src/Form/Part/PartBaseType.php +++ b/src/Form/Part/PartBaseType.php @@ -52,15 +52,8 @@ use Symfony\Component\Security\Core\Security; class PartBaseType extends AbstractType { - protected \Symfony\Bundle\SecurityBundle\Security $security; - protected UrlGeneratorInterface $urlGenerator; - protected EventCommentNeededHelper $event_comment_needed_helper; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, UrlGeneratorInterface $urlGenerator, EventCommentNeededHelper $event_comment_needed_helper) + public function __construct(protected \Symfony\Bundle\SecurityBundle\Security $security, protected UrlGeneratorInterface $urlGenerator, protected EventCommentNeededHelper $event_comment_needed_helper) { - $this->security = $security; - $this->urlGenerator = $urlGenerator; - $this->event_comment_needed_helper = $event_comment_needed_helper; } public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Form/Part/PartLotType.php b/src/Form/Part/PartLotType.php index e0e3f98c..d845b2c4 100644 --- a/src/Form/Part/PartLotType.php +++ b/src/Form/Part/PartLotType.php @@ -38,11 +38,8 @@ use Symfony\Component\Security\Core\Security; class PartLotType extends AbstractType { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(protected \Symfony\Bundle\SecurityBundle\Security $security) { - $this->security = $security; } public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Form/Permissions/PermissionGroupType.php b/src/Form/Permissions/PermissionGroupType.php index c395337f..f3f7ffec 100644 --- a/src/Form/Permissions/PermissionGroupType.php +++ b/src/Form/Permissions/PermissionGroupType.php @@ -30,12 +30,10 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class PermissionGroupType extends AbstractType { - protected PermissionManager $resolver; protected array $perm_structure; - public function __construct(PermissionManager $resolver) + public function __construct(protected PermissionManager $resolver) { - $this->resolver = $resolver; $this->perm_structure = $resolver->getPermissionStructure(); } @@ -68,9 +66,7 @@ class PermissionGroupType extends AbstractType { parent::configureOptions($resolver); - $resolver->setDefault('group_name', static function (Options $options) { - return trim($options['name']); - }); + $resolver->setDefault('group_name', static fn(Options $options): string => trim((string) $options['name'])); $resolver->setDefault('inherit', false); diff --git a/src/Form/Permissions/PermissionType.php b/src/Form/Permissions/PermissionType.php index 804fed0a..ab5ee86b 100644 --- a/src/Form/Permissions/PermissionType.php +++ b/src/Form/Permissions/PermissionType.php @@ -33,12 +33,10 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class PermissionType extends AbstractType { - protected PermissionManager $resolver; protected array $perm_structure; - public function __construct(PermissionManager $resolver) + public function __construct(protected PermissionManager $resolver) { - $this->resolver = $resolver; $this->perm_structure = $resolver->getPermissionStructure(); } @@ -46,9 +44,7 @@ class PermissionType extends AbstractType { parent::configureOptions($resolver); - $resolver->setDefault('perm_name', static function (Options $options) { - return $options['name']; - }); + $resolver->setDefault('perm_name', static fn(Options $options) => $options['name']); $resolver->setDefault('label', function (Options $options) { if (!empty($this->perm_structure['perms'][$options['perm_name']]['label'])) { @@ -58,9 +54,7 @@ class PermissionType extends AbstractType return $options['name']; }); - $resolver->setDefault('multi_checkbox', static function (Options $options) { - return !$options['disabled']; - }); + $resolver->setDefault('multi_checkbox', static fn(Options $options) => !$options['disabled']); $resolver->setDefaults([ 'inherit' => false, diff --git a/src/Form/Permissions/PermissionsMapper.php b/src/Form/Permissions/PermissionsMapper.php index 9ecf09f7..07c47bdd 100644 --- a/src/Form/Permissions/PermissionsMapper.php +++ b/src/Form/Permissions/PermissionsMapper.php @@ -34,13 +34,8 @@ use Traversable; */ final class PermissionsMapper implements DataMapperInterface { - private PermissionManager $resolver; - private bool $inherit; - - public function __construct(PermissionManager $resolver, bool $inherit = false) + public function __construct(private readonly PermissionManager $resolver, private readonly bool $inherit = false) { - $this->inherit = $inherit; - $this->resolver = $resolver; } /** diff --git a/src/Form/Permissions/PermissionsType.php b/src/Form/Permissions/PermissionsType.php index e5688729..b0c7ba9d 100644 --- a/src/Form/Permissions/PermissionsType.php +++ b/src/Form/Permissions/PermissionsType.php @@ -33,12 +33,10 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class PermissionsType extends AbstractType { - protected PermissionManager $resolver; protected array $perm_structure; - public function __construct(PermissionManager $resolver) + public function __construct(protected PermissionManager $resolver) { - $this->resolver = $resolver; $this->perm_structure = $resolver->getPermissionStructure(); } diff --git a/src/Form/ProjectSystem/ProjectBuildType.php b/src/Form/ProjectSystem/ProjectBuildType.php index 206ce3f0..6d6a194a 100644 --- a/src/Form/ProjectSystem/ProjectBuildType.php +++ b/src/Form/ProjectSystem/ProjectBuildType.php @@ -38,11 +38,8 @@ use Symfony\Component\Security\Core\Security; class ProjectBuildType extends AbstractType implements DataMapperInterface { - private \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(private readonly \Symfony\Bundle\SecurityBundle\Security $security) { - $this->security = $security; } public function configureOptions(OptionsResolver $resolver) @@ -79,10 +76,10 @@ class ProjectBuildType extends AbstractType implements DataMapperInterface $form->add('addBuildsToBuildsPart', CheckboxType::class, [ 'label' => 'project.build.add_builds_to_builds_part', 'required' => false, - 'disabled' => $build_request->getProject()->getBuildPart() === null, + 'disabled' => !$build_request->getProject()->getBuildPart() instanceof \App\Entity\Parts\Part, ]); - if ($build_request->getProject()->getBuildPart()) { + if ($build_request->getProject()->getBuildPart() instanceof \App\Entity\Parts\Part) { $form->add('buildsPartLot', PartLotSelectType::class, [ 'label' => 'project.build.builds_part_lot', 'required' => false, diff --git a/src/Form/Type/CurrencyEntityType.php b/src/Form/Type/CurrencyEntityType.php index 46aeac66..07f0a9f8 100644 --- a/src/Form/Type/CurrencyEntityType.php +++ b/src/Form/Type/CurrencyEntityType.php @@ -36,12 +36,9 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class CurrencyEntityType extends StructuralEntityType { - protected ?string $base_currency; - - public function __construct(EntityManagerInterface $em, NodesListBuilder $builder, TranslatorInterface $translator, StructuralEntityChoiceHelper $choiceHelper, ?string $base_currency) + public function __construct(EntityManagerInterface $em, NodesListBuilder $builder, TranslatorInterface $translator, StructuralEntityChoiceHelper $choiceHelper, protected ?string $base_currency) { parent::__construct($em, $builder, $translator, $choiceHelper); - $this->base_currency = $base_currency; } public function configureOptions(OptionsResolver $resolver): void @@ -56,11 +53,7 @@ class CurrencyEntityType extends StructuralEntityType // This options allows you to override the currency shown for the null value $resolver->setDefault('base_currency', null); - $resolver->setDefault('choice_attr', function (Options $options) { - return function ($choice) use ($options) { - return $this->choice_helper->generateChoiceAttrCurrency($choice, $options); - }; - }); + $resolver->setDefault('choice_attr', fn(Options $options) => fn($choice) => $this->choice_helper->generateChoiceAttrCurrency($choice, $options)); $resolver->setDefault('empty_message', function (Options $options) { //By default, we use the global base currency: diff --git a/src/Form/Type/Helper/StructuralEntityChoiceHelper.php b/src/Form/Type/Helper/StructuralEntityChoiceHelper.php index da52b83e..3540e892 100644 --- a/src/Form/Type/Helper/StructuralEntityChoiceHelper.php +++ b/src/Form/Type/Helper/StructuralEntityChoiceHelper.php @@ -34,22 +34,15 @@ use Symfony\Contracts\Translation\TranslatorInterface; class StructuralEntityChoiceHelper { - private AttachmentURLGenerator $attachmentURLGenerator; - private TranslatorInterface $translator; - - public function __construct(AttachmentURLGenerator $attachmentURLGenerator, TranslatorInterface $translator) + public function __construct(private readonly AttachmentURLGenerator $attachmentURLGenerator, private readonly TranslatorInterface $translator) { - $this->attachmentURLGenerator = $attachmentURLGenerator; - $this->translator = $translator; } /** * Generates the choice attributes for the given AbstractStructuralDBElement. - * @param AbstractNamedDBElement $choice - * @param Options|array $options * @return array|string[] */ - public function generateChoiceAttr(AbstractNamedDBElement $choice, $options): array + public function generateChoiceAttr(AbstractNamedDBElement $choice, \Symfony\Component\OptionsResolver\Options|array $options): array { $tmp = [ 'data-level' => 0, @@ -69,19 +62,19 @@ class StructuralEntityChoiceHelper $level = $choice->getLevel(); /** @var AbstractStructuralDBElement|null $parent */ $parent = $options['subentities_of'] ?? null; - if (null !== $parent) { + if ($parent instanceof \App\Entity\Base\AbstractStructuralDBElement) { $level -= $parent->getLevel() - 1; } $tmp += [ 'data-level' => $level, - 'data-parent' => $choice->getParent() ? $choice->getParent()->getFullPath() : null, + 'data-parent' => $choice->getParent() instanceof \App\Entity\Base\AbstractStructuralDBElement ? $choice->getParent()->getFullPath() : null, 'data-path' => $choice->getFullPath('->'), ]; } if ($choice instanceof HasMasterAttachmentInterface) { - $tmp['data-image'] = $choice->getMasterPictureAttachment() ? + $tmp['data-image'] = $choice->getMasterPictureAttachment() instanceof \App\Entity\Attachments\Attachment ? $this->attachmentURLGenerator->getThumbnailURL($choice->getMasterPictureAttachment(), 'thumbnail_xs') : null @@ -97,37 +90,21 @@ class StructuralEntityChoiceHelper /** * Generates the choice attributes for the given AbstractStructuralDBElement. - * @param Currency $choice - * @param Options|array $options * @return array|string[] */ - public function generateChoiceAttrCurrency(Currency $choice, $options): array + public function generateChoiceAttrCurrency(Currency $choice, \Symfony\Component\OptionsResolver\Options|array $options): array { $tmp = $this->generateChoiceAttr($choice, $options); + $symbol = empty($choice->getIsoCode()) ? null : Currencies::getSymbol($choice->getIsoCode()); + $tmp['data-short'] = $options['short'] ? $symbol : $choice->getName(); - if(!empty($choice->getIsoCode())) { - $symbol = Currencies::getSymbol($choice->getIsoCode()); - } else { - $symbol = null; - } - - if ($options['short']) { - $tmp['data-short'] = $symbol; - } else { - $tmp['data-short'] = $choice->getName(); - } - - $tmp += [ + return $tmp + [ 'data-symbol' => $symbol, ]; - - return $tmp; } /** * Returns the choice label for the given AbstractStructuralDBElement. - * @param AbstractNamedDBElement $choice - * @return string */ public function generateChoiceLabel(AbstractNamedDBElement $choice): string { @@ -136,12 +113,10 @@ class StructuralEntityChoiceHelper /** * Returns the choice value for the given AbstractStructuralDBElement. - * @param AbstractNamedDBElement|null $element - * @return string|int|null */ - public function generateChoiceValue(?AbstractNamedDBElement $element) + public function generateChoiceValue(?AbstractNamedDBElement $element): string|int|null { - if ($element === null) { + if (!$element instanceof \App\Entity\Base\AbstractNamedDBElement) { return null; } @@ -162,10 +137,6 @@ class StructuralEntityChoiceHelper return $element->getID(); } - /** - * @param AbstractDBElement $element - * @return string|null - */ public function generateGroupBy(AbstractDBElement $element): ?string { //Show entities that are not added to DB yet separately from other entities diff --git a/src/Form/Type/Helper/StructuralEntityChoiceLoader.php b/src/Form/Type/Helper/StructuralEntityChoiceLoader.php index 4f5347ad..fe7b71dd 100644 --- a/src/Form/Type/Helper/StructuralEntityChoiceLoader.php +++ b/src/Form/Type/Helper/StructuralEntityChoiceLoader.php @@ -28,17 +28,10 @@ use Symfony\Component\OptionsResolver\Options; class StructuralEntityChoiceLoader extends AbstractChoiceLoader { - private Options $options; - private NodesListBuilder $builder; - private EntityManagerInterface $entityManager; - private ?string $additional_element = null; - public function __construct(Options $options, NodesListBuilder $builder, EntityManagerInterface $entityManager) + public function __construct(private readonly Options $options, private readonly NodesListBuilder $builder, private readonly EntityManagerInterface $entityManager) { - $this->options = $options; - $this->builder = $builder; - $this->entityManager = $entityManager; } protected function loadChoices(): iterable diff --git a/src/Form/Type/MasterPictureAttachmentType.php b/src/Form/Type/MasterPictureAttachmentType.php index 7aba9cc6..b5edbd55 100644 --- a/src/Form/Type/MasterPictureAttachmentType.php +++ b/src/Form/Type/MasterPictureAttachmentType.php @@ -42,32 +42,28 @@ class MasterPictureAttachmentType extends AbstractType $resolver->setDefaults([ 'filter' => 'picture', 'choice_translation_domain' => false, - 'choice_attr' => static function (Options $options) { - return static function ($choice, $key, $value) use ($options) { - /** @var Attachment $choice */ - $tmp = ['data-subtext' => $choice->getFilename() ?? 'URL']; + 'choice_attr' => static fn(Options $options) => static function ($choice, $key, $value) use ($options) { + /** @var Attachment $choice */ + $tmp = ['data-subtext' => $choice->getFilename() ?? 'URL']; - if ('picture' === $options['filter'] && !$choice->isPicture()) { - $tmp += ['disabled' => 'disabled']; - } elseif ('3d_model' === $options['filter'] && !$choice->is3DModel()) { - $tmp += ['disabled' => 'disabled']; - } + if ('picture' === $options['filter'] && !$choice->isPicture()) { + $tmp += ['disabled' => 'disabled']; + } elseif ('3d_model' === $options['filter'] && !$choice->is3DModel()) { + $tmp += ['disabled' => 'disabled']; + } - return $tmp; - }; + return $tmp; }, 'choice_label' => 'name', - 'choice_loader' => static function (Options $options) { - return new CallbackChoiceLoader( - static function () use ($options) { - $entity = $options['entity']; - if (!$entity instanceof AttachmentContainingDBElement) { - throw new RuntimeException('$entity must have Attachments! (be of type AttachmentContainingDBElement)'); - } + 'choice_loader' => static fn(Options $options) => new CallbackChoiceLoader( + static function () use ($options) { + $entity = $options['entity']; + if (!$entity instanceof AttachmentContainingDBElement) { + throw new RuntimeException('$entity must have Attachments! (be of type AttachmentContainingDBElement)'); + } - return $entity->getAttachments()->toArray(); - }); - }, + return $entity->getAttachments()->toArray(); + }), ]); $resolver->setAllowedValues('filter', ['', 'picture', '3d_model']); diff --git a/src/Form/Type/PartLotSelectType.php b/src/Form/Type/PartLotSelectType.php index 76e31ecb..2f15443e 100644 --- a/src/Form/Type/PartLotSelectType.php +++ b/src/Form/Type/PartLotSelectType.php @@ -43,17 +43,11 @@ class PartLotSelectType extends AbstractType $resolver->setDefaults([ 'class' => PartLot::class, - 'choice_label' => ChoiceList::label($this, static function (PartLot $part_lot) { - return ($part_lot->getStorageLocation() ? $part_lot->getStorageLocation()->getFullPath() : '') - . ' (' . $part_lot->getName() . '): ' . $part_lot->getAmount(); - }), - 'query_builder' => function (Options $options) { - return static function (EntityRepository $er) use ($options) { - return $er->createQueryBuilder('l') - ->where('l.part = :part') - ->setParameter('part', $options['part']); - }; - } + 'choice_label' => ChoiceList::label($this, static fn(PartLot $part_lot): string => ($part_lot->getStorageLocation() instanceof \App\Entity\Parts\Storelocation ? $part_lot->getStorageLocation()->getFullPath() : '') + . ' (' . $part_lot->getName() . '): ' . $part_lot->getAmount()), + 'query_builder' => fn(Options $options) => static fn(EntityRepository $er) => $er->createQueryBuilder('l') + ->where('l.part = :part') + ->setParameter('part', $options['part']) ]); } } \ No newline at end of file diff --git a/src/Form/Type/PartSelectType.php b/src/Form/Type/PartSelectType.php index c78ce55e..d81f70cd 100644 --- a/src/Form/Type/PartSelectType.php +++ b/src/Form/Type/PartSelectType.php @@ -19,18 +19,8 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class PartSelectType extends AbstractType implements DataMapperInterface { - private UrlGeneratorInterface $urlGenerator; - private EntityManagerInterface $em; - private PartPreviewGenerator $previewGenerator; - private AttachmentURLGenerator $attachmentURLGenerator; - - public function __construct(UrlGeneratorInterface $urlGenerator, EntityManagerInterface $em, PartPreviewGenerator $previewGenerator, - AttachmentURLGenerator $attachmentURLGenerator) + public function __construct(private readonly UrlGeneratorInterface $urlGenerator, private readonly EntityManagerInterface $em, private readonly PartPreviewGenerator $previewGenerator, private readonly AttachmentURLGenerator $attachmentURLGenerator) { - $this->urlGenerator = $urlGenerator; - $this->em = $em; - $this->previewGenerator = $previewGenerator; - $this->attachmentURLGenerator = $attachmentURLGenerator; } public function buildForm(FormBuilderInterface $builder, array $options) @@ -96,10 +86,10 @@ class PartSelectType extends AbstractType implements DataMapperInterface $resolver->setDefaults([ //Prefill the selected choice with the needed data, so the user can see it without an additional Ajax request 'choice_attr' => ChoiceList::attr($this, function (?Part $part) { - if($part) { + if($part instanceof \App\Entity\Parts\Part) { //Determine the picture to show: $preview_attachment = $this->previewGenerator->getTablePreviewAttachment($part); - if ($preview_attachment !== null) { + if ($preview_attachment instanceof \App\Entity\Attachments\Attachment) { $preview_url = $this->attachmentURLGenerator->getThumbnailURL($preview_attachment, 'thumbnail_sm'); } else { @@ -107,10 +97,10 @@ class PartSelectType extends AbstractType implements DataMapperInterface } } - return $part ? [ + return $part instanceof \App\Entity\Parts\Part ? [ 'data-description' => mb_strimwidth($part->getDescription(), 0, 127, '...'), - 'data-category' => $part->getCategory() ? $part->getCategory()->getName() : '', - 'data-footprint' => $part->getFootprint() ? $part->getFootprint()->getName() : '', + 'data-category' => $part->getCategory() instanceof \App\Entity\Parts\Category ? $part->getCategory()->getName() : '', + 'data-footprint' => $part->getFootprint() instanceof \App\Entity\Parts\Footprint ? $part->getFootprint()->getName() : '', 'data-image' => $preview_url, ] : []; }) diff --git a/src/Form/Type/RichTextEditorType.php b/src/Form/Type/RichTextEditorType.php index 1d076916..fd796e52 100644 --- a/src/Form/Type/RichTextEditorType.php +++ b/src/Form/Type/RichTextEditorType.php @@ -48,18 +48,13 @@ class RichTextEditorType extends AbstractType protected function optionsToAttrArray(array $options): array { - $tmp = []; - - //Set novalidate attribute, or we will get problems that form can not be submitted as textarea is not focusable - $tmp['novalidate'] = 'novalidate'; - - $tmp['data-mode'] = $options['mode']; - - //Add our data-controller element to the textarea - $tmp['data-controller'] = 'elements--ckeditor'; - - - return $tmp; + return [ + //Set novalidate attribute, or we will get problems that form can not be submitted as textarea is not focusable + 'novalidate' => 'novalidate', + 'data-mode' => $options['mode'], + //Add our data-controller element to the textarea + 'data-controller' => 'elements--ckeditor', + ]; } public function getParent(): string diff --git a/src/Form/Type/SIUnitType.php b/src/Form/Type/SIUnitType.php index 3f40acc9..c018d5e1 100644 --- a/src/Form/Type/SIUnitType.php +++ b/src/Form/Type/SIUnitType.php @@ -38,11 +38,8 @@ use Traversable; final class SIUnitType extends AbstractType implements DataMapperInterface { - protected SIFormatter $si_formatter; - - public function __construct(SIFormatter $SIFormatter) + public function __construct(protected SIFormatter $si_formatter) { - $this->si_formatter = $SIFormatter; } public function configureOptions(OptionsResolver $resolver): void @@ -91,7 +88,7 @@ final class SIUnitType extends AbstractType implements DataMapperInterface $resolver->setDefaults([ 'min' => 0, 'max' => '', - 'step' => static function (Options $options) { + 'step' => static function (Options $options): int|string { if (true === $options['is_integer']) { return 1; } @@ -138,7 +135,7 @@ final class SIUnitType extends AbstractType implements DataMapperInterface //Check if we need to make this thing small if (isset($options['attr']['class'])) { - $view->vars['sm'] = str_contains($options['attr']['class'], 'form-control-sm'); + $view->vars['sm'] = str_contains((string) $options['attr']['class'], 'form-control-sm'); } $view->vars['unit'] = $options['unit']; diff --git a/src/Form/Type/StructuralEntityType.php b/src/Form/Type/StructuralEntityType.php index 9c489b47..8afb6ce2 100644 --- a/src/Form/Type/StructuralEntityType.php +++ b/src/Form/Type/StructuralEntityType.php @@ -44,21 +44,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class StructuralEntityType extends AbstractType { - protected EntityManagerInterface $em; - protected TranslatorInterface $translator; - protected StructuralEntityChoiceHelper $choice_helper; - - /** - * @var NodesListBuilder - */ - protected NodesListBuilder $builder; - - public function __construct(EntityManagerInterface $em, NodesListBuilder $builder, TranslatorInterface $translator, StructuralEntityChoiceHelper $choice_helper) + public function __construct(protected EntityManagerInterface $em, protected NodesListBuilder $builder, protected TranslatorInterface $translator, protected StructuralEntityChoiceHelper $choice_helper) { - $this->em = $em; - $this->builder = $builder; - $this->translator = $translator; - $this->choice_helper = $choice_helper; } public function buildForm(FormBuilderInterface $builder, array $options): void @@ -81,11 +68,7 @@ class StructuralEntityType extends AbstractType }); $builder->addModelTransformer(new CallbackTransformer( - function ($value) use ($options) { - return $this->modelTransform($value, $options); - }, function ($value) use ($options) { - return $this->modelReverseTransform($value, $options); - })); + fn($value) => $this->modelTransform($value, $options), fn($value) => $this->modelReverseTransform($value, $options))); } public function configureOptions(OptionsResolver $resolver): void @@ -96,25 +79,11 @@ class StructuralEntityType extends AbstractType 'show_fullpath_in_subtext' => true, //When this is enabled, the full path will be shown in subtext 'subentities_of' => null, //Only show entities with the given parent class 'disable_not_selectable' => false, //Disable entries with not selectable property - 'choice_value' => function (?AbstractNamedDBElement $element) { - return $this->choice_helper->generateChoiceValue($element); - }, //Use the element id as option value and for comparing items - 'choice_loader' => function (Options $options) { - return new StructuralEntityChoiceLoader($options, $this->builder, $this->em); - }, - 'choice_label' => function (Options $options) { - return function ($choice, $key, $value) { - return $this->choice_helper->generateChoiceLabel($choice); - }; - }, - 'choice_attr' => function (Options $options) { - return function ($choice, $key, $value) use ($options) { - return $this->choice_helper->generateChoiceAttr($choice, $options); - }; - }, - 'group_by' => function (AbstractNamedDBElement $element) { - return $this->choice_helper->generateGroupBy($element); - }, + 'choice_value' => fn(?AbstractNamedDBElement $element) => $this->choice_helper->generateChoiceValue($element), //Use the element id as option value and for comparing items + 'choice_loader' => fn(Options $options) => new StructuralEntityChoiceLoader($options, $this->builder, $this->em), + 'choice_label' => fn(Options $options) => fn($choice, $key, $value) => $this->choice_helper->generateChoiceLabel($choice), + 'choice_attr' => fn(Options $options) => fn($choice, $key, $value) => $this->choice_helper->generateChoiceAttr($choice, $options), + 'group_by' => fn(AbstractNamedDBElement $element) => $this->choice_helper->generateGroupBy($element), 'choice_translation_domain' => false, //Don't translate the entity names ]); diff --git a/src/Form/Type/ThemeChoiceType.php b/src/Form/Type/ThemeChoiceType.php index 96b47510..c5a45ac4 100644 --- a/src/Form/Type/ThemeChoiceType.php +++ b/src/Form/Type/ThemeChoiceType.php @@ -26,11 +26,8 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class ThemeChoiceType extends AbstractType { - private array $available_themes; - - public function __construct(array $available_themes) + public function __construct(private readonly array $available_themes) { - $this->available_themes = $available_themes; } public function getParent(): string @@ -42,9 +39,7 @@ class ThemeChoiceType extends AbstractType { $resolver->setDefaults([ 'choices' => $this->available_themes, - 'choice_label' => static function ($entity, $key, $value) { - return $value; - }, + 'choice_label' => static fn($entity, $key, $value) => $value, 'choice_translation_domain' => false, 'placeholder' => 'user_settings.theme.placeholder' ]); diff --git a/src/Form/Type/TriStateCheckboxType.php b/src/Form/Type/TriStateCheckboxType.php index 6e8dafc4..df4b0f3a 100644 --- a/src/Form/Type/TriStateCheckboxType.php +++ b/src/Form/Type/TriStateCheckboxType.php @@ -147,17 +147,11 @@ final class TriStateCheckboxType extends AbstractType implements DataTransformer */ public function reverseTransform($value) { - switch ($value) { - case 'true': - return true; - case 'false': - return false; - case 'indeterminate': - case 'null': - case '': - return null; - default: - throw new InvalidArgumentException('Invalid value encountered!: '.$value); - } + return match ($value) { + 'true' => true, + 'false' => false, + 'indeterminate', 'null', '' => null, + default => throw new InvalidArgumentException('Invalid value encountered!: '.$value), + }; } } diff --git a/src/Form/Type/UserSelectType.php b/src/Form/Type/UserSelectType.php index 97d8e26d..a089f66d 100644 --- a/src/Form/Type/UserSelectType.php +++ b/src/Form/Type/UserSelectType.php @@ -32,11 +32,7 @@ class UserSelectType extends AbstractType { $resolver->setDefaults([ 'class' => User::class, - 'choice_label' => function (Options $options) { - return function (User $choice, $key, $value) { - return $choice->getFullName(true); - }; - }, + 'choice_label' => fn(Options $options) => fn(User $choice, $key, $value) => $choice->getFullName(true), ]); } diff --git a/src/Form/UserAdminForm.php b/src/Form/UserAdminForm.php index d42ea9d9..2b690619 100644 --- a/src/Form/UserAdminForm.php +++ b/src/Form/UserAdminForm.php @@ -48,11 +48,8 @@ use Symfony\Component\Validator\Constraints\Length; class UserAdminForm extends AbstractType { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(protected \Symfony\Bundle\SecurityBundle\Security $security) { - $this->security = $security; } public function configureOptions(OptionsResolver $resolver): void diff --git a/src/Form/UserSettingsType.php b/src/Form/UserSettingsType.php index de7017d6..07b4a38a 100644 --- a/src/Form/UserSettingsType.php +++ b/src/Form/UserSettingsType.php @@ -44,13 +44,8 @@ use Symfony\Component\Validator\Constraints\File; class UserSettingsType extends AbstractType { - protected \Symfony\Bundle\SecurityBundle\Security $security; - protected bool $demo_mode; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, bool $demo_mode) + public function __construct(protected \Symfony\Bundle\SecurityBundle\Security $security, protected bool $demo_mode) { - $this->security = $security; - $this->demo_mode = $demo_mode; } public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Helpers/Projects/ProjectBuildRequest.php b/src/Helpers/Projects/ProjectBuildRequest.php index 4cb942d1..d29cf303 100644 --- a/src/Helpers/Projects/ProjectBuildRequest.php +++ b/src/Helpers/Projects/ProjectBuildRequest.php @@ -30,8 +30,7 @@ use App\Validator\Constraints\ProjectSystem\ValidProjectBuildRequest; */ final class ProjectBuildRequest { - private Project $project; - private int $number_of_builds; + private readonly int $number_of_builds; /** * @var array @@ -48,19 +47,17 @@ final class ProjectBuildRequest * @param Project $project The project that should be build * @param int $number_of_builds The number of builds that should be created */ - public function __construct(Project $project, int $number_of_builds) + public function __construct(private readonly Project $project, int $number_of_builds) { if ($number_of_builds < 1) { throw new \InvalidArgumentException('Number of builds must be at least 1!'); } - - $this->project = $project; $this->number_of_builds = $number_of_builds; $this->initializeArray(); //By default, use the first available lot of builds part if there is one. - if($project->getBuildPart() !== null) { + if($project->getBuildPart() instanceof \App\Entity\Parts\Part) { $this->add_build_to_builds_part = true; foreach( $project->getBuildPart()->getPartLots() as $lot) { if (!$lot->isInstockUnknown()) { @@ -89,8 +86,6 @@ final class ProjectBuildRequest /** * Ensure that the projectBOMEntry belongs to the project, otherwise throw an exception. - * @param ProjectBOMEntry $entry - * @return void */ private function ensureBOMEntryValid(ProjectBOMEntry $entry): void { @@ -101,7 +96,6 @@ final class ProjectBuildRequest /** * Returns the partlot where the builds should be added to, or null if it should not be added to any lot. - * @return PartLot|null */ public function getBuildsPartLot(): ?PartLot { @@ -110,7 +104,6 @@ final class ProjectBuildRequest /** * Return if the builds should be added to the builds part of this project as new stock - * @return bool */ public function getAddBuildsToBuildsPart(): bool { @@ -119,7 +112,6 @@ final class ProjectBuildRequest /** * Set if the builds should be added to the builds part of this project as new stock - * @param bool $new_value * @return $this */ public function setAddBuildsToBuildsPart(bool $new_value): self @@ -136,17 +128,16 @@ final class ProjectBuildRequest /** * Set the partlot where the builds should be added to, or null if it should not be added to any lot. * The part lot must belong to the project build part, or an exception is thrown! - * @param PartLot|null $new_part_lot * @return $this */ public function setBuildsPartLot(?PartLot $new_part_lot): self { //Ensure that this new_part_lot belongs to the project - if (($new_part_lot !== null && $new_part_lot->getPart() !== $this->project->getBuildPart()) || $this->project->getBuildPart() === null) { + if (($new_part_lot instanceof \App\Entity\Parts\PartLot && $new_part_lot->getPart() !== $this->project->getBuildPart()) || !$this->project->getBuildPart() instanceof \App\Entity\Parts\Part) { throw new \InvalidArgumentException('The given part lot does not belong to the projects build part!'); } - if ($new_part_lot !== null) { + if ($new_part_lot instanceof \App\Entity\Parts\PartLot) { $this->setAddBuildsToBuildsPart(true); } @@ -157,7 +148,6 @@ final class ProjectBuildRequest /** * Returns the comment where the user can write additional information about the build. - * @return string */ public function getComment(): string { @@ -166,7 +156,6 @@ final class ProjectBuildRequest /** * Sets the comment where the user can write additional information about the build. - * @param string $comment */ public function setComment(string $comment): void { @@ -176,9 +165,8 @@ final class ProjectBuildRequest /** * Returns the amount of parts that should be withdrawn from the given lot for the corresponding BOM entry. * @param PartLot|int $lot The part lot (or the ID of the part lot) for which the withdrawal amount should be got - * @return float */ - public function getLotWithdrawAmount($lot): float + public function getLotWithdrawAmount(\App\Entity\Parts\PartLot|int $lot): float { if ($lot instanceof PartLot) { $lot_id = $lot->getID(); @@ -198,10 +186,9 @@ final class ProjectBuildRequest /** * Sets the amount of parts that should be withdrawn from the given lot for the corresponding BOM entry. * @param PartLot|int $lot The part lot (or the ID of the part lot) for which the withdrawal amount should be got - * @param float $amount * @return $this */ - public function setLotWithdrawAmount($lot, float $amount): self + public function setLotWithdrawAmount(\App\Entity\Parts\PartLot|int $lot, float $amount): self { if ($lot instanceof PartLot) { $lot_id = $lot->getID(); @@ -218,8 +205,6 @@ final class ProjectBuildRequest /** * Returns the sum of all withdraw amounts for the given BOM entry. - * @param ProjectBOMEntry $entry - * @return float */ public function getWithdrawAmountSum(ProjectBOMEntry $entry): float { @@ -239,14 +224,13 @@ final class ProjectBuildRequest /** * Returns the number of available lots to take stock from for the given BOM entry. - * @param ProjectBOMEntry $projectBOMEntry * @return PartLot[]|null Returns null if the entry is a non-part BOM entry */ public function getPartLotsForBOMEntry(ProjectBOMEntry $projectBOMEntry): ?array { $this->ensureBOMEntryValid($projectBOMEntry); - if ($projectBOMEntry->getPart() === null) { + if (!$projectBOMEntry->getPart() instanceof \App\Entity\Parts\Part) { return null; } @@ -256,8 +240,6 @@ final class ProjectBuildRequest /** * Returns the needed amount of parts for the given BOM entry. - * @param ProjectBOMEntry $entry - * @return float */ public function getNeededAmountForBOMEntry(ProjectBOMEntry $entry): float { @@ -281,14 +263,11 @@ final class ProjectBuildRequest */ public function getPartBomEntries(): array { - return $this->project->getBomEntries()->filter(function (ProjectBOMEntry $entry) { - return $entry->isPartBomEntry(); - })->toArray(); + return $this->project->getBomEntries()->filter(fn(ProjectBOMEntry $entry) => $entry->isPartBomEntry())->toArray(); } /** * Returns which project should be build - * @return Project */ public function getProject(): Project { @@ -297,7 +276,6 @@ final class ProjectBuildRequest /** * Returns the number of builds that should be created. - * @return int */ public function getNumberOfBuilds(): int { diff --git a/src/Helpers/Trees/TreeViewNode.php b/src/Helpers/Trees/TreeViewNode.php index 85053239..8fa328a3 100644 --- a/src/Helpers/Trees/TreeViewNode.php +++ b/src/Helpers/Trees/TreeViewNode.php @@ -30,10 +30,6 @@ use JsonSerializable; */ final class TreeViewNode implements JsonSerializable { - private string $text; - private ?string $href; - private ?array $nodes; - private ?TreeViewNodeState $state = null; private ?array $tags = null; @@ -51,12 +47,8 @@ final class TreeViewNode implements JsonSerializable * @param array|null $nodes An array containing other TreeViewNodes. They will be used as children nodes of the * newly created nodes. Set to null, if it should not have children. */ - public function __construct(string $text, ?string $href = null, ?array $nodes = null) + public function __construct(private string $text, private ?string $href = null, private ?array $nodes = null) { - $this->text = $text; - $this->href = $href; - $this->nodes = $nodes; - //$this->state = new TreeViewNodeState(); } @@ -94,8 +86,6 @@ final class TreeViewNode implements JsonSerializable * Sets the node text. * * @param string $text the new node text - * - * @return TreeViewNode */ public function setText(string $text): self { @@ -116,8 +106,6 @@ final class TreeViewNode implements JsonSerializable * Sets the href link. * * @param string|null $href the new href link - * - * @return TreeViewNode */ public function setHref(?string $href): self { @@ -140,8 +128,6 @@ final class TreeViewNode implements JsonSerializable * Sets the children nodes. * * @param array|null $nodes The new children nodes - * - * @return TreeViewNode */ public function setNodes(?array $nodes): self { @@ -165,7 +151,7 @@ final class TreeViewNode implements JsonSerializable public function setDisabled(?bool $disabled): self { //Lazy loading of state, so it does not need to get serialized and transfered, when it is empty. - if (null === $this->state) { + if (!$this->state instanceof \App\Helpers\Trees\TreeViewNodeState) { $this->state = new TreeViewNodeState(); } @@ -177,7 +163,7 @@ final class TreeViewNode implements JsonSerializable public function setSelected(?bool $selected): self { //Lazy loading of state, so it does not need to get serialized and transfered, when it is empty. - if (null === $this->state) { + if (!$this->state instanceof \App\Helpers\Trees\TreeViewNodeState) { $this->state = new TreeViewNodeState(); } @@ -189,7 +175,7 @@ final class TreeViewNode implements JsonSerializable public function setExpanded(?bool $selected = true): self { //Lazy loading of state, so it does not need to get serialized and transfered, when it is empty. - if (null === $this->state) { + if (!$this->state instanceof \App\Helpers\Trees\TreeViewNodeState) { $this->state = new TreeViewNodeState(); } @@ -215,17 +201,11 @@ final class TreeViewNode implements JsonSerializable return $this; } - /** - * @return string|null - */ public function getIcon(): ?string { return $this->icon; } - /** - * @param string|null $icon - */ public function setIcon(?string $icon): self { $this->icon = $icon; @@ -252,7 +232,7 @@ final class TreeViewNode implements JsonSerializable $ret['nodes'] = $this->nodes; } - if (null !== $this->state) { + if ($this->state instanceof \App\Helpers\Trees\TreeViewNodeState) { $ret['state'] = $this->state; } diff --git a/src/Migration/AbstractMultiPlatformMigration.php b/src/Migration/AbstractMultiPlatformMigration.php index 324eeb8d..48fff8bd 100644 --- a/src/Migration/AbstractMultiPlatformMigration.php +++ b/src/Migration/AbstractMultiPlatformMigration.php @@ -30,14 +30,11 @@ use Psr\Log\LoggerInterface; abstract class AbstractMultiPlatformMigration extends AbstractMigration { - public const ADMIN_PW_LENGTH = 10; + final public const ADMIN_PW_LENGTH = 10; protected string $admin_pw = ''; - protected LoggerInterface $logger; - - public function __construct(Connection $connection, LoggerInterface $logger) + public function __construct(Connection $connection, protected LoggerInterface $logger) { - $this->logger = $logger; parent::__construct($connection, $logger); } @@ -45,34 +42,22 @@ abstract class AbstractMultiPlatformMigration extends AbstractMigration { $db_type = $this->getDatabaseType(); - switch ($db_type) { - case 'mysql': - $this->mySQLUp($schema); - break; - case 'sqlite': - $this->sqLiteUp($schema); - break; - default: - $this->abortIf(true, "Database type '$db_type' is not supported!"); - break; - } + match ($db_type) { + 'mysql' => $this->mySQLUp($schema), + 'sqlite' => $this->sqLiteUp($schema), + default => $this->abortIf(true, "Database type '$db_type' is not supported!"), + }; } public function down(Schema $schema): void { $db_type = $this->getDatabaseType(); - switch ($db_type) { - case 'mysql': - $this->mySQLDown($schema); - break; - case 'sqlite': - $this->sqLiteDown($schema); - break; - default: - $this->abortIf(true, "Database type is not supported!"); - break; - } + match ($db_type) { + 'mysql' => $this->mySQLDown($schema), + 'sqlite' => $this->sqLiteDown($schema), + default => $this->abortIf(true, "Database type is not supported!"), + }; } /** @@ -91,7 +76,7 @@ abstract class AbstractMultiPlatformMigration extends AbstractMigration return 0; } return (int) $version; - } catch (Exception $dBALException) { + } catch (Exception) { //when the table was not found, we can proceed, because we have an empty DB! return 0; } @@ -112,7 +97,7 @@ abstract class AbstractMultiPlatformMigration extends AbstractMigration } //As we don't have access to container, just use the default PHP pw hash function - return password_hash($this->admin_pw, PASSWORD_DEFAULT); + return password_hash((string) $this->admin_pw, PASSWORD_DEFAULT); } public function postUp(Schema $schema): void @@ -129,8 +114,6 @@ abstract class AbstractMultiPlatformMigration extends AbstractMigration /** * Checks if a foreign key on a table exists in the database. * This method is only supported for MySQL/MariaDB databases yet! - * @param string $table - * @param string $fk_name * @return bool Returns true, if the foreign key exists * @throws Exception */ diff --git a/src/Repository/AbstractPartsContainingRepository.php b/src/Repository/AbstractPartsContainingRepository.php index b42d075f..0603ce06 100644 --- a/src/Repository/AbstractPartsContainingRepository.php +++ b/src/Repository/AbstractPartsContainingRepository.php @@ -51,7 +51,6 @@ abstract class AbstractPartsContainingRepository extends StructuralDBElementRepo /** * Returns the count of the parts associated with this element and all its children. * Please be aware that this function is pretty slow on large trees! - * @param AbstractPartsContainingDBElement $element * @return int */ public function getPartsCountRecursive(AbstractPartsContainingDBElement $element): int @@ -64,8 +63,6 @@ abstract class AbstractPartsContainingRepository extends StructuralDBElementRepo * This function is used to limit the recursion depth (remaining_depth is decreased on each call). * If the recursion limit is reached (remaining_depth <= 0), a RuntimeException is thrown. * @internal This function is not intended to be called directly, use getPartsCountRecursive() instead. - * @param AbstractPartsContainingDBElement $element - * @param int $remaining_depth * @return int */ protected function getPartsCountRecursiveWithDepthN(AbstractPartsContainingDBElement $element, int $remaining_depth): int diff --git a/src/Repository/DBElementRepository.php b/src/Repository/DBElementRepository.php index 0f7024b6..1f1fe7ee 100644 --- a/src/Repository/DBElementRepository.php +++ b/src/Repository/DBElementRepository.php @@ -57,7 +57,7 @@ class DBElementRepository extends EntityRepository public function changeID(AbstractDBElement $element, int $new_id): void { $qb = $this->createQueryBuilder('element'); - $q = $qb->update(get_class($element), 'element') + $q = $qb->update($element::class, 'element') ->set('element.id', $new_id) ->where('element.id = ?1') ->setParameter(1, $element->getID()) @@ -87,7 +87,7 @@ class DBElementRepository extends EntityRepository protected function setField(AbstractDBElement $element, string $field, int $new_value): void { - $reflection = new ReflectionClass(get_class($element)); + $reflection = new ReflectionClass($element::class); $property = $reflection->getProperty($field); $property->setAccessible(true); $property->setValue($element, $new_value); diff --git a/src/Repository/LabelProfileRepository.php b/src/Repository/LabelProfileRepository.php index 76372f34..f3459af9 100644 --- a/src/Repository/LabelProfileRepository.php +++ b/src/Repository/LabelProfileRepository.php @@ -84,7 +84,7 @@ class LabelProfileRepository extends NamedDBElementRepository $type_children[] = $node; } - if (!empty($type_children)) { + if ($type_children !== []) { //Use default label e.g. 'part_label'. $$ marks that it will be translated in TreeViewGenerator $tmp = new TreeViewNode('$$'.$type.'.label', null, $type_children); @@ -112,7 +112,6 @@ class LabelProfileRepository extends NamedDBElementRepository /** * Returns all LabelProfiles that can be used for parts - * @return array */ public function getPartLabelProfiles(): array { @@ -121,7 +120,6 @@ class LabelProfileRepository extends NamedDBElementRepository /** * Returns all LabelProfiles that can be used for part lots - * @return array */ public function getPartLotsLabelProfiles(): array { @@ -130,7 +128,6 @@ class LabelProfileRepository extends NamedDBElementRepository /** * Returns all LabelProfiles that can be used for storelocations - * @return array */ public function getStorelocationsLabelProfiles(): array { diff --git a/src/Repository/LogEntryRepository.php b/src/Repository/LogEntryRepository.php index 16ada41b..a3456b6c 100644 --- a/src/Repository/LogEntryRepository.php +++ b/src/Repository/LogEntryRepository.php @@ -41,7 +41,7 @@ class LogEntryRepository extends DBElementRepository /** @var AbstractDBElement $element */ $element = $criteria['target']; $criteria['target_id'] = $element->getID(); - $criteria['target_type'] = AbstractLogEntry::targetTypeClassToID(get_class($element)); + $criteria['target_type'] = AbstractLogEntry::targetTypeClassToID($element::class); unset($criteria['target']); } @@ -117,7 +117,7 @@ class LogEntryRepository extends DBElementRepository ->orderBy('log.timestamp', 'DESC'); $qb->setParameters([ - 'target_type' => AbstractLogEntry::targetTypeClassToID(get_class($element)), + 'target_type' => AbstractLogEntry::targetTypeClassToID($element::class), 'target_id' => $element->getID(), 'until' => $until, ]); @@ -143,7 +143,7 @@ class LogEntryRepository extends DBElementRepository ->orderBy('log.timestamp', 'DESC'); $qb->setParameters([ - 'target_type' => AbstractLogEntry::targetTypeClassToID(get_class($element)), + 'target_type' => AbstractLogEntry::targetTypeClassToID($element::class), 'target_id' => $element->getID(), 'until' => $timestamp, ]); @@ -151,13 +151,12 @@ class LogEntryRepository extends DBElementRepository $query = $qb->getQuery(); $count = $query->getSingleScalarResult(); - return !($count > 0); + return $count <= 0; } /** * Gets the last log entries ordered by timestamp. * - * @param string $order * @param null $limit * @param null $offset */ @@ -216,7 +215,7 @@ class LogEntryRepository extends DBElementRepository ->orderBy('log.timestamp', 'DESC'); $qb->setParameters([ - 'target_type' => AbstractLogEntry::targetTypeClassToID(get_class($element)), + 'target_type' => AbstractLogEntry::targetTypeClassToID($element::class), 'target_id' => $element->getID(), ]); diff --git a/src/Repository/ParameterRepository.php b/src/Repository/ParameterRepository.php index 37420306..694d6bb2 100644 --- a/src/Repository/ParameterRepository.php +++ b/src/Repository/ParameterRepository.php @@ -26,8 +26,6 @@ class ParameterRepository extends DBElementRepository * Find parameters using a parameter name * @param string $name The name to search for * @param bool $exact True, if only exact names should match. False, if the name just needs to be contained in the parameter name - * @param int $max_results - * @return array */ public function autocompleteParamName(string $name, bool $exact = false, int $max_results = 50): array { diff --git a/src/Repository/StructuralDBElementRepository.php b/src/Repository/StructuralDBElementRepository.php index 442c5860..dbecfc2f 100644 --- a/src/Repository/StructuralDBElementRepository.php +++ b/src/Repository/StructuralDBElementRepository.php @@ -100,8 +100,6 @@ class StructuralDBElementRepository extends NamedDBElementRepository * Creates a structure of AbstractStructuralDBElements from a path separated by $separator, which splits the various levels. * This function will try to use existing elements, if they are already in the database. If not, they will be created. * An array of the created elements will be returned, with the last element being the deepest element. - * @param string $path - * @param string $separator * @return AbstractStructuralDBElement[] */ public function getNewEntityFromPath(string $path, string $separator = '->'): array @@ -118,7 +116,7 @@ class StructuralDBElementRepository extends NamedDBElementRepository $entity = $this->getNewEntityFromCache($name, $parent); //See if we already have an element with this name and parent in the database - if (!$entity) { + if (!$entity instanceof \App\Entity\Base\AbstractStructuralDBElement) { $entity = $this->findOneBy(['name' => $name, 'parent' => $parent]); } if (null === $entity) { @@ -140,7 +138,7 @@ class StructuralDBElementRepository extends NamedDBElementRepository private function getNewEntityFromCache(string $name, ?AbstractStructuralDBElement $parent): ?AbstractStructuralDBElement { - $key = $parent ? $parent->getFullPath('%->%').'%->%'.$name : $name; + $key = $parent instanceof \App\Entity\Base\AbstractStructuralDBElement ? $parent->getFullPath('%->%').'%->%'.$name : $name; if (isset($this->new_entity_cache[$key])) { return $this->new_entity_cache[$key]; } @@ -157,8 +155,6 @@ class StructuralDBElementRepository extends NamedDBElementRepository * Returns an element of AbstractStructuralDBElements queried from a path separated by $separator, which splits the various levels. * An array of the created elements will be returned, with the last element being the deepest element. * If no element was found, an empty array will be returned. - * @param string $path - * @param string $separator * @return AbstractStructuralDBElement[] */ public function getEntityByPath(string $path, string $separator = '->'): array diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 648f86bd..4cb51b64 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -44,7 +44,7 @@ final class UserRepository extends NamedDBElementRepository implements PasswordU */ public function getAnonymousUser(): ?User { - if (null === $this->anonymous_user) { + if (!$this->anonymous_user instanceof \App\Entity\UserSystem\User) { $this->anonymous_user = $this->findOneBy([ 'id' => User::ID_ANONYMOUS, ]); @@ -78,7 +78,7 @@ final class UserRepository extends NamedDBElementRepository implements PasswordU try { return $qb->getQuery()->getOneOrNullResult(); - } catch (NonUniqueResultException $nonUniqueResultException) { + } catch (NonUniqueResultException) { return null; } } diff --git a/src/Security/EnsureSAMLUserForSAMLLoginChecker.php b/src/Security/EnsureSAMLUserForSAMLLoginChecker.php index 583760c1..0d80630d 100644 --- a/src/Security/EnsureSAMLUserForSAMLLoginChecker.php +++ b/src/Security/EnsureSAMLUserForSAMLLoginChecker.php @@ -29,11 +29,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; class EnsureSAMLUserForSAMLLoginChecker implements EventSubscriberInterface { - private TranslatorInterface $translator; - - public function __construct(TranslatorInterface $translator) + public function __construct(private readonly TranslatorInterface $translator) { - $this->translator = $translator; } public static function getSubscribedEvents(): array @@ -53,10 +50,9 @@ class EnsureSAMLUserForSAMLLoginChecker implements EventSubscriberInterface if ($user instanceof User && !$user->isSAMLUser()) { throw new CustomUserMessageAccountStatusException($this->translator->trans('saml.error.cannot_login_local_user_per_saml', [], 'security')); } - } else { //Ensure that you can not login locally with a SAML user (even if this should not happen, as the password is not set) - if ($user instanceof User && $user->isSamlUser()) { - throw new CustomUserMessageAccountStatusException($this->translator->trans('saml.error.cannot_login_saml_user_locally', [], 'security')); - } + } elseif ($user instanceof User && $user->isSamlUser()) { + //Ensure that you can not login locally with a SAML user (even if this should not happen, as the password is not set) + throw new CustomUserMessageAccountStatusException($this->translator->trans('saml.error.cannot_login_saml_user_locally', [], 'security')); } } } \ No newline at end of file diff --git a/src/Security/SamlUserFactory.php b/src/Security/SamlUserFactory.php index b5434be9..84704987 100644 --- a/src/Security/SamlUserFactory.php +++ b/src/Security/SamlUserFactory.php @@ -31,22 +31,14 @@ use Symfony\Component\Security\Core\User\UserInterface; class SamlUserFactory implements SamlUserFactoryInterface, EventSubscriberInterface { - private EntityManagerInterface $em; - private array $saml_role_mapping; - private bool $update_group_on_login; + private readonly array $saml_role_mapping; - public function __construct(EntityManagerInterface $entityManager, ?array $saml_role_mapping, bool $update_group_on_login) + public function __construct(private readonly EntityManagerInterface $em, ?array $saml_role_mapping, private readonly bool $update_group_on_login) { - $this->em = $entityManager; - if ($saml_role_mapping) { - $this->saml_role_mapping = $saml_role_mapping; - } else { - $this->saml_role_mapping = []; - } - $this->update_group_on_login = $update_group_on_login; + $this->saml_role_mapping = $saml_role_mapping ?: []; } - public const SAML_PASSWORD_PLACEHOLDER = '!!SAML!!'; + final public const SAML_PASSWORD_PLACEHOLDER = '!!SAML!!'; public function createUser($username, array $attributes = []): UserInterface { @@ -70,8 +62,6 @@ class SamlUserFactory implements SamlUserFactoryInterface, EventSubscriberInterf /** * This method is called after a successful authentication. It is used to update the group of the user, * based on the new SAML attributes. - * @param AuthenticationSuccessEvent $event - * @return void */ public function onAuthenticationSuccess(AuthenticationSuccessEvent $event): void { @@ -98,7 +88,6 @@ class SamlUserFactory implements SamlUserFactoryInterface, EventSubscriberInterf /** * Maps the given SAML attributes to a local group. * @param array $attributes The SAML attributes - * @return Group|null */ public function mapSAMLAttributesToLocalGroup(array $attributes): ?Group { @@ -109,7 +98,7 @@ class SamlUserFactory implements SamlUserFactoryInterface, EventSubscriberInterf //Check if we can find a group with the given ID if ($group_id !== null) { $group = $this->em->find(Group::class, $group_id); - if ($group !== null) { + if ($group instanceof \App\Entity\UserSystem\Group) { return $group; } } @@ -127,7 +116,7 @@ class SamlUserFactory implements SamlUserFactoryInterface, EventSubscriberInterf */ public function mapSAMLRolesToLocalGroupID(array $roles, array $map = null): ?int { - $map = $map ?? $this->saml_role_mapping; + $map ??= $this->saml_role_mapping; //Iterate over the mapping (from first to last) and check if we have a match foreach ($map as $saml_role => $group_id) { diff --git a/src/Security/UserChecker.php b/src/Security/UserChecker.php index f64fb50e..55fa3db3 100644 --- a/src/Security/UserChecker.php +++ b/src/Security/UserChecker.php @@ -31,11 +31,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; final class UserChecker implements UserCheckerInterface { - private TranslatorInterface $translator; - - public function __construct(TranslatorInterface $translator) + public function __construct(private readonly TranslatorInterface $translator) { - $this->translator = $translator; } /** diff --git a/src/Security/Voter/AttachmentVoter.php b/src/Security/Voter/AttachmentVoter.php index 95d20733..2f27d232 100644 --- a/src/Security/Voter/AttachmentVoter.php +++ b/src/Security/Voter/AttachmentVoter.php @@ -45,12 +45,9 @@ use function in_array; class AttachmentVoter extends ExtendedVoter { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, \Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, protected \Symfony\Bundle\SecurityBundle\Security $security) { parent::__construct($resolver, $entityManager); - $this->security = $security; } /** @@ -76,7 +73,7 @@ class AttachmentVoter extends ExtendedVoter if (is_object($subject)) { //If the attachment has no element (which should not happen), we deny access, as we can not determine if the user is allowed to access the associated element $target_element = $subject->getElement(); - if ($target_element) { + if ($target_element instanceof \App\Entity\Attachments\AttachmentContainingDBElement) { return $this->security->isGranted($this->mapOperation($attribute), $target_element); } } @@ -112,7 +109,7 @@ class AttachmentVoter extends ExtendedVoter $param = 'parts'; } else { - throw new RuntimeException('Encountered unknown Parameter type: ' . (is_object($subject) ? get_class($subject) : $subject)); + throw new RuntimeException('Encountered unknown Parameter type: ' . (is_object($subject) ? $subject::class : $subject)); } return $this->resolver->inherit($user, $param, $this->mapOperation($attribute)) ?? false; @@ -123,21 +120,12 @@ class AttachmentVoter extends ExtendedVoter private function mapOperation(string $attribute): string { - switch ($attribute) { - //We can view the attachment if we can view the element - case 'read': - case 'view': - return 'read'; - //We can edit/create/delete the attachment if we can edit the element - case 'edit': - case 'create': - case 'delete': - return 'edit'; - case 'show_history': - return 'show_history'; - } - - throw new \RuntimeException('Encountered unknown attribute "'.$attribute.'" in AttachmentVoter!'); + return match ($attribute) { + 'read', 'view' => 'read', + 'edit', 'create', 'delete' => 'edit', + 'show_history' => 'show_history', + default => throw new \RuntimeException('Encountered unknown attribute "'.$attribute.'" in AttachmentVoter!'), + }; } /** diff --git a/src/Security/Voter/ExtendedVoter.php b/src/Security/Voter/ExtendedVoter.php index 825d768c..2474d02b 100644 --- a/src/Security/Voter/ExtendedVoter.php +++ b/src/Security/Voter/ExtendedVoter.php @@ -34,13 +34,8 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter; */ abstract class ExtendedVoter extends Voter { - protected EntityManagerInterface $entityManager; - protected PermissionManager $resolver; - - public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager) + public function __construct(protected PermissionManager $resolver, protected EntityManagerInterface $entityManager) { - $this->resolver = $resolver; - $this->entityManager = $entityManager; } final protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool @@ -57,7 +52,7 @@ abstract class ExtendedVoter extends Voter /** @var UserRepository $repo */ $repo = $this->entityManager->getRepository(User::class); $user = $repo->getAnonymousUser(); - if (null === $user) { + if (!$user instanceof \App\Entity\UserSystem\User) { return false; } } @@ -68,8 +63,6 @@ abstract class ExtendedVoter extends Voter /** * Similar to voteOnAttribute, but checking for the anonymous user is already done. * The current user (or the anonymous user) is passed by $user. - * - * @param string $attribute */ abstract protected function voteOnUser(string $attribute, $subject, User $user): bool; } diff --git a/src/Security/Voter/LogEntryVoter.php b/src/Security/Voter/LogEntryVoter.php index df1033c0..0c9f86da 100644 --- a/src/Security/Voter/LogEntryVoter.php +++ b/src/Security/Voter/LogEntryVoter.php @@ -30,14 +30,11 @@ use Symfony\Component\Security\Core\Security; class LogEntryVoter extends ExtendedVoter { - public const ALLOWED_OPS = ['read', 'show_details', 'delete']; + final public const ALLOWED_OPS = ['read', 'show_details', 'delete']; - private \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, \Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, private readonly \Symfony\Bundle\SecurityBundle\Security $security) { parent::__construct($resolver, $entityManager); - $this->security = $security; } protected function voteOnUser(string $attribute, $subject, User $user): bool diff --git a/src/Security/Voter/OrderdetailVoter.php b/src/Security/Voter/OrderdetailVoter.php index 6b2ff874..f550807d 100644 --- a/src/Security/Voter/OrderdetailVoter.php +++ b/src/Security/Voter/OrderdetailVoter.php @@ -49,12 +49,9 @@ use Symfony\Component\Security\Core\Security; class OrderdetailVoter extends ExtendedVoter { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, \Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, protected \Symfony\Bundle\SecurityBundle\Security $security) { parent::__construct($resolver, $entityManager); - $this->security = $security; } protected const ALLOWED_PERMS = ['read', 'edit', 'create', 'delete', 'show_history', 'revert_element']; @@ -65,27 +62,16 @@ class OrderdetailVoter extends ExtendedVoter throw new \RuntimeException('This voter can only handle Orderdetail objects!'); } - switch ($attribute) { - case 'read': - $operation = 'read'; - break; - case 'edit': //As long as we can edit, we can also edit orderdetails - case 'create': - case 'delete': - $operation = 'edit'; - break; - case 'show_history': - $operation = 'show_history'; - break; - case 'revert_element': - $operation = 'revert_element'; - break; - default: - throw new \RuntimeException('Encountered unknown operation "'.$attribute.'"!'); - } + $operation = match ($attribute) { + 'read' => 'read', + 'edit', 'create', 'delete' => 'edit', + 'show_history' => 'show_history', + 'revert_element' => 'revert_element', + default => throw new \RuntimeException('Encountered unknown operation "'.$attribute.'"!'), + }; //If we have no part associated use the generic part permission - if (is_string($subject) || $subject->getPart() === null) { + if (is_string($subject) || !$subject->getPart() instanceof \App\Entity\Parts\Part) { return $this->resolver->inherit($user, 'parts', $operation) ?? false; } diff --git a/src/Security/Voter/ParameterVoter.php b/src/Security/Voter/ParameterVoter.php index 6e38c718..edc096a2 100644 --- a/src/Security/Voter/ParameterVoter.php +++ b/src/Security/Voter/ParameterVoter.php @@ -41,11 +41,8 @@ use Symfony\Component\Security\Core\Security; class ParameterVoter extends ExtendedVoter { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, \Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, protected \Symfony\Bundle\SecurityBundle\Security $security) { - $this->security = $security; parent::__construct($resolver, $entityManager); } @@ -60,31 +57,14 @@ class ParameterVoter extends ExtendedVoter if (is_object($subject)) { //If the attachment has no element (which should not happen), we deny access, as we can not determine if the user is allowed to access the associated element $target_element = $subject->getElement(); - if ($target_element !== null) { - //Depending on the operation delegate either to the attachments element or to the attachment permission - - - switch ($attribute) { - //We can view the attachment if we can view the element - case 'read': - case 'view': - $operation = 'read'; - break; - //We can edit/create/delete the attachment if we can edit the element - case 'edit': - case 'create': - case 'delete': - $operation = 'edit'; - break; - case 'show_history': - $operation = 'show_history'; - break; - case 'revert_element': - $operation = 'revert_element'; - break; - default: - throw new RuntimeException('Unknown operation: '.$attribute); - } + if ($target_element instanceof \App\Entity\Base\AbstractDBElement) { + $operation = match ($attribute) { + 'read', 'view' => 'read', + 'edit', 'create', 'delete' => 'edit', + 'show_history' => 'show_history', + 'revert_element' => 'revert_element', + default => throw new RuntimeException('Unknown operation: '.$attribute), + }; return $this->security->isGranted($operation, $target_element); } @@ -118,7 +98,7 @@ class ParameterVoter extends ExtendedVoter $param = 'parts'; } else { - throw new RuntimeException('Encountered unknown Parameter type: ' . (is_object($subject) ? get_class($subject) : $subject)); + throw new RuntimeException('Encountered unknown Parameter type: ' . (is_object($subject) ? $subject::class : $subject)); } return $this->resolver->inherit($user, $param, $attribute) ?? false; diff --git a/src/Security/Voter/PartLotVoter.php b/src/Security/Voter/PartLotVoter.php index 1d495c9a..8293e234 100644 --- a/src/Security/Voter/PartLotVoter.php +++ b/src/Security/Voter/PartLotVoter.php @@ -49,12 +49,9 @@ use Symfony\Component\Security\Core\Security; class PartLotVoter extends ExtendedVoter { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, \Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, protected \Symfony\Bundle\SecurityBundle\Security $security) { parent::__construct($resolver, $entityManager); - $this->security = $security; } protected const ALLOWED_PERMS = ['read', 'edit', 'create', 'delete', 'show_history', 'revert_element', 'withdraw', 'add', 'move']; @@ -78,27 +75,16 @@ class PartLotVoter extends ExtendedVoter return $base_permission && $lot_permission; } - switch ($attribute) { - case 'read': - $operation = 'read'; - break; - case 'edit': //As long as we can edit, we can also edit orderdetails - case 'create': - case 'delete': - $operation = 'edit'; - break; - case 'show_history': - $operation = 'show_history'; - break; - case 'revert_element': - $operation = 'revert_element'; - break; - default: - throw new \RuntimeException('Encountered unknown operation "'.$attribute.'"!'); - } + $operation = match ($attribute) { + 'read' => 'read', + 'edit', 'create', 'delete' => 'edit', + 'show_history' => 'show_history', + 'revert_element' => 'revert_element', + default => throw new \RuntimeException('Encountered unknown operation "'.$attribute.'"!'), + }; //If we have no part associated use the generic part permission - if (is_string($subject) || $subject->getPart() === null) { + if (is_string($subject) || !$subject->getPart() instanceof \App\Entity\Parts\Part) { return $this->resolver->inherit($user, 'parts', $operation) ?? false; } diff --git a/src/Security/Voter/PartVoter.php b/src/Security/Voter/PartVoter.php index fb1e3a38..878fc6a4 100644 --- a/src/Security/Voter/PartVoter.php +++ b/src/Security/Voter/PartVoter.php @@ -32,7 +32,7 @@ use App\Entity\UserSystem\User; */ class PartVoter extends ExtendedVoter { - public const READ = 'read'; + final public const READ = 'read'; protected function supports($attribute, $subject): bool { diff --git a/src/Security/Voter/PricedetailVoter.php b/src/Security/Voter/PricedetailVoter.php index 8cae7452..98898ecf 100644 --- a/src/Security/Voter/PricedetailVoter.php +++ b/src/Security/Voter/PricedetailVoter.php @@ -49,12 +49,9 @@ use Symfony\Component\Security\Core\Security; class PricedetailVoter extends ExtendedVoter { - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, \Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, protected \Symfony\Bundle\SecurityBundle\Security $security) { parent::__construct($resolver, $entityManager); - $this->security = $security; } protected const ALLOWED_PERMS = ['read', 'edit', 'create', 'delete', 'show_history', 'revert_element']; @@ -65,27 +62,16 @@ class PricedetailVoter extends ExtendedVoter throw new \RuntimeException('This voter can only handle Pricedetails objects!'); } - switch ($attribute) { - case 'read': - $operation = 'read'; - break; - case 'edit': //As long as we can edit, we can also edit orderdetails - case 'create': - case 'delete': - $operation = 'edit'; - break; - case 'show_history': - $operation = 'show_history'; - break; - case 'revert_element': - $operation = 'revert_element'; - break; - default: - throw new \RuntimeException('Encountered unknown operation "'.$attribute.'"!'); - } + $operation = match ($attribute) { + 'read' => 'read', + 'edit', 'create', 'delete' => 'edit', + 'show_history' => 'show_history', + 'revert_element' => 'revert_element', + default => throw new \RuntimeException('Encountered unknown operation "'.$attribute.'"!'), + }; //If we have no part associated use the generic part permission - if (is_string($subject) || $subject->getOrderdetail() === null || $subject->getOrderdetail()->getPart() === null) { + if (is_string($subject) || !$subject->getOrderdetail() instanceof \App\Entity\PriceInformations\Orderdetail || !$subject->getOrderdetail()->getPart() instanceof \App\Entity\Parts\Part) { return $this->resolver->inherit($user, 'parts', $operation) ?? false; } diff --git a/src/Security/Voter/StructureVoter.php b/src/Security/Voter/StructureVoter.php index a37083ea..79cef811 100644 --- a/src/Security/Voter/StructureVoter.php +++ b/src/Security/Voter/StructureVoter.php @@ -77,11 +77,7 @@ class StructureVoter extends ExtendedVoter */ protected function instanceToPermissionName($subject): ?string { - if (!is_string($subject)) { - $class_name = get_class($subject); - } else { - $class_name = $subject; - } + $class_name = is_string($subject) ? $subject : $subject::class; //If it is existing in index, we can skip the loop if (isset(static::OBJ_PERM_MAP[$class_name])) { diff --git a/src/Serializer/PartNormalizer.php b/src/Serializer/PartNormalizer.php index ce910d8c..740d9861 100644 --- a/src/Serializer/PartNormalizer.php +++ b/src/Serializer/PartNormalizer.php @@ -44,13 +44,8 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface, Cach 'storage_location' => 'storelocation', ]; - private ObjectNormalizer $normalizer; - private StructuralElementFromNameDenormalizer $locationDenormalizer; - - public function __construct(ObjectNormalizer $normalizer, StructuralElementFromNameDenormalizer $locationDenormalizer) + public function __construct(private readonly ObjectNormalizer $normalizer, private readonly StructuralElementFromNameDenormalizer $locationDenormalizer) { - $this->normalizer = $normalizer; - $this->locationDenormalizer = $locationDenormalizer; } public function supportsNormalization($data, string $format = null): bool @@ -120,12 +115,12 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface, Cach throw new \InvalidArgumentException('This normalizer only supports Part objects!'); } - if ((isset($data['instock']) && trim($data['instock']) !== "") || (isset($data['storelocation']) && trim($data['storelocation']) !== "")) { + if ((isset($data['instock']) && trim((string) $data['instock']) !== "") || (isset($data['storelocation']) && trim((string) $data['storelocation']) !== "")) { $partLot = new PartLot(); if (isset($data['instock']) && $data['instock'] !== "") { //Replace comma with dot - $instock = (float) str_replace(',', '.', $data['instock']); + $instock = (float) str_replace(',', '.', (string) $data['instock']); $partLot->setAmount($instock); } else { @@ -157,7 +152,7 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface, Cach $pricedetail = new Pricedetail(); $pricedetail->setMinDiscountQuantity(1); $pricedetail->setPriceRelatedQuantity(1); - $price = BigDecimal::of(str_replace(',', '.', $data['price'])); + $price = BigDecimal::of(str_replace(',', '.', (string) $data['price'])); $pricedetail->setPrice($price); $orderdetail->addPricedetail($pricedetail); diff --git a/src/Serializer/StructuralElementDenormalizer.php b/src/Serializer/StructuralElementDenormalizer.php index 2d7fd3f3..e7b90744 100644 --- a/src/Serializer/StructuralElementDenormalizer.php +++ b/src/Serializer/StructuralElementDenormalizer.php @@ -31,15 +31,10 @@ use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; class StructuralElementDenormalizer implements \Symfony\Component\Serializer\Normalizer\DenormalizerInterface, CacheableSupportsMethodInterface { - private DenormalizerInterface $normalizer; - private EntityManagerInterface $entityManager; - private array $object_cache = []; - public function __construct(ObjectNormalizer $normalizer, EntityManagerInterface $entityManager) + public function __construct(private readonly ObjectNormalizer $normalizer, private readonly EntityManagerInterface $entityManager) { - $this->normalizer = $normalizer; - $this->entityManager = $entityManager; } public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool @@ -61,7 +56,7 @@ class StructuralElementDenormalizer implements \Symfony\Component\Serializer\Nor $path = $deserialized_entity->getFullPath(AbstractStructuralDBElement::PATH_DELIMITER_ARROW); $db_elements = $repo->getEntityByPath($path, AbstractStructuralDBElement::PATH_DELIMITER_ARROW); - if ($db_elements) { + if ($db_elements !== []) { //We already have the entity in the database, so we can return it return end($db_elements); } diff --git a/src/Serializer/StructuralElementFromNameDenormalizer.php b/src/Serializer/StructuralElementFromNameDenormalizer.php index 8516c951..9de31048 100644 --- a/src/Serializer/StructuralElementFromNameDenormalizer.php +++ b/src/Serializer/StructuralElementFromNameDenormalizer.php @@ -28,11 +28,8 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; class StructuralElementFromNameDenormalizer implements DenormalizerInterface, CacheableSupportsMethodInterface { - private EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $em) + public function __construct(private readonly EntityManagerInterface $em) { - $this->em = $em; } public function supportsDenormalization($data, string $type, string $format = null): bool @@ -54,14 +51,14 @@ class StructuralElementFromNameDenormalizer implements DenormalizerInterface, Ca foreach ($elements as $element) { $this->em->persist($element); } - if (empty($elements)) { + if ($elements === []) { return null; } return end($elements); } $elements = $repo->getEntityByPath($data, $path_delimiter); - if (empty($elements)) { + if ($elements === []) { return null; } return end($elements); diff --git a/src/Serializer/StructuralElementNormalizer.php b/src/Serializer/StructuralElementNormalizer.php index 060fecaf..fb6a42b1 100644 --- a/src/Serializer/StructuralElementNormalizer.php +++ b/src/Serializer/StructuralElementNormalizer.php @@ -27,11 +27,8 @@ use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; class StructuralElementNormalizer implements NormalizerInterface, CacheableSupportsMethodInterface { - private NormalizerInterface $normalizer; - - public function __construct(ObjectNormalizer $normalizer) + public function __construct(private readonly ObjectNormalizer $normalizer) { - $this->normalizer = $normalizer; } public function supportsNormalization($data, string $format = null): bool diff --git a/src/Services/Attachments/AttachmentManager.php b/src/Services/Attachments/AttachmentManager.php index 81b1334f..3057b5b1 100644 --- a/src/Services/Attachments/AttachmentManager.php +++ b/src/Services/Attachments/AttachmentManager.php @@ -35,11 +35,8 @@ use function strlen; */ class AttachmentManager { - protected AttachmentPathResolver $pathResolver; - - public function __construct(AttachmentPathResolver $pathResolver) + public function __construct(protected AttachmentPathResolver $pathResolver) { - $this->pathResolver = $pathResolver; } /** diff --git a/src/Services/Attachments/AttachmentPathResolver.php b/src/Services/Attachments/AttachmentPathResolver.php index 635d0bc6..116072b5 100644 --- a/src/Services/Attachments/AttachmentPathResolver.php +++ b/src/Services/Attachments/AttachmentPathResolver.php @@ -32,14 +32,12 @@ use Symfony\Component\Filesystem\Filesystem; */ class AttachmentPathResolver { - protected string $project_dir; - protected ?string $media_path; protected ?string $footprints_path; protected ?string $models_path; protected ?string $secure_path; - protected array $placeholders; + protected array $placeholders = ['%MEDIA%', '%BASE%/data/media', '%FOOTPRINTS%', '%FOOTPRINTS_3D%', '%SECURE%']; protected array $pathes; protected array $placeholders_regex; protected array $pathes_regex; @@ -53,18 +51,13 @@ class AttachmentPathResolver * Set to null if this ressource should be disabled. * @param string|null $models_path set to null if this ressource should be disabled */ - public function __construct(string $project_dir, string $media_path, string $secure_path, ?string $footprints_path, ?string $models_path) + public function __construct(protected string $project_dir, string $media_path, string $secure_path, ?string $footprints_path, ?string $models_path) { - $this->project_dir = $project_dir; - //Determine the path for our ressources $this->media_path = $this->parameterToAbsolutePath($media_path); $this->footprints_path = $this->parameterToAbsolutePath($footprints_path); $this->models_path = $this->parameterToAbsolutePath($models_path); $this->secure_path = $this->parameterToAbsolutePath($secure_path); - - //Here we define the valid placeholders and their replacement values - $this->placeholders = ['%MEDIA%', '%BASE%/data/media', '%FOOTPRINTS%', '%FOOTPRINTS_3D%', '%SECURE%']; $this->pathes = [$this->media_path, $this->media_path, $this->footprints_path, $this->models_path, $this->secure_path]; //Remove all disabled placeholders @@ -248,7 +241,7 @@ class AttachmentPathResolver $ret = []; foreach ($array as $item) { - $item = str_replace(['\\'], ['/'], $item); + $item = str_replace(['\\'], ['/'], (string) $item); $ret[] = '/'.preg_quote($item, '/').'/'; } diff --git a/src/Services/Attachments/AttachmentReverseSearch.php b/src/Services/Attachments/AttachmentReverseSearch.php index efcbb5bd..5f4f86de 100644 --- a/src/Services/Attachments/AttachmentReverseSearch.php +++ b/src/Services/Attachments/AttachmentReverseSearch.php @@ -34,18 +34,8 @@ use Symfony\Component\Filesystem\Filesystem; */ class AttachmentReverseSearch { - protected EntityManagerInterface $em; - protected AttachmentPathResolver $pathResolver; - protected CacheManager $cacheManager; - protected AttachmentURLGenerator $attachmentURLGenerator; - - public function __construct(EntityManagerInterface $em, AttachmentPathResolver $pathResolver, - CacheManager $cacheManager, AttachmentURLGenerator $attachmentURLGenerator) + public function __construct(protected EntityManagerInterface $em, protected AttachmentPathResolver $pathResolver, protected CacheManager $cacheManager, protected AttachmentURLGenerator $attachmentURLGenerator) { - $this->em = $em; - $this->pathResolver = $pathResolver; - $this->cacheManager = $cacheManager; - $this->attachmentURLGenerator = $attachmentURLGenerator; } /** diff --git a/src/Services/Attachments/AttachmentSubmitHandler.php b/src/Services/Attachments/AttachmentSubmitHandler.php index 4dca3c4c..c85470d8 100644 --- a/src/Services/Attachments/AttachmentSubmitHandler.php +++ b/src/Services/Attachments/AttachmentSubmitHandler.php @@ -55,16 +55,7 @@ use Symfony\Contracts\HttpClient\HttpClientInterface; */ class AttachmentSubmitHandler { - protected AttachmentPathResolver $pathResolver; protected array $folder_mapping; - protected bool $allow_attachments_downloads; - protected HttpClientInterface $httpClient; - protected MimeTypesInterface $mimeTypes; - protected FileTypeFilterTools $filterTools; - /** - * @var string The user configured maximum upload size. This is a string like "10M" or "1G" and will be converted to - */ - protected string $max_upload_size; private ?int $max_upload_size_bytes = null; @@ -72,18 +63,13 @@ class AttachmentSubmitHandler 'asp', 'cgi', 'py', 'pl', 'exe', 'aspx', 'js', 'mjs', 'jsp', 'css', 'jar', 'html', 'htm', 'shtm', 'shtml', 'htaccess', 'htpasswd', '']; - public function __construct(AttachmentPathResolver $pathResolver, bool $allow_attachments_downloads, - HttpClientInterface $httpClient, MimeTypesInterface $mimeTypes, - FileTypeFilterTools $filterTools, string $max_upload_size) + public function __construct(protected AttachmentPathResolver $pathResolver, protected bool $allow_attachments_downloads, + protected HttpClientInterface $httpClient, protected MimeTypesInterface $mimeTypes, + protected FileTypeFilterTools $filterTools, /** + * @var string The user configured maximum upload size. This is a string like "10M" or "1G" and will be converted to + */ + protected string $max_upload_size) { - $this->pathResolver = $pathResolver; - $this->allow_attachments_downloads = $allow_attachments_downloads; - $this->httpClient = $httpClient; - $this->mimeTypes = $mimeTypes; - $this->max_upload_size = $max_upload_size; - - $this->filterTools = $filterTools; - //The mapping used to determine which folder will be used for an attachment type $this->folder_mapping = [ PartAttachment::class => 'part', @@ -155,25 +141,21 @@ class AttachmentSubmitHandler */ public function generateAttachmentPath(Attachment $attachment, bool $secure_upload = false): string { - if ($secure_upload) { - $base_path = $this->pathResolver->getSecurePath(); - } else { - $base_path = $this->pathResolver->getMediaPath(); - } + $base_path = $secure_upload ? $this->pathResolver->getSecurePath() : $this->pathResolver->getMediaPath(); //Ensure the given attachment class is known to mapping - if (!isset($this->folder_mapping[get_class($attachment)])) { - throw new InvalidArgumentException('The given attachment class is not known! The passed class was: '.get_class($attachment)); + if (!isset($this->folder_mapping[$attachment::class])) { + throw new InvalidArgumentException('The given attachment class is not known! The passed class was: '.$attachment::class); } //Ensure the attachment has an assigned element - if (null === $attachment->getElement()) { + if (!$attachment->getElement() instanceof \App\Entity\Attachments\AttachmentContainingDBElement) { throw new InvalidArgumentException('The given attachment is not assigned to an element! An element is needed to generate a path!'); } //Build path return $base_path.DIRECTORY_SEPARATOR //Base path - .$this->folder_mapping[get_class($attachment)].DIRECTORY_SEPARATOR.$attachment->getElement()->getID(); + .$this->folder_mapping[$attachment::class].DIRECTORY_SEPARATOR.$attachment->getElement()->getID(); } /** @@ -194,7 +176,7 @@ class AttachmentSubmitHandler $options = $resolver->resolve($options); //When a file is given then upload it, otherwise check if we need to download the URL - if ($file) { + if ($file instanceof \Symfony\Component\HttpFoundation\File\UploadedFile) { $this->upload($attachment, $file, $options); } elseif ($options['download_url'] && $attachment->isExternal()) { $this->downloadURL($attachment, $options); @@ -210,7 +192,7 @@ class AttachmentSubmitHandler //this is only possible if the attachment is new (not yet persisted to DB) if ($options['become_preview_if_empty'] && null === $attachment->getID() && $attachment->isPicture()) { $element = $attachment->getElement(); - if ($element instanceof AttachmentContainingDBElement && null === $element->getMasterPictureAttachment()) { + if ($element instanceof AttachmentContainingDBElement && !$element->getMasterPictureAttachment() instanceof \App\Entity\Attachments\Attachment) { $element->setMasterPictureAttachment($attachment); } } @@ -220,8 +202,6 @@ class AttachmentSubmitHandler /** * Rename attachments with an unsafe extension (meaning files which would be run by a to a safe one). - * @param Attachment $attachment - * @return Attachment */ protected function renameBlacklistedExtensions(Attachment $attachment): Attachment { @@ -391,7 +371,7 @@ class AttachmentSubmitHandler $new_path = $this->pathResolver->realPathToPlaceholder($new_path); //Save the path to the attachment $attachment->setPath($new_path); - } catch (TransportExceptionInterface $transportExceptionInterface) { + } catch (TransportExceptionInterface) { throw new AttachmentDownloadException('Transport error!'); } @@ -428,8 +408,6 @@ class AttachmentSubmitHandler /** * Parses the given file size string and returns the size in bytes. * Taken from https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Validator/Constraints/File.php - * @param string $maxSize - * @return int */ private function parseFileSizeString(string $maxSize): int { diff --git a/src/Services/Attachments/AttachmentURLGenerator.php b/src/Services/Attachments/AttachmentURLGenerator.php index cbeab36a..7108cf12 100644 --- a/src/Services/Attachments/AttachmentURLGenerator.php +++ b/src/Services/Attachments/AttachmentURLGenerator.php @@ -32,26 +32,12 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class AttachmentURLGenerator { - protected Packages $assets; protected string $public_path; - protected AttachmentPathResolver $pathResolver; - protected UrlGeneratorInterface $urlGenerator; - protected AttachmentManager $attachmentHelper; - protected CacheManager $thumbnailManager; - protected LoggerInterface $logger; - - public function __construct(Packages $assets, AttachmentPathResolver $pathResolver, - UrlGeneratorInterface $urlGenerator, AttachmentManager $attachmentHelper, - CacheManager $thumbnailManager, LoggerInterface $logger) + public function __construct(protected Packages $assets, protected AttachmentPathResolver $pathResolver, + protected UrlGeneratorInterface $urlGenerator, protected AttachmentManager $attachmentHelper, + protected CacheManager $thumbnailManager, protected LoggerInterface $logger) { - $this->assets = $assets; - $this->pathResolver = $pathResolver; - $this->urlGenerator = $urlGenerator; - $this->attachmentHelper = $attachmentHelper; - $this->thumbnailManager = $thumbnailManager; - $this->logger = $logger; - //Determine a normalized path to the public folder (assets are relative to this folder) $this->public_path = $this->pathResolver->parameterToAbsolutePath('public'); } diff --git a/src/Services/Attachments/BuiltinAttachmentsFinder.php b/src/Services/Attachments/BuiltinAttachmentsFinder.php index 7c3c8f4b..f3f8740f 100644 --- a/src/Services/Attachments/BuiltinAttachmentsFinder.php +++ b/src/Services/Attachments/BuiltinAttachmentsFinder.php @@ -33,13 +33,8 @@ use Symfony\Contracts\Cache\CacheInterface; */ class BuiltinAttachmentsFinder { - protected AttachmentPathResolver $pathResolver; - protected CacheInterface $cache; - - public function __construct(CacheInterface $cache, AttachmentPathResolver $pathResolver) + public function __construct(protected CacheInterface $cache, protected AttachmentPathResolver $pathResolver) { - $this->pathResolver = $pathResolver; - $this->cache = $cache; } /** @@ -49,7 +44,6 @@ class BuiltinAttachmentsFinder * '%FOOTPRINTS%/path/to/folder/file1.png', * '%FOOTPRINTS%/path/to/folder/file2.png', * ] - * @return array */ public function getListOfFootprintsGroupedByFolder(): array { @@ -109,7 +103,7 @@ class BuiltinAttachmentsFinder return $results; }); - } catch (InvalidArgumentException $invalidArgumentException) { + } catch (InvalidArgumentException) { return []; } } diff --git a/src/Services/Attachments/FileTypeFilterTools.php b/src/Services/Attachments/FileTypeFilterTools.php index 1b06655a..948b429b 100644 --- a/src/Services/Attachments/FileTypeFilterTools.php +++ b/src/Services/Attachments/FileTypeFilterTools.php @@ -43,13 +43,8 @@ class FileTypeFilterTools protected const AUDIO_EXTS = ['mp3', 'flac', 'ogg', 'oga', 'wav', 'm4a', 'opus']; protected const ALLOWED_MIME_PLACEHOLDERS = ['image/*', 'audio/*', 'video/*']; - protected MimeTypesInterface $mimeTypes; - protected CacheInterface $cache; - - public function __construct(MimeTypesInterface $mimeTypes, CacheInterface $cache) + public function __construct(protected MimeTypesInterface $mimeTypes, protected CacheInterface $cache) { - $this->mimeTypes = $mimeTypes; - $this->cache = $cache; } /** diff --git a/src/Services/Attachments/PartPreviewGenerator.php b/src/Services/Attachments/PartPreviewGenerator.php index 39d1c65c..5917e88b 100644 --- a/src/Services/Attachments/PartPreviewGenerator.php +++ b/src/Services/Attachments/PartPreviewGenerator.php @@ -27,11 +27,8 @@ use App\Entity\Parts\Part; class PartPreviewGenerator { - protected AttachmentManager $attachmentHelper; - - public function __construct(AttachmentManager $attachmentHelper) + public function __construct(protected AttachmentManager $attachmentHelper) { - $this->attachmentHelper = $attachmentHelper; } /** @@ -55,21 +52,21 @@ class PartPreviewGenerator $list[] = $attachment; } - if (null !== $part->getFootprint()) { + if ($part->getFootprint() instanceof \App\Entity\Parts\Footprint) { $attachment = $part->getFootprint()->getMasterPictureAttachment(); if ($this->isAttachmentValidPicture($attachment)) { $list[] = $attachment; } } - if (null !== $part->getBuiltProject()) { + if ($part->getBuiltProject() instanceof \App\Entity\ProjectSystem\Project) { $attachment = $part->getBuiltProject()->getMasterPictureAttachment(); if ($this->isAttachmentValidPicture($attachment)) { $list[] = $attachment; } } - if (null !== $part->getCategory()) { + if ($part->getCategory() instanceof \App\Entity\Parts\Category) { $attachment = $part->getCategory()->getMasterPictureAttachment(); if ($this->isAttachmentValidPicture($attachment)) { $list[] = $attachment; @@ -77,7 +74,7 @@ class PartPreviewGenerator } foreach ($part->getPartLots() as $lot) { - if (null !== $lot->getStorageLocation()) { + if ($lot->getStorageLocation() instanceof \App\Entity\Parts\Storelocation) { $attachment = $lot->getStorageLocation()->getMasterPictureAttachment(); if ($this->isAttachmentValidPicture($attachment)) { $list[] = $attachment; @@ -85,14 +82,14 @@ class PartPreviewGenerator } } - if (null !== $part->getPartUnit()) { + if ($part->getPartUnit() instanceof \App\Entity\Parts\MeasurementUnit) { $attachment = $part->getPartUnit()->getMasterPictureAttachment(); if ($this->isAttachmentValidPicture($attachment)) { $list[] = $attachment; } } - if (null !== $part->getManufacturer()) { + if ($part->getManufacturer() instanceof \App\Entity\Parts\Manufacturer) { $attachment = $part->getManufacturer()->getMasterPictureAttachment(); if ($this->isAttachmentValidPicture($attachment)) { $list[] = $attachment; @@ -117,7 +114,7 @@ class PartPreviewGenerator } //Otherwise check if the part has a footprint with a valid master attachment - if (null !== $part->getFootprint()) { + if ($part->getFootprint() instanceof \App\Entity\Parts\Footprint) { $attachment = $part->getFootprint()->getMasterPictureAttachment(); if ($this->isAttachmentValidPicture($attachment)) { return $attachment; @@ -125,7 +122,7 @@ class PartPreviewGenerator } //With lowest priority use the master attachment of the project this part represents (when existing) - if (null !== $part->getBuiltProject()) { + if ($part->getBuiltProject() instanceof \App\Entity\ProjectSystem\Project) { $attachment = $part->getBuiltProject()->getMasterPictureAttachment(); if ($this->isAttachmentValidPicture($attachment)) { return $attachment; @@ -145,7 +142,7 @@ class PartPreviewGenerator */ protected function isAttachmentValidPicture(?Attachment $attachment): bool { - return null !== $attachment + return $attachment instanceof \App\Entity\Attachments\Attachment && $attachment->isPicture() && $this->attachmentHelper->isFileExisting($attachment); } diff --git a/src/Services/CustomEnvVarProcessor.php b/src/Services/CustomEnvVarProcessor.php index 8969b765..f269cc7d 100644 --- a/src/Services/CustomEnvVarProcessor.php +++ b/src/Services/CustomEnvVarProcessor.php @@ -35,7 +35,7 @@ final class CustomEnvVarProcessor implements EnvVarProcessorInterface $env = $getEnv($name); return !empty($env) && 'null://null' !== $env; - } catch (EnvNotFoundException $envNotFoundException) { + } catch (EnvNotFoundException) { return false; } } diff --git a/src/Services/ElementTypeNameGenerator.php b/src/Services/ElementTypeNameGenerator.php index cbe8344f..b31ecf07 100644 --- a/src/Services/ElementTypeNameGenerator.php +++ b/src/Services/ElementTypeNameGenerator.php @@ -50,15 +50,10 @@ use Symfony\Contracts\Translation\TranslatorInterface; class ElementTypeNameGenerator { - protected TranslatorInterface $translator; - private EntityURLGenerator $entityURLGenerator; protected array $mapping; - public function __construct(TranslatorInterface $translator, EntityURLGenerator $entityURLGenerator) + public function __construct(protected TranslatorInterface $translator, private readonly EntityURLGenerator $entityURLGenerator) { - $this->translator = $translator; - $this->entityURLGenerator = $entityURLGenerator; - //Child classes has to become before parent classes $this->mapping = [ Attachment::class => $this->translator->trans('attachment.label'), @@ -97,7 +92,7 @@ class ElementTypeNameGenerator */ public function getLocalizedTypeLabel($entity): string { - $class = is_string($entity) ? $entity : get_class($entity); + $class = is_string($entity) ? $entity : $entity::class; //Check if we have a direct array entry for our entity class, then we can use it if (isset($this->mapping[$class])) { @@ -112,7 +107,7 @@ class ElementTypeNameGenerator } //When nothing was found throw an exception - throw new EntityNotSupportedException(sprintf('No localized label for the element with type %s was found!', is_object($entity) ? get_class($entity) : (string) $entity)); + throw new EntityNotSupportedException(sprintf('No localized label for the element with type %s was found!', is_object($entity) ? $entity::class : (string) $entity)); } /** @@ -143,7 +138,6 @@ class ElementTypeNameGenerator * "Type: ID" (on elements without a name). If possible the value is given as a link to the element. * @param AbstractDBElement $entity The entity for which the label should be generated * @param bool $include_associated If set to true, the associated entity (like the part belonging to a part lot) is included in the label to give further information - * @return string */ public function formatLabelHTMLForEntity(AbstractDBElement $entity, bool $include_associated = false): string { @@ -155,7 +149,7 @@ class ElementTypeNameGenerator $this->entityURLGenerator->infoURL($entity), $this->getTypeNameCombination($entity, true) ); - } catch (EntityNotSupportedException $exception) { + } catch (EntityNotSupportedException) { $tmp = $this->getTypeNameCombination($entity, true); } } else { //Target does not have a name @@ -168,17 +162,17 @@ class ElementTypeNameGenerator //Add a hint to the associated element if possible if ($include_associated) { - if ($entity instanceof Attachment && null !== $entity->getElement()) { + if ($entity instanceof Attachment && $entity->getElement() instanceof \App\Entity\Attachments\AttachmentContainingDBElement) { $on = $entity->getElement(); - } elseif ($entity instanceof AbstractParameter && null !== $entity->getElement()) { + } elseif ($entity instanceof AbstractParameter && $entity->getElement() instanceof \App\Entity\Base\AbstractDBElement) { $on = $entity->getElement(); - } elseif ($entity instanceof PartLot && null !== $entity->getPart()) { + } elseif ($entity instanceof PartLot && $entity->getPart() instanceof \App\Entity\Parts\Part) { $on = $entity->getPart(); - } elseif ($entity instanceof Orderdetail && null !== $entity->getPart()) { + } elseif ($entity instanceof Orderdetail && $entity->getPart() instanceof \App\Entity\Parts\Part) { $on = $entity->getPart(); - } elseif ($entity instanceof Pricedetail && null !== $entity->getOrderdetail() && null !== $entity->getOrderdetail()->getPart()) { + } elseif ($entity instanceof Pricedetail && $entity->getOrderdetail() instanceof \App\Entity\PriceInformations\Orderdetail && $entity->getOrderdetail()->getPart() instanceof \App\Entity\Parts\Part) { $on = $entity->getOrderdetail()->getPart(); - } elseif ($entity instanceof ProjectBOMEntry && null !== $entity->getProject()) { + } elseif ($entity instanceof ProjectBOMEntry && $entity->getProject() instanceof \App\Entity\ProjectSystem\Project) { $on = $entity->getProject(); } @@ -189,7 +183,7 @@ class ElementTypeNameGenerator $this->entityURLGenerator->infoURL($on), $this->getTypeNameCombination($on, true) ); - } catch (EntityNotSupportedException $exception) { + } catch (EntityNotSupportedException) { } } } @@ -200,9 +194,6 @@ class ElementTypeNameGenerator /** * Create a HTML formatted label for a deleted element of which we only know the class and the ID. * Please note that it is not checked if the element really not exists anymore, so you have to do this yourself. - * @param string $class - * @param int $id - * @return string */ public function formatElementDeletedHTML(string $class, int $id): string { diff --git a/src/Services/EntityURLGenerator.php b/src/Services/EntityURLGenerator.php index 5f45e58c..487bed39 100644 --- a/src/Services/EntityURLGenerator.php +++ b/src/Services/EntityURLGenerator.php @@ -57,13 +57,8 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; */ class EntityURLGenerator { - protected UrlGeneratorInterface $urlGenerator; - protected AttachmentURLGenerator $attachmentURLGenerator; - - public function __construct(UrlGeneratorInterface $urlGenerator, AttachmentURLGenerator $attachmentURLGenerator) + public function __construct(protected UrlGeneratorInterface $urlGenerator, protected AttachmentURLGenerator $attachmentURLGenerator) { - $this->urlGenerator = $urlGenerator; - $this->attachmentURLGenerator = $attachmentURLGenerator; } /** @@ -79,29 +74,19 @@ class EntityURLGenerator * @throws EntityNotSupportedException thrown if the entity is not supported for the given type * @throws InvalidArgumentException thrown if the givent type is not existing */ - public function getURL($entity, string $type): string + public function getURL(mixed $entity, string $type): string { - switch ($type) { - case 'info': - return $this->infoURL($entity); - case 'edit': - return $this->editURL($entity); - case 'create': - return $this->createURL($entity); - case 'clone': - return $this->cloneURL($entity); - case 'list': - case 'list_parts': - return $this->listPartsURL($entity); - case 'delete': - return $this->deleteURL($entity); - case 'file_download': - return $this->downloadURL($entity); - case 'file_view': - return $this->viewURL($entity); - } - - throw new InvalidArgumentException('Method is not supported!'); + return match ($type) { + 'info' => $this->infoURL($entity), + 'edit' => $this->editURL($entity), + 'create' => $this->createURL($entity), + 'clone' => $this->cloneURL($entity), + 'list', 'list_parts' => $this->listPartsURL($entity), + 'delete' => $this->deleteURL($entity), + 'file_download' => $this->downloadURL($entity), + 'file_view' => $this->viewURL($entity), + default => throw new InvalidArgumentException('Method is not supported!'), + }; } /** @@ -134,7 +119,7 @@ class EntityURLGenerator 'timestamp' => $dateTime->getTimestamp(), ] ); - } catch (EntityNotSupportedException $exception) { + } catch (EntityNotSupportedException) { if ($entity instanceof PartLot) { return $this->urlGenerator->generate('part_info', [ 'id' => $entity->getPart()->getID(), @@ -168,7 +153,7 @@ class EntityURLGenerator } //Otherwise throw an error - throw new EntityNotSupportedException('The given entity is not supported yet! Passed class type: '.get_class($entity)); + throw new EntityNotSupportedException('The given entity is not supported yet! Passed class type: '.$entity::class); } public function viewURL(Attachment $entity): string @@ -191,7 +176,7 @@ class EntityURLGenerator } //Otherwise throw an error - throw new EntityNotSupportedException(sprintf('The given entity is not supported yet! Passed class type: %s', get_class($entity))); + throw new EntityNotSupportedException(sprintf('The given entity is not supported yet! Passed class type: %s', $entity::class)); } /** @@ -235,7 +220,7 @@ class EntityURLGenerator * * @throws EntityNotSupportedException If the method is not supported for the given Entity */ - public function editURL($entity): string + public function editURL(mixed $entity): string { $map = [ Part::class => 'part_edit', @@ -265,7 +250,7 @@ class EntityURLGenerator * * @throws EntityNotSupportedException If the method is not supported for the given Entity */ - public function createURL($entity): string + public function createURL(mixed $entity): string { $map = [ Part::class => 'part_new', @@ -373,9 +358,9 @@ class EntityURLGenerator * * @throws EntityNotSupportedException */ - protected function mapToController(array $map, $entity): string + protected function mapToController(array $map, mixed $entity): string { - $class = get_class($entity); + $class = $entity::class; //Check if we have an direct mapping for the given class if (!array_key_exists($class, $map)) { @@ -386,7 +371,7 @@ class EntityURLGenerator } } - throw new EntityNotSupportedException(sprintf('The given entity is not supported yet! Passed class type: %s', get_class($entity))); + throw new EntityNotSupportedException(sprintf('The given entity is not supported yet! Passed class type: %s', $entity::class)); } return $map[$class]; diff --git a/src/Services/Formatters/AmountFormatter.php b/src/Services/Formatters/AmountFormatter.php index ccc4c4b3..d092f2cd 100644 --- a/src/Services/Formatters/AmountFormatter.php +++ b/src/Services/Formatters/AmountFormatter.php @@ -32,25 +32,20 @@ use Symfony\Component\OptionsResolver\OptionsResolver; */ class AmountFormatter { - protected SIFormatter $siFormatter; - - public function __construct(SIFormatter $siFormatter) + public function __construct(protected SIFormatter $siFormatter) { - $this->siFormatter = $siFormatter; } /** * Formats the given value using the measurement unit and options. * - * @param float|string|int $value * @param MeasurementUnit|null $unit The measurement unit, whose unit symbol should be used for formatting. * If set to null, it is assumed that the part amount is measured in pieces. * * @return string The formatted string - * * @throws InvalidArgumentException thrown if $value is not numeric */ - public function format($value, ?MeasurementUnit $unit = null, array $options = []): string + public function format(float|string|int $value, ?MeasurementUnit $unit = null, array $options = []): string { if (!is_numeric($value)) { throw new InvalidArgumentException('$value must be an numeric value!'); diff --git a/src/Services/Formatters/MarkdownParser.php b/src/Services/Formatters/MarkdownParser.php index 1c1d8ff8..f3ef07df 100644 --- a/src/Services/Formatters/MarkdownParser.php +++ b/src/Services/Formatters/MarkdownParser.php @@ -29,11 +29,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class MarkdownParser { - protected TranslatorInterface $translator; - - public function __construct(TranslatorInterface $translator) + public function __construct(protected TranslatorInterface $translator) { - $this->translator = $translator; } /** diff --git a/src/Services/Formatters/MoneyFormatter.php b/src/Services/Formatters/MoneyFormatter.php index 1907fe90..3e65e159 100644 --- a/src/Services/Formatters/MoneyFormatter.php +++ b/src/Services/Formatters/MoneyFormatter.php @@ -28,12 +28,10 @@ use NumberFormatter; class MoneyFormatter { - protected string $base_currency; protected string $locale; - public function __construct(string $base_currency) + public function __construct(protected string $base_currency) { - $this->base_currency = $base_currency; $this->locale = Locale::getDefault(); } @@ -45,10 +43,10 @@ class MoneyFormatter * @param int $decimals the number of decimals that should be shown * @param bool $show_all_digits if set to true, all digits are shown, even if they are null */ - public function format($value, ?Currency $currency = null, int $decimals = 5, bool $show_all_digits = false): string + public function format(string|float $value, ?Currency $currency = null, int $decimals = 5, bool $show_all_digits = false): string { $iso_code = $this->base_currency; - if (null !== $currency && !empty($currency->getIsoCode())) { + if ($currency instanceof \App\Entity\PriceInformations\Currency && !empty($currency->getIsoCode())) { $iso_code = $currency->getIsoCode(); } diff --git a/src/Services/Formatters/SIFormatter.php b/src/Services/Formatters/SIFormatter.php index 619c2de3..a6d69d0b 100644 --- a/src/Services/Formatters/SIFormatter.php +++ b/src/Services/Formatters/SIFormatter.php @@ -93,11 +93,7 @@ class SIFormatter [$divisor, $symbol] = $this->getPrefixByMagnitude($this->getMagnitude($value)); $value /= $divisor; //Build the format string, e.g.: %.2d km - if ('' !== $unit || '' !== $symbol) { - $format_string = '%.'.$decimals.'f '.$symbol.$unit; - } else { - $format_string = '%.'.$decimals.'f'; - } + $format_string = '' !== $unit || '' !== $symbol ? '%.'.$decimals.'f '.$symbol.$unit : '%.'.$decimals.'f'; return sprintf($format_string, $value); } diff --git a/src/Services/ImportExportSystem/BOMImporter.php b/src/Services/ImportExportSystem/BOMImporter.php index 72fa84d5..72103436 100644 --- a/src/Services/ImportExportSystem/BOMImporter.php +++ b/src/Services/ImportExportSystem/BOMImporter.php @@ -54,9 +54,6 @@ class BOMImporter /** * Converts the given file into an array of BOM entries using the given options and save them into the given project. * The changes are not saved into the database yet. - * @param File $file - * @param array $options - * @param Project $project * @return ProjectBOMEntry[] */ public function importFileIntoProject(File $file, Project $project, array $options): array @@ -73,8 +70,6 @@ class BOMImporter /** * Converts the given file into an array of BOM entries using the given options. - * @param File $file - * @param array $options * @return ProjectBOMEntry[] */ public function fileToBOMEntries(File $file, array $options): array @@ -94,12 +89,10 @@ class BOMImporter $resolver = $this->configureOptions($resolver); $options = $resolver->resolve($options); - switch ($options['type']) { - case 'kicad_pcbnew': - return $this->parseKiCADPCB($data, $options); - default: - throw new InvalidArgumentException('Invalid import type!'); - } + return match ($options['type']) { + 'kicad_pcbnew' => $this->parseKiCADPCB($data, $options), + default => throw new InvalidArgumentException('Invalid import type!'), + }; } private function parseKiCADPCB(string $data, array $options = []): array @@ -112,9 +105,7 @@ class BOMImporter foreach ($csv->getRecords() as $offset => $entry) { //Translate the german field names to english - $entry = array_combine(array_map(static function ($key) { - return self::MAP_KICAD_PCB_FIELDS[$key] ?? $key; - }, array_keys($entry)), $entry); + $entry = array_combine(array_map(static fn($key) => self::MAP_KICAD_PCB_FIELDS[$key] ?? $key, array_keys($entry)), $entry); //Ensure that the entry has all required fields if (!isset ($entry['Designator'])) { diff --git a/src/Services/ImportExportSystem/EntityExporter.php b/src/Services/ImportExportSystem/EntityExporter.php index a4825869..a4c3b48e 100644 --- a/src/Services/ImportExportSystem/EntityExporter.php +++ b/src/Services/ImportExportSystem/EntityExporter.php @@ -39,11 +39,8 @@ use function Symfony\Component\String\u; */ class EntityExporter { - protected SerializerInterface $serializer; - - public function __construct(SerializerInterface $serializer) + public function __construct(protected SerializerInterface $serializer) { - $this->serializer = $serializer; } protected function configureOptions(OptionsResolver $resolver): void @@ -67,7 +64,7 @@ class EntityExporter * @param array $options The options to use for exporting * @return string The serialized data */ - public function exportEntities($entities, array $options): string + public function exportEntities(\App\Entity\Base\AbstractNamedDBElement|array $entities, array $options): string { if (!is_array($entities)) { $entities = [$entities]; @@ -111,7 +108,7 @@ class EntityExporter * * @throws ReflectionException */ - public function exportEntityFromRequest($entities, Request $request): Response + public function exportEntityFromRequest(\App\Entity\Base\AbstractNamedDBElement|array $entities, Request $request): Response { $options = [ 'format' => $request->get('format') ?? 'json', diff --git a/src/Services/ImportExportSystem/EntityImporter.php b/src/Services/ImportExportSystem/EntityImporter.php index c798f9f5..60014554 100644 --- a/src/Services/ImportExportSystem/EntityImporter.php +++ b/src/Services/ImportExportSystem/EntityImporter.php @@ -38,15 +38,8 @@ use Symfony\Component\Validator\Validator\ValidatorInterface; class EntityImporter { - protected SerializerInterface $serializer; - protected EntityManagerInterface $em; - protected ValidatorInterface $validator; - - public function __construct(SerializerInterface $serializer, EntityManagerInterface $em, ValidatorInterface $validator) + public function __construct(protected SerializerInterface $serializer, protected EntityManagerInterface $em, protected ValidatorInterface $validator) { - $this->serializer = $serializer; - $this->em = $em; - $this->validator = $validator; } /** @@ -68,7 +61,7 @@ class EntityImporter if (!is_a($class_name, AbstractNamedDBElement::class, true)) { throw new InvalidArgumentException('$class_name must be a StructuralDBElement type!'); } - if (null !== $parent && !is_a($parent, $class_name)) { + if ($parent instanceof \App\Entity\Base\AbstractStructuralDBElement && !$parent instanceof $class_name) { throw new InvalidArgumentException('$parent must have the same type as specified in $class_name!'); } @@ -297,20 +290,13 @@ class EntityImporter //Convert the extension to lower case $extension = strtolower($extension); - switch ($extension) { - case 'json': - return 'json'; - case 'xml': - return 'xml'; - case 'csv': - case 'tsv': - return 'csv'; - case 'yaml': - case 'yml': - return 'yaml'; - default: - return null; - } + return match ($extension) { + 'json' => 'json', + 'xml' => 'xml', + 'csv', 'tsv' => 'csv', + 'yaml', 'yml' => 'yaml', + default => null, + }; } /** diff --git a/src/Services/ImportExportSystem/PartKeeprImporter/PKDatastructureImporter.php b/src/Services/ImportExportSystem/PartKeeprImporter/PKDatastructureImporter.php index 52732a44..31939d31 100644 --- a/src/Services/ImportExportSystem/PartKeeprImporter/PKDatastructureImporter.php +++ b/src/Services/ImportExportSystem/PartKeeprImporter/PKDatastructureImporter.php @@ -87,7 +87,7 @@ class PKDatastructureImporter $this->em->flush(); - return count($distributor_data); + return is_countable($distributor_data) ? count($distributor_data) : 0; } public function importManufacturers(array $data): int @@ -130,7 +130,7 @@ class PKDatastructureImporter $this->importAttachments($data, 'manufacturericlogo', Manufacturer::class, 'manufacturer_id', ManufacturerAttachment::class); - return count($manufacturer_data); + return is_countable($manufacturer_data) ? count($manufacturer_data) : 0; } public function importPartUnits(array $data): int @@ -151,7 +151,7 @@ class PKDatastructureImporter $this->em->flush(); - return count($partunit_data); + return is_countable($partunit_data) ? count($partunit_data) : 0; } public function importCategories(array $data): int @@ -180,15 +180,11 @@ class PKDatastructureImporter } $this->em->flush(); - return count($partcategory_data); + return is_countable($partcategory_data) ? count($partcategory_data) : 0; } /** * The common import functions for footprints and storeloactions - * @param array $data - * @param string $target_class - * @param string $data_prefix - * @return int */ private function importElementsWithCategory(array $data, string $target_class, string $data_prefix): int { @@ -249,7 +245,7 @@ class PKDatastructureImporter $this->em->flush(); - return count($footprint_data) + count($footprintcategory_data); + return (is_countable($footprint_data) ? count($footprint_data) : 0) + (is_countable($footprintcategory_data) ? count($footprintcategory_data) : 0); } public function importFootprints(array $data): int diff --git a/src/Services/ImportExportSystem/PartKeeprImporter/PKImportHelper.php b/src/Services/ImportExportSystem/PartKeeprImporter/PKImportHelper.php index 3709fac2..d51bc225 100644 --- a/src/Services/ImportExportSystem/PartKeeprImporter/PKImportHelper.php +++ b/src/Services/ImportExportSystem/PartKeeprImporter/PKImportHelper.php @@ -28,18 +28,14 @@ use Doctrine\ORM\EntityManagerInterface; */ class PKImportHelper { - protected EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $em) + public function __construct(protected EntityManagerInterface $em) { - $this->em = $em; } /** * Purges the database tables for the import, so that all data can be created from scratch. * Existing users and groups are not purged. * This is needed to avoid ID collisions. - * @return void */ public function purgeDatabaseForImport(): void { @@ -50,8 +46,6 @@ class PKImportHelper /** * Extracts the current database schema version from the PartKeepr XML dump. - * @param array $data - * @return string */ public function getDatabaseSchemaVersion(array $data): string { @@ -64,7 +58,6 @@ class PKImportHelper /** * Checks that the database schema of the PartKeepr XML dump is compatible with the importer - * @param array $data * @return bool True if the schema is compatible, false otherwise */ public function checkVersion(array $data): bool diff --git a/src/Services/ImportExportSystem/PartKeeprImporter/PKImportHelperTrait.php b/src/Services/ImportExportSystem/PartKeeprImporter/PKImportHelperTrait.php index a318c281..76326ebd 100644 --- a/src/Services/ImportExportSystem/PartKeeprImporter/PKImportHelperTrait.php +++ b/src/Services/ImportExportSystem/PartKeeprImporter/PKImportHelperTrait.php @@ -45,7 +45,6 @@ trait PKImportHelperTrait * @param array $attachment_row The attachment row from the PartKeepr database * @param string $target_class The target class for the attachment * @param string $type The type of the attachment (attachment or image) - * @return Attachment * @throws \Exception */ protected function convertAttachmentDataToEntity(array $attachment_row, string $target_class, string $type): Attachment @@ -87,10 +86,10 @@ trait PKImportHelperTrait //Use mime type to determine the extension like PartKeepr does in legacy implementation (just use the second part of the mime type) //See UploadedFile.php:291 in PartKeepr (https://github.com/partkeepr/PartKeepr/blob/f6176c3354b24fa39ac8bc4328ee0df91de3d5b6/src/PartKeepr/UploadedFileBundle/Entity/UploadedFile.php#L291) if (!empty ($attachment_row['mimetype'])) { - $attachment_row['extension'] = explode('/', $attachment_row['mimetype'])[1]; + $attachment_row['extension'] = explode('/', (string) $attachment_row['mimetype'])[1]; } else { //If the mime type is empty, we use the original extension - $attachment_row['extension'] = pathinfo($attachment_row['originalname'], PATHINFO_EXTENSION); + $attachment_row['extension'] = pathinfo((string) $attachment_row['originalname'], PATHINFO_EXTENSION); } } @@ -115,7 +114,6 @@ trait PKImportHelperTrait * @param string $target_class The target class (e.g. Part) * @param string $target_id_field The field name where the target ID is stored * @param string $attachment_class The attachment class (e.g. PartAttachment) - * @return void */ protected function importAttachments(array $data, string $table_name, string $target_class, string $target_id_field, string $attachment_class): void { @@ -156,12 +154,9 @@ trait PKImportHelperTrait /** * Assigns the parent to the given entity, using the numerical IDs from the imported data. - * @param string $class - * @param int|string $element_id - * @param int|string $parent_id * @return AbstractStructuralDBElement The structural element that was modified (with $element_id) */ - protected function setParent(string $class, $element_id, $parent_id): AbstractStructuralDBElement + protected function setParent(string $class, int|string $element_id, int|string $parent_id): AbstractStructuralDBElement { $element = $this->em->find($class, (int) $element_id); if (!$element) { @@ -184,7 +179,6 @@ trait PKImportHelperTrait /** * Sets the given field of the given entity to the entity with the given ID. - * @return AbstractDBElement */ protected function setAssociationField(AbstractDBElement $element, string $field, string $other_class, $other_id): AbstractDBElement { @@ -205,11 +199,8 @@ trait PKImportHelperTrait /** * Set the ID of an entity to a specific value. Must be called before persisting the entity, but before flushing. - * @param AbstractDBElement $element - * @param int|string $id - * @return void */ - protected function setIDOfEntity(AbstractDBElement $element, $id): void + protected function setIDOfEntity(AbstractDBElement $element, int|string $id): void { if (!is_int($id) && !is_string($id)) { throw new \InvalidArgumentException('ID must be an integer or string'); @@ -217,7 +208,7 @@ trait PKImportHelperTrait $id = (int) $id; - $metadata = $this->em->getClassMetadata(get_class($element)); + $metadata = $this->em->getClassMetadata($element::class); $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_NONE); $metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator()); $metadata->setIdentifierValues($element, ['id' => $id]); diff --git a/src/Services/ImportExportSystem/PartKeeprImporter/PKOptionalImporter.php b/src/Services/ImportExportSystem/PartKeeprImporter/PKOptionalImporter.php index 4d3af4f4..e192eefa 100644 --- a/src/Services/ImportExportSystem/PartKeeprImporter/PKOptionalImporter.php +++ b/src/Services/ImportExportSystem/PartKeeprImporter/PKOptionalImporter.php @@ -45,7 +45,6 @@ class PKOptionalImporter /** * Import the projects from the given data. - * @param array $data * @return int The number of imported projects */ public function importProjects(array $data): int @@ -99,12 +98,11 @@ class PKOptionalImporter $this->importAttachments($data, 'projectattachment', Project::class, 'project_id', ProjectAttachment::class); - return count($projects_data); + return is_countable($projects_data) ? count($projects_data) : 0; } /** * Import the users from the given data. - * @param array $data * @return int The number of imported users */ public function importUsers(array $data): int @@ -144,6 +142,6 @@ class PKOptionalImporter $this->em->flush(); - return count($users_data); + return is_countable($users_data) ? count($users_data) : 0; } } \ No newline at end of file diff --git a/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php b/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php index 3e00b033..3690ccbc 100644 --- a/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php +++ b/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php @@ -45,13 +45,10 @@ class PKPartImporter { use PKImportHelperTrait; - private string $base_currency; - - public function __construct(EntityManagerInterface $em, PropertyAccessorInterface $propertyAccessor, string $default_currency) + public function __construct(EntityManagerInterface $em, PropertyAccessorInterface $propertyAccessor, private readonly string $base_currency) { $this->em = $em; $this->propertyAccessor = $propertyAccessor; - $this->base_currency = $default_currency; } public function importParts(array $data): int @@ -128,7 +125,7 @@ class PKPartImporter //Import attachments $this->importAttachments($data, 'partattachment', Part::class, 'part_id', PartAttachment::class); - return count($part_data); + return is_countable($part_data) ? count($part_data) : 0; } protected function importPartManufacturers(array $data): void @@ -146,7 +143,7 @@ class PKPartImporter throw new \RuntimeException(sprintf('Could not find part with ID %s', $partmanufacturer['part_id'])); } $manufacturer = $this->em->find(Manufacturer::class, (int) $partmanufacturer['manufacturer_id']); - if (!$manufacturer) { + if (!$manufacturer instanceof \App\Entity\Parts\Manufacturer) { throw new \RuntimeException(sprintf('Could not find manufacturer with ID %s', $partmanufacturer['manufacturer_id'])); } $part->setManufacturer($manufacturer); @@ -190,7 +187,7 @@ class PKPartImporter } $part = $this->em->find(Part::class, (int) $partparameter['part_id']); - if (!$part) { + if (!$part instanceof \App\Entity\Parts\Part) { throw new \RuntimeException(sprintf('Could not find part with ID %s', $partparameter['part_id'])); } @@ -203,8 +200,6 @@ class PKPartImporter /** * Returns the currency for the given ISO code. If the currency does not exist, it is created. * This function returns null if the ISO code is the base currency. - * @param string $currency_iso_code - * @return Currency|null */ protected function getOrCreateCurrency(string $currency_iso_code): ?Currency { @@ -240,12 +235,12 @@ class PKPartImporter foreach ($data['partdistributor'] as $partdistributor) { //Retrieve the part $part = $this->em->find(Part::class, (int) $partdistributor['part_id']); - if (!$part) { + if (!$part instanceof \App\Entity\Parts\Part) { throw new \RuntimeException(sprintf('Could not find part with ID %s', $partdistributor['part_id'])); } //Retrieve the distributor $supplier = $this->em->find(Supplier::class, (int) $partdistributor['distributor_id']); - if (!$supplier) { + if (!$supplier instanceof \App\Entity\Parts\Supplier) { throw new \RuntimeException(sprintf('Could not find supplier with ID %s', $partdistributor['distributor_id'])); } @@ -305,9 +300,6 @@ class PKPartImporter /** * Returns the (parameter) unit symbol for the given ID. - * @param array $data - * @param int $id - * @return string */ protected function getUnitSymbol(array $data, int $id): string { diff --git a/src/Services/LabelSystem/BarcodeGenerator.php b/src/Services/LabelSystem/BarcodeGenerator.php index 801154a3..90cbc5d7 100644 --- a/src/Services/LabelSystem/BarcodeGenerator.php +++ b/src/Services/LabelSystem/BarcodeGenerator.php @@ -50,12 +50,8 @@ use InvalidArgumentException; final class BarcodeGenerator { - private BarcodeContentGenerator $barcodeContentGenerator; - - - public function __construct(BarcodeContentGenerator $barcodeContentGenerator) + public function __construct(private readonly BarcodeContentGenerator $barcodeContentGenerator) { - $this->barcodeContentGenerator = $barcodeContentGenerator; } public function generateHTMLBarcode(LabelOptions $options, object $target): ?string @@ -126,18 +122,11 @@ final class BarcodeGenerator public function getContent(LabelOptions $options, AbstractDBElement $target): ?string { - switch ($options->getBarcodeType()) { - case 'qr': - case 'datamatrix': - return $this->barcodeContentGenerator->getURLContent($target); - case 'code39': - case 'code93': - case 'code128': - return $this->barcodeContentGenerator->get1DBarcodeContent($target); - case 'none': - return null; - default: - throw new InvalidArgumentException('Unknown label type!'); - } + return match ($options->getBarcodeType()) { + 'qr', 'datamatrix' => $this->barcodeContentGenerator->getURLContent($target), + 'code39', 'code93', 'code128' => $this->barcodeContentGenerator->get1DBarcodeContent($target), + 'none' => null, + default => throw new InvalidArgumentException('Unknown label type!'), + }; } } diff --git a/src/Services/LabelSystem/Barcodes/BarcodeContentGenerator.php b/src/Services/LabelSystem/Barcodes/BarcodeContentGenerator.php index 588e34b4..6930bd79 100644 --- a/src/Services/LabelSystem/Barcodes/BarcodeContentGenerator.php +++ b/src/Services/LabelSystem/Barcodes/BarcodeContentGenerator.php @@ -62,11 +62,8 @@ final class BarcodeContentGenerator Storelocation::class => 'location', ]; - private UrlGeneratorInterface $urlGenerator; - - public function __construct(UrlGeneratorInterface $urlGenerator) + public function __construct(private readonly UrlGeneratorInterface $urlGenerator) { - $this->urlGenerator = $urlGenerator; } /** @@ -97,17 +94,17 @@ final class BarcodeContentGenerator private function classToString(array $map, object $target): string { - $class = get_class($target); + $class = $target::class; if (isset($map[$class])) { return $map[$class]; } foreach ($map as $class => $string) { - if (is_a($target, $class)) { + if ($target instanceof $class) { return $string; } } - throw new InvalidArgumentException('Unknown object class '.get_class($target)); + throw new InvalidArgumentException('Unknown object class '.$target::class); } } diff --git a/src/Services/LabelSystem/Barcodes/BarcodeRedirector.php b/src/Services/LabelSystem/Barcodes/BarcodeRedirector.php index 198cb43b..f9b289b3 100644 --- a/src/Services/LabelSystem/Barcodes/BarcodeRedirector.php +++ b/src/Services/LabelSystem/Barcodes/BarcodeRedirector.php @@ -49,13 +49,8 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; final class BarcodeRedirector { - private UrlGeneratorInterface $urlGenerator; - private EntityManagerInterface $em; - - public function __construct(UrlGeneratorInterface $urlGenerator, EntityManagerInterface $entityManager) + public function __construct(private readonly UrlGeneratorInterface $urlGenerator, private readonly EntityManagerInterface $em) { - $this->urlGenerator = $urlGenerator; - $this->em = $entityManager; } /** @@ -76,7 +71,7 @@ final class BarcodeRedirector case 'lot': //Try to determine the part to the given lot $lot = $this->em->find(PartLot::class, $id); - if (null === $lot) { + if (!$lot instanceof \App\Entity\Parts\PartLot) { throw new EntityNotFoundException(); } diff --git a/src/Services/LabelSystem/LabelExampleElementsGenerator.php b/src/Services/LabelSystem/LabelExampleElementsGenerator.php index 0bc3761a..d3717208 100644 --- a/src/Services/LabelSystem/LabelExampleElementsGenerator.php +++ b/src/Services/LabelSystem/LabelExampleElementsGenerator.php @@ -57,16 +57,12 @@ final class LabelExampleElementsGenerator { public function getElement(string $type): object { - switch ($type) { - case 'part': - return $this->getExamplePart(); - case 'part_lot': - return $this->getExamplePartLot(); - case 'storelocation': - return $this->getStorelocation(); - default: - throw new InvalidArgumentException('Unknown $type.'); - } + return match ($type) { + 'part' => $this->getExamplePart(), + 'part_lot' => $this->getExamplePartLot(), + 'storelocation' => $this->getStorelocation(), + default => throw new InvalidArgumentException('Unknown $type.'), + }; } public function getExamplePart(): Part diff --git a/src/Services/LabelSystem/LabelGenerator.php b/src/Services/LabelSystem/LabelGenerator.php index 4afb20ae..d5ae2718 100644 --- a/src/Services/LabelSystem/LabelGenerator.php +++ b/src/Services/LabelSystem/LabelGenerator.php @@ -58,11 +58,8 @@ final class LabelGenerator public const MM_TO_POINTS_FACTOR = 2.83465; - private LabelHTMLGenerator $labelHTMLGenerator; - - public function __construct(LabelHTMLGenerator $labelHTMLGenerator) + public function __construct(private readonly LabelHTMLGenerator $labelHTMLGenerator) { - $this->labelHTMLGenerator = $labelHTMLGenerator; } /** diff --git a/src/Services/LabelSystem/LabelHTMLGenerator.php b/src/Services/LabelSystem/LabelHTMLGenerator.php index bd8aa7b3..6fd28aef 100644 --- a/src/Services/LabelSystem/LabelHTMLGenerator.php +++ b/src/Services/LabelSystem/LabelHTMLGenerator.php @@ -52,29 +52,13 @@ use Twig\Error\Error; final class LabelHTMLGenerator { - private Environment $twig; - private ElementTypeNameGenerator $elementTypeNameGenerator; - private LabelTextReplacer $replacer; - private BarcodeGenerator $barcodeGenerator; - private SandboxedTwigProvider $sandboxedTwigProvider; - private string $partdb_title; - private \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(ElementTypeNameGenerator $elementTypeNameGenerator, LabelTextReplacer $replacer, Environment $twig, - BarcodeGenerator $barcodeGenerator, SandboxedTwigProvider $sandboxedTwigProvider, \Symfony\Bundle\SecurityBundle\Security $security, string $partdb_title) + public function __construct(private readonly ElementTypeNameGenerator $elementTypeNameGenerator, private readonly LabelTextReplacer $replacer, private readonly Environment $twig, private readonly BarcodeGenerator $barcodeGenerator, private readonly SandboxedTwigProvider $sandboxedTwigProvider, private readonly \Symfony\Bundle\SecurityBundle\Security $security, private readonly string $partdb_title) { - $this->twig = $twig; - $this->elementTypeNameGenerator = $elementTypeNameGenerator; - $this->replacer = $replacer; - $this->barcodeGenerator = $barcodeGenerator; - $this->sandboxedTwigProvider = $sandboxedTwigProvider; - $this->security = $security; - $this->partdb_title = $partdb_title; } public function getLabelHTML(LabelOptions $options, array $elements): string { - if (empty($elements)) { + if ($elements === []) { throw new InvalidArgumentException('$elements must not be empty'); } diff --git a/src/Services/LabelSystem/LabelProfileDropdownHelper.php b/src/Services/LabelSystem/LabelProfileDropdownHelper.php index 8245c062..4dadd36f 100644 --- a/src/Services/LabelSystem/LabelProfileDropdownHelper.php +++ b/src/Services/LabelSystem/LabelProfileDropdownHelper.php @@ -50,15 +50,8 @@ use Symfony\Contracts\Cache\TagAwareCacheInterface; final class LabelProfileDropdownHelper { - private TagAwareCacheInterface $cache; - private EntityManagerInterface $entityManager; - private UserCacheKeyGenerator $keyGenerator; - - public function __construct(TagAwareCacheInterface $treeCache, EntityManagerInterface $entityManager, UserCacheKeyGenerator $keyGenerator) + public function __construct(private readonly TagAwareCacheInterface $cache, private readonly EntityManagerInterface $entityManager, private readonly UserCacheKeyGenerator $keyGenerator) { - $this->cache = $treeCache; - $this->entityManager = $entityManager; - $this->keyGenerator = $keyGenerator; } public function getDropdownProfiles(string $type): array diff --git a/src/Services/LabelSystem/LabelTextReplacer.php b/src/Services/LabelSystem/LabelTextReplacer.php index 5b94352b..3c0b5f92 100644 --- a/src/Services/LabelSystem/LabelTextReplacer.php +++ b/src/Services/LabelSystem/LabelTextReplacer.php @@ -49,11 +49,8 @@ use App\Services\LabelSystem\PlaceholderProviders\PlaceholderProviderInterface; */ final class LabelTextReplacer { - private iterable $providers; - - public function __construct(iterable $providers) + public function __construct(private readonly iterable $providers) { - $this->providers = $providers; } /** @@ -89,9 +86,7 @@ final class LabelTextReplacer public function replace(string $lines, object $target): string { $patterns = [ - '/(\[\[[A-Z_0-9]+\]\])/' => function ($match) use ($target) { - return $this->handlePlaceholder($match[0], $target); - }, + '/(\[\[[A-Z_0-9]+\]\])/' => fn($match) => $this->handlePlaceholder($match[0], $target), ]; return preg_replace_callback_array($patterns, $lines); diff --git a/src/Services/LabelSystem/PlaceholderProviders/AbstractDBElementProvider.php b/src/Services/LabelSystem/PlaceholderProviders/AbstractDBElementProvider.php index f765cd0c..081b3e91 100644 --- a/src/Services/LabelSystem/PlaceholderProviders/AbstractDBElementProvider.php +++ b/src/Services/LabelSystem/PlaceholderProviders/AbstractDBElementProvider.php @@ -46,11 +46,8 @@ use App\Services\ElementTypeNameGenerator; final class AbstractDBElementProvider implements PlaceholderProviderInterface { - private ElementTypeNameGenerator $elementTypeNameGenerator; - - public function __construct(ElementTypeNameGenerator $elementTypeNameGenerator) + public function __construct(private readonly ElementTypeNameGenerator $elementTypeNameGenerator) { - $this->elementTypeNameGenerator = $elementTypeNameGenerator; } public function replace(string $placeholder, object $label_target, array $options = []): ?string diff --git a/src/Services/LabelSystem/PlaceholderProviders/BarcodeProvider.php b/src/Services/LabelSystem/PlaceholderProviders/BarcodeProvider.php index 06144831..868f8038 100644 --- a/src/Services/LabelSystem/PlaceholderProviders/BarcodeProvider.php +++ b/src/Services/LabelSystem/PlaceholderProviders/BarcodeProvider.php @@ -26,13 +26,8 @@ use App\Services\LabelSystem\Barcodes\BarcodeContentGenerator; final class BarcodeProvider implements PlaceholderProviderInterface { - private BarcodeGenerator $barcodeGenerator; - private BarcodeContentGenerator $barcodeContentGenerator; - - public function __construct(BarcodeGenerator $barcodeGenerator, BarcodeContentGenerator $barcodeContentGenerator) + public function __construct(private readonly BarcodeGenerator $barcodeGenerator, private readonly BarcodeContentGenerator $barcodeContentGenerator) { - $this->barcodeGenerator = $barcodeGenerator; - $this->barcodeContentGenerator = $barcodeContentGenerator; } public function replace(string $placeholder, object $label_target, array $options = []): ?string @@ -40,7 +35,7 @@ final class BarcodeProvider implements PlaceholderProviderInterface if ('[[1D_CONTENT]]' === $placeholder) { try { return $this->barcodeContentGenerator->get1DBarcodeContent($label_target); - } catch (\InvalidArgumentException $e) { + } catch (\InvalidArgumentException) { return 'ERROR!'; } } @@ -48,7 +43,7 @@ final class BarcodeProvider implements PlaceholderProviderInterface if ('[[2D_CONTENT]]' === $placeholder) { try { return $this->barcodeContentGenerator->getURLContent($label_target); - } catch (\InvalidArgumentException $e) { + } catch (\InvalidArgumentException) { return 'ERROR!'; } } diff --git a/src/Services/LabelSystem/PlaceholderProviders/GlobalProviders.php b/src/Services/LabelSystem/PlaceholderProviders/GlobalProviders.php index 5fd32a73..50efd563 100644 --- a/src/Services/LabelSystem/PlaceholderProviders/GlobalProviders.php +++ b/src/Services/LabelSystem/PlaceholderProviders/GlobalProviders.php @@ -53,15 +53,8 @@ use Symfony\Component\Security\Core\Security; */ final class GlobalProviders implements PlaceholderProviderInterface { - private string $partdb_title; - private \Symfony\Bundle\SecurityBundle\Security $security; - private UrlGeneratorInterface $url_generator; - - public function __construct(string $partdb_title, \Symfony\Bundle\SecurityBundle\Security $security, UrlGeneratorInterface $url_generator) + public function __construct(private readonly string $partdb_title, private readonly \Symfony\Bundle\SecurityBundle\Security $security, private readonly UrlGeneratorInterface $url_generator) { - $this->partdb_title = $partdb_title; - $this->security = $security; - $this->url_generator = $url_generator; } public function replace(string $placeholder, object $label_target, array $options = []): ?string diff --git a/src/Services/LabelSystem/PlaceholderProviders/PartLotProvider.php b/src/Services/LabelSystem/PlaceholderProviders/PartLotProvider.php index a4fdf32a..ce071e9f 100644 --- a/src/Services/LabelSystem/PlaceholderProviders/PartLotProvider.php +++ b/src/Services/LabelSystem/PlaceholderProviders/PartLotProvider.php @@ -49,13 +49,8 @@ use Locale; final class PartLotProvider implements PlaceholderProviderInterface { - private LabelTextReplacer $labelTextReplacer; - private AmountFormatter $amountFormatter; - - public function __construct(LabelTextReplacer $labelTextReplacer, AmountFormatter $amountFormatter) + public function __construct(private readonly LabelTextReplacer $labelTextReplacer, private readonly AmountFormatter $amountFormatter) { - $this->labelTextReplacer = $labelTextReplacer; - $this->amountFormatter = $amountFormatter; } public function replace(string $placeholder, object $label_target, array $options = []): ?string @@ -74,7 +69,7 @@ final class PartLotProvider implements PlaceholderProviderInterface } if ('[[EXPIRATION_DATE]]' === $placeholder) { - if (null === $label_target->getExpirationDate()) { + if (!$label_target->getExpirationDate() instanceof \DateTimeInterface) { return ''; } $formatter = IntlDateFormatter::create( @@ -95,19 +90,19 @@ final class PartLotProvider implements PlaceholderProviderInterface } if ('[[LOCATION]]' === $placeholder) { - return $label_target->getStorageLocation() ? $label_target->getStorageLocation()->getName() : ''; + return $label_target->getStorageLocation() instanceof \App\Entity\Parts\Storelocation ? $label_target->getStorageLocation()->getName() : ''; } if ('[[LOCATION_FULL]]' === $placeholder) { - return $label_target->getStorageLocation() ? $label_target->getStorageLocation()->getFullPath() : ''; + return $label_target->getStorageLocation() instanceof \App\Entity\Parts\Storelocation ? $label_target->getStorageLocation()->getFullPath() : ''; } if ('[[OWNER]]' === $placeholder) { - return $label_target->getOwner() ? $label_target->getOwner()->getFullName() : ''; + return $label_target->getOwner() instanceof \App\Entity\UserSystem\User ? $label_target->getOwner()->getFullName() : ''; } if ('[[OWNER_USERNAME]]' === $placeholder) { - return $label_target->getOwner() ? $label_target->getOwner()->getUsername() : ''; + return $label_target->getOwner() instanceof \App\Entity\UserSystem\User ? $label_target->getOwner()->getUsername() : ''; } return $this->labelTextReplacer->handlePlaceholder($placeholder, $label_target->getPart()); diff --git a/src/Services/LabelSystem/PlaceholderProviders/PartProvider.php b/src/Services/LabelSystem/PlaceholderProviders/PartProvider.php index 48e547f6..d794b855 100644 --- a/src/Services/LabelSystem/PlaceholderProviders/PartProvider.php +++ b/src/Services/LabelSystem/PlaceholderProviders/PartProvider.php @@ -48,13 +48,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; final class PartProvider implements PlaceholderProviderInterface { - private SIFormatter $siFormatter; - private TranslatorInterface $translator; - - public function __construct(SIFormatter $SIFormatter, TranslatorInterface $translator) + public function __construct(private readonly SIFormatter $siFormatter, private readonly TranslatorInterface $translator) { - $this->siFormatter = $SIFormatter; - $this->translator = $translator; } public function replace(string $placeholder, object $part, array $options = []): ?string @@ -64,27 +59,27 @@ final class PartProvider implements PlaceholderProviderInterface } if ('[[CATEGORY]]' === $placeholder) { - return $part->getCategory() ? $part->getCategory()->getName() : ''; + return $part->getCategory() instanceof \App\Entity\Parts\Category ? $part->getCategory()->getName() : ''; } if ('[[CATEGORY_FULL]]' === $placeholder) { - return $part->getCategory() ? $part->getCategory()->getFullPath() : ''; + return $part->getCategory() instanceof \App\Entity\Parts\Category ? $part->getCategory()->getFullPath() : ''; } if ('[[MANUFACTURER]]' === $placeholder) { - return $part->getManufacturer() ? $part->getManufacturer()->getName() : ''; + return $part->getManufacturer() instanceof \App\Entity\Parts\Manufacturer ? $part->getManufacturer()->getName() : ''; } if ('[[MANUFACTURER_FULL]]' === $placeholder) { - return $part->getManufacturer() ? $part->getManufacturer()->getFullPath() : ''; + return $part->getManufacturer() instanceof \App\Entity\Parts\Manufacturer ? $part->getManufacturer()->getFullPath() : ''; } if ('[[FOOTPRINT]]' === $placeholder) { - return $part->getFootprint() ? $part->getFootprint()->getName() : ''; + return $part->getFootprint() instanceof \App\Entity\Parts\Footprint ? $part->getFootprint()->getName() : ''; } if ('[[FOOTPRINT_FULL]]' === $placeholder) { - return $part->getFootprint() ? $part->getFootprint()->getFullPath() : ''; + return $part->getFootprint() instanceof \App\Entity\Parts\Footprint ? $part->getFootprint()->getFullPath() : ''; } if ('[[MASS]]' === $placeholder) { @@ -114,7 +109,7 @@ final class PartProvider implements PlaceholderProviderInterface } if ('[[DESCRIPTION_T]]' === $placeholder) { - return strip_tags($parsedown->line($part->getDescription())); + return strip_tags((string) $parsedown->line($part->getDescription())); } if ('[[COMMENT]]' === $placeholder) { @@ -122,7 +117,7 @@ final class PartProvider implements PlaceholderProviderInterface } if ('[[COMMENT_T]]' === $placeholder) { - return strip_tags($parsedown->line($part->getComment())); + return strip_tags((string) $parsedown->line($part->getComment())); } return null; diff --git a/src/Services/LabelSystem/PlaceholderProviders/StorelocationProvider.php b/src/Services/LabelSystem/PlaceholderProviders/StorelocationProvider.php index aac7f985..85c1d13a 100644 --- a/src/Services/LabelSystem/PlaceholderProviders/StorelocationProvider.php +++ b/src/Services/LabelSystem/PlaceholderProviders/StorelocationProvider.php @@ -28,11 +28,11 @@ class StorelocationProvider implements PlaceholderProviderInterface { if ($label_target instanceof Storelocation) { if ('[[OWNER]]' === $placeholder) { - return $label_target->getOwner() ? $label_target->getOwner()->getFullName() : ''; + return $label_target->getOwner() instanceof \App\Entity\UserSystem\User ? $label_target->getOwner()->getFullName() : ''; } if ('[[OWNER_USERNAME]]' === $placeholder) { - return $label_target->getOwner() ? $label_target->getOwner()->getUsername() : ''; + return $label_target->getOwner() instanceof \App\Entity\UserSystem\User ? $label_target->getOwner()->getUsername() : ''; } } diff --git a/src/Services/LabelSystem/PlaceholderProviders/StructuralDBElementProvider.php b/src/Services/LabelSystem/PlaceholderProviders/StructuralDBElementProvider.php index f4aebd8a..31d7618e 100644 --- a/src/Services/LabelSystem/PlaceholderProviders/StructuralDBElementProvider.php +++ b/src/Services/LabelSystem/PlaceholderProviders/StructuralDBElementProvider.php @@ -58,10 +58,10 @@ final class StructuralDBElementProvider implements PlaceholderProviderInterface return $label_target->getFullPath(); } if ('[[PARENT]]' === $placeholder) { - return $label_target->getParent() ? $label_target->getParent()->getName() : ''; + return $label_target->getParent() instanceof \App\Entity\Base\AbstractStructuralDBElement ? $label_target->getParent()->getName() : ''; } if ('[[PARENT_FULL_PATH]]' === $placeholder) { - return $label_target->getParent() ? $label_target->getParent()->getFullPath() : ''; + return $label_target->getParent() instanceof \App\Entity\Base\AbstractStructuralDBElement ? $label_target->getParent()->getFullPath() : ''; } } diff --git a/src/Services/LabelSystem/SandboxedTwigProvider.php b/src/Services/LabelSystem/SandboxedTwigProvider.php index 66488fca..39b47bfb 100644 --- a/src/Services/LabelSystem/SandboxedTwigProvider.php +++ b/src/Services/LabelSystem/SandboxedTwigProvider.php @@ -114,11 +114,8 @@ final class SandboxedTwigProvider ]; private const ALLOWED_PROPERTIES = []; - private FormatExtension $appExtension; - - public function __construct(FormatExtension $appExtension) + public function __construct(private readonly FormatExtension $appExtension) { - $this->appExtension = $appExtension; } public function getTwig(LabelOptions $options): Environment diff --git a/src/Services/LogSystem/EventCommentHelper.php b/src/Services/LogSystem/EventCommentHelper.php index 4afcf04d..cf06b724 100644 --- a/src/Services/LogSystem/EventCommentHelper.php +++ b/src/Services/LogSystem/EventCommentHelper.php @@ -45,11 +45,10 @@ class EventCommentHelper { protected const MAX_MESSAGE_LENGTH = 255; - protected ?string $message; + protected ?string $message = null; public function __construct() { - $this->message = null; } /** @@ -60,11 +59,7 @@ class EventCommentHelper public function setMessage(?string $message): void { //Restrict the length of the string - if ($message) { - $this->message = mb_strimwidth($message, 0, self::MAX_MESSAGE_LENGTH, '...'); - } else { - $this->message = null; - } + $this->message = $message ? mb_strimwidth($message, 0, self::MAX_MESSAGE_LENGTH, '...') : null; } /** diff --git a/src/Services/LogSystem/EventCommentNeededHelper.php b/src/Services/LogSystem/EventCommentNeededHelper.php index 7305b304..23e22072 100644 --- a/src/Services/LogSystem/EventCommentNeededHelper.php +++ b/src/Services/LogSystem/EventCommentNeededHelper.php @@ -26,9 +26,7 @@ namespace App\Services\LogSystem; */ class EventCommentNeededHelper { - protected array $enforce_change_comments_for; - - public const VALID_OPERATION_TYPES = [ + final public const VALID_OPERATION_TYPES = [ 'part_edit', 'part_create', 'part_delete', @@ -38,15 +36,12 @@ class EventCommentNeededHelper 'datastructure_delete', ]; - public function __construct(array $enforce_change_comments_for) + public function __construct(protected array $enforce_change_comments_for) { - $this->enforce_change_comments_for = $enforce_change_comments_for; } /** * Checks if a log change comment is needed for the given operation type - * @param string $comment_type - * @return bool */ public function isCommentNeeded(string $comment_type): bool { diff --git a/src/Services/LogSystem/EventLogger.php b/src/Services/LogSystem/EventLogger.php index dde19edc..afc1c69b 100644 --- a/src/Services/LogSystem/EventLogger.php +++ b/src/Services/LogSystem/EventLogger.php @@ -30,22 +30,8 @@ use Symfony\Component\Security\Core\Security; class EventLogger { - protected int $minimum_log_level; - protected array $blacklist; - protected array $whitelist; - protected EntityManagerInterface $em; - protected \Symfony\Bundle\SecurityBundle\Security $security; - protected ConsoleInfoHelper $console_info_helper; - - public function __construct(int $minimum_log_level, array $blacklist, array $whitelist, EntityManagerInterface $em, - \Symfony\Bundle\SecurityBundle\Security $security, ConsoleInfoHelper $console_info_helper) + public function __construct(protected int $minimum_log_level, protected array $blacklist, protected array $whitelist, protected EntityManagerInterface $em, protected \Symfony\Bundle\SecurityBundle\Security $security, protected ConsoleInfoHelper $console_info_helper) { - $this->minimum_log_level = $minimum_log_level; - $this->blacklist = $blacklist; - $this->whitelist = $whitelist; - $this->em = $em; - $this->security = $security; - $this->console_info_helper = $console_info_helper; } /** @@ -58,14 +44,14 @@ class EventLogger { $user = $this->security->getUser(); //If the user is not specified explicitly, set it to the current user - if ((null === $user || $user instanceof User) && null === $logEntry->getUser()) { - if (null === $user) { + if ((!$user instanceof \Symfony\Component\Security\Core\User\UserInterface || $user instanceof User) && !$logEntry->getUser() instanceof \App\Entity\UserSystem\User) { + if (!$user instanceof \App\Entity\UserSystem\User) { $repo = $this->em->getRepository(User::class); $user = $repo->getAnonymousUser(); } //If no anonymous user is available skip the log (needed for data fixtures) - if (null === $user) { + if (!$user instanceof \App\Entity\UserSystem\User) { return false; } $logEntry->setUser($user); @@ -88,15 +74,13 @@ class EventLogger /** * Same as log(), but this function can be safely called from within the onFlush() doctrine event, as it * updated the changesets of the unit of work. - * @param AbstractLogEntry $logEntry - * @return bool */ public function logFromOnFlush(AbstractLogEntry $logEntry): bool { if ($this->log($logEntry)) { $uow = $this->em->getUnitOfWork(); //As we call it from onFlush, we have to recompute the changeset here, according to https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/reference/events.html#reference-events-on-flush - $uow->computeChangeSet($this->em->getClassMetadata(get_class($logEntry)), $logEntry); + $uow->computeChangeSet($this->em->getClassMetadata($logEntry::class), $logEntry); return true; } @@ -125,9 +109,9 @@ class EventLogger ?array $whitelist = null ): bool { //Apply the global settings, if nothing was specified - $minimum_log_level = $minimum_log_level ?? $this->minimum_log_level; - $blacklist = $blacklist ?? $this->blacklist; - $whitelist = $whitelist ?? $this->whitelist; + $minimum_log_level ??= $this->minimum_log_level; + $blacklist ??= $this->blacklist; + $whitelist ??= $this->whitelist; //Don't add the entry if it does not reach the minimum level if ($logEntry->getLevel() > $minimum_log_level) { @@ -135,17 +119,12 @@ class EventLogger } //Check if the event type is blacklisted - if (!empty($blacklist) && $this->isObjectClassInArray($logEntry, $blacklist)) { + if ($blacklist !== [] && $this->isObjectClassInArray($logEntry, $blacklist)) { return false; } - //Check for whitelisting - if (!empty($whitelist) && !$this->isObjectClassInArray($logEntry, $whitelist)) { - return false; - } - // By default, all things should be added - return true; + return !($whitelist !== [] && !$this->isObjectClassInArray($logEntry, $whitelist)); } /** @@ -157,13 +136,13 @@ class EventLogger protected function isObjectClassInArray(object $object, array $classes): bool { //Check if the class is directly in the classes array - if (in_array(get_class($object), $classes, true)) { + if (in_array($object::class, $classes, true)) { return true; } //Iterate over all classes and check for inheritance foreach ($classes as $class) { - if (is_a($object, $class)) { + if ($object instanceof $class) { return true; } } diff --git a/src/Services/LogSystem/EventUndoHelper.php b/src/Services/LogSystem/EventUndoHelper.php index f2328cbc..2416ced0 100644 --- a/src/Services/LogSystem/EventUndoHelper.php +++ b/src/Services/LogSystem/EventUndoHelper.php @@ -46,18 +46,16 @@ use InvalidArgumentException; class EventUndoHelper { - public const MODE_UNDO = 'undo'; - public const MODE_REVERT = 'revert'; + final public const MODE_UNDO = 'undo'; + final public const MODE_REVERT = 'revert'; protected const ALLOWED_MODES = [self::MODE_REVERT, self::MODE_UNDO]; - protected ?AbstractLogEntry $undone_event; - protected string $mode; + protected ?AbstractLogEntry $undone_event = null; + protected string $mode = self::MODE_UNDO; public function __construct() { - $this->undone_event = null; - $this->mode = self::MODE_UNDO; } public function setMode(string $mode): void diff --git a/src/Services/LogSystem/LogDataFormatter.php b/src/Services/LogSystem/LogDataFormatter.php index 1980c029..46dae945 100644 --- a/src/Services/LogSystem/LogDataFormatter.php +++ b/src/Services/LogSystem/LogDataFormatter.php @@ -29,25 +29,14 @@ class LogDataFormatter { private const STRING_MAX_LENGTH = 1024; - private TranslatorInterface $translator; - private EntityManagerInterface $entityManager; - private ElementTypeNameGenerator $elementTypeNameGenerator; - - public function __construct(TranslatorInterface $translator, EntityManagerInterface $entityManager, ElementTypeNameGenerator $elementTypeNameGenerator) + public function __construct(private readonly TranslatorInterface $translator, private readonly EntityManagerInterface $entityManager, private readonly ElementTypeNameGenerator $elementTypeNameGenerator) { - $this->translator = $translator; - $this->entityManager = $entityManager; - $this->elementTypeNameGenerator = $elementTypeNameGenerator; } /** * Formats the given data of a log entry as HTML - * @param mixed $data - * @param AbstractLogEntry $logEntry - * @param string $fieldName - * @return string */ - public function formatData($data, AbstractLogEntry $logEntry, string $fieldName): string + public function formatData(mixed $data, AbstractLogEntry $logEntry, string $fieldName): string { if (is_string($data)) { $tmp = '"' . mb_strimwidth(htmlspecialchars($data), 0, self::STRING_MAX_LENGTH, ) . '"'; @@ -55,9 +44,8 @@ class LogDataFormatter //Show special characters and line breaks $tmp = preg_replace('/\n/', '\\n
', $tmp); $tmp = preg_replace('/\r/', '\\r', $tmp); - $tmp = preg_replace('/\t/', '\\t', $tmp); - return $tmp; + return preg_replace('/\t/', '\\t', $tmp); } if (is_bool($data)) { @@ -126,7 +114,7 @@ class LogDataFormatter } - } catch (\InvalidArgumentException|\ReflectionException $exception) { + } catch (\InvalidArgumentException|\ReflectionException) { return 'unknown target class: ' . $id; } } @@ -147,7 +135,7 @@ class LogDataFormatter try { $dateTime = new \DateTime($date, new \DateTimeZone($timezone)); - } catch (\Exception $exception) { + } catch (\Exception) { return 'unknown DateTime format'; } diff --git a/src/Services/LogSystem/LogDiffFormatter.php b/src/Services/LogSystem/LogDiffFormatter.php index 92b6d814..500e1a72 100644 --- a/src/Services/LogSystem/LogDiffFormatter.php +++ b/src/Services/LogSystem/LogDiffFormatter.php @@ -29,7 +29,6 @@ class LogDiffFormatter * If the diff is not possible, an empty string is returned. * @param $old_data * @param $new_data - * @return string */ public function formatDiff($old_data, $new_data): string { @@ -67,7 +66,7 @@ class LogDiffFormatter //Positive difference if ($difference > 0) { return sprintf('+%s', $difference); - } else if ($difference < 0) { + } elseif ($difference < 0) { return sprintf('%s', $difference); } else { return sprintf('%s', $difference); diff --git a/src/Services/LogSystem/LogEntryExtraFormatter.php b/src/Services/LogSystem/LogEntryExtraFormatter.php index 8ec328d0..017de1e0 100644 --- a/src/Services/LogSystem/LogEntryExtraFormatter.php +++ b/src/Services/LogSystem/LogEntryExtraFormatter.php @@ -48,13 +48,9 @@ class LogEntryExtraFormatter { protected const CONSOLE_SEARCH = ['', '', '', '', '']; protected const CONSOLE_REPLACE = ['→', '', '', '', '']; - protected TranslatorInterface $translator; - protected ElementTypeNameGenerator $elementTypeNameGenerator; - public function __construct(TranslatorInterface $translator, ElementTypeNameGenerator $elementTypeNameGenerator) + public function __construct(protected TranslatorInterface $translator, protected ElementTypeNameGenerator $elementTypeNameGenerator) { - $this->translator = $translator; - $this->elementTypeNameGenerator = $elementTypeNameGenerator; } /** @@ -163,7 +159,7 @@ class LogEntryExtraFormatter '%s %s (%s)', $context->getOldInstock(), $context->getNewInstock(), - (!$context->isWithdrawal() ? '+' : '-').$context->getDifference(true) + ($context->isWithdrawal() ? '-' : '+').$context->getDifference(true) ); $array['log.instock_changed.comment'] = htmlspecialchars($context->getComment()); } diff --git a/src/Services/LogSystem/LogLevelHelper.php b/src/Services/LogSystem/LogLevelHelper.php index 926531da..efc8dd93 100644 --- a/src/Services/LogSystem/LogLevelHelper.php +++ b/src/Services/LogSystem/LogLevelHelper.php @@ -29,30 +29,20 @@ class LogLevelHelper * Returns the FontAwesome icon class for the given log level. * This returns just the specific icon class (so 'fa-info' for example). * @param string $logLevel The string representation of the log level (one of the LogLevel::* constants) - * @return string */ public function logLevelToIconClass(string $logLevel): string { - switch ($logLevel) { - case LogLevel::DEBUG: - return 'fa-bug'; - case LogLevel::INFO: - return 'fa-info'; - case LogLevel::NOTICE: - return 'fa-flag'; - case LogLevel::WARNING: - return 'fa-exclamation-circle'; - case LogLevel::ERROR: - return 'fa-exclamation-triangle'; - case LogLevel::CRITICAL: - return 'fa-bolt'; - case LogLevel::ALERT: - return 'fa-radiation'; - case LogLevel::EMERGENCY: - return 'fa-skull-crossbones'; - default: - return 'fa-question-circle'; - } + return match ($logLevel) { + LogLevel::DEBUG => 'fa-bug', + LogLevel::INFO => 'fa-info', + LogLevel::NOTICE => 'fa-flag', + LogLevel::WARNING => 'fa-exclamation-circle', + LogLevel::ERROR => 'fa-exclamation-triangle', + LogLevel::CRITICAL => 'fa-bolt', + LogLevel::ALERT => 'fa-radiation', + LogLevel::EMERGENCY => 'fa-skull-crossbones', + default => 'fa-question-circle', + }; } /** @@ -63,18 +53,11 @@ class LogLevelHelper public function logLevelToTableColorClass(string $logLevel): string { - switch ($logLevel) { - case LogLevel::EMERGENCY: - case LogLevel::ALERT: - case LogLevel::CRITICAL: - case LogLevel::ERROR: - return 'table-danger'; - case LogLevel::WARNING: - return 'table-warning'; - case LogLevel::NOTICE: - return 'table-info'; - default: - return ''; - } + return match ($logLevel) { + LogLevel::EMERGENCY, LogLevel::ALERT, LogLevel::CRITICAL, LogLevel::ERROR => 'table-danger', + LogLevel::WARNING => 'table-warning', + LogLevel::NOTICE => 'table-info', + default => '', + }; } } \ No newline at end of file diff --git a/src/Services/LogSystem/LogTargetHelper.php b/src/Services/LogSystem/LogTargetHelper.php index 63946a0f..e8ea4a6b 100644 --- a/src/Services/LogSystem/LogTargetHelper.php +++ b/src/Services/LogSystem/LogTargetHelper.php @@ -40,21 +40,12 @@ use Symfony\Contracts\Translation\TranslatorInterface; class LogTargetHelper { - protected EntityManagerInterface $em; protected LogEntryRepository $entryRepository; - protected EntityURLGenerator $entityURLGenerator; - protected ElementTypeNameGenerator $elementTypeNameGenerator; - protected TranslatorInterface $translator; - public function __construct(EntityManagerInterface $entityManager, EntityURLGenerator $entityURLGenerator, - ElementTypeNameGenerator $elementTypeNameGenerator, TranslatorInterface $translator) + public function __construct(protected EntityManagerInterface $em, protected EntityURLGenerator $entityURLGenerator, + protected ElementTypeNameGenerator $elementTypeNameGenerator, protected TranslatorInterface $translator) { - $this->em = $entityManager; - $this->entryRepository = $entityManager->getRepository(AbstractLogEntry::class); - - $this->entityURLGenerator = $entityURLGenerator; - $this->elementTypeNameGenerator = $elementTypeNameGenerator; - $this->translator = $translator; + $this->entryRepository = $em->getRepository(AbstractLogEntry::class); } private function configureOptions(OptionsResolver $resolver): self @@ -79,7 +70,7 @@ class LogTargetHelper $target = $this->entryRepository->getTargetElement($context); //If the target is null and the context has a target, that means that the target was deleted. Show it that way. - if ($target === null) { + if (!$target instanceof \App\Entity\Base\AbstractDBElement) { if ($context->hasTarget()) { return $this->elementTypeNameGenerator->formatElementDeletedHTML($context->getTargetClass(), $context->getTargetId()); diff --git a/src/Services/LogSystem/TimeTravel.php b/src/Services/LogSystem/TimeTravel.php index daeed7ea..5cc4be79 100644 --- a/src/Services/LogSystem/TimeTravel.php +++ b/src/Services/LogSystem/TimeTravel.php @@ -43,12 +43,10 @@ use ReflectionClass; class TimeTravel { - protected EntityManagerInterface $em; protected LogEntryRepository $repo; - public function __construct(EntityManagerInterface $em) + public function __construct(protected EntityManagerInterface $em) { - $this->em = $em; $this->repo = $em->getRepository(AbstractLogEntry::class); } @@ -126,7 +124,7 @@ class TimeTravel } // Revert any of the associated elements - $metadata = $this->em->getClassMetadata(get_class($element)); + $metadata = $this->em->getClassMetadata($element::class); $associations = $metadata->getAssociationMappings(); foreach ($associations as $field => $mapping) { if ( @@ -148,10 +146,10 @@ class TimeTravel } elseif ( //Revert *_TO_MANY associations (collection properties) (ClassMetadataInfo::MANY_TO_MANY === $mapping['type'] || ClassMetadataInfo::ONE_TO_MANY === $mapping['type']) - && false === $mapping['isOwningSide'] + && !$mapping['isOwningSide'] ) { $target_elements = $this->getField($element, $field); - if (null === $target_elements || count($target_elements) > 10) { + if (null === $target_elements || (is_countable($target_elements) ? count($target_elements) : 0) > 10) { continue; } foreach ($target_elements as $target_element) { @@ -200,7 +198,7 @@ class TimeTravel if (!$element instanceof TimeStampableInterface) { return; } - $metadata = $this->em->getClassMetadata(get_class($element)); + $metadata = $this->em->getClassMetadata($element::class); $old_data = $logEntry->getOldData(); foreach ($old_data as $field => $data) { @@ -232,19 +230,16 @@ class TimeTravel protected function getField(AbstractDBElement $element, string $field) { - $reflection = new ReflectionClass(get_class($element)); + $reflection = new ReflectionClass($element::class); $property = $reflection->getProperty($field); $property->setAccessible(true); return $property->getValue($element); } - /** - * @param DateTime|int|null $new_value - */ - protected function setField(AbstractDBElement $element, string $field, $new_value): void + protected function setField(AbstractDBElement $element, string $field, \DateTime|int|null $new_value): void { - $reflection = new ReflectionClass(get_class($element)); + $reflection = new ReflectionClass($element::class); $property = $reflection->getProperty($field); $property->setAccessible(true); diff --git a/src/Services/Misc/DBInfoHelper.php b/src/Services/Misc/DBInfoHelper.php index 896c0637..3d5c27a7 100644 --- a/src/Services/Misc/DBInfoHelper.php +++ b/src/Services/Misc/DBInfoHelper.php @@ -31,11 +31,9 @@ use Doctrine\ORM\EntityManagerInterface; class DBInfoHelper { protected Connection $connection; - protected EntityManagerInterface $entityManager; - public function __construct(EntityManagerInterface $entityManager) + public function __construct(protected EntityManagerInterface $entityManager) { - $this->entityManager = $entityManager; $this->connection = $entityManager->getConnection(); } @@ -58,7 +56,6 @@ class DBInfoHelper /** * Returns the database version of the used database. - * @return string|null * @throws \Doctrine\DBAL\Exception */ public function getDatabaseVersion(): ?string @@ -84,7 +81,7 @@ class DBInfoHelper if ($this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform) { try { return $this->connection->fetchOne('SELECT SUM(data_length + index_length) FROM information_schema.TABLES WHERE table_schema = DATABASE()'); - } catch (\Doctrine\DBAL\Exception $e) { + } catch (\Doctrine\DBAL\Exception) { return null; } } @@ -92,7 +89,7 @@ class DBInfoHelper if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) { try { return $this->connection->fetchOne('SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size();'); - } catch (\Doctrine\DBAL\Exception $e) { + } catch (\Doctrine\DBAL\Exception) { return null; } } @@ -102,7 +99,6 @@ class DBInfoHelper /** * Returns the name of the database. - * @return string|null */ public function getDatabaseName(): ?string { @@ -111,14 +107,13 @@ class DBInfoHelper /** * Returns the name of the database user. - * @return string|null */ public function getDatabaseUsername(): ?string { if ($this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform) { try { return $this->connection->fetchOne('SELECT USER()'); - } catch (\Doctrine\DBAL\Exception $e) { + } catch (\Doctrine\DBAL\Exception) { return null; } } diff --git a/src/Services/Misc/RangeParser.php b/src/Services/Misc/RangeParser.php index ab6e9aba..ddd4fd3b 100644 --- a/src/Services/Misc/RangeParser.php +++ b/src/Services/Misc/RangeParser.php @@ -94,7 +94,7 @@ class RangeParser $this->parse($range_str); return true; - } catch (InvalidArgumentException $exception) { + } catch (InvalidArgumentException) { return false; } } diff --git a/src/Services/Parameters/ParameterExtractor.php b/src/Services/Parameters/ParameterExtractor.php index a5c6a0c0..c1151970 100644 --- a/src/Services/Parameters/ParameterExtractor.php +++ b/src/Services/Parameters/ParameterExtractor.php @@ -74,7 +74,7 @@ class ParameterExtractor $split = $this->splitString($input); foreach ($split as $param_string) { $tmp = $this->stringToParam($param_string, $class); - if (null !== $tmp) { + if ($tmp instanceof \App\Entity\Parameters\AbstractParameter) { $parameters[] = $tmp; } } @@ -89,7 +89,7 @@ class ParameterExtractor $matches = []; preg_match($regex, $input, $matches); - if (!empty($matches)) { + if ($matches !== []) { [, $name, $value] = $matches; $value = trim($value); diff --git a/src/Services/Parts/PartLotWithdrawAddHelper.php b/src/Services/Parts/PartLotWithdrawAddHelper.php index a6f7060c..f63ae15f 100644 --- a/src/Services/Parts/PartLotWithdrawAddHelper.php +++ b/src/Services/Parts/PartLotWithdrawAddHelper.php @@ -9,20 +9,12 @@ use App\Services\LogSystem\EventLogger; final class PartLotWithdrawAddHelper { - private EventLogger $eventLogger; - private EventCommentHelper $eventCommentHelper; - - - public function __construct(EventLogger $eventLogger, EventCommentHelper $eventCommentHelper) + public function __construct(private readonly EventLogger $eventLogger, private readonly EventCommentHelper $eventCommentHelper) { - $this->eventLogger = $eventLogger; - $this->eventCommentHelper = $eventCommentHelper; } /** * Checks whether the given part can - * @param PartLot $partLot - * @return bool */ public function canAdd(PartLot $partLot): bool { @@ -32,16 +24,11 @@ final class PartLotWithdrawAddHelper } //So far all other restrictions are defined at the storelocation level - if($partLot->getStorageLocation() === null) { + if(!$partLot->getStorageLocation() instanceof \App\Entity\Parts\Storelocation) { return true; } - //We can not add parts if the storage location of the lot is marked as full - if($partLot->getStorageLocation()->isFull()) { - return false; - } - - return true; + return !$partLot->getStorageLocation()->isFull(); } public function canWithdraw(PartLot $partLot): bool @@ -50,13 +37,8 @@ final class PartLotWithdrawAddHelper if ($partLot->isInstockUnknown()) { return false; } - //Part must contain more than 0 parts - if ($partLot->getAmount() <= 0) { - return false; - } - - return true; + return $partLot->getAmount() > 0; } /** @@ -153,7 +135,6 @@ final class PartLotWithdrawAddHelper * @param PartLot $target The part lot to which the parts should be added * @param float $amount The amount of parts that should be moved * @param string|null $comment A comment describing the reason for the move - * @return void */ public function move(PartLot $origin, PartLot $target, float $amount, ?string $comment = null): void { diff --git a/src/Services/Parts/PartsTableActionHandler.php b/src/Services/Parts/PartsTableActionHandler.php index b3cccb0e..d5e1f8a1 100644 --- a/src/Services/Parts/PartsTableActionHandler.php +++ b/src/Services/Parts/PartsTableActionHandler.php @@ -37,15 +37,8 @@ use Symfony\Component\Security\Core\Security; final class PartsTableActionHandler { - private EntityManagerInterface $entityManager; - private \Symfony\Bundle\SecurityBundle\Security $security; - private UrlGeneratorInterface $urlGenerator; - - public function __construct(EntityManagerInterface $entityManager, \Symfony\Bundle\SecurityBundle\Security $security, UrlGeneratorInterface $urlGenerator) + public function __construct(private readonly EntityManagerInterface $entityManager, private readonly \Symfony\Bundle\SecurityBundle\Security $security, private readonly UrlGeneratorInterface $urlGenerator) { - $this->entityManager = $entityManager; - $this->security = $security; - $this->urlGenerator = $urlGenerator; } /** @@ -86,10 +79,8 @@ final class PartsTableActionHandler if ($action === 'generate_label') { $targets = implode(',', array_map(static fn (Part $part) => $part->getID(), $selected_parts)); } else { //For lots we have to extract the part lots - $targets = implode(',', array_map(static function (Part $part) { - //We concat the lot IDs of every part with a comma (which are later concated with a comma too per part) - return implode(',', array_map(static fn (PartLot $lot) => $lot->getID(), $part->getPartLots()->toArray())); - }, $selected_parts)); + $targets = implode(',', array_map(static fn(Part $part): string => //We concat the lot IDs of every part with a comma (which are later concated with a comma too per part) +implode(',', array_map(static fn (PartLot $lot) => $lot->getID(), $part->getPartLots()->toArray())), $selected_parts)); } return new RedirectResponse( @@ -106,18 +97,11 @@ final class PartsTableActionHandler $matches = []; if (preg_match('/^export_(json|yaml|xml|csv)$/', $action, $matches)) { $ids = implode(',', array_map(static fn (Part $part) => $part->getID(), $selected_parts)); - switch ($target_id) { - case 1: - default: - $level = 'simple'; - break; - case 2: - $level = 'extended'; - break; - case 3: - $level = 'full'; - break; - } + $level = match ($target_id) { + 2 => 'extended', + 3 => 'full', + default => 'simple', + }; return new RedirectResponse( diff --git a/src/Services/Parts/PricedetailHelper.php b/src/Services/Parts/PricedetailHelper.php index a270c622..14c914d4 100644 --- a/src/Services/Parts/PricedetailHelper.php +++ b/src/Services/Parts/PricedetailHelper.php @@ -34,12 +34,10 @@ use function count; class PricedetailHelper { - protected string $base_currency; protected string $locale; - public function __construct(string $base_currency) + public function __construct(protected string $base_currency) { - $this->base_currency = $base_currency; $this->locale = Locale::getDefault(); } @@ -67,9 +65,7 @@ class PricedetailHelper } else { // We have to sort the pricedetails manually $array = $pricedetails->map( - static function (Pricedetail $pricedetail) { - return $pricedetail->getMinDiscountQuantity(); - } + static fn(Pricedetail $pricedetail) => $pricedetail->getMinDiscountQuantity() )->toArray(); sort($array); $max_amount = end($array); @@ -154,13 +150,13 @@ class PricedetailHelper $pricedetail = $orderdetail->findPriceForQty($amount); //When we don't have information about this amount, ignore it - if (null === $pricedetail) { + if (!$pricedetail instanceof \App\Entity\PriceInformations\Pricedetail) { continue; } $converted = $this->convertMoneyToCurrency($pricedetail->getPricePerUnit(), $pricedetail->getCurrency(), $currency); //Ignore price information that can not be converted to base currency. - if (null !== $converted) { + if ($converted instanceof \Brick\Math\BigDecimal) { $avg = $avg->plus($converted); ++$count; } @@ -193,9 +189,9 @@ class PricedetailHelper $val_base = $value; //Convert value to base currency - if (null !== $originCurrency) { + if ($originCurrency instanceof \App\Entity\PriceInformations\Currency) { //Without an exchange rate we can not calculate the exchange rate - if (null === $originCurrency->getExchangeRate() || $originCurrency->getExchangeRate()->isZero()) { + if (!$originCurrency->getExchangeRate() instanceof \Brick\Math\BigDecimal || $originCurrency->getExchangeRate()->isZero()) { return null; } @@ -204,9 +200,9 @@ class PricedetailHelper $val_target = $val_base; //Convert value in base currency to target currency - if (null !== $targetCurrency) { + if ($targetCurrency instanceof \App\Entity\PriceInformations\Currency) { //Without an exchange rate we can not calculate the exchange rate - if (null === $targetCurrency->getExchangeRate()) { + if (!$targetCurrency->getExchangeRate() instanceof \Brick\Math\BigDecimal) { return null; } diff --git a/src/Services/ProjectSystem/ProjectBuildHelper.php b/src/Services/ProjectSystem/ProjectBuildHelper.php index 0e091547..30f31c33 100644 --- a/src/Services/ProjectSystem/ProjectBuildHelper.php +++ b/src/Services/ProjectSystem/ProjectBuildHelper.php @@ -27,24 +27,19 @@ use App\Services\Parts\PartLotWithdrawAddHelper; class ProjectBuildHelper { - private PartLotWithdrawAddHelper $withdraw_add_helper; - - public function __construct(PartLotWithdrawAddHelper $withdraw_add_helper) + public function __construct(private readonly PartLotWithdrawAddHelper $withdraw_add_helper) { - $this->withdraw_add_helper = $withdraw_add_helper; } /** * Returns the maximum buildable amount of the given BOM entry based on the stock of the used parts. * This function only works for BOM entries that are associated with a part. - * @param ProjectBOMEntry $projectBOMEntry - * @return int */ public function getMaximumBuildableCountForBOMEntry(ProjectBOMEntry $projectBOMEntry): int { $part = $projectBOMEntry->getPart(); - if ($part === null) { + if (!$part instanceof \App\Entity\Parts\Part) { throw new \InvalidArgumentException('This function cannot determine the maximum buildable count for a BOM entry without a part!'); } @@ -59,8 +54,6 @@ class ProjectBuildHelper /** * Returns the maximum buildable amount of the given project, based on the stock of the used parts in the BOM. - * @param Project $project - * @return int */ public function getMaximumBuildableCount(Project $project): int { @@ -81,9 +74,7 @@ class ProjectBuildHelper /** * Checks if the given project can be built with the current stock. * This means that the maximum buildable count is greater or equal than the requested $number_of_projects - * @param Project $project * @parm int $number_of_builds - * @return bool */ public function isProjectBuildable(Project $project, int $number_of_builds = 1): bool { @@ -93,9 +84,6 @@ class ProjectBuildHelper /** * Check if the given BOM entry can be built with the current stock. * This means that the maximum buildable count is greater or equal than the requested $number_of_projects - * @param ProjectBOMEntry $bom_entry - * @param int $number_of_builds - * @return bool */ public function isBOMEntryBuildable(ProjectBOMEntry $bom_entry, int $number_of_builds = 1): bool { @@ -120,7 +108,7 @@ class ProjectBuildHelper $part = $bomEntry->getPart(); //Skip BOM entries without a part (as we can not determine that) - if ($part === null) { + if (!$part instanceof \App\Entity\Parts\Part) { continue; } @@ -138,8 +126,6 @@ class ProjectBuildHelper * Withdraw the parts from the stock using the given ProjectBuildRequest and create the build parts entries, if needed. * The ProjectBuildRequest has to be validated before!! * You have to flush changes to DB afterward - * @param ProjectBuildRequest $buildRequest - * @return void */ public function doBuild(ProjectBuildRequest $buildRequest): void { diff --git a/src/Services/ProjectSystem/ProjectBuildPartHelper.php b/src/Services/ProjectSystem/ProjectBuildPartHelper.php index 136e2ff7..80ab9395 100644 --- a/src/Services/ProjectSystem/ProjectBuildPartHelper.php +++ b/src/Services/ProjectSystem/ProjectBuildPartHelper.php @@ -10,8 +10,6 @@ class ProjectBuildPartHelper /** * Returns a part that represents the builds of a project. This part is not saved to the database, and can be used * as initial data for the new part form. - * @param Project $project - * @return Part */ public function getPartInitialization(Project $project): Part { diff --git a/src/Services/Tools/ExchangeRateUpdater.php b/src/Services/Tools/ExchangeRateUpdater.php index 241e2539..04ef4d26 100644 --- a/src/Services/Tools/ExchangeRateUpdater.php +++ b/src/Services/Tools/ExchangeRateUpdater.php @@ -27,13 +27,8 @@ use Swap\Swap; class ExchangeRateUpdater { - private string $base_currency; - private Swap $swap; - - public function __construct(string $base_currency, Swap $swap) + public function __construct(private readonly string $base_currency, private readonly Swap $swap) { - $this->base_currency = $base_currency; - $this->swap = $swap; } /** diff --git a/src/Services/Tools/StatisticsHelper.php b/src/Services/Tools/StatisticsHelper.php index f31cb440..0ee736f9 100644 --- a/src/Services/Tools/StatisticsHelper.php +++ b/src/Services/Tools/StatisticsHelper.php @@ -62,13 +62,11 @@ use InvalidArgumentException; class StatisticsHelper { - protected EntityManagerInterface $em; protected PartRepository $part_repo; protected AttachmentRepository $attachment_repo; - public function __construct(EntityManagerInterface $em) + public function __construct(protected EntityManagerInterface $em) { - $this->em = $em; $this->part_repo = $this->em->getRepository(Part::class); $this->attachment_repo = $this->em->getRepository(Attachment::class); } diff --git a/src/Services/Tools/TagFinder.php b/src/Services/Tools/TagFinder.php index d52b3008..bfc7c9db 100644 --- a/src/Services/Tools/TagFinder.php +++ b/src/Services/Tools/TagFinder.php @@ -34,11 +34,8 @@ use function array_slice; */ class TagFinder { - protected EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(protected EntityManagerInterface $em) { - $this->em = $entityManager; } /** @@ -78,7 +75,7 @@ class TagFinder //Iterate over each possible tags (which are comma separated) and extract tags which match our keyword foreach ($possible_tags as $tags) { - $tags = explode(',', $tags['tags']); + $tags = explode(',', (string) $tags['tags']); $results = array_merge($results, preg_grep($keyword_regex, $tags)); } diff --git a/src/Services/TranslationExtractor/PermissionExtractor.php b/src/Services/TranslationExtractor/PermissionExtractor.php index 03acd5db..e17cba7a 100644 --- a/src/Services/TranslationExtractor/PermissionExtractor.php +++ b/src/Services/TranslationExtractor/PermissionExtractor.php @@ -32,7 +32,7 @@ use Symfony\Component\Translation\MessageCatalogue; */ final class PermissionExtractor implements ExtractorInterface { - private array $permission_structure; + private readonly array $permission_structure; private bool $finished = false; public function __construct(PermissionManager $resolver) diff --git a/src/Services/Trees/NodesListBuilder.php b/src/Services/Trees/NodesListBuilder.php index 66ec2d40..30b868d3 100644 --- a/src/Services/Trees/NodesListBuilder.php +++ b/src/Services/Trees/NodesListBuilder.php @@ -34,15 +34,8 @@ use Symfony\Contracts\Cache\TagAwareCacheInterface; */ class NodesListBuilder { - protected EntityManagerInterface $em; - protected TagAwareCacheInterface $cache; - protected UserCacheKeyGenerator $keyGenerator; - - public function __construct(EntityManagerInterface $em, TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator) + public function __construct(protected EntityManagerInterface $em, protected TagAwareCacheInterface $cache, protected UserCacheKeyGenerator $keyGenerator) { - $this->em = $em; - $this->keyGenerator = $keyGenerator; - $this->cache = $treeCache; } /** @@ -56,7 +49,7 @@ class NodesListBuilder */ public function typeToNodesList(string $class_name, ?AbstractStructuralDBElement $parent = null): array { - $parent_id = null !== $parent ? $parent->getID() : '0'; + $parent_id = $parent instanceof \App\Entity\Base\AbstractStructuralDBElement ? $parent->getID() : '0'; // Backslashes are not allowed in cache keys $secure_class_name = str_replace('\\', '_', $class_name); $key = 'list_'.$this->keyGenerator->generateKey().'_'.$secure_class_name.$parent_id; @@ -81,6 +74,6 @@ class NodesListBuilder */ public function getChildrenFlatList(AbstractStructuralDBElement $element): array { - return $this->typeToNodesList(get_class($element), $element); + return $this->typeToNodesList($element::class, $element); } } diff --git a/src/Services/Trees/SidebarTreeUpdater.php b/src/Services/Trees/SidebarTreeUpdater.php index 13c3fb6c..16853d7e 100644 --- a/src/Services/Trees/SidebarTreeUpdater.php +++ b/src/Services/Trees/SidebarTreeUpdater.php @@ -27,19 +27,18 @@ use Symfony\Contracts\Cache\TagAwareCacheInterface; final class SidebarTreeUpdater { private const CACHE_KEY = 'sidebar_tree_updated'; - private const TTL = 60 * 60 * 24; // 24 hours + private const TTL = 60 * 60 * 24; - private CacheInterface $cache; - - public function __construct(TagAwareCacheInterface $treeCache) + public function __construct( + // 24 hours + private readonly TagAwareCacheInterface $cache + ) { - $this->cache = $treeCache; } /** * Returns the time when the sidebar tree was updated the last time. * The frontend uses this information to reload the sidebar tree. - * @return \DateTimeInterface */ public function getLastTreeUpdate(): \DateTimeInterface { diff --git a/src/Services/Trees/StructuralElementRecursionHelper.php b/src/Services/Trees/StructuralElementRecursionHelper.php index 3096740c..bc46d7f7 100644 --- a/src/Services/Trees/StructuralElementRecursionHelper.php +++ b/src/Services/Trees/StructuralElementRecursionHelper.php @@ -27,11 +27,8 @@ use Doctrine\ORM\EntityManagerInterface; class StructuralElementRecursionHelper { - protected EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $em) + public function __construct(protected EntityManagerInterface $em) { - $this->em = $em; } /** diff --git a/src/Services/Trees/ToolsTreeBuilder.php b/src/Services/Trees/ToolsTreeBuilder.php index 587dfbc7..37c84642 100644 --- a/src/Services/Trees/ToolsTreeBuilder.php +++ b/src/Services/Trees/ToolsTreeBuilder.php @@ -49,24 +49,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class ToolsTreeBuilder { - protected TranslatorInterface $translator; - protected UrlGeneratorInterface $urlGenerator; - protected UserCacheKeyGenerator $keyGenerator; - protected TagAwareCacheInterface $cache; - protected \Symfony\Bundle\SecurityBundle\Security $security; - - public function __construct(TranslatorInterface $translator, UrlGeneratorInterface $urlGenerator, - TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator, - \Symfony\Bundle\SecurityBundle\Security $security) + public function __construct(protected TranslatorInterface $translator, protected UrlGeneratorInterface $urlGenerator, protected TagAwareCacheInterface $cache, protected UserCacheKeyGenerator $keyGenerator, protected \Symfony\Bundle\SecurityBundle\Security $security) { - $this->translator = $translator; - $this->urlGenerator = $urlGenerator; - - $this->cache = $treeCache; - - $this->keyGenerator = $keyGenerator; - - $this->security = $security; } /** diff --git a/src/Services/Trees/TreeViewGenerator.php b/src/Services/Trees/TreeViewGenerator.php index e5bb4ddc..61f32922 100644 --- a/src/Services/Trees/TreeViewGenerator.php +++ b/src/Services/Trees/TreeViewGenerator.php @@ -47,26 +47,8 @@ use function count; class TreeViewGenerator { - protected EntityURLGenerator $urlGenerator; - protected EntityManagerInterface $em; - protected TagAwareCacheInterface $cache; - protected UserCacheKeyGenerator $keyGenerator; - protected TranslatorInterface $translator; - - protected bool $rootNodeExpandedByDefault; - protected bool $rootNodeEnabled; - - public function __construct(EntityURLGenerator $URLGenerator, EntityManagerInterface $em, - TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator, TranslatorInterface $translator, bool $rootNodeExpandedByDefault, bool $rootNodeEnabled) + public function __construct(protected EntityURLGenerator $urlGenerator, protected EntityManagerInterface $em, protected TagAwareCacheInterface $cache, protected UserCacheKeyGenerator $keyGenerator, protected TranslatorInterface $translator, protected bool $rootNodeExpandedByDefault, protected bool $rootNodeEnabled) { - $this->urlGenerator = $URLGenerator; - $this->em = $em; - $this->cache = $treeCache; - $this->keyGenerator = $keyGenerator; - $this->translator = $translator; - - $this->rootNodeExpandedByDefault = $rootNodeExpandedByDefault; - $this->rootNodeEnabled = $rootNodeEnabled; } /** @@ -92,7 +74,7 @@ class TreeViewGenerator $href = $this->urlGenerator->createURL(new $class()); $new_node = new TreeViewNode($this->translator->trans('entity.tree.new'), $href); //When the id of the selected element is null, then we have a new element, and we need to select "new" node - if (null === $selectedElement || null === $selectedElement->getID()) { + if (!$selectedElement instanceof \App\Entity\Base\AbstractDBElement || null === $selectedElement->getID()) { $new_node->setSelected(true); } $head[] = $new_node; @@ -116,7 +98,7 @@ class TreeViewGenerator $recursiveIterator = new RecursiveIteratorIterator($treeIterator, RecursiveIteratorIterator::SELF_FIRST); foreach ($recursiveIterator as $item) { /** @var TreeViewNode $item */ - if (null !== $selectedElement && $item->getId() === $selectedElement->getID()) { + if ($selectedElement instanceof \App\Entity\Base\AbstractDBElement && $item->getId() === $selectedElement->getID()) { $item->setSelected(true); } @@ -202,7 +184,7 @@ class TreeViewGenerator if (!is_a($class, AbstractNamedDBElement::class, true)) { throw new InvalidArgumentException('$class must be a class string that implements StructuralDBElement or NamedDBElement!'); } - if (null !== $parent && !is_a($parent, $class)) { + if ($parent instanceof \App\Entity\Base\AbstractStructuralDBElement && !$parent instanceof $class) { throw new InvalidArgumentException('$parent must be of the type $class!'); } @@ -210,7 +192,7 @@ class TreeViewGenerator $repo = $this->em->getRepository($class); //If we just want a part of a tree, don't cache it - if (null !== $parent) { + if ($parent instanceof \App\Entity\Base\AbstractStructuralDBElement) { return $repo->getGenericNodeTree($parent); } diff --git a/src/Services/UserSystem/PasswordResetManager.php b/src/Services/UserSystem/PasswordResetManager.php index 7b8a5be3..2a4c9274 100644 --- a/src/Services/UserSystem/PasswordResetManager.php +++ b/src/Services/UserSystem/PasswordResetManager.php @@ -35,21 +35,13 @@ use Symfony\Contracts\Translation\TranslatorInterface; class PasswordResetManager { - protected MailerInterface $mailer; - protected EntityManagerInterface $em; protected PasswordHasherInterface $passwordEncoder; - protected TranslatorInterface $translator; - protected UserPasswordHasherInterface $userPasswordEncoder; - public function __construct(MailerInterface $mailer, EntityManagerInterface $em, - TranslatorInterface $translator, UserPasswordHasherInterface $userPasswordEncoder, + public function __construct(protected MailerInterface $mailer, protected EntityManagerInterface $em, + protected TranslatorInterface $translator, protected UserPasswordHasherInterface $userPasswordEncoder, PasswordHasherFactoryInterface $encoderFactory) { - $this->em = $em; - $this->mailer = $mailer; $this->passwordEncoder = $encoderFactory->getPasswordHasher(User::class); - $this->translator = $translator; - $this->userPasswordEncoder = $userPasswordEncoder; } public function request(string $name_or_email): void @@ -59,7 +51,7 @@ class PasswordResetManager //Try to find a user by the given string $user = $repo->findByEmailOrName($name_or_email); //Do nothing if no user was found - if (null === $user) { + if (!$user instanceof \App\Entity\UserSystem\User) { return; } @@ -109,7 +101,7 @@ class PasswordResetManager $user = $repo->findOneBy(['name' => $username]); //If no user matching the name, show an error message - if (null === $user) { + if (!$user instanceof \App\Entity\UserSystem\User) { return false; } diff --git a/src/Services/UserSystem/PermissionManager.php b/src/Services/UserSystem/PermissionManager.php index 47e42635..5ef71d4c 100644 --- a/src/Services/UserSystem/PermissionManager.php +++ b/src/Services/UserSystem/PermissionManager.php @@ -40,19 +40,16 @@ use Symfony\Component\Yaml\Yaml; class PermissionManager { protected $permission_structure; - - protected bool $is_debug; protected string $cache_file; /** * PermissionResolver constructor. */ - public function __construct(bool $kernel_debug, string $kernel_cache_dir) + public function __construct(protected bool $is_debug, string $kernel_cache_dir) { $cache_dir = $kernel_cache_dir; //Here the cached structure will be saved. $this->cache_file = $cache_dir.'/permissions.php.cache'; - $this->is_debug = $kernel_debug; $this->permission_structure = $this->generatePermissionStructure(); } @@ -113,7 +110,7 @@ class PermissionManager /** @var Group $parent */ $parent = $user->getGroup(); - while (null !== $parent) { //The top group, has parent == null + while ($parent instanceof \App\Entity\Base\AbstractStructuralDBElement) { //The top group, has parent == null //Check if our current element gives an info about disallow/allow $allowed = $this->dontInherit($parent, $permission, $operation); if (null !== $allowed) { @@ -196,8 +193,6 @@ class PermissionManager /** * This functions sets all operations mentioned in the alsoSet value of a permission, so that the structure is always valid. - * @param HasPermissionsInterface $user - * @return void */ public function ensureCorrectSetOperations(HasPermissionsInterface $user): void { @@ -215,12 +210,7 @@ class PermissionManager //Set every op listed in also Set foreach ($op['alsoSet'] as $set_also) { //If the alsoSet value contains a dot then we set the operation of another permission - if (str_contains($set_also, '.')) { - [$set_perm, $set_op] = explode('.', $set_also); - } else { - //Else we set the operation of the same permission - [$set_perm, $set_op] = [$perm_key, $set_also]; - } + [$set_perm, $set_op] = str_contains((string) $set_also, '.') ? explode('.', (string) $set_also) : [$perm_key, $set_also]; //Check if we change the value of the permission if ($this->dontInherit($user, $set_perm, $set_op) !== true) { @@ -237,9 +227,6 @@ class PermissionManager /** * Sets all possible operations of all possible permissions of the given entity to the given value. - * @param HasPermissionsInterface $perm_holder - * @param bool|null $new_value - * @return void */ public function setAllPermissions(HasPermissionsInterface $perm_holder, ?bool $new_value): void { @@ -253,11 +240,6 @@ class PermissionManager /** * Sets all operations of the given permissions to the given value. * Please note that you have to call ensureCorrectSetOperations() after this function, to ensure that all alsoSet values are set. - * - * @param HasPermissionsInterface $perm_holder - * @param string $permission - * @param bool|null $new_value - * @return void */ public function setAllOperationsOfPermission(HasPermissionsInterface $perm_holder, string $permission, ?bool $new_value): void { @@ -272,11 +254,6 @@ class PermissionManager /** * This function sets all operations of the given permission to the given value, except the ones listed in the except array. - * @param HasPermissionsInterface $perm_holder - * @param string $permission - * @param bool|null $new_value - * @param array $except - * @return void */ public function setAllOperationsOfPermissionExcept(HasPermissionsInterface $perm_holder, string $permission, ?bool $new_value, array $except): void { diff --git a/src/Services/UserSystem/PermissionPresetsHelper.php b/src/Services/UserSystem/PermissionPresetsHelper.php index 7f7dc405..bf9aad8a 100644 --- a/src/Services/UserSystem/PermissionPresetsHelper.php +++ b/src/Services/UserSystem/PermissionPresetsHelper.php @@ -25,18 +25,15 @@ use App\Security\Interfaces\HasPermissionsInterface; class PermissionPresetsHelper { - public const PRESET_ALL_INHERIT = 'all_inherit'; - public const PRESET_ALL_FORBID = 'all_forbid'; - public const PRESET_ALL_ALLOW = 'all_allow'; - public const PRESET_READ_ONLY = 'read_only'; - public const PRESET_EDITOR = 'editor'; - public const PRESET_ADMIN = 'admin'; + final public const PRESET_ALL_INHERIT = 'all_inherit'; + final public const PRESET_ALL_FORBID = 'all_forbid'; + final public const PRESET_ALL_ALLOW = 'all_allow'; + final public const PRESET_READ_ONLY = 'read_only'; + final public const PRESET_EDITOR = 'editor'; + final public const PRESET_ADMIN = 'admin'; - private PermissionManager $permissionResolver; - - public function __construct(PermissionManager $permissionResolver) + public function __construct(private readonly PermissionManager $permissionResolver) { - $this->permissionResolver = $permissionResolver; } /** @@ -44,7 +41,6 @@ class PermissionPresetsHelper * The permission data will be reset during the process and then the preset will be applied. * * @param string $preset_name The name of the preset to use - * @return HasPermissionsInterface */ public function applyPreset(HasPermissionsInterface $perm_holder, string $preset_name): HasPermissionsInterface { diff --git a/src/Services/UserSystem/PermissionSchemaUpdater.php b/src/Services/UserSystem/PermissionSchemaUpdater.php index f182c018..72231bcb 100644 --- a/src/Services/UserSystem/PermissionSchemaUpdater.php +++ b/src/Services/UserSystem/PermissionSchemaUpdater.php @@ -29,7 +29,6 @@ class PermissionSchemaUpdater { /** * Check if the given user/group needs an update of its permission schema. - * @param HasPermissionsInterface $holder * @return bool True if the permission schema needs an update, false otherwise. */ public function isSchemaUpdateNeeded(HasPermissionsInterface $holder): bool @@ -42,12 +41,11 @@ class PermissionSchemaUpdater /** * Upgrades the permission schema of the given user/group to the chosen version. * Please note that this function does not flush the changes to DB! - * @param HasPermissionsInterface $holder - * @param int $target_version * @return bool True, if an upgrade was done, false if it was not needed. */ public function upgradeSchema(HasPermissionsInterface $holder, int $target_version = PermissionData::CURRENT_SCHEMA_VERSION): bool { + $e = null; if ($target_version > PermissionData::CURRENT_SCHEMA_VERSION) { throw new \InvalidArgumentException('The target version is higher than the maximum possible schema version!'); } @@ -66,7 +64,7 @@ class PermissionSchemaUpdater $method->setAccessible(true); $method->invoke($this, $holder); } catch (\ReflectionException $e) { - throw new \RuntimeException('Could not find update method for schema version '.($n + 1)); + throw new \RuntimeException('Could not find update method for schema version '.($n + 1), $e->getCode(), $e); } //Bump the schema version @@ -80,8 +78,6 @@ class PermissionSchemaUpdater /** * Upgrades the permission schema of the given group and all of its parent groups to the chosen version. * Please note that this function does not flush the changes to DB! - * @param Group $group - * @param int $target_version * @return bool True if an upgrade was done, false if it was not needed. */ public function groupUpgradeSchemaRecursively(Group $group, int $target_version = PermissionData::CURRENT_SCHEMA_VERSION): bool @@ -101,14 +97,12 @@ class PermissionSchemaUpdater /** * Upgrades the permissions schema of the given users and its parent (including parent groups) to the chosen version. * Please note that this function does not flush the changes to DB! - * @param User $user - * @param int $target_version * @return bool True if an upgrade was done, false if it was not needed. */ public function userUpgradeSchemaRecursively(User $user, int $target_version = PermissionData::CURRENT_SCHEMA_VERSION): bool { $updated = $this->upgradeSchema($user, $target_version); - if ($user->getGroup()) { + if ($user->getGroup() instanceof \App\Entity\UserSystem\Group) { $updated = $this->groupUpgradeSchemaRecursively($user->getGroup(), $target_version) || $updated; } diff --git a/src/Services/UserSystem/TFA/BackupCodeGenerator.php b/src/Services/UserSystem/TFA/BackupCodeGenerator.php index 942dd050..9beddf39 100644 --- a/src/Services/UserSystem/TFA/BackupCodeGenerator.php +++ b/src/Services/UserSystem/TFA/BackupCodeGenerator.php @@ -31,7 +31,6 @@ use RuntimeException; class BackupCodeGenerator { protected int $code_length; - protected int $code_count; /** * BackupCodeGenerator constructor. @@ -39,7 +38,7 @@ class BackupCodeGenerator * @param int $code_length how many characters a single code should have * @param int $code_count how many codes are generated for a whole backup set */ - public function __construct(int $code_length, int $code_count) + public function __construct(int $code_length, protected int $code_count) { if ($code_length > 32) { throw new RuntimeException('Backup code can have maximum 32 digits!'); @@ -47,8 +46,6 @@ class BackupCodeGenerator if ($code_length < 6) { throw new RuntimeException('Code must have at least 6 digits to ensure security!'); } - - $this->code_count = $code_count; $this->code_length = $code_length; } diff --git a/src/Services/UserSystem/TFA/BackupCodeManager.php b/src/Services/UserSystem/TFA/BackupCodeManager.php index fb98a33e..1fb572c6 100644 --- a/src/Services/UserSystem/TFA/BackupCodeManager.php +++ b/src/Services/UserSystem/TFA/BackupCodeManager.php @@ -29,11 +29,8 @@ use App\Entity\UserSystem\User; */ class BackupCodeManager { - protected BackupCodeGenerator $backupCodeGenerator; - - public function __construct(BackupCodeGenerator $backupCodeGenerator) + public function __construct(protected BackupCodeGenerator $backupCodeGenerator) { - $this->backupCodeGenerator = $backupCodeGenerator; } /** diff --git a/src/Services/UserSystem/UserAvatarHelper.php b/src/Services/UserSystem/UserAvatarHelper.php index 95b94dca..026cdcd5 100644 --- a/src/Services/UserSystem/UserAvatarHelper.php +++ b/src/Services/UserSystem/UserAvatarHelper.php @@ -33,34 +33,18 @@ use Symfony\Component\HttpFoundation\File\UploadedFile; class UserAvatarHelper { - private bool $use_gravatar; - private Packages $packages; - private AttachmentURLGenerator $attachmentURLGenerator; - private FilterService $filterService; - private EntityManagerInterface $entityManager; - private AttachmentSubmitHandler $submitHandler; - - public function __construct(bool $use_gravatar, Packages $packages, AttachmentURLGenerator $attachmentURLGenerator, - FilterService $filterService, EntityManagerInterface $entityManager, AttachmentSubmitHandler $attachmentSubmitHandler) + public function __construct(private readonly bool $use_gravatar, private readonly Packages $packages, private readonly AttachmentURLGenerator $attachmentURLGenerator, private readonly FilterService $filterService, private readonly EntityManagerInterface $entityManager, private readonly AttachmentSubmitHandler $submitHandler) { - $this->use_gravatar = $use_gravatar; - $this->packages = $packages; - $this->attachmentURLGenerator = $attachmentURLGenerator; - $this->filterService = $filterService; - $this->entityManager = $entityManager; - $this->submitHandler = $attachmentSubmitHandler; } /** * Returns the URL to the profile picture of the given user (in big size) - * @param User $user - * @return string */ public function getAvatarURL(User $user): string { //Check if the user has a master attachment defined (meaning he has explicitly defined a profile picture) - if ($user->getMasterPictureAttachment() !== null) { + if ($user->getMasterPictureAttachment() instanceof \App\Entity\Attachments\Attachment) { return $this->attachmentURLGenerator->getThumbnailURL($user->getMasterPictureAttachment(), 'thumbnail_md'); } @@ -76,7 +60,7 @@ class UserAvatarHelper public function getAvatarSmURL(User $user): string { //Check if the user has a master attachment defined (meaning he has explicitly defined a profile picture) - if ($user->getMasterPictureAttachment() !== null) { + if ($user->getMasterPictureAttachment() instanceof \App\Entity\Attachments\Attachment) { return $this->attachmentURLGenerator->getThumbnailURL($user->getMasterPictureAttachment(), 'thumbnail_xs'); } @@ -88,7 +72,7 @@ class UserAvatarHelper try { //Otherwise we can serve the relative path via Asset component return $this->filterService->getUrlOfFilteredImage('/img/default_avatar.png', 'thumbnail_xs'); - } catch (\Imagine\Exception\RuntimeException $e) { + } catch (\Imagine\Exception\RuntimeException) { //If the filter fails, we can not serve the thumbnail and fall back to the original image and log an warning return $this->packages->getUrl('/img/default_avatar.png'); } @@ -97,7 +81,7 @@ class UserAvatarHelper public function getAvatarMdURL(User $user): string { //Check if the user has a master attachment defined (meaning he has explicitly defined a profile picture) - if ($user->getMasterPictureAttachment() !== null) { + if ($user->getMasterPictureAttachment() instanceof \App\Entity\Attachments\Attachment) { return $this->attachmentURLGenerator->getThumbnailURL($user->getMasterPictureAttachment(), 'thumbnail_sm'); } @@ -109,7 +93,7 @@ class UserAvatarHelper try { //Otherwise we can serve the relative path via Asset component return $this->filterService->getUrlOfFilteredImage('/img/default_avatar.png', 'thumbnail_xs'); - } catch (\Imagine\Exception\RuntimeException $e) { + } catch (\Imagine\Exception\RuntimeException) { //If the filter fails, we can not serve the thumbnail and fall back to the original image and log an warning return $this->packages->getUrl('/img/default_avatar.png'); } @@ -136,22 +120,18 @@ class UserAvatarHelper $url = 'https://www.gravatar.com/avatar/'; $url .= md5(strtolower(trim($email))); - $url .= "?s=${s}&d=${d}&r=${r}"; - return $url; + return $url . "?s=${s}&d=${d}&r=${r}"; } /** * Handles the upload of the user avatar. - * @param User $user - * @param UploadedFile $file - * @return Attachment */ public function handleAvatarUpload(User $user, UploadedFile $file): Attachment { //Determine which attachment to user //If the user already has a master attachment, we use this one - if ($user->getMasterPictureAttachment()) { + if ($user->getMasterPictureAttachment() instanceof \App\Entity\Attachments\Attachment) { $attachment = $user->getMasterPictureAttachment(); } else { //Otherwise we have to create one $attachment = new UserAttachment(); diff --git a/src/Services/UserSystem/UserCacheKeyGenerator.php b/src/Services/UserSystem/UserCacheKeyGenerator.php index dd9e6ccb..69caeff3 100644 --- a/src/Services/UserSystem/UserCacheKeyGenerator.php +++ b/src/Services/UserSystem/UserCacheKeyGenerator.php @@ -32,13 +32,8 @@ use Symfony\Component\Security\Core\Security; */ class UserCacheKeyGenerator { - protected \Symfony\Bundle\SecurityBundle\Security $security; - protected RequestStack $requestStack; - - public function __construct(\Symfony\Bundle\SecurityBundle\Security $security, RequestStack $requestStack) + public function __construct(protected \Symfony\Bundle\SecurityBundle\Security $security, protected RequestStack $requestStack) { - $this->security = $security; - $this->requestStack = $requestStack; } /** @@ -51,10 +46,10 @@ class UserCacheKeyGenerator { $request = $this->requestStack->getCurrentRequest(); //Retrieve the locale from the request, if possible, otherwise use the default locale - $locale = $request ? $request->getLocale() : Locale::getDefault(); + $locale = $request instanceof \Symfony\Component\HttpFoundation\Request ? $request->getLocale() : Locale::getDefault(); //If no user was specified, use the currently used one. - if (null === $user) { + if (!$user instanceof \App\Entity\UserSystem\User) { $user = $this->security->getUser(); } diff --git a/src/Twig/AttachmentExtension.php b/src/Twig/AttachmentExtension.php index b02f749d..c0897ab2 100644 --- a/src/Twig/AttachmentExtension.php +++ b/src/Twig/AttachmentExtension.php @@ -27,22 +27,17 @@ use Twig\TwigFunction; final class AttachmentExtension extends AbstractExtension { - protected AttachmentURLGenerator $attachmentURLGenerator; - protected FAIconGenerator $FAIconGenerator; - - public function __construct(AttachmentURLGenerator $attachmentURLGenerator, FAIconGenerator $FAIconGenerator) + public function __construct(protected AttachmentURLGenerator $attachmentURLGenerator, protected FAIconGenerator $FAIconGenerator) { - $this->attachmentURLGenerator = $attachmentURLGenerator; - $this->FAIconGenerator = $FAIconGenerator; } public function getFunctions(): array { return [ /* Returns the URL to a thumbnail of the given attachment */ - new TwigFunction('attachment_thumbnail', [$this->attachmentURLGenerator, 'getThumbnailURL']), + new TwigFunction('attachment_thumbnail', fn(\App\Entity\Attachments\Attachment $attachment, string $filter_name = 'thumbnail_sm'): ?string => $this->attachmentURLGenerator->getThumbnailURL($attachment, $filter_name)), /* Returns the font awesome icon class which is representing the given file extension */ - new TwigFunction('ext_to_fa_icon', [$this->FAIconGenerator, 'fileExtensionToFAType']), + new TwigFunction('ext_to_fa_icon', fn(string $extension): string => $this->FAIconGenerator->fileExtensionToFAType($extension)), ]; } } \ No newline at end of file diff --git a/src/Twig/BarcodeExtension.php b/src/Twig/BarcodeExtension.php index 6020b65e..5e8984d2 100644 --- a/src/Twig/BarcodeExtension.php +++ b/src/Twig/BarcodeExtension.php @@ -30,7 +30,7 @@ final class BarcodeExtension extends AbstractExtension { return [ /* Generates a barcode with the given Type and Data and returns it as an SVG represenation */ - new TwigFunction('barcode_svg', [$this, 'barcodeSVG']), + new TwigFunction('barcode_svg', fn(string $content, string $type = 'QRCODE'): string => $this->barcodeSVG($content, $type)), ]; } diff --git a/src/Twig/EntityExtension.php b/src/Twig/EntityExtension.php index 402a28b3..1a8f5d37 100644 --- a/src/Twig/EntityExtension.php +++ b/src/Twig/EntityExtension.php @@ -44,24 +44,15 @@ use Twig\TwigTest; final class EntityExtension extends AbstractExtension { - protected EntityURLGenerator $entityURLGenerator; - protected TreeViewGenerator $treeBuilder; - private ElementTypeNameGenerator $nameGenerator; - - public function __construct(EntityURLGenerator $entityURLGenerator, TreeViewGenerator $treeBuilder, ElementTypeNameGenerator $elementTypeNameGenerator) + public function __construct(protected EntityURLGenerator $entityURLGenerator, protected TreeViewGenerator $treeBuilder, private readonly ElementTypeNameGenerator $nameGenerator) { - $this->entityURLGenerator = $entityURLGenerator; - $this->treeBuilder = $treeBuilder; - $this->nameGenerator = $elementTypeNameGenerator; } public function getTests(): array { return [ /* Checks if the given variable is an entitity (instance of AbstractDBElement) */ - new TwigTest('entity', static function ($var) { - return $var instanceof AbstractDBElement; - }), + new TwigTest('entity', static fn($var) => $var instanceof AbstractDBElement), ]; } @@ -69,16 +60,16 @@ final class EntityExtension extends AbstractExtension { return [ /* Returns a string representation of the given entity */ - new TwigFunction('entity_type', [$this, 'getEntityType']), + new TwigFunction('entity_type', fn(object $entity): ?string => $this->getEntityType($entity)), /* Returns the URL to the given entity */ - new TwigFunction('entity_url', [$this, 'generateEntityURL']), + new TwigFunction('entity_url', fn(\App\Entity\Base\AbstractDBElement $entity, string $method = 'info'): string => $this->generateEntityURL($entity, $method)), /* Returns the URL to the given entity in timetravel mode */ - new TwigFunction('timetravel_url', [$this, 'timeTravelURL']), + new TwigFunction('timetravel_url', fn(\App\Entity\Base\AbstractDBElement $element, \DateTimeInterface $dateTime): ?string => $this->timeTravelURL($element, $dateTime)), /* Generates a JSON array of the given tree */ - new TwigFunction('tree_data', [$this, 'treeData']), + new TwigFunction('tree_data', fn(\App\Entity\Base\AbstractDBElement $element, string $type = 'newEdit'): string => $this->treeData($element, $type)), /* Gets a human readable label for the type of the given entity */ - new TwigFunction('entity_type_label', [$this->nameGenerator, 'getLocalizedTypeLabel']), + new TwigFunction('entity_type_label', fn(object|string $entity): string => $this->nameGenerator->getLocalizedTypeLabel($entity)), ]; } @@ -86,14 +77,14 @@ final class EntityExtension extends AbstractExtension { try { return $this->entityURLGenerator->timeTravelURL($element, $dateTime); - } catch (EntityNotSupportedException $e) { + } catch (EntityNotSupportedException) { return null; } } public function treeData(AbstractDBElement $element, string $type = 'newEdit'): string { - $tree = $this->treeBuilder->getTreeView(get_class($element), null, $type, $element); + $tree = $this->treeBuilder->getTreeView($element::class, null, $type, $element); return json_encode($tree, JSON_THROW_ON_ERROR); } diff --git a/src/Twig/FormatExtension.php b/src/Twig/FormatExtension.php index 775a3fe4..d5fe0e91 100644 --- a/src/Twig/FormatExtension.php +++ b/src/Twig/FormatExtension.php @@ -34,37 +34,26 @@ use Twig\TwigFilter; final class FormatExtension extends AbstractExtension { - protected MarkdownParser $markdownParser; - protected MoneyFormatter $moneyFormatter; - protected SIFormatter $siformatter; - protected AmountFormatter $amountFormatter; - - - public function __construct(MarkdownParser $markdownParser, MoneyFormatter $moneyFormatter, - SIFormatter $SIFormatter, AmountFormatter $amountFormatter) + public function __construct(protected MarkdownParser $markdownParser, protected MoneyFormatter $moneyFormatter, protected SIFormatter $siformatter, protected AmountFormatter $amountFormatter) { - $this->markdownParser = $markdownParser; - $this->moneyFormatter = $moneyFormatter; - $this->siformatter = $SIFormatter; - $this->amountFormatter = $amountFormatter; } public function getFilters(): array { return [ /* Mark the given text as markdown, which will be rendered in the browser */ - new TwigFilter('format_markdown', [$this->markdownParser, 'markForRendering'], [ + new TwigFilter('format_markdown', fn(string $markdown, bool $inline_mode = false): string => $this->markdownParser->markForRendering($markdown, $inline_mode), [ 'pre_escape' => 'html', 'is_safe' => ['html'], ]), /* Format the given amount as money, using a given currency */ - new TwigFilter('format_money', [$this, 'formatCurrency']), + new TwigFilter('format_money', fn($amount, ?\App\Entity\PriceInformations\Currency $currency = null, int $decimals = 5): string => $this->formatCurrency($amount, $currency, $decimals)), /* Format the given number using SI prefixes and the given unit (string) */ - new TwigFilter('format_si', [$this, 'siFormat']), + new TwigFilter('format_si', fn($value, $unit, $decimals = 2, bool $show_all_digits = false): string => $this->siFormat($value, $unit, $decimals, $show_all_digits)), /** Format the given amount using the given MeasurementUnit */ - new TwigFilter('format_amount', [$this, 'amountFormat']), + new TwigFilter('format_amount', fn($value, ?\App\Entity\Parts\MeasurementUnit $unit, array $options = []): string => $this->amountFormat($value, $unit, $options)), /** Format the given number of bytes as human-readable number */ - new TwigFilter('format_bytes', [$this, 'formatBytes']), + new TwigFilter('format_bytes', fn(int $bytes, int $precision = 2): string => $this->formatBytes($bytes, $precision)), ]; } @@ -89,8 +78,6 @@ final class FormatExtension extends AbstractExtension /** * @param $bytes - * @param int $precision - * @return string */ public function formatBytes(int $bytes, int $precision = 2): string { diff --git a/src/Twig/LogExtension.php b/src/Twig/LogExtension.php index a56b9275..c8edb106 100644 --- a/src/Twig/LogExtension.php +++ b/src/Twig/LogExtension.php @@ -28,20 +28,15 @@ use Twig\TwigFunction; final class LogExtension extends AbstractExtension { - private LogDataFormatter $logDataFormatter; - private LogDiffFormatter $logDiffFormatter; - - public function __construct(LogDataFormatter $logDataFormatter, LogDiffFormatter $logDiffFormatter) + public function __construct(private readonly LogDataFormatter $logDataFormatter, private readonly LogDiffFormatter $logDiffFormatter) { - $this->logDataFormatter = $logDataFormatter; - $this->logDiffFormatter = $logDiffFormatter; } public function getFunctions() { return [ - new TwigFunction('format_log_data', [$this->logDataFormatter, 'formatData'], ['is_safe' => ['html']]), - new TwigFunction('format_log_diff', [$this->logDiffFormatter, 'formatDiff'], ['is_safe' => ['html']]), + new TwigFunction('format_log_data', fn($data, \App\Entity\LogSystem\AbstractLogEntry $logEntry, string $fieldName): string => $this->logDataFormatter->formatData($data, $logEntry, $fieldName), ['is_safe' => ['html']]), + new TwigFunction('format_log_diff', fn($old_data, $new_data): string => $this->logDiffFormatter->formatDiff($old_data, $new_data), ['is_safe' => ['html']]), ]; } } \ No newline at end of file diff --git a/src/Twig/MiscExtension.php b/src/Twig/MiscExtension.php index 6181e9cd..54e34d09 100644 --- a/src/Twig/MiscExtension.php +++ b/src/Twig/MiscExtension.php @@ -25,11 +25,8 @@ use Twig\Extension\AbstractExtension; final class MiscExtension extends AbstractExtension { - private EventCommentNeededHelper $eventCommentNeededHelper; - - public function __construct(EventCommentNeededHelper $eventCommentNeededHelper) + public function __construct(private readonly EventCommentNeededHelper $eventCommentNeededHelper) { - $this->eventCommentNeededHelper = $eventCommentNeededHelper; } public function getFunctions(): array diff --git a/src/Twig/Sandbox/InheritanceSecurityPolicy.php b/src/Twig/Sandbox/InheritanceSecurityPolicy.php index b70be7a5..db1cd2b5 100644 --- a/src/Twig/Sandbox/InheritanceSecurityPolicy.php +++ b/src/Twig/Sandbox/InheritanceSecurityPolicy.php @@ -35,19 +35,11 @@ use function is_array; */ final class InheritanceSecurityPolicy implements SecurityPolicyInterface { - private array $allowedTags; - private array $allowedFilters; private array $allowedMethods; - private array $allowedProperties; - private array $allowedFunctions; - public function __construct(array $allowedTags = [], array $allowedFilters = [], array $allowedMethods = [], array $allowedProperties = [], array $allowedFunctions = []) + public function __construct(private array $allowedTags = [], private array $allowedFilters = [], array $allowedMethods = [], private array $allowedProperties = [], private array $allowedFunctions = []) { - $this->allowedTags = $allowedTags; - $this->allowedFilters = $allowedFilters; $this->setAllowedMethods($allowedMethods); - $this->allowedProperties = $allowedProperties; - $this->allowedFunctions = $allowedFunctions; } public function setAllowedTags(array $tags): void @@ -65,7 +57,7 @@ final class InheritanceSecurityPolicy implements SecurityPolicyInterface $this->allowedMethods = []; foreach ($methods as $class => $m) { $this->allowedMethods[$class] = array_map( - static function ($value) { return strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); }, is_array($m) ? $m : [$m]); + static fn($value): string => strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), is_array($m) ? $m : [$m]); } } @@ -120,7 +112,7 @@ final class InheritanceSecurityPolicy implements SecurityPolicyInterface } if (!$allowed) { - $class = get_class($obj); + $class = $obj::class; throw new SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method); } @@ -141,7 +133,7 @@ final class InheritanceSecurityPolicy implements SecurityPolicyInterface } if (!$allowed) { - $class = get_class($obj); + $class = $obj::class; throw new SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property); } diff --git a/src/Twig/TwigCoreExtension.php b/src/Twig/TwigCoreExtension.php index 6b12299a..dc63b2e1 100644 --- a/src/Twig/TwigCoreExtension.php +++ b/src/Twig/TwigCoreExtension.php @@ -30,11 +30,8 @@ use Twig\TwigTest; */ final class TwigCoreExtension extends AbstractExtension { - protected ObjectNormalizer $objectNormalizer; - - public function __construct(ObjectNormalizer $objectNormalizer) + public function __construct(protected ObjectNormalizer $objectNormalizer) { - $this->objectNormalizer = $objectNormalizer; } public function getTests(): array @@ -43,13 +40,9 @@ final class TwigCoreExtension extends AbstractExtension /* * Checks if a given variable is an instance of a given class. E.g. ` x is instanceof('App\Entity\Parts\Part')` */ - new TwigTest('instanceof', static function ($var, $instance) { - return $var instanceof $instance; - }), + new TwigTest('instanceof', static fn($var, $instance) => $var instanceof $instance), /* Checks if a given variable is an object. E.g. `x is object` */ - new TwigTest('object', static function ($var) { - return is_object($var); - }), + new TwigTest('object', static fn($var): object => is_object($var)), ]; } @@ -57,7 +50,7 @@ final class TwigCoreExtension extends AbstractExtension { return [ /* Converts the given object to an array representation of the public/accessible properties */ - new TwigFilter('to_array', [$this, 'toArray']), + new TwigFilter('to_array', fn($object) => $this->toArray($object)), ]; } diff --git a/src/Twig/UserExtension.php b/src/Twig/UserExtension.php index 3b0ec75c..d2c8880f 100644 --- a/src/Twig/UserExtension.php +++ b/src/Twig/UserExtension.php @@ -50,7 +50,7 @@ use Twig\TwigFunction; final class UserExtension extends AbstractExtension { - private LogEntryRepository $repo; + private readonly LogEntryRepository $repo; public function __construct(EntityManagerInterface $em) { @@ -60,7 +60,7 @@ final class UserExtension extends AbstractExtension public function getFilters(): array { return [ - new TwigFilter('remove_locale_from_path', [$this, 'removeLocaleFromPath']), + new TwigFilter('remove_locale_from_path', fn(string $path): string => $this->removeLocaleFromPath($path)), ]; } @@ -68,9 +68,9 @@ final class UserExtension extends AbstractExtension { return [ /* Returns the user which has edited the given entity the last time. */ - new TwigFunction('last_editing_user', [$this->repo, 'getLastEditingUser']), + new TwigFunction('last_editing_user', fn(\App\Entity\Base\AbstractDBElement $element): ?\App\Entity\UserSystem\User => $this->repo->getLastEditingUser($element)), /* Returns the user which has created the given entity. */ - new TwigFunction('creating_user', [$this->repo, 'getCreatingUser']), + new TwigFunction('creating_user', fn(\App\Entity\Base\AbstractDBElement $element): ?\App\Entity\UserSystem\User => $this->repo->getCreatingUser($element)), ]; } diff --git a/src/Validator/Constraints/Misc/ValidRangeValidator.php b/src/Validator/Constraints/Misc/ValidRangeValidator.php index 8385cc92..8bc5af0c 100644 --- a/src/Validator/Constraints/Misc/ValidRangeValidator.php +++ b/src/Validator/Constraints/Misc/ValidRangeValidator.php @@ -49,11 +49,8 @@ use Symfony\Component\Validator\Exception\UnexpectedValueException; class ValidRangeValidator extends ConstraintValidator { - protected RangeParser $rangeParser; - - public function __construct(RangeParser $rangeParser) + public function __construct(protected RangeParser $rangeParser) { - $this->rangeParser = $rangeParser; } public function validate($value, Constraint $constraint): void diff --git a/src/Validator/Constraints/NoLockoutValidator.php b/src/Validator/Constraints/NoLockoutValidator.php index c2de80e2..0cf60f59 100644 --- a/src/Validator/Constraints/NoLockoutValidator.php +++ b/src/Validator/Constraints/NoLockoutValidator.php @@ -33,17 +33,11 @@ use Symfony\Component\Validator\ConstraintValidator; class NoLockoutValidator extends ConstraintValidator { - protected PermissionManager $resolver; protected array $perm_structure; - protected \Symfony\Bundle\SecurityBundle\Security $security; - protected EntityManagerInterface $entityManager; - public function __construct(PermissionManager $resolver, \Symfony\Bundle\SecurityBundle\Security $security, EntityManagerInterface $entityManager) + public function __construct(protected PermissionManager $resolver, protected \Symfony\Bundle\SecurityBundle\Security $security, protected EntityManagerInterface $entityManager) { - $this->resolver = $resolver; $this->perm_structure = $resolver->getPermissionStructure(); - $this->security = $security; - $this->entityManager = $entityManager; } /** @@ -64,12 +58,12 @@ class NoLockoutValidator extends ConstraintValidator if ($perm_holder instanceof User || $perm_holder instanceof Group) { $user = $this->security->getUser(); - if (null === $user) { + if (!$user instanceof \Symfony\Component\Security\Core\User\UserInterface) { $user = $this->entityManager->getRepository(User::class)->getAnonymousUser(); } //Check if the change_permission permission has changed from allow to disallow - if (($user instanceof User) && false === ($this->resolver->inherit( + if (($user instanceof User) && !($this->resolver->inherit( $user, 'users', 'edit_permissions' diff --git a/src/Validator/Constraints/ValidFileFilterValidator.php b/src/Validator/Constraints/ValidFileFilterValidator.php index ccce30ce..d591a968 100644 --- a/src/Validator/Constraints/ValidFileFilterValidator.php +++ b/src/Validator/Constraints/ValidFileFilterValidator.php @@ -32,11 +32,8 @@ use function is_string; class ValidFileFilterValidator extends ConstraintValidator { - protected FileTypeFilterTools $filterTools; - - public function __construct(FileTypeFilterTools $filterTools) + public function __construct(protected FileTypeFilterTools $filterTools) { - $this->filterTools = $filterTools; } /** diff --git a/src/Validator/Constraints/ValidGoogleAuthCodeValidator.php b/src/Validator/Constraints/ValidGoogleAuthCodeValidator.php index bb66f395..276201f3 100644 --- a/src/Validator/Constraints/ValidGoogleAuthCodeValidator.php +++ b/src/Validator/Constraints/ValidGoogleAuthCodeValidator.php @@ -36,11 +36,8 @@ use function strlen; class ValidGoogleAuthCodeValidator extends ConstraintValidator { - protected GoogleAuthenticatorInterface $googleAuthenticator; - - public function __construct(GoogleAuthenticatorInterface $googleAuthenticator) + public function __construct(protected GoogleAuthenticatorInterface $googleAuthenticator) { - $this->googleAuthenticator = $googleAuthenticator; } public function validate($value, Constraint $constraint): void diff --git a/src/Validator/Constraints/ValidPartLotValidator.php b/src/Validator/Constraints/ValidPartLotValidator.php index d77ecd0e..5e5b22d9 100644 --- a/src/Validator/Constraints/ValidPartLotValidator.php +++ b/src/Validator/Constraints/ValidPartLotValidator.php @@ -32,11 +32,8 @@ use Symfony\Component\Validator\ConstraintValidator; class ValidPartLotValidator extends ConstraintValidator { - protected EntityManagerInterface $em; - - public function __construct(EntityManagerInterface $em) + public function __construct(protected EntityManagerInterface $em) { - $this->em = $em; } /** @@ -56,7 +53,7 @@ class ValidPartLotValidator extends ConstraintValidator } //We can only validate the values if we know the storelocation - if ($value->getStorageLocation()) { + if ($value->getStorageLocation() instanceof \App\Entity\Parts\Storelocation) { $repo = $this->em->getRepository(Storelocation::class); //We can only determine associated parts, if the part have an ID //When the storage location is new (no ID), we can just assume there are no other parts diff --git a/src/Validator/Constraints/ValidPermissionValidator.php b/src/Validator/Constraints/ValidPermissionValidator.php index 9b31048f..7bc6c4e7 100644 --- a/src/Validator/Constraints/ValidPermissionValidator.php +++ b/src/Validator/Constraints/ValidPermissionValidator.php @@ -30,12 +30,10 @@ use Symfony\Component\Validator\ConstraintValidator; class ValidPermissionValidator extends ConstraintValidator { - protected PermissionManager $resolver; protected array $perm_structure; - public function __construct(PermissionManager $resolver) + public function __construct(protected PermissionManager $resolver) { - $this->resolver = $resolver; } /** diff --git a/src/Validator/Constraints/ValidThemeValidator.php b/src/Validator/Constraints/ValidThemeValidator.php index ec437b87..f83bb500 100644 --- a/src/Validator/Constraints/ValidThemeValidator.php +++ b/src/Validator/Constraints/ValidThemeValidator.php @@ -26,11 +26,8 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException; class ValidThemeValidator extends ConstraintValidator { - private array $available_themes; - - public function __construct(array $available_themes) + public function __construct(private readonly array $available_themes) { - $this->available_themes = $available_themes; } public function validate($value, Constraint $constraint)