Completed
Pull Request — master (#239)
by Luc
04:49
created

OfferLabelProjector::getLabelName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
namespace CultuurNet\UDB3\Label\ReadModels\JSON;
4
5
use Broadway\Domain\DomainMessage;
6
use Broadway\EventHandling\EventListenerInterface;
7
use CultuurNet\UDB3\Event\ReadModel\DocumentGoneException;
8
use CultuurNet\UDB3\Event\ReadModel\DocumentRepositoryInterface;
9
use CultuurNet\UDB3\Label\Events\MadeInvisible;
10
use CultuurNet\UDB3\Label\Events\MadeVisible;
11
use CultuurNet\UDB3\Label\ReadModels\Relations\Repository\ReadRepositoryInterface;
12
use Psr\Log\LoggerAwareInterface;
13
use Psr\Log\LoggerAwareTrait;
14
use Psr\Log\NullLogger;
15
use ValueObjects\Identity\UUID;
16
use ValueObjects\String\String as StringLiteral;
17
18
class OfferLabelProjector implements EventListenerInterface, LoggerAwareInterface
19
{
20
    use LoggerAwareTrait;
21
22
    /**
23
     * @var ReadRepositoryInterface
24
     */
25
    private $relationRepository;
26
27
    /**
28
     * @var DocumentRepositoryInterface
29
     */
30
    private $offerRepository;
31
32
    /**
33
     * OfferLabelProjector constructor.
34
     * @param DocumentRepositoryInterface $offerRepository
35
     * @param ReadRepositoryInterface $relationRepository
36
     */
37
    public function __construct(
38
        DocumentRepositoryInterface $offerRepository,
39
        ReadRepositoryInterface $relationRepository
40
    ) {
41
        $this->offerRepository = $offerRepository;
42
        $this->relationRepository = $relationRepository;
43
        $this->logger = new NullLogger();
44
    }
45
46
    /**
47
     * @param DomainMessage $domainMessage
48
     */
49
    public function handle(DomainMessage $domainMessage)
50
    {
51
        $event = $domainMessage->getPayload();
52
53
        if ($event instanceof MadeVisible) {
54
            $this->applyMadeVisible($domainMessage->getPayload());
55
        } else if ($event instanceof MadeInvisible) {
56
            $this->applyMadeInvisible($domainMessage->getPayload());
57
        }
58
    }
59
60
    /**
61
     * @param MadeVisible $madeVisible
62
     */
63
    public function applyMadeVisible(MadeVisible $madeVisible)
64
    {
65
        $this->updateLabels($madeVisible->getUuid(), $madeVisible->getName(), true);
66
    }
67
68
    /**
69
     * @param MadeInvisible $madeInvisible
70
     */
71
    public function applyMadeInvisible(MadeInvisible $madeInvisible)
72
    {
73
        $this->updateLabels($madeInvisible->getUuid(), $madeInvisible->getName(), false);
74
    }
75
76
    /**
77
     * @param UUID $uuid
78
     * @param StringLiteral $labelName
79
     * @param bool $madeVisible
80
     */
81
    private function updateLabels(
82
        UUID $uuid,
83
        StringLiteral $labelName,
84
        $madeVisible
85
    ) {
86
        $offers = $this->getRelatedOffers($uuid);
87
88
        $removeFrom = $madeVisible ? 'hiddenLabels' : 'labels';
89
        $addTo = $madeVisible ? 'labels' : 'hiddenLabels';
90
91
        foreach ($offers as $offer) {
92
            $offerLd = $offer->getBody();
93
94
            $addToArray = isset($offerLd->{$addTo}) ? (array) $offerLd->{$addTo} : [];
95
96
            $addToArray[] = $labelName->toNative();
97
            $offerLd->{$addTo} = array_unique($addToArray);
98
99
            if (isset($offerLd->{$removeFrom})) {
100
                $offerLd->{$removeFrom} = array_diff((array) $offerLd->{$removeFrom}, [$labelName]);
101
102
                if (count($offerLd->{$removeFrom}) === 0) {
103
                    unset($offerLd->{$removeFrom});
104
                }
105
            }
106
107
            $this->offerRepository->save($offer->withBody($offerLd));
108
        }
109
    }
110
111
    /**
112
     * @param UUID $uuid
113
     * @return \CultuurNet\UDB3\ReadModel\JsonDocument[]|\Generator
114
     */
115
    private function getRelatedOffers(UUID $uuid)
116
    {
117
        $labelRelations = $this->relationRepository->getLabelRelations($uuid);
118
119
        foreach ($labelRelations as $labelRelation) {
120
            try {
121
                $offer = $this->offerRepository->get((string) $labelRelation->getRelationId());
122
123
                if ($offer) {
124
                    yield $offer;
125
                }
126
            } catch (DocumentGoneException $exception) {
127
                $this->logger->alert(
128
                    'Can not update visibility of label: "'. $labelRelation->getUuid() . '"'
129
                    . ' for the relation with id: "' . $labelRelation->getRelationId() . '"'
130
                    . ' because the document could not be retrieved.'
131
                );
132
            }
133
        }
134
    }
135
}
136