ChatlasEventHandler   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 52
c 1
b 0
f 0
dl 0
loc 112
rs 10
wmc 21

4 Methods

Rating   Name   Duplication   Size   Complexity  
B afterSaveAssociated() 0 31 8
A afterDelete() 0 8 3
A implementedEvents() 0 6 1
B afterSave() 0 27 9
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * Chatlas BEdita plugin
6
 *
7
 * Copyright 2023 Atlas Srl
8
 */
9
namespace BEdita\Chatlas\Event;
10
11
use ArrayObject;
12
use BEdita\Chatlas\Index\CollectionHandler;
13
use BEdita\Core\Model\Entity\ObjectEntity;
14
use BEdita\Core\ORM\Association\RelatedTo;
15
use Cake\Datasource\EntityInterface;
16
use Cake\Event\Event;
17
use Cake\Event\EventInterface;
18
use Cake\Event\EventListenerInterface;
19
use Cake\ORM\Locator\LocatorAwareTrait;
20
use Cake\Utility\Hash;
21
22
/**
23
 * Event listener for chatlas collection related events.
24
 */
25
class ChatlasEventHandler implements EventListenerInterface
26
{
27
    use LocatorAwareTrait;
28
29
    /**
30
     * @inheritDoc
31
     */
32
    public function implementedEvents(): array
33
    {
34
        return [
35
            'Model.afterDelete' => 'afterDelete',
36
            'Model.afterSave' => 'afterSave',
37
            'Associated.afterSave' => 'afterSaveAssociated',
38
        ];
39
    }
40
41
    /**
42
     * After save listener:
43
     *  * create or update collections
44
     *  * add, update or remove documents from collections
45
     *
46
     * @param \Cake\Event\EventInterface $event The dispatched event.
47
     * @param \Cake\Datasource\EntityInterface $entity The Entity saved.
48
     * @param \ArrayObject $options The options
49
     * @return void
50
     */
51
    public function afterSave(EventInterface $event, EntityInterface $entity, ArrayObject $options): void
52
    {
53
        $type = (string)$entity->get('type');
54
        if (empty($type) || !$entity instanceof ObjectEntity || !empty($options['_skipAfterSave'])) {
55
            return;
56
        }
57
        $handler = new CollectionHandler();
58
        if ($type === 'collections') {
59
            if ($entity->isNew()) {
60
                $handler->createCollection($entity);
61
62
                return;
63
            }
64
65
            $handler->updateCollection($entity);
66
        }
67
        // Look if there is a `DocumentOf` relation
68
        if (!$entity->getTable()->hasAssociation('DocumentOf')) {
69
            return;
70
        }
71
        $entity->getTable()->loadInto($entity, ['DocumentOf']);
72
        $collections = $entity->get('document_of');
73
        if (empty($collections)) {
74
            return;
75
        }
76
        foreach ($collections as $collection) {
77
            $handler->updateDocument($collection, $entity);
78
        }
79
    }
80
81
    /**
82
     * Handle 'Associated.afterSave'
83
     *
84
     * @param \Cake\Event\Event $event Dispatched event.
85
     * @return void
86
     */
87
    public function afterSaveAssociated(Event $event): void
88
    {
89
        $data = $event->getData();
90
        $association = Hash::get($data, 'association');
91
        if (empty($association) || !$association instanceof RelatedTo) {
92
            return;
93
        }
94
        $name = $association->getName();
95
        if (!in_array($name, ['DocumentOf', 'HasDocuments'])) {
96
            return;
97
        }
98
        $entity = Hash::get($data, 'entity');
99
        if (!$entity instanceof ObjectEntity) {
100
            return;
101
        }
102
        $handler = new CollectionHandler();
103
        $action = Hash::get($data, 'action');
104
        $related = (array)Hash::get($data, 'relatedEntities');
105
        foreach ($related as $item) {
106
            if ($name === 'DocumentOf') {
107
                $collection = $item;
108
                $document = $entity;
109
            } else {
110
                $collection = $entity;
111
                $document = $item;
112
            }
113
114
            if ($action === 'remove') {
115
                $handler->removeDocument($collection, $document);
116
            } else {
117
                $handler->updateDocument($collection, $document, true);
118
            }
119
        }
120
    }
121
122
    /**
123
     * After delete listener: remove collections
124
     *
125
     * @param \Cake\Event\EventInterface $event The dispatched event.
126
     * @param \Cake\Datasource\EntityInterface $entity The Entity saved.
127
     * @return void
128
     */
129
    public function afterDelete(EventInterface $event, EntityInterface $entity): void
130
    {
131
        $type = (string)$entity->get('type');
132
        if (!$entity instanceof ObjectEntity || $type !== 'collections') {
133
            return;
134
        }
135
        $handler = new CollectionHandler();
136
        $handler->removeCollection($entity);
137
    }
138
}
139