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

ItemVisibilityProjector::updateLabels()   C

Complexity

Conditions 7
Paths 28

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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