From c91d1b783044de4c8d3edab87768c4ea07cfda83 Mon Sep 17 00:00:00 2001 From: Dominik Chrastecky Date: Fri, 16 Feb 2024 10:11:23 +0100 Subject: [PATCH] Add a job to reanalyze more posts based on date --- config/packages/messenger.yaml | 1 + src/Command/TriggerJobCommand.php | 45 ++++++++++++++++++- src/Message/ReanalyzePostsMessage.php | 13 ++++++ src/MessageHandler/ReanalyzePostsHandler.php | 47 ++++++++++++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 src/Message/ReanalyzePostsMessage.php create mode 100644 src/MessageHandler/ReanalyzePostsHandler.php diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index afa067b..7390f70 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -17,6 +17,7 @@ framework: App\Message\AnalyzePostReportMessage: async App\Message\AnalyzeUserMessage: async App\Message\BanUserMessage: async + App\Message\ReanalyzePostsMessage: async App\Message\RemoveCommentMessage: async App\Message\RemovePostMessage: async App\Message\RestoreCommentMessage: async diff --git a/src/Command/TriggerJobCommand.php b/src/Command/TriggerJobCommand.php index b060c37..3d61223 100644 --- a/src/Command/TriggerJobCommand.php +++ b/src/Command/TriggerJobCommand.php @@ -2,6 +2,12 @@ namespace App\Command; +use DateTime; +use DateTimeImmutable; +use DateTimeInterface; +use LogicException; +use ReflectionClass; +use ReflectionNamedType; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -11,6 +17,7 @@ use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Stamp\TransportNamesStamp; +use TypeError; #[AsCommand(name: 'app:trigger-job', description: 'Triggers an arbitrary job by providing a class and its arguments')] final class TriggerJobCommand extends Command @@ -55,10 +62,46 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $badges = $input->getOption('sync') ? [new TransportNamesStamp(['sync'])] : []; - $message = new $class(...$args); + $message = $this->createInstance($class, $args); $this->messageBus->dispatch($message, $badges); $io->success('Successfully dispatched the job.'); return Command::SUCCESS; } + + /** + * @template T of object + * @param class-string $class + * @param array $args + * @return T + */ + private function createInstance(string $class, array $args): object + { + try { + return new $class(...$args); + } catch (TypeError) { + $reflection = new ReflectionClass($class); + $arguments = $reflection->getConstructor()?->getParameters() ?? throw new LogicException('Not constructor found'); + $namedParameters = !array_is_list($args); + $i = 0; + foreach ($arguments as $argument) { + $type = $argument->getType(); + if (!$type instanceof ReflectionNamedType) { + throw new LogicException('Can only handle single (or nullable) types for construction'); + } + $value = $namedParameters ? $args[$argument->getName()] : $args[$i]; + + if (is_a($type->getName(), DateTime::class, true)) { + $value = new DateTime($value); + } else if (is_a($type->getName(), DateTimeInterface::class, true)) { + $value = new DateTimeImmutable($value); + } + + $namedParameters ? ($args[$argument->getName()] = $value) : ($args[$i] = $value); + ++$i; + } + + return new $class(...$args); + } + } } diff --git a/src/Message/ReanalyzePostsMessage.php b/src/Message/ReanalyzePostsMessage.php new file mode 100644 index 0000000..e2c8f8f --- /dev/null +++ b/src/Message/ReanalyzePostsMessage.php @@ -0,0 +1,13 @@ +getPosts($message->since) as $post) { + $this->messageBus->dispatch(new AnalyzePostMessage($post->post->id), [ + new DispatchAfterCurrentBusStamp(), + ]); + } + } + + /** + * @return iterable + */ + private function getPosts(DateTimeInterface $until): iterable + { + $page = 1; + do { + $posts = $this->api->post()->getPosts(page: $page, sort: SortType::New, listingType: ListingType::All); + foreach ($posts as $post) { + yield $post; + } + } while (isset($post) && $post->post->published > $until); + } +}