Completed
Push — master ( 98f37a...19732d )
by Paweł
07:58
created

RouteService::persistAsLastChild()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
ccs 0
cts 0
cp 0
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
/*
4
 * This file is part of the Superdesk Web Publisher Content Bundle.
5
 *
6
 * Copyright 2016 Sourcefabric z.ú. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2016 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Bundle\ContentBundle\Service;
16
17
use Behat\Transliterator\Transliterator;
18
use SWP\Bundle\ContentBundle\Event\RouteEvent;
19
use SWP\Bundle\ContentBundle\Model\RouteInterface;
20
use SWP\Bundle\ContentBundle\Model\RouteRepositoryInterface;
21
use SWP\Bundle\ContentBundle\RouteEvents;
22
use SWP\Bundle\StorageBundle\Doctrine\ORM\NestedTreeEntityRepository;
23
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
24
25
/**
26
 * Class RouteService.
27
 */
28
class RouteService implements RouteServiceInterface
29
{
30
    /**
31
     * @var EventDispatcherInterface
32
     */
33
    private $eventDispatcher;
34 29
35
    /**
36 29
     * @var RouteRepositoryInterface
37 29
     */
38
    private $routeRepository;
39
40
    public function __construct(EventDispatcherInterface $eventDispatcher, RouteRepositoryInterface $routeRepository)
41
    {
42 19
        $this->eventDispatcher = $eventDispatcher;
43
        $this->routeRepository = $routeRepository;
44 19
    }
45
46 19
    public function createRoute(RouteInterface $route)
47
    {
48 19
        $this->dispatchRouteEvent(RouteEvents::PRE_CREATE, $route);
49
50 19
        $route = $this->fillRoute($route);
51
52
        $this->dispatchRouteEvent(RouteEvents::POST_CREATE, $route);
53
54
        return $route;
55
    }
56
57
    public function updateRoute(RouteInterface $previousRoute, RouteInterface $route): RouteInterface
58
    {
59
        $this->dispatchRouteEvent(RouteEvents::PRE_UPDATE, $route);
60
61
        $route = $this->fillRoute($route);
62
        if ($previousRoute->getParent() !== $route->getParent()) {
63
            $this->changePositionInTree($previousRoute, $route, -1);
64
        } else {
65
            $this->changePositionInTree($previousRoute, $route);
66
        }
67 19
68
        $this->dispatchRouteEvent(RouteEvents::POST_UPDATE, $route);
69 19
70 19
        return $route;
71
    }
72
73
    public function fillRoute(RouteInterface $route): RouteInterface
74
    {
75
        if (null === $route->getSlug()) {
76
            $route->setSlug(Transliterator::urlize($route->getName()));
77 29
        }
78
79 29
        switch ($route->getType()) {
80 29
            case RouteInterface::TYPE_CONTENT:
81 13
                $route->setVariablePattern(null);
82 13
                $route->setStaticPrefix($this->generatePath($route));
83 13
                $route->setRequirements([]);
84
85 13
                break;
86 26
            case RouteInterface::TYPE_COLLECTION:
87 26
                $route->setVariablePattern('/{slug}');
88 26
                $route->setStaticPrefix($this->generatePath($route));
89 26
                $route->setRequirement('slug', '[a-zA-Z0-9*\-_]+');
90 26
                $route->setDefault('slug', null);
91
92 26
                break;
93
            case RouteInterface::TYPE_CUSTOM:
94
                $route->setStaticPrefix($this->generatePath($route));
95
96
                break;
97 29
            default:
98
                throw new \InvalidArgumentException(sprintf('Route type "%s" is unsupported!', $route->getType()));
99
        }
100
101
        return $route;
102
    }
103
104
    protected function changePositionInTree(RouteInterface $previousRoute, RouteInterface $route, int $position = null): void
105 29
    {
106
        if ($this->routeRepository instanceof NestedTreeEntityRepository) {
107 29
            if (null !== $position) {
108 29
                $this->persistAsLastChild($route);
109
            }
110
111
            if ($previousRoute->getPosition() === $route->getPosition() && null !== $position) {
112
                $route->setPosition($position);
113
            } else {
114
                if ($route->getPosition() > 0) {
115
                    $previousChild = $this->routeRepository->findOneBy(
116
                        ['position' => $route->getPosition() - 1, 'parent' => $route->getParent()]
117
                    );
118
                    if (null !== $previousChild) {
119
                        $this->routeRepository->persistAsNextSiblingOf($route, $previousChild);
120
                    } else {
121
                        $this->persistAsLastChild($route);
122
                    }
123
                } else {
124
                    if (null !== $route->getParent()) {
125
                        $this->routeRepository->persistAsFirstChildOf($route, $route->getParent());
126
                    } else {
127
                        $this->routeRepository->persistAsFirstChild($route);
128
                    }
129
                }
130
            }
131
        }
132
    }
133
134
    private function persistAsLastChild(RouteInterface $route): void
135
    {
136
        if (null !== $route->getParent()) {
137
            $this->routeRepository->persistAsLastChildOf($route, $route->getParent());
0 ignored issues
show
Bug introduced by
The method persistAsLastChildOf() does not exist on SWP\Bundle\ContentBundle...outeRepositoryInterface. Did you maybe mean persist()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
138
        } else {
139
            $this->routeRepository->persistAsLastChild($route);
0 ignored issues
show
Bug introduced by
The method persistAsLastChild() does not exist on SWP\Bundle\ContentBundle...outeRepositoryInterface. Did you maybe mean persist()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
140
        }
141
    }
142
143
    /**
144
     * @param RouteInterface $route
145
     *
146
     * @return string
147
     */
148
    protected function generatePath(RouteInterface $route)
149
    {
150
        $slug = $route->getSlug();
151
152
        if (null === $parent = $route->getParent()) {
153
            return '/'.$slug;
154
        }
155
156
        return sprintf('%s/%s', $parent->getStaticPrefix(), $slug);
157
    }
158
159
    /**
160
     * @param string         $eventName
161
     * @param RouteInterface $route
162
     */
163
    private function dispatchRouteEvent($eventName, RouteInterface $route)
164
    {
165
        $this->eventDispatcher->dispatch($eventName, new RouteEvent($route, $eventName));
166
    }
167
}
168