Completed
Pull Request — develop (#111)
by Wachter
12:56
created

RoutableSubscriber::handleRemove()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.009

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 9
cts 10
cp 0.9
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 9
nc 3
nop 1
crap 3.009
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\Bundle\ArticleBundle\Document\Subscriber;
13
14
use Doctrine\ORM\EntityManagerInterface;
15
use Sulu\Bundle\ArticleBundle\Document\Behavior\RoutableBehavior;
16
use Sulu\Bundle\RouteBundle\Entity\RouteRepositoryInterface;
17
use Sulu\Bundle\RouteBundle\Manager\RouteManagerInterface;
18
use Sulu\Component\DocumentManager\Event\AbstractMappingEvent;
19
use Sulu\Component\DocumentManager\Event\ConfigureOptionsEvent;
20
use Sulu\Component\DocumentManager\Event\MetadataLoadEvent;
21
use Sulu\Component\DocumentManager\Event\RemoveEvent;
22
use Sulu\Component\DocumentManager\Events;
23
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
24
25
/**
26
 * Handles document-manager events to create/update/remove routes.
27
 */
28
class RoutableSubscriber implements EventSubscriberInterface
29
{
30
    /**
31
     * @var RouteManagerInterface
32
     */
33
    private $routeManager;
34
35
    /**
36
     * @var RouteRepositoryInterface
37
     */
38
    private $routeRepository;
39
40
    /**
41
     * @var EntityManagerInterface
42
     */
43
    private $entityManager;
44
45
    /**
46
     * @param RouteManagerInterface $routeManager
47
     * @param RouteRepositoryInterface $routeRepository
48
     * @param EntityManagerInterface $entityManager
49
     */
50 35
    public function __construct(RouteManagerInterface $routeManager, RouteRepositoryInterface $routeRepository, EntityManagerInterface $entityManager)
51
    {
52 35
        $this->routeManager = $routeManager;
53 35
        $this->routeRepository = $routeRepository;
54 35
        $this->entityManager = $entityManager;
55 35
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60 31
    public static function getSubscribedEvents()
61
    {
62
        return [
63 31
            Events::HYDRATE => [['handleHydrate', -500]],
64 31
            Events::PERSIST => [['handleRouteUpdate', 1], ['handleRoute', 0]],
65 31
            Events::REMOVE => [['handleRemove', -500]],
66 31
            Events::METADATA_LOAD => 'handleMetadataLoad',
67 31
            Events::CONFIGURE_OPTIONS => 'configureOptions',
68
        ];
69
    }
70
71
    /**
72
     * Load route.
73
     *
74
     * @param AbstractMappingEvent $event
75
     */
76 31
    public function handleHydrate(AbstractMappingEvent $event)
77
    {
78 31
        $document = $event->getDocument();
79 31
        if (!$document instanceof RoutableBehavior || null === $document->getRoutePath()) {
80 29
            return;
81
        }
82
83 31
        $route = $this->routeRepository->findByPath($document->getRoutePath(), $document->getOriginalLocale());
84 31
        if (!$route) {
85 30
            return;
86
        }
87
88 31
        $document->setRoute($route);
89 31
    }
90
91
    /**
92
     * Generate route.
93
     *
94
     * @param AbstractMappingEvent $event
95
     */
96 32
    public function handleRoute(AbstractMappingEvent $event)
97
    {
98 32
        $document = $event->getDocument();
99 32
        if (!$document instanceof RoutableBehavior || null !== $document->getRoutePath()) {
100 9
            return;
101
        }
102
103 32
        $document->setUuid($event->getNode()->getIdentifier());
104
105 32
        $route = $this->routeManager->create($document, $event->getOption('route_path'));
106 32
        $this->entityManager->persist($route);
107 32
        $this->entityManager->flush();
108 32
    }
109
110
    /**
111
     * Update route if route-path was changed.
112
     *
113
     * @param AbstractMappingEvent $event
114
     */
115 31
    public function handleRouteUpdate(AbstractMappingEvent $event)
116
    {
117 31
        $document = $event->getDocument();
118 31
        if (!$document instanceof RoutableBehavior
119 31
            || null === $document->getRoute()
120 31
            || null === ($routePath = $event->getOption('route_path'))
121
        ) {
122 30
            return;
123
        }
124
125 1
        $route = $this->routeManager->update($document, $routePath);
126 1
        $document->setRoutePath($route->getPath());
127 1
        $this->entityManager->persist($route);
0 ignored issues
show
Bug introduced by
It seems like $route defined by $this->routeManager->upd...($document, $routePath) on line 125 can be null; however, Doctrine\Common\Persiste...bjectManager::persist() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
128 1
        $this->entityManager->flush();
129 1
    }
130
131
    /**
132
     * Removes route.
133
     *
134
     * @param RemoveEvent $event
135
     */
136 3
    public function handleRemove(RemoveEvent $event)
137
    {
138 3
        $document = $event->getDocument();
139 3
        if (!$document instanceof RoutableBehavior) {
140
            return;
141
        }
142
143 3
        $route = $this->routeRepository->findByPath($document->getRoutePath(), $document->getOriginalLocale());
144 3
        if (!$route) {
145 2
            return;
146
        }
147
148 1
        $this->entityManager->remove($route);
149 1
        $this->entityManager->flush();
150 1
    }
151
152
    /**
153
     * Add route to metadata.
154
     *
155
     * @param MetadataLoadEvent $event
156
     */
157 30
    public function handleMetadataLoad(MetadataLoadEvent $event)
158
    {
159 30
        if (!$event->getMetadata()->getReflectionClass()->implementsInterface(RoutableBehavior::class)) {
160 1
            return;
161
        }
162
163 30
        $metadata = $event->getMetadata();
164 30
        $metadata->addFieldMapping(
165 30
            'routePath',
166
            [
167 30
                'encoding' => 'system_localized',
168
                'property' => 'routePath',
169
            ]
170
        );
171 30
    }
172
173
    /**
174
     * Add route-path to options.
175
     *
176
     * @param ConfigureOptionsEvent $event
177
     */
178 30
    public function configureOptions(ConfigureOptionsEvent $event)
179
    {
180 30
        $options = $event->getOptions();
181 30
        $options->setDefaults(['route_path' => null]);
182 30
    }
183
}
184