Completed
Push — master ( b5d2f5...98f37a )
by Paweł
14s
created

RouteService::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
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 30
35
    /**
36 30
     * @var RouteRepositoryInterface
37 30
     */
38
    private $routeRepository;
39
40
    public function __construct(EventDispatcherInterface $eventDispatcher, RouteRepositoryInterface $routeRepository)
41
    {
42 20
        $this->eventDispatcher = $eventDispatcher;
43
        $this->routeRepository = $routeRepository;
44 20
    }
45
46 20
    public function createRoute(RouteInterface $route)
47
    {
48 20
        $this->dispatchRouteEvent(RouteEvents::PRE_CREATE, $route);
49
50 20
        $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 20
68
        $this->dispatchRouteEvent(RouteEvents::POST_UPDATE, $route);
69 20
70 20
        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 30
        }
78
79 30
        switch ($route->getType()) {
80 30
            case RouteInterface::TYPE_CONTENT:
81 14
                $route->setVariablePattern(null);
82 14
                $route->setStaticPrefix($this->generatePath($route));
83 14
                $route->setRequirements([]);
84
85 14
                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 30
            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 30
    {
106
        if ($this->routeRepository instanceof NestedTreeEntityRepository) {
107 30
            if (null !== $position) {
108 30
                if (null !== $route->getParent()) {
109
                    $this->routeRepository->persistAsLastChildOf($route, $route->getParent());
110
                } else {
111
                    $this->routeRepository->persistAsLastChild($route);
112
                }
113
            }
114
115
            if ($previousRoute->getPosition() === $route->getPosition() && null !== $position) {
116
                $route->setPosition($position);
117
            } else {
118
                if ($route->getPosition() > 0) {
119
                    $previousChild = $this->routeRepository->findOneBy(
120
                            ['position' => $route->getPosition() - 1, 'parent' => $route->getParent()]
121
                        );
122
                    $this->routeRepository->persistAsNextSiblingOf($route, $previousChild);
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
    /**
135
     * @param RouteInterface $route
136
     *
137
     * @return string
138
     */
139
    protected function generatePath(RouteInterface $route)
140
    {
141
        $slug = $route->getSlug();
142
143
        if (null === $parent = $route->getParent()) {
144
            return '/'.$slug;
145
        }
146
147
        return sprintf('%s/%s', $parent->getStaticPrefix(), $slug);
148
    }
149
150
    /**
151
     * @param string         $eventName
152
     * @param RouteInterface $route
153
     */
154
    private function dispatchRouteEvent($eventName, RouteInterface $route)
155
    {
156
        $this->eventDispatcher->dispatch($eventName, new RouteEvent($route, $eventName));
157
    }
158
}
159