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