Completed
Push — master ( 9f7c3f...7b233a )
by
unknown
28s queued 13s
created

LocationMarkedAsDuplicateProcessManager::handle()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 50
rs 8.7797
c 0
b 0
f 0
cc 5
nc 7
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace CultuurNet\UDB3\Event;
6
7
use Broadway\CommandHandling\CommandBusInterface;
8
use Broadway\Domain\DomainMessage;
9
use Broadway\EventHandling\EventListenerInterface;
10
use CultuurNet\UDB3\Event\Commands\UpdateLocation;
11
use CultuurNet\UDB3\Event\ValueObjects\LocationId;
12
use CultuurNet\UDB3\Offer\IriOfferIdentifier;
13
use CultuurNet\UDB3\Offer\OfferType;
14
use CultuurNet\UDB3\Place\Events\MarkedAsDuplicate;
15
use CultuurNet\UDB3\Search\ResultsGeneratorInterface;
16
use Psr\Log\LoggerAwareInterface;
17
use Psr\Log\LoggerInterface;
18
use Psr\Log\NullLogger;
19
20
final class LocationMarkedAsDuplicateProcessManager implements EventListenerInterface, LoggerAwareInterface
21
{
22
    /**
23
     * @var LoggerInterface
24
     */
25
    private $logger;
26
27
    /**
28
     * @var ResultsGeneratorInterface
29
     */
30
    private $searchResultsGenerator;
31
32
    /**
33
     * @var CommandBusInterface
34
     */
35
    private $commandBus;
36
37
    public function __construct(
38
        ResultsGeneratorInterface $searchResultsGenerator,
39
        CommandBusInterface $commandBus
40
    ) {
41
        $this->searchResultsGenerator = $searchResultsGenerator;
42
        $this->commandBus = $commandBus;
43
        $this->logger = new NullLogger();
44
    }
45
46
    public function setLogger(LoggerInterface $logger): void
47
    {
48
        $this->logger = $logger;
49
50
        if ($this->searchResultsGenerator instanceof LoggerAwareInterface) {
51
            $this->searchResultsGenerator->setLogger($logger);
52
        }
53
    }
54
55
    public function handle(DomainMessage $domainMessage): void
56
    {
57
        $domainEvent = $domainMessage->getPayload();
58
59
        // Only handle (Place)MarkedAsDuplicate events.
60
        if (!($domainEvent instanceof MarkedAsDuplicate)) {
61
            return;
62
        }
63
64
        $duplicatePlaceId = $domainEvent->getPlaceId();
65
        $canonicalPlaceId = $domainEvent->getDuplicateOf();
66
67
        $query = "location.mainId:{$duplicatePlaceId}";
68
        $results = $this->searchResultsGenerator->search($query);
69
70
        $commands = [];
71
        $skipped = [];
72
73
        /* @var IriOfferIdentifier $result */
74
        foreach ($results as $result) {
75
            if (!$result->getType()->sameValueAs(OfferType::EVENT())) {
76
                $skipped[] = $result->getId();
77
                $this->logger->warning(
78
                    'Skipped result with id ' . $result->getId() . ' because it\'s not an event according to the @id parser.'
79
                );
80
                continue;
81
            }
82
83
            // Keep all updates in-memory and dispatch them only after looping through all search results, as the
84
            // pagination of results gets influenced by updating events in the loop.
85
            $commands[] = new UpdateLocation($result->getId(), new LocationId($canonicalPlaceId));
86
        }
87
88
        foreach ($commands as $command) {
89
            $this->commandBus->dispatch($command);
90
91
            $this->logger->info(
92
                'Dispatched UpdateLocation for result with id ' . $command->getItemId()
93
            );
94
        }
95
96
        $updated = count($commands);
97
        $total = $updated + count($skipped);
98
99
        $this->logger->info('Received ' . $total . ' results from the search api.');
100
        $this->logger->info('Updated ' . $updated . ' events to the canonical location.');
101
        $this->logger->info(
102
            'Skipped ' . count($skipped) . ' events:' . PHP_EOL . implode(PHP_EOL, $skipped)
103
        );
104
    }
105
}
106