diff --git a/.gitattributes b/.gitattributes index 260e1eb9..63f97811 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,7 +14,5 @@ /infection.json.dist export-ignore /node_modules export-ignore /phpunit.xml.dist export-ignore -/psalm-baseline.xml export-ignore -/psalm.xml export-ignore /rector.php export-ignore /tests export-ignore diff --git a/.gitignore b/.gitignore index 4c0aa2d7..64cb5e5a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ /.phpunit.result.cache +/.claude/*.local.json + # Symfony CLI https://symfony.com/doc/current/setup/symfony_server.html#different-php-settings-per-project /.php-version /php.ini diff --git a/infection.json.dist b/infection.json.dist new file mode 100644 index 00000000..e458f4c9 --- /dev/null +++ b/infection.json.dist @@ -0,0 +1,16 @@ +{ + "source": { + "directories": [ + "src" + ] + }, + "logs": { + "text": "php://stderr", + "github": true, + "stryker": { + "badge": "master" + } + }, + "minMsi": 100.00, + "minCoveredMsi": 100.00 +} diff --git a/phpstan.neon b/phpstan.neon index 8d8a3583..947e0c89 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -26,11 +26,11 @@ parameters: ignoreErrors: - - identifier: missingType.iterableValue + identifiers: + - missingType.iterableValue + - doctrine.associationType + - doctrine.columnType + - missingType.generics - - identifier: doctrine.associationType - - - identifier: doctrine.columnType - - - identifier: missingType.generics - path: src/Form + identifier: class.notFound + message: '#League\\Flysystem\\#' diff --git a/rector.php b/rector.php index 968b47e3..e8e94775 100644 --- a/rector.php +++ b/rector.php @@ -22,4 +22,9 @@ $rectorConfig->sets([ LevelSetList::UP_TO_PHP_81, ]); + + $rectorConfig->skip([ + \Rector\Php81\Rector\Class_\SpatieEnumClassToEnumRector::class, + \Rector\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector::class, + ]); }; diff --git a/src/Command/ProcessFeedsCommand.php b/src/Command/ProcessFeedsCommand.php index 19d6ea3f..8a167ac2 100644 --- a/src/Command/ProcessFeedsCommand.php +++ b/src/Command/ProcessFeedsCommand.php @@ -14,13 +14,9 @@ final class ProcessFeedsCommand extends Command { protected static $defaultName = 'setono:sylius-feed:process'; - private FeedProcessorInterface $feedProcessor; - - public function __construct(FeedProcessorInterface $feedProcessor) + public function __construct(private readonly FeedProcessorInterface $feedProcessor) { parent::__construct(); - - $this->feedProcessor = $feedProcessor; } protected function configure(): void diff --git a/src/Controller/Action/Admin/ProcessFeedAction.php b/src/Controller/Action/Admin/ProcessFeedAction.php index 19f19ca6..2717e62d 100644 --- a/src/Controller/Action/Admin/ProcessFeedAction.php +++ b/src/Controller/Action/Admin/ProcessFeedAction.php @@ -13,32 +13,14 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Contracts\Translation\TranslatorInterface; -/** - * @psalm-suppress UndefinedClass - * @psalm-suppress MixedArgument - * @psalm-suppress UndefinedInterfaceMethod - * @psalm-suppress MixedAssignment - */ final class ProcessFeedAction { - private MessageBusInterface $commandBus; - - private UrlGeneratorInterface $urlGenerator; - - private FlashBagInterface|RequestStack $flashBag; - - private TranslatorInterface $translator; - public function __construct( - MessageBusInterface $commandBus, - UrlGeneratorInterface $urlGenerator, - FlashBagInterface|RequestStack $requestStackOrFlashBag, - TranslatorInterface $translator, + private readonly MessageBusInterface $commandBus, + private readonly UrlGeneratorInterface $urlGenerator, + private readonly FlashBagInterface|RequestStack $flashBag, + private readonly TranslatorInterface $translator, ) { - $this->commandBus = $commandBus; - $this->urlGenerator = $urlGenerator; - $this->flashBag = $requestStackOrFlashBag; - $this->translator = $translator; } public function __invoke(int $id): RedirectResponse diff --git a/src/Controller/Action/Admin/SeverityCountAction.php b/src/Controller/Action/Admin/SeverityCountAction.php index c6c3bb39..03f4f024 100644 --- a/src/Controller/Action/Admin/SeverityCountAction.php +++ b/src/Controller/Action/Admin/SeverityCountAction.php @@ -10,14 +10,10 @@ final class SeverityCountAction { - private ViolationRepositoryInterface $violationRepository; - - private Environment $twig; - - public function __construct(ViolationRepositoryInterface $violationRepository, Environment $twig) - { - $this->violationRepository = $violationRepository; - $this->twig = $twig; + public function __construct( + private readonly ViolationRepositoryInterface $violationRepository, + private readonly Environment $twig, + ) { } public function __invoke(int $feed = null): Response diff --git a/src/Controller/Action/Shop/ShowFeedAction.php b/src/Controller/Action/Shop/ShowFeedAction.php index 4ef9e373..68b4dd19 100644 --- a/src/Controller/Action/Shop/ShowFeedAction.php +++ b/src/Controller/Action/Shop/ShowFeedAction.php @@ -16,42 +16,22 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Mime\MimeTypesInterface; -/** - * @psalm-suppress UndefinedDocblockClass - * @psalm-suppress UndefinedClass - */ final class ShowFeedAction { - private FeedRepositoryInterface $repository; - - private ChannelContextInterface $channelContext; - - private LocaleContextInterface $localeContext; - - private FeedPathGeneratorInterface $feedPathGenerator; - /** @var FilesystemInterface|FilesystemOperator */ private $filesystem; - private MimeTypesInterface $mimeTypes; - /** - * @psalm-suppress UndefinedDocblockClass - * * @param FilesystemInterface|FilesystemOperator $filesystem */ public function __construct( - FeedRepositoryInterface $repository, - ChannelContextInterface $channelContext, - LocaleContextInterface $localeContext, - FeedPathGeneratorInterface $feedPathGenerator, + private readonly FeedRepositoryInterface $repository, + private readonly ChannelContextInterface $channelContext, + private readonly LocaleContextInterface $localeContext, + private readonly FeedPathGeneratorInterface $feedPathGenerator, $filesystem, - MimeTypesInterface $mimeTypes, + private readonly MimeTypesInterface $mimeTypes, ) { - $this->repository = $repository; - $this->channelContext = $channelContext; - $this->localeContext = $localeContext; - $this->feedPathGenerator = $feedPathGenerator; if (interface_exists(FilesystemInterface::class) && $filesystem instanceof FilesystemInterface) { $this->filesystem = $filesystem; } elseif ($filesystem instanceof FilesystemOperator) { @@ -63,7 +43,6 @@ public function __construct( FilesystemOperator::class, )); } - $this->mimeTypes = $mimeTypes; } public function __invoke(string $code): StreamedResponse diff --git a/src/DTO/SeverityCount.php b/src/DTO/SeverityCount.php index b38934c8..cb750277 100644 --- a/src/DTO/SeverityCount.php +++ b/src/DTO/SeverityCount.php @@ -6,14 +6,8 @@ final class SeverityCount { - private string $severity; - - private int $count; - - public function __construct(string $severity, int $count) + public function __construct(private readonly string $severity, private readonly int $count) { - $this->severity = $severity; - $this->count = $count; } public function getSeverity(): string diff --git a/src/DataProvider/DataProvider.php b/src/DataProvider/DataProvider.php index 9631741c..448c932b 100644 --- a/src/DataProvider/DataProvider.php +++ b/src/DataProvider/DataProvider.php @@ -20,35 +20,17 @@ class DataProvider implements DataProviderInterface { - private BatcherFactoryInterface $batcherFactory; - - private QueryRebuilderInterface $queryRebuilder; - - private EventDispatcherInterface $eventDispatcher; - - private ManagerRegistry $managerRegistry; - - private string $class; - /** @var CollectionBatcherInterface[] */ private array $batchers = []; - private int $batchSize; - public function __construct( - BatcherFactoryInterface $batcherFactory, - QueryRebuilderInterface $queryRebuilder, - EventDispatcherInterface $eventDispatcher, - ManagerRegistry $managerRegistry, - string $class, - int $batchSize = 100, + private readonly BatcherFactoryInterface $batcherFactory, + private readonly QueryRebuilderInterface $queryRebuilder, + private readonly EventDispatcherInterface $eventDispatcher, + private readonly ManagerRegistry $managerRegistry, + private readonly string $class, + private readonly int $batchSize = 100, ) { - $this->batcherFactory = $batcherFactory; - $this->queryRebuilder = $queryRebuilder; - $this->eventDispatcher = $eventDispatcher; - $this->managerRegistry = $managerRegistry; - $this->class = $class; - $this->batchSize = $batchSize; } public function getClass(): string @@ -69,10 +51,8 @@ public function getBatchCount(ChannelInterface $channel, LocaleInterface $locale return $this->getBatcher($channel, $locale)->getBatchCount($this->batchSize); } - /** @psalm-suppress MixedReturnTypeCoercion */ public function getItems(BatchInterface $batch): iterable { - /** @psalm-suppress MixedReturnTypeCoercion */ return $this->queryRebuilder->rebuild($batch)->getResult(); } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index da282b99..eb3a565b 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -19,10 +19,6 @@ final class Configuration implements ConfigurationInterface { - /** - * @psalm-suppress MixedMethodCall - * @psalm-suppress UndefinedInterfaceMethod - */ public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('setono_sylius_feed'); @@ -56,9 +52,6 @@ public function getConfigTreeBuilder(): TreeBuilder return $treeBuilder; } - /** - * @psalm-suppress MixedMethodCall, UndefinedInterfaceMethod - */ private function addResourcesSection(ArrayNodeDefinition $node): void { $node diff --git a/src/Event/BatchGeneratedEvent.php b/src/Event/BatchGeneratedEvent.php index 8445390d..bf924bee 100644 --- a/src/Event/BatchGeneratedEvent.php +++ b/src/Event/BatchGeneratedEvent.php @@ -8,11 +8,8 @@ final class BatchGeneratedEvent { - private FeedInterface $feed; - - public function __construct(FeedInterface $feed) + public function __construct(private readonly FeedInterface $feed) { - $this->feed = $feed; } public function getFeed(): FeedInterface diff --git a/src/Event/FeedShowMenuBuilderEvent.php b/src/Event/FeedShowMenuBuilderEvent.php index 8ec49dc2..df3510c7 100644 --- a/src/Event/FeedShowMenuBuilderEvent.php +++ b/src/Event/FeedShowMenuBuilderEvent.php @@ -11,13 +11,12 @@ final class FeedShowMenuBuilderEvent extends MenuBuilderEvent { - private FeedInterface $feed; - - public function __construct(FactoryInterface $factory, ItemInterface $menu, FeedInterface $feed) - { + public function __construct( + FactoryInterface $factory, + ItemInterface $menu, + private readonly FeedInterface $feed, + ) { parent::__construct($factory, $menu); - - $this->feed = $feed; } public function getFeed(): FeedInterface diff --git a/src/Event/GenerateBatchItemEvent.php b/src/Event/GenerateBatchItemEvent.php index 264ef3a4..db69320c 100644 --- a/src/Event/GenerateBatchItemEvent.php +++ b/src/Event/GenerateBatchItemEvent.php @@ -11,30 +11,17 @@ final class GenerateBatchItemEvent { - private FeedInterface $feed; - - private FeedTypeInterface $feedType; - - private ChannelInterface $channel; - - private LocaleInterface $locale; - - /** @var object|array */ - private $item; - - private ?object $rootItem; - /** * @param object|array $item */ - public function __construct(FeedInterface $feed, FeedTypeInterface $feedType, ChannelInterface $channel, LocaleInterface $locale, $item, object $rootItem = null) - { - $this->feed = $feed; - $this->feedType = $feedType; - $this->channel = $channel; - $this->locale = $locale; - $this->item = $item; - $this->rootItem = $rootItem; + public function __construct( + private readonly FeedInterface $feed, + private readonly FeedTypeInterface $feedType, + private readonly ChannelInterface $channel, + private readonly LocaleInterface $locale, + private $item, + private readonly ?object $rootItem = null, + ) { } public function getFeed(): FeedInterface diff --git a/src/Event/GenerateBatchViolationEvent.php b/src/Event/GenerateBatchViolationEvent.php index 3facff8e..d229d2b6 100644 --- a/src/Event/GenerateBatchViolationEvent.php +++ b/src/Event/GenerateBatchViolationEvent.php @@ -12,30 +12,17 @@ final class GenerateBatchViolationEvent { - private FeedInterface $feed; - - private FeedTypeInterface $feedType; - - private ChannelInterface $channel; - - private LocaleInterface $locale; - - /** @var object|array */ - private $item; - - private ConstraintViolationListInterface $constraintViolationList; - /** * @param object|array $item */ - public function __construct(FeedInterface $feed, FeedTypeInterface $feedType, ChannelInterface $channel, LocaleInterface $locale, $item, ConstraintViolationListInterface $constraintViolationList) - { - $this->feed = $feed; - $this->feedType = $feedType; - $this->channel = $channel; - $this->locale = $locale; - $this->item = $item; - $this->constraintViolationList = $constraintViolationList; + public function __construct( + private readonly FeedInterface $feed, + private readonly FeedTypeInterface $feedType, + private readonly ChannelInterface $channel, + private readonly LocaleInterface $locale, + private $item, + private readonly ConstraintViolationListInterface $constraintViolationList, + ) { } public function getFeed(): FeedInterface diff --git a/src/Event/QueryBuilderEvent.php b/src/Event/QueryBuilderEvent.php index 1e0455c2..8dcee53b 100644 --- a/src/Event/QueryBuilderEvent.php +++ b/src/Event/QueryBuilderEvent.php @@ -11,24 +11,12 @@ final class QueryBuilderEvent { - private DataProviderInterface $dataProvider; - - private QueryBuilder $queryBuilder; - - private ChannelInterface $channel; - - private LocaleInterface $locale; - public function __construct( - DataProviderInterface $dataProvider, - QueryBuilder $queryBuilder, - ChannelInterface $channel, - LocaleInterface $locale, + private readonly DataProviderInterface $dataProvider, + private readonly QueryBuilder $queryBuilder, + private readonly ChannelInterface $channel, + private readonly LocaleInterface $locale, ) { - $this->dataProvider = $dataProvider; - $this->queryBuilder = $queryBuilder; - $this->channel = $channel; - $this->locale = $locale; } public function getDataProvider(): DataProviderInterface diff --git a/src/EventListener/DeleteGeneratedFilesSubscriber.php b/src/EventListener/DeleteGeneratedFilesSubscriber.php index d516f220..30f540c8 100644 --- a/src/EventListener/DeleteGeneratedFilesSubscriber.php +++ b/src/EventListener/DeleteGeneratedFilesSubscriber.php @@ -15,18 +15,12 @@ use Symfony\Component\Workflow\Event\TransitionEvent; use Webmozart\Assert\Assert; -/** - * @psalm-suppress UndefinedDocblockClass - * @psalm-suppress UndefinedClass - */ final class DeleteGeneratedFilesSubscriber implements EventSubscriberInterface { /** @var FilesystemInterface|FilesystemOperator */ private $filesystem; /** - * @psalm-suppress UndefinedDocblockClass - * * @param FilesystemInterface|FilesystemOperator $filesystem */ public function __construct($filesystem) @@ -67,7 +61,7 @@ public function delete(TransitionEvent $event): void } else { $filesystem->deleteDirectory($feed->getCode()); } - } catch (RootViolationException|UnableToDeleteDirectory $e) { + } catch (RootViolationException|UnableToDeleteDirectory) { } } } diff --git a/src/EventListener/Filter/AbstractFilterListener.php b/src/EventListener/Filter/AbstractFilterListener.php index 31fe3158..177ccdd9 100644 --- a/src/EventListener/Filter/AbstractFilterListener.php +++ b/src/EventListener/Filter/AbstractFilterListener.php @@ -11,11 +11,8 @@ abstract class AbstractFilterListener { - private string $class; - - public function __construct(string $class) + public function __construct(private readonly string $class) { - $this->class = $class; } protected function isEligible(QueryBuilderEvent $event, array $additionalInstanceChecks = []): bool diff --git a/src/EventListener/IncrementFinishedBatchesSubscriber.php b/src/EventListener/IncrementFinishedBatchesSubscriber.php index 32be5f6f..ebaab3a7 100644 --- a/src/EventListener/IncrementFinishedBatchesSubscriber.php +++ b/src/EventListener/IncrementFinishedBatchesSubscriber.php @@ -10,11 +10,8 @@ final class IncrementFinishedBatchesSubscriber implements EventSubscriberInterface { - private FeedRepositoryInterface $feedRepository; - - public function __construct(FeedRepositoryInterface $feedRepository) + public function __construct(private readonly FeedRepositoryInterface $feedRepository) { - $this->feedRepository = $feedRepository; } public static function getSubscribedEvents(): array diff --git a/src/EventListener/MoveGeneratedFeedSubscriber.php b/src/EventListener/MoveGeneratedFeedSubscriber.php index dca13d96..46fd1b66 100644 --- a/src/EventListener/MoveGeneratedFeedSubscriber.php +++ b/src/EventListener/MoveGeneratedFeedSubscriber.php @@ -18,10 +18,6 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Workflow\Event\TransitionEvent; -/** - * @psalm-suppress UndefinedDocblockClass - * @psalm-suppress UndefinedClass - */ final class MoveGeneratedFeedSubscriber implements EventSubscriberInterface { /** @var FilesystemInterface|FilesystemOperator */ @@ -30,21 +26,15 @@ final class MoveGeneratedFeedSubscriber implements EventSubscriberInterface /** @var FilesystemInterface|FilesystemOperator */ private $filesystem; - private FeedPathGeneratorInterface $temporaryFeedPathGenerator; - - private FeedPathGeneratorInterface $feedPathGenerator; - /** - * @psalm-suppress UndefinedDocblockClass - * * @param FilesystemInterface|FilesystemOperator $temporaryFilesystem * @param FilesystemInterface|FilesystemOperator $filesystem */ public function __construct( $temporaryFilesystem, $filesystem, - FeedPathGeneratorInterface $temporaryFeedPathGenerator, - FeedPathGeneratorInterface $feedPathGenerator, + private readonly FeedPathGeneratorInterface $temporaryFeedPathGenerator, + private readonly FeedPathGeneratorInterface $feedPathGenerator, ) { if (interface_exists(FilesystemInterface::class) && $temporaryFilesystem instanceof FilesystemInterface) { $this->temporaryFilesystem = $temporaryFilesystem; @@ -68,8 +58,6 @@ public function __construct( FilesystemOperator::class, )); } - $this->temporaryFeedPathGenerator = $temporaryFeedPathGenerator; - $this->feedPathGenerator = $feedPathGenerator; } public static function getSubscribedEvents(): array @@ -130,7 +118,7 @@ public function move(TransitionEvent $event): void try { $filesystem->delete((string) $newPath); - } catch (FileNotFoundException|UnableToDeleteFile $e) { + } catch (FileNotFoundException|UnableToDeleteFile) { } if (interface_exists(FilesystemInterface::class) && $filesystem instanceof FilesystemInterface) { diff --git a/src/EventListener/SendFinishGenerationCommandSubscriber.php b/src/EventListener/SendFinishGenerationCommandSubscriber.php index 06af45fe..0da01098 100644 --- a/src/EventListener/SendFinishGenerationCommandSubscriber.php +++ b/src/EventListener/SendFinishGenerationCommandSubscriber.php @@ -12,14 +12,10 @@ final class SendFinishGenerationCommandSubscriber implements EventSubscriberInterface { - private FeedRepositoryInterface $feedRepository; - - private MessageBusInterface $commandBus; - - public function __construct(FeedRepositoryInterface $feedRepository, MessageBusInterface $commandBus) - { - $this->feedRepository = $feedRepository; - $this->commandBus = $commandBus; + public function __construct( + private readonly FeedRepositoryInterface $feedRepository, + private readonly MessageBusInterface $commandBus, + ) { } public static function getSubscribedEvents(): array diff --git a/src/EventListener/StartProcessingSubscriber.php b/src/EventListener/StartProcessingSubscriber.php index d5f2035c..7ba39b26 100644 --- a/src/EventListener/StartProcessingSubscriber.php +++ b/src/EventListener/StartProcessingSubscriber.php @@ -14,11 +14,8 @@ final class StartProcessingSubscriber implements EventSubscriberInterface { - private FeedTypeRegistryInterface $feedTypeRegistry; - - public function __construct(FeedTypeRegistryInterface $feedTypeRegistry) + public function __construct(private readonly FeedTypeRegistryInterface $feedTypeRegistry) { - $this->feedTypeRegistry = $feedTypeRegistry; } public static function getSubscribedEvents(): array diff --git a/src/Exception/GenerateBatchException.php b/src/Exception/GenerateBatchException.php index 1d473a33..926dae51 100644 --- a/src/Exception/GenerateBatchException.php +++ b/src/Exception/GenerateBatchException.php @@ -10,7 +10,7 @@ final class GenerateBatchException extends RuntimeException implements ExceptionInterface { - private string $originalMessage; + private readonly string $originalMessage; private ?int $feedId = null; diff --git a/src/Exception/UndefinedBlockException.php b/src/Exception/UndefinedBlockException.php index 26868997..f431c575 100644 --- a/src/Exception/UndefinedBlockException.php +++ b/src/Exception/UndefinedBlockException.php @@ -8,9 +8,9 @@ final class UndefinedBlockException extends InvalidArgumentException implements ExceptionInterface { - private string $block; + private readonly string $block; - private array $requiredBlocks; + private readonly array $requiredBlocks; /** * @param array $requiredBlocks diff --git a/src/Factory/ViolationFactory.php b/src/Factory/ViolationFactory.php index ebb7d97e..600079f4 100644 --- a/src/Factory/ViolationFactory.php +++ b/src/Factory/ViolationFactory.php @@ -13,11 +13,8 @@ final class ViolationFactory implements ViolationFactoryInterface { - private FactoryInterface $decoratedFactory; - - public function __construct(FactoryInterface $decoratedFactory) + public function __construct(private readonly FactoryInterface $decoratedFactory) { - $this->decoratedFactory = $decoratedFactory; } public function createNew(): ViolationInterface diff --git a/src/Feed/Model/Google/Shopping/DateRange.php b/src/Feed/Model/Google/Shopping/DateRange.php index a7c59722..c63e1948 100644 --- a/src/Feed/Model/Google/Shopping/DateRange.php +++ b/src/Feed/Model/Google/Shopping/DateRange.php @@ -6,16 +6,10 @@ use JsonSerializable; -final class DateRange implements JsonSerializable +final class DateRange implements JsonSerializable, \Stringable { - private DateTime $start; - - private DateTime $end; - - public function __construct(DateTime $start, DateTime $end) + public function __construct(private readonly DateTime $start, private readonly DateTime $end) { - $this->start = $start; - $this->end = $end; } public function __toString(): string diff --git a/src/Feed/Model/Google/Shopping/DateTime.php b/src/Feed/Model/Google/Shopping/DateTime.php index 3fb32bb1..1ffd53ef 100644 --- a/src/Feed/Model/Google/Shopping/DateTime.php +++ b/src/Feed/Model/Google/Shopping/DateTime.php @@ -7,7 +7,7 @@ use DateTime as BaseDateTime; use JsonSerializable; -final class DateTime extends BaseDateTime implements JsonSerializable +final class DateTime extends BaseDateTime implements JsonSerializable, \Stringable { public function __toString(): string { diff --git a/src/Feed/Model/Google/Shopping/Price.php b/src/Feed/Model/Google/Shopping/Price.php index e4d982cf..979edefa 100644 --- a/src/Feed/Model/Google/Shopping/Price.php +++ b/src/Feed/Model/Google/Shopping/Price.php @@ -7,11 +7,11 @@ use JsonSerializable; use Webmozart\Assert\Assert; -final class Price implements JsonSerializable +final class Price implements JsonSerializable, \Stringable { - private int $amount; + private readonly int $amount; - private string $currency; + private readonly string $currency; /** * @param object|string $currency diff --git a/src/FeedContext/Google/Shopping/ProductItemContext.php b/src/FeedContext/Google/Shopping/ProductItemContext.php index 64424f14..3f2d7b6a 100644 --- a/src/FeedContext/Google/Shopping/ProductItemContext.php +++ b/src/FeedContext/Google/Shopping/ProductItemContext.php @@ -42,20 +42,11 @@ class ProductItemContext implements ItemContextInterface { - private RouterInterface $router; - - private CacheManager $cacheManager; - - private AvailabilityCheckerInterface $availabilityChecker; - public function __construct( - RouterInterface $router, - CacheManager $cacheManager, - AvailabilityCheckerInterface $availabilityChecker, + private readonly RouterInterface $router, + private readonly CacheManager $cacheManager, + private readonly AvailabilityCheckerInterface $availabilityChecker, ) { - $this->router = $router; - $this->cacheManager = $cacheManager; - $this->availabilityChecker = $availabilityChecker; } public function getContextList(object $product, ChannelInterface $channel, LocaleInterface $locale): ContextListInterface @@ -63,7 +54,7 @@ public function getContextList(object $product, ChannelInterface $channel, Local if (!$product instanceof ProductInterface) { throw new InvalidArgumentException(sprintf( 'The class %s is not an instance of %s', - get_class($product), + $product::class, ProductInterface::class, )); } diff --git a/src/FeedType/FeedType.php b/src/FeedType/FeedType.php index 1d1451df..4d8db8b7 100644 --- a/src/FeedType/FeedType.php +++ b/src/FeedType/FeedType.php @@ -11,31 +11,16 @@ final class FeedType implements FeedTypeInterface { - private string $code; - - private string $template; - - private DataProviderInterface $dataProvider; - - private FeedContextInterface $feedContext; - - private ItemContextInterface $itemContext; - - private array $validationGroups; + private readonly array $validationGroups; public function __construct( - string $code, - string $template, - DataProviderInterface $dataProvider, - FeedContextInterface $feedContext, - ItemContextInterface $itemContext, + private readonly string $code, + private readonly string $template, + private readonly DataProviderInterface $dataProvider, + private readonly FeedContextInterface $feedContext, + private readonly ItemContextInterface $itemContext, array $validationGroups = [], ) { - $this->code = $code; - $this->template = $template; - $this->dataProvider = $dataProvider; - $this->feedContext = $feedContext; - $this->itemContext = $itemContext; $this->validationGroups = count($validationGroups) === 0 ? [Constraint::DEFAULT_GROUP] : $validationGroups; } diff --git a/src/Form/DataTransformer/FeedTypeToCodeTransformer.php b/src/Form/DataTransformer/FeedTypeToCodeTransformer.php index 7aa2534b..fb5b6952 100644 --- a/src/Form/DataTransformer/FeedTypeToCodeTransformer.php +++ b/src/Form/DataTransformer/FeedTypeToCodeTransformer.php @@ -14,11 +14,8 @@ */ final class FeedTypeToCodeTransformer implements DataTransformerInterface { - private FeedTypeRegistryInterface $feedTypeRegistry; - - public function __construct(FeedTypeRegistryInterface $feedTypeRegistry) + public function __construct(private readonly FeedTypeRegistryInterface $feedTypeRegistry) { - $this->feedTypeRegistry = $feedTypeRegistry; } /** diff --git a/src/Form/Type/FeedTypeChoiceType.php b/src/Form/Type/FeedTypeChoiceType.php index c8649b7d..49448969 100644 --- a/src/Form/Type/FeedTypeChoiceType.php +++ b/src/Form/Type/FeedTypeChoiceType.php @@ -17,11 +17,8 @@ */ final class FeedTypeChoiceType extends AbstractType { - private FeedTypeRegistryInterface $feedTypeRegistry; - - public function __construct(FeedTypeRegistryInterface $feedTypeRegistry) + public function __construct(private readonly FeedTypeRegistryInterface $feedTypeRegistry) { - $this->feedTypeRegistry = $feedTypeRegistry; } public function buildForm(FormBuilderInterface $builder, array $options): void @@ -36,9 +33,7 @@ public function configureOptions(OptionsResolver $resolver): void 'placeholder' => 'setono_sylius_feed.form.feed.feed_type_placeholder', 'label' => 'setono_sylius_feed.form.feed.feed_type', 'choices' => $this->feedTypeRegistry->all(), - 'choice_label' => static function (FeedTypeInterface $choice): string { - return 'setono_sylius_feed.feed_type.' . $choice->getCode(); - }, + 'choice_label' => static fn (FeedTypeInterface $choice): string => 'setono_sylius_feed.feed_type.' . $choice->getCode(), 'choice_value' => 'code', ]) ; diff --git a/src/Generator/FeedPathGenerator.php b/src/Generator/FeedPathGenerator.php index f04b0e6e..caeb791d 100644 --- a/src/Generator/FeedPathGenerator.php +++ b/src/Generator/FeedPathGenerator.php @@ -11,11 +11,8 @@ final class FeedPathGenerator implements FeedPathGeneratorInterface { - private FeedExtensionResolverInterface $feedExtensionResolver; - - public function __construct(FeedExtensionResolverInterface $feedExtensionResolver) + public function __construct(private readonly FeedExtensionResolverInterface $feedExtensionResolver) { - $this->feedExtensionResolver = $feedExtensionResolver; } /** diff --git a/src/Generator/TemporaryFeedPathGenerator.php b/src/Generator/TemporaryFeedPathGenerator.php index ae707162..ee5b9556 100644 --- a/src/Generator/TemporaryFeedPathGenerator.php +++ b/src/Generator/TemporaryFeedPathGenerator.php @@ -11,10 +11,6 @@ use SplFileInfo; use Webmozart\Assert\Assert; -/** - * @psalm-suppress UndefinedDocblockClass - * @psalm-suppress UndefinedClass - */ final class TemporaryFeedPathGenerator implements FeedPathGeneratorInterface { public const BASE_FILENAME = '_feed'; @@ -36,8 +32,6 @@ public static function getBaseFile(SplFileInfo $dir): SplFileInfo } /** - * @psalm-suppress UndefinedDocblockClass - * * @param FilesystemInterface|FilesystemOperator $filesystem */ public static function getPartialFile(SplFileInfo $dir, $filesystem): SplFileInfo diff --git a/src/Menu/FeedShowMenuBuilder.php b/src/Menu/FeedShowMenuBuilder.php index 4e39bcc9..cf67eb20 100644 --- a/src/Menu/FeedShowMenuBuilder.php +++ b/src/Menu/FeedShowMenuBuilder.php @@ -14,25 +14,13 @@ final class FeedShowMenuBuilder { - private FactoryInterface $factory; - - private EventDispatcherInterface $eventDispatcher; - - private Registry $workflowRegistry; - public function __construct( - FactoryInterface $factory, - EventDispatcherInterface $eventDispatcher, - Registry $workflowRegistry, + private readonly FactoryInterface $factory, + private readonly EventDispatcherInterface $eventDispatcher, + private readonly Registry $workflowRegistry, ) { - $this->factory = $factory; - $this->eventDispatcher = $eventDispatcher; - $this->workflowRegistry = $workflowRegistry; } - /** - * @psalm-suppress InternalMethod - */ public function createMenu(array $options): ItemInterface { $menu = $this->factory->createItem('root'); diff --git a/src/Message/Command/FinishGeneration.php b/src/Message/Command/FinishGeneration.php index 67b83a15..e4eecb9a 100644 --- a/src/Message/Command/FinishGeneration.php +++ b/src/Message/Command/FinishGeneration.php @@ -6,11 +6,8 @@ final class FinishGeneration implements CommandInterface { - private int $feedId; - - public function __construct(int $feedId) + public function __construct(private readonly int $feedId) { - $this->feedId = $feedId; } public function getFeedId(): int diff --git a/src/Message/Command/GenerateBatch.php b/src/Message/Command/GenerateBatch.php index 7744b083..3af97d7f 100644 --- a/src/Message/Command/GenerateBatch.php +++ b/src/Message/Command/GenerateBatch.php @@ -17,20 +17,16 @@ final class GenerateBatch implements CommandInterface private int $localeId; - private BatchInterface $batch; - /** * @param int|FeedInterface $feed * @param int|ChannelInterface $channel * @param int|LocaleInterface $locale */ - public function __construct($feed, $channel, $locale, BatchInterface $batch) + public function __construct($feed, $channel, $locale, private readonly BatchInterface $batch) { $this->setFeedId($feed instanceof FeedInterface ? (int) $feed->getId() : $feed); $this->setChannelId($channel instanceof ChannelInterface ? (int) $channel->getId() : $channel); $this->setLocaleId($locale instanceof LocaleInterface ? (int) $locale->getId() : $locale); - - $this->batch = $batch; } public function getFeedId(): int diff --git a/src/Message/Command/ProcessFeed.php b/src/Message/Command/ProcessFeed.php index f3ee46dd..5a51c3e2 100644 --- a/src/Message/Command/ProcessFeed.php +++ b/src/Message/Command/ProcessFeed.php @@ -6,11 +6,8 @@ final class ProcessFeed implements CommandInterface { - private int $feedId; - - public function __construct(int $feedId) + public function __construct(private readonly int $feedId) { - $this->feedId = $feedId; } public function getFeedId(): int diff --git a/src/Message/Handler/FinishGenerationHandler.php b/src/Message/Handler/FinishGenerationHandler.php index 1691948d..ca20c972 100644 --- a/src/Message/Handler/FinishGenerationHandler.php +++ b/src/Message/Handler/FinishGenerationHandler.php @@ -29,48 +29,26 @@ use Twig\Environment; use Webmozart\Assert\Assert; -/** - * @psalm-suppress UndefinedDocblockClass - * @psalm-suppress UndefinedClass - * @psalm-suppress DeprecatedInterface - * @psalm-suppress InternalMethod - */ final class FinishGenerationHandler implements MessageHandlerInterface { use GetFeedTrait; - private ObjectManager $feedManager; - - /** @var FilesystemInterface|FilesystemOperator */ - private $filesystem; - - private Registry $workflowRegistry; - - private Environment $twig; - - private FeedTypeRegistryInterface $feedTypeRegistry; - - private FeedPathGeneratorInterface $temporaryFeedPathGenerator; - - private LoggerInterface $logger; + private FilesystemInterface|FilesystemOperator $filesystem; /** - * @psalm-suppress UndefinedDocblockClass - * * @param FilesystemInterface|FilesystemOperator $filesystem */ public function __construct( FeedRepositoryInterface $feedRepository, - ObjectManager $feedManager, + private ObjectManager $feedManager, $filesystem, - Registry $workflowRegistry, - Environment $twig, - FeedTypeRegistryInterface $feedTypeRegistry, - FeedPathGeneratorInterface $temporaryFeedPathGenerator, - LoggerInterface $logger, + private readonly Registry $workflowRegistry, + private Environment $twig, + private readonly FeedTypeRegistryInterface $feedTypeRegistry, + private readonly FeedPathGeneratorInterface $temporaryFeedPathGenerator, + private readonly LoggerInterface $logger, ) { $this->feedRepository = $feedRepository; - $this->feedManager = $feedManager; if (interface_exists(FilesystemInterface::class) && $filesystem instanceof FilesystemInterface) { $this->filesystem = $filesystem; } elseif ($filesystem instanceof FilesystemOperator) { @@ -82,11 +60,6 @@ public function __construct( FilesystemOperator::class, )); } - $this->workflowRegistry = $workflowRegistry; - $this->twig = $twig; - $this->feedTypeRegistry = $feedTypeRegistry; - $this->temporaryFeedPathGenerator = $temporaryFeedPathGenerator; - $this->logger = $logger; } public function __invoke(FinishGeneration $message): void @@ -115,7 +88,7 @@ public function __invoke(FinishGeneration $message): void [$feedStart, $feedEnd] = $this->getFeedParts($feed, $feedType, $channel, $locale); - fwrite($batchStream, $feedStart); + fwrite($batchStream, (string) $feedStart); $filesystem = $this->filesystem; @@ -150,7 +123,7 @@ public function __invoke(FinishGeneration $message): void $filesystem->delete($path); } - fwrite($batchStream, $feedEnd); + fwrite($batchStream, (string) $feedEnd); if (interface_exists(FilesystemInterface::class) && $filesystem instanceof FilesystemInterface) { /** @var resource|false $res */ diff --git a/src/Message/Handler/GenerateBatchHandler.php b/src/Message/Handler/GenerateBatchHandler.php index 272803ad..fe59babd 100644 --- a/src/Message/Handler/GenerateBatchHandler.php +++ b/src/Message/Handler/GenerateBatchHandler.php @@ -45,12 +45,6 @@ use Twig\Environment; use Webmozart\Assert\Assert; -/** - * @psalm-suppress UndefinedDocblockClass - * @psalm-suppress UndefinedClass - * @psalm-suppress DeprecatedInterface - * @psalm-suppress InternalMethod - */ final class GenerateBatchHandler implements MessageHandlerInterface { use GetChannelTrait; @@ -59,59 +53,28 @@ final class GenerateBatchHandler implements MessageHandlerInterface private RequestContext $initialRequestContext; - private ObjectManager $feedManager; + private FilesystemInterface|FilesystemOperator $filesystem; - private FeedTypeRegistryInterface $feedTypeRegistry; - - private Environment $twig; - - /** @var FilesystemInterface|FilesystemOperator */ - private $filesystem; - - private FeedPathGeneratorInterface $temporaryFeedPathGenerator; - - private EventDispatcherInterface $eventDispatcher; - - private Registry $workflowRegistry; - - private ValidatorInterface $validator; - - private ViolationFactoryInterface $violationFactory; - - private SerializerInterface $serializer; - - private UrlGeneratorInterface $urlGenerator; - - private LoggerInterface $logger; - - /** - * @psalm-suppress UndefinedDocblockClass - * - * @param FilesystemOperator|FilesystemInterface $filesystem - */ public function __construct( FeedRepositoryInterface $feedRepository, ChannelRepositoryInterface $channelRepository, RepositoryInterface $localeRepository, - ObjectManager $feedManager, - FeedTypeRegistryInterface $feedTypeRegistry, - Environment $twig, + private readonly ObjectManager $feedManager, + private readonly FeedTypeRegistryInterface $feedTypeRegistry, + private readonly Environment $twig, $filesystem, - FeedPathGeneratorInterface $temporaryFeedPathGenerator, - EventDispatcherInterface $eventDispatcher, - Registry $workflowRegistry, - ValidatorInterface $validator, - ViolationFactoryInterface $violationFactory, - SerializerInterface $serializer, - UrlGeneratorInterface $urlGenerator, - LoggerInterface $logger, + private readonly FeedPathGeneratorInterface $temporaryFeedPathGenerator, + private readonly EventDispatcherInterface $eventDispatcher, + private readonly Registry $workflowRegistry, + private readonly ValidatorInterface $validator, + private readonly ViolationFactoryInterface $violationFactory, + private readonly SerializerInterface $serializer, + private readonly UrlGeneratorInterface $urlGenerator, + private readonly LoggerInterface $logger, ) { $this->feedRepository = $feedRepository; $this->channelRepository = $channelRepository; $this->localeRepository = $localeRepository; - $this->feedManager = $feedManager; - $this->feedTypeRegistry = $feedTypeRegistry; - $this->twig = $twig; if (interface_exists(FilesystemInterface::class) && $filesystem instanceof FilesystemInterface) { $this->filesystem = $filesystem; } elseif ($filesystem instanceof FilesystemOperator) { @@ -123,14 +86,6 @@ public function __construct( FilesystemOperator::class, )); } - $this->temporaryFeedPathGenerator = $temporaryFeedPathGenerator; - $this->eventDispatcher = $eventDispatcher; - $this->workflowRegistry = $workflowRegistry; - $this->validator = $validator; - $this->violationFactory = $violationFactory; - $this->serializer = $serializer; - $this->urlGenerator = $urlGenerator; - $this->logger = $logger; } public function __invoke(GenerateBatch $message): void diff --git a/src/Message/Handler/GenerateFeedHandler.php b/src/Message/Handler/GenerateFeedHandler.php index d608c6ed..50d8b4ba 100644 --- a/src/Message/Handler/GenerateFeedHandler.php +++ b/src/Message/Handler/GenerateFeedHandler.php @@ -17,31 +17,22 @@ use Symfony\Component\Messenger\Handler\MessageHandlerInterface; use Symfony\Component\Messenger\MessageBusInterface; -/** - * @psalm-suppress DeprecatedInterface - */ final class GenerateFeedHandler implements MessageHandlerInterface { use GetChannelTrait; use GetFeedTrait; use GetLocaleTrait; - private FeedTypeRegistryInterface $feedTypeRegistry; - - private MessageBusInterface $commandBus; - public function __construct( FeedRepositoryInterface $feedRepository, ChannelRepositoryInterface $channelRepository, RepositoryInterface $localeRepository, - FeedTypeRegistryInterface $feedTypeRegistry, - MessageBusInterface $commandBus, + private readonly FeedTypeRegistryInterface $feedTypeRegistry, + private readonly MessageBusInterface $commandBus, ) { $this->feedRepository = $feedRepository; $this->channelRepository = $channelRepository; $this->localeRepository = $localeRepository; - $this->feedTypeRegistry = $feedTypeRegistry; - $this->commandBus = $commandBus; } public function __invoke(GenerateFeed $message): void diff --git a/src/Message/Handler/ProcessFeedHandler.php b/src/Message/Handler/ProcessFeedHandler.php index 560513ec..2bebf360 100644 --- a/src/Message/Handler/ProcessFeedHandler.php +++ b/src/Message/Handler/ProcessFeedHandler.php @@ -19,38 +19,19 @@ use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Workflow\Registry; -/** - * @psalm-suppress DeprecatedInterface - * @psalm-suppress InternalMethod - */ final class ProcessFeedHandler implements MessageHandlerInterface { use GetFeedTrait; - private ObjectManager $feedManager; - - private FeedTypeRegistryInterface $feedTypeRegistry; - - private MessageBusInterface $commandBus; - - private Registry $workflowRegistry; - - private TemplateValidatorInterface $templateValidator; - public function __construct( FeedRepositoryInterface $feedRepository, - ObjectManager $feedManager, - FeedTypeRegistryInterface $feedTypeRegistry, - MessageBusInterface $commandBus, - Registry $workflowRegistry, - TemplateValidatorInterface $templateValidator, + private readonly ObjectManager $feedManager, + private readonly FeedTypeRegistryInterface $feedTypeRegistry, + private readonly MessageBusInterface $commandBus, + private readonly Registry $workflowRegistry, + private readonly TemplateValidatorInterface $templateValidator, ) { $this->feedRepository = $feedRepository; - $this->feedManager = $feedManager; - $this->feedTypeRegistry = $feedTypeRegistry; - $this->commandBus = $commandBus; - $this->workflowRegistry = $workflowRegistry; - $this->templateValidator = $templateValidator; } public function __invoke(ProcessFeed $message): void diff --git a/src/Model/Feed.php b/src/Model/Feed.php index a8638e1a..58c42c39 100644 --- a/src/Model/Feed.php +++ b/src/Model/Feed.php @@ -29,16 +29,10 @@ class Feed implements FeedInterface protected int $finishedBatches = 0; - /** - * @var Collection|ChannelInterface[] - * @psalm-var Collection - */ + /** @var Collection */ protected Collection $channels; - /** - * @var Collection|ViolationInterface[] - * @psalm-var Collection - */ + /** @var Collection */ protected Collection $violations; public function __construct() diff --git a/src/Processor/FeedProcessor.php b/src/Processor/FeedProcessor.php index 3cbefb01..dd126a65 100644 --- a/src/Processor/FeedProcessor.php +++ b/src/Processor/FeedProcessor.php @@ -4,7 +4,7 @@ namespace Setono\SyliusFeedPlugin\Processor; -use Psr\Log\LoggerAwareTrait; +use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Setono\SyliusFeedPlugin\Message\Command\ProcessFeed; use Setono\SyliusFeedPlugin\Repository\FeedRepositoryInterface; @@ -12,16 +12,12 @@ final class FeedProcessor implements FeedProcessorInterface { - use LoggerAwareTrait; + private LoggerInterface $logger; - private FeedRepositoryInterface $feedRepository; - - private MessageBusInterface $commandBus; - - public function __construct(FeedRepositoryInterface $feedRepository, MessageBusInterface $commandBus) - { - $this->feedRepository = $feedRepository; - $this->commandBus = $commandBus; + public function __construct( + private readonly FeedRepositoryInterface $feedRepository, + private readonly MessageBusInterface $commandBus, + ) { $this->logger = new NullLogger(); } @@ -34,4 +30,9 @@ public function process(): void $this->commandBus->dispatch(new ProcessFeed((int) $feed->getId())); } } + + public function setLogger(LoggerInterface $logger): void + { + $this->logger = $logger; + } } diff --git a/src/Resolver/FeedExtensionResolver.php b/src/Resolver/FeedExtensionResolver.php index 2b3af364..fe16130f 100644 --- a/src/Resolver/FeedExtensionResolver.php +++ b/src/Resolver/FeedExtensionResolver.php @@ -10,14 +10,10 @@ final class FeedExtensionResolver implements FeedExtensionResolverInterface { - private FeedTypeRegistryInterface $feedTypeRegistry; - - private Environment $twig; - - public function __construct(FeedTypeRegistryInterface $feedTypeRegistry, Environment $twig) - { - $this->feedTypeRegistry = $feedTypeRegistry; - $this->twig = $twig; + public function __construct( + private readonly FeedTypeRegistryInterface $feedTypeRegistry, + private readonly Environment $twig, + ) { } public function resolve(FeedInterface $feed): string diff --git a/src/Twig/Extension.php b/src/Twig/Extension.php index d94d05ce..0c1e811b 100644 --- a/src/Twig/Extension.php +++ b/src/Twig/Extension.php @@ -15,29 +15,23 @@ final class Extension extends AbstractExtension { - private RequestStack $requestStack; - - private UrlGeneratorInterface $urlGenerator; - public function __construct( - RequestStack $requestStack, - UrlGeneratorInterface $urlGenerator, + private readonly RequestStack $requestStack, + private readonly UrlGeneratorInterface $urlGenerator, ) { - $this->requestStack = $requestStack; - $this->urlGenerator = $urlGenerator; } public function getFilters(): array { return [ - new TwigFilter('setono_sylius_feed_remove_empty_tags', [$this, 'removeEmptyTags']), + new TwigFilter('setono_sylius_feed_remove_empty_tags', $this->removeEmptyTags(...)), ]; } public function getFunctions(): array { return [ - new TwigFunction('setono_sylius_feed_generate_feed_url', [$this, 'generateFeedUrl']), + new TwigFunction('setono_sylius_feed_generate_feed_url', $this->generateFeedUrl(...)), ]; } diff --git a/src/Validator/TemplateValidator.php b/src/Validator/TemplateValidator.php index a1a75224..2cc6d975 100644 --- a/src/Validator/TemplateValidator.php +++ b/src/Validator/TemplateValidator.php @@ -9,11 +9,8 @@ final class TemplateValidator implements TemplateValidatorInterface { - private Environment $twig; - - public function __construct(Environment $twig) + public function __construct(private readonly Environment $twig) { - $this->twig = $twig; } public function validate(string $template): void diff --git a/tests/Application/src/Entity/.gitignore b/tests/Application/src/Entity/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Resolver/FeedExtensionResolverTest.php b/tests/Resolver/FeedExtensionResolverTest.php index 9a6f312c..c792e568 100644 --- a/tests/Resolver/FeedExtensionResolverTest.php +++ b/tests/Resolver/FeedExtensionResolverTest.php @@ -26,11 +26,11 @@ public function it_resolves_extension(): void $feedType->method('getTemplate')->willReturn('template.twig.html'); $feedTypeRegistry = $this->createMock(FeedTypeRegistryInterface::class); - $feedTypeRegistry->method('get')->with($this->equalTo('feed_type'))->willReturn($feedType); + $feedTypeRegistry->method('get')->with(self::equalTo('feed_type'))->willReturn($feedType); $resolver = new FeedExtensionResolver($feedTypeRegistry, $this->getTwig()); - $this->assertSame('xml', $resolver->resolve($feed)); + self::assertSame('xml', $resolver->resolve($feed)); } private function getTwig(): Environment