ParentSubscriber   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 9
Bugs 3 Features 1
Metric Value
c 9
b 3
f 1
dl 0
loc 145
wmc 14
lcom 1
cbo 7
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A getSubscribedEvents() 0 11 1
A handleMove() 0 6 1
A handleSetParentNodeFromDocument() 0 21 4
A handleHydrate() 0 21 3
A handleChangeParent() 0 13 2
A mapParent() 0 12 2
1
<?php
2
3
/*
4
 * This file is part of Sulu.
5
 *
6
 * (c) MASSIVE ART WebServices GmbH
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Sulu\Component\DocumentManager\Subscriber\Behavior\Mapping;
13
14
use PHPCR\NodeInterface;
15
use Sulu\Component\DocumentManager\Behavior\Mapping\ParentBehavior;
16
use Sulu\Component\DocumentManager\DocumentInspector;
17
use Sulu\Component\DocumentManager\DocumentManagerInterface;
18
use Sulu\Component\DocumentManager\Event\HydrateEvent;
19
use Sulu\Component\DocumentManager\Event\MoveEvent;
20
use Sulu\Component\DocumentManager\Event\PersistEvent;
21
use Sulu\Component\DocumentManager\Events;
22
use Sulu\Component\DocumentManager\ProxyFactory;
23
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
24
25
/**
26
 * Set the parent and children on the document.
27
 */
28
class ParentSubscriber implements EventSubscriberInterface
29
{
30
    /**
31
     * @var ProxyFactory
32
     */
33
    private $proxyFactory;
34
35
    /**
36
     * @var DocumentInspector
37
     */
38
    private $inspector;
39
40
    /**
41
     * @var DocumentManagerInterface
42
     */
43
    private $documentManager;
44
45
    /**
46
     * @param ProxyFactory $proxyFactory
47
     * @param DocumentInspector $inspector
48
     * @param DocumentManagerInterface $documentManager
49
     */
50
    public function __construct(
51
        ProxyFactory $proxyFactory,
52
        DocumentInspector $inspector,
53
        DocumentManagerInterface $documentManager
54
55
    ) {
56
        $this->proxyFactory = $proxyFactory;
57
        $this->inspector = $inspector;
58
        $this->documentManager = $documentManager;
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public static function getSubscribedEvents()
65
    {
66
        return [
67
            Events::HYDRATE => 'handleHydrate',
68
            Events::PERSIST => [
69
                ['handleChangeParent', 0],
70
                ['handleSetParentNodeFromDocument', 490],
71
            ],
72
            Events::MOVE => 'handleMove',
73
        ];
74
    }
75
76
    /**
77
     * @param MoveEvent $event
78
     */
79
    public function handleMove(MoveEvent $event)
80
    {
81
        $document = $event->getDocument();
82
        $node = $this->inspector->getNode($event->getDocument());
83
        $this->mapParent($document, $node);
84
    }
85
86
    /**
87
     * @param PersistEvent $event
88
     */
89
    public function handleSetParentNodeFromDocument(PersistEvent $event)
90
    {
91
        $document = $event->getDocument();
92
93
        if (!$document instanceof ParentBehavior) {
94
            return;
95
        }
96
97
        if ($event->hasParentNode()) {
98
            return;
99
        }
100
101
        $parentDocument = $document->getParent();
102
103
        if (!$parentDocument) {
104
            return;
105
        }
106
107
        $parentNode = $this->inspector->getNode($parentDocument);
108
        $event->setParentNode($parentNode);
109
    }
110
111
    /**
112
     * @param HydrateEvent $event
113
     */
114
    public function handleHydrate(HydrateEvent $event)
115
    {
116
        $document = $event->getDocument();
117
118
        if (!$document instanceof ParentBehavior) {
119
            return;
120
        }
121
122
        $node = $event->getNode();
123
124
        if ($node->getDepth() == 0) {
125
            throw new \RuntimeException(sprintf(
126
                'Cannot apply parent behavior to root node "%s" with type "%s" for document of class "%s"',
127
                $node->getPath(),
128
                $node->getPrimaryNodeType()->getName(),
129
                get_class($document)
130
            ));
131
        }
132
133
        $this->mapParent($document, $node, $event->getOptions());
0 ignored issues
show
Documentation introduced by
$event->getOptions() is of type object<Symfony\Component...solver\OptionsResolver>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
134
    }
135
136
    /**
137
     * @param PersistEvent $event
138
     */
139
    public function handleChangeParent(PersistEvent $event)
140
    {
141
        $document = $event->getDocument();
142
143
        $node = $this->inspector->getNode($document);
144
        $parentNode = $event->getParentNode();
145
146
        if ($parentNode->getPath() === $node->getParent()->getPath()) {
147
            return;
148
        }
149
150
        $this->documentManager->move($document, $parentNode->getPath());
151
    }
152
153
    /**
154
     * Map parent document to given document.
155
     *
156
     * @param object $document child-document
157
     * @param NodeInterface $node to determine parent
158
     * @param array $options options to load parent
159
     */
160
    private function mapParent($document, NodeInterface $node, $options = [])
161
    {
162
        // TODO: performance warning: We are eagerly fetching the parent node
163
        $targetNode = $node->getParent();
164
165
        // Do not map non-referenceable parent nodes
166
        if (!$targetNode->hasProperty('jcr:uuid')) {
167
            return;
168
        }
169
170
        $document->setParent($this->proxyFactory->createProxyForNode($document, $targetNode, $options));
171
    }
172
}
173