Completed
Push — develop ( 7df1b3...61c51f )
by Alexander
12:30
created

RoutableSubscriber::configureOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
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
    public function __construct(RouteManagerInterface $routeManager, RouteRepositoryInterface $routeRepository, EntityManagerInterface $entityManager)
51
    {
52
        $this->routeManager = $routeManager;
53
        $this->routeRepository = $routeRepository;
54
        $this->entityManager = $entityManager;
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60
    public static function getSubscribedEvents()
61
    {
62
        return [
63
            Events::HYDRATE => [['handleHydrate', -500]],
64
            Events::PERSIST => [['handleRouteUpdate', 1], ['handleRoute', 0]],
65
            Events::REMOVE => [['handleRemove', -500]],
66
            Events::METADATA_LOAD => 'handleMetadataLoad',
67
            Events::CONFIGURE_OPTIONS => 'configureOptions',
68
        ];
69
    }
70
71
    /**
72
     * Load route.
73
     *
74
     * @param AbstractMappingEvent $event
75
     */
76
    public function handleHydrate(AbstractMappingEvent $event)
77
    {
78
        $document = $event->getDocument();
79
        if (!$document instanceof RoutableBehavior || null === $document->getRoutePath()) {
80
            return;
81
        }
82
83
        $route = $this->routeRepository->findByPath($document->getRoutePath(), $document->getOriginalLocale());
84
        if (!$route) {
85
            return;
86
        }
87
88
        $document->setRoute($route);
89
    }
90
91
    /**
92
     * Generate route.
93
     *
94
     * @param AbstractMappingEvent $event
95
     */
96
    public function handleRoute(AbstractMappingEvent $event)
97
    {
98
        $document = $event->getDocument();
99
        if (!$document instanceof RoutableBehavior || null !== $document->getRoutePath()) {
100
            return;
101
        }
102
103
        $document->setUuid($event->getNode()->getIdentifier());
104
105
        $route = $this->routeManager->create($document, $event->getOption('route_path'));
106
        $this->entityManager->persist($route);
107
        $this->entityManager->flush();
108
    }
109
110
    /**
111
     * Update route if route-path was changed.
112
     *
113
     * @param AbstractMappingEvent $event
114
     */
115
    public function handleRouteUpdate(AbstractMappingEvent $event)
116
    {
117
        $document = $event->getDocument();
118
        if (!$document instanceof RoutableBehavior
119
            || null === $document->getRoute()
120
            || null === ($routePath = $event->getOption('route_path'))
121
        ) {
122
            return;
123
        }
124
125
        $route = $this->routeManager->update($document, $routePath);
126
        $document->setRoutePath($route->getPath());
127
        $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
        $this->entityManager->flush();
129
    }
130
131
    /**
132
     * Removes route.
133
     *
134
     * @param RemoveEvent $event
135
     */
136
    public function handleRemove(RemoveEvent $event)
137
    {
138
        $document = $event->getDocument();
139
        if (!$document instanceof RoutableBehavior) {
140
            return;
141
        }
142
143
        $route = $this->routeRepository->findByPath($document->getRoutePath(), $document->getOriginalLocale());
144
        if (!$route) {
145
            return;
146
        }
147
148
        $this->entityManager->remove($route);
149
        $this->entityManager->flush();
150
    }
151
152
    /**
153
     * Add route to metadata.
154
     *
155
     * @param MetadataLoadEvent $event
156
     */
157
    public function handleMetadataLoad(MetadataLoadEvent $event)
158
    {
159
        if (!$event->getMetadata()->getReflectionClass()->implementsInterface(RoutableBehavior::class)) {
160
            return;
161
        }
162
163
        $metadata = $event->getMetadata();
164
        $metadata->addFieldMapping(
165
            'routePath',
166
            [
167
                'encoding' => 'system_localized',
168
                'property' => 'routePath',
169
            ]
170
        );
171
    }
172
173
    /**
174
     * Add route-path to options.
175
     *
176
     * @param ConfigureOptionsEvent $event
177
     */
178
    public function configureOptions(ConfigureOptionsEvent $event)
179
    {
180
        $options = $event->getOptions();
181
        $options->setDefaults(['route_path' => null]);
182
    }
183
}
184