diff --git a/docs/model/product-feeds.md b/docs/model/product-feeds.md index f4595f2cfea..9c5816589ab 100644 --- a/docs/model/product-feeds.md +++ b/docs/model/product-feeds.md @@ -40,6 +40,10 @@ In such a case, this feed will be generated every four hours. Feeds have their default times set in their own `services.yaml` files, but can be easily changed in your project's `feed.yaml` file. You only need to copy service definition from feed `services.yaml` file and change the hours and minutes to expected ones. +## How to run feed outside scheduled time? + +If you want to run feed outside scheduled time, you can use the `php bin/console shopsys:feed-schedule` command with `--feed-name` argument to schedule one feed or `--all` argument to schedule all feeds and then run `php bin/console shopsys:cron --module="Shopsys\FrameworkBundle\Model\Feed\FeedCronModule" --instance-name=export` to generate the feeds. + ## How to limit a product feed to a specific domain? If you want to limit a product feed to a specific domain, you can use the `domain_ids` parameter in the feed's service definition. diff --git a/packages/framework/src/Command/ScheduleFeedsCommand.php b/packages/framework/src/Command/ScheduleFeedsCommand.php new file mode 100644 index 00000000000..5b924eb9e6f --- /dev/null +++ b/packages/framework/src/Command/ScheduleFeedsCommand.php @@ -0,0 +1,67 @@ +setDescription('Schedule feeds to be generated in the next cron run.') + ->addOption(self::OPTION_FEED_NAME, null, InputOption::VALUE_OPTIONAL, 'name of feed to be scheduled') + ->addOption(self::OPTION_ALL, null, InputOption::VALUE_NONE, 'schedule all feeds'); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $optionAll = $input->getOption(self::OPTION_ALL); + $optionFeedName = $input->getOption(self::OPTION_FEED_NAME); + + $symfonyStyle = new SymfonyStyle($input, $output); + + if ($optionAll === true) { + $symfonyStyle->info('Marking all feeds for scheduling...'); + $this->feedFacade->scheduleAllFeeds(); + } elseif ($optionFeedName !== null) { + $symfonyStyle->info('Marking feed for scheduling...'); + $this->feedFacade->scheduleFeedByName($optionFeedName); + } else { + $symfonyStyle->error('You have to specify either --all or --feed-name option.'); + + return Command::FAILURE; + } + + $symfonyStyle->success('Done!'); + + return Command::SUCCESS; + } +} diff --git a/packages/framework/src/Model/Feed/FeedFacade.php b/packages/framework/src/Model/Feed/FeedFacade.php index d5ab9c804ad..33afb91fcb6 100644 --- a/packages/framework/src/Model/Feed/FeedFacade.php +++ b/packages/framework/src/Model/Feed/FeedFacade.php @@ -137,15 +137,24 @@ public function scheduleFeedsForCurrentTime(): void { $feedConfigsToSchedule = $this->feedRegistry->getFeedConfigsForCurrentTime(); - foreach ($feedConfigsToSchedule as $feedConfig) { - $feedModules = $this->feedModuleRepository->getFeedModulesByConfig($feedConfig); + $this->markFeedConfigsForScheduling($feedConfigsToSchedule); + } - foreach ($feedModules as $feedModule) { - $feedModule->schedule(); - } - } + public function scheduleAllFeeds(): void + { + $feedConfigsToSchedule = $this->feedRegistry->getAllFeedConfigs(); - $this->em->flush(); + $this->markFeedConfigsForScheduling($feedConfigsToSchedule); + } + + /** + * @param string $name + */ + public function scheduleFeedByName(string $name): void + { + $feedConfigsToSchedule = [$this->feedRegistry->getFeedConfigByName($name)]; + + $this->markFeedConfigsForScheduling($feedConfigsToSchedule); } /** @@ -156,4 +165,20 @@ public function markFeedModuleAsUnscheduled(FeedModule $feedModule): void $feedModule->unschedule(); $this->em->flush(); } + + /** + * @param array $feedConfigsToSchedule + */ + protected function markFeedConfigsForScheduling(array $feedConfigsToSchedule): void + { + foreach ($feedConfigsToSchedule as $feedConfig) { + $feedModules = $this->feedModuleRepository->getFeedModulesByConfig($feedConfig); + + foreach ($feedModules as $feedModule) { + $feedModule->schedule(); + } + } + + $this->em->flush(); + } }