Completed
Push — master ( 0be8e1...585ca2 )
by Daniel
59:26 queued 46:02
created

RouteFactory::createPageRoute()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 23
ccs 0
cts 0
cp 0
rs 9.2222
c 0
b 0
f 0
cc 6
nc 3
nop 2
crap 42
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Silverback\ApiComponentBundle\Factory;
6
7
use ApiPlatform\Core\Validator\ValidatorInterface;
8
use Cocur\Slugify\SlugifyInterface;
9
use Doctrine\Common\Collections\ArrayCollection;
10
use Doctrine\Common\Persistence\ObjectManager;
11
use Doctrine\ORM\EntityManagerInterface;
12
use Silverback\ApiComponentBundle\Entity\Content\AbstractContent;
13
use Silverback\ApiComponentBundle\Entity\Content\Page\Dynamic\DynamicContent;
14
use Silverback\ApiComponentBundle\Entity\Content\Page\StaticPage;
15
use Silverback\ApiComponentBundle\Entity\Route\ChildRouteInterface;
16
use Silverback\ApiComponentBundle\Entity\Route\Route;
17
use Silverback\ApiComponentBundle\Entity\Route\RouteAwareInterface;
18
use Silverback\ApiComponentBundle\Repository\Content\Page\DynamicPageRepository;
19
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
20
21
final class RouteFactory
22
{
23
    private $slugify;
24
    private $manager;
25
    private $validator;
26
    private $dynamicPageRepository;
27
28
    public function __construct(
29
        ObjectManager $manager,
30
        SlugifyInterface $slugify,
31
        ValidatorInterface $validator,
32
        DynamicPageRepository $dynamicPageRepository
33
    ) {
34
        $this->slugify = $slugify;
35
        $this->manager = $manager;
36
        $this->validator = $validator;
37
        $this->dynamicPageRepository = $dynamicPageRepository;
38
    }
39
40
    /**
41
     * @param RouteAwareInterface $entity
42
     * @param int|null $postfix
43
     * @return Route
44
     */
45
    public function createFromRouteAwareEntity(RouteAwareInterface $entity, int $postfix = 0): Route
46
    {
47
        $pageRoute = $this->slugify->slugify($entity->getDefaultRoute() ?: '');
48
        $prefixEntity = $entity;
49
        if ($entity instanceof DynamicContent && !$entity->getParentRoute()) {
0 ignored issues
show
Bug introduced by
Are you sure the usage of $entity->getParentRoute() targeting Silverback\ApiComponentB...ntent::getParentRoute() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
50
            $dynamicPage = $this->dynamicPageRepository->findOneBy([
51
                'dynamicPageClass' => \get_class($entity)
52
            ]);
53
            if ($dynamicPage) {
54
                $prefixEntity = $dynamicPage;
55
            }
56
        }
57
        $routePrefix = $this->getRoutePrefix($prefixEntity);
58
        $fullRoute = $routePrefix . $pageRoute;
59
        if ($postfix > 0) {
60
            $fullRoute .= '-' . $postfix;
61
        }
62
63
        $repository = $this->manager->getRepository(Route::class);
64
        $existing = $repository->findOneBy(['route' => $fullRoute]);
65
        if ($existing) {
66
            return $this->createFromRouteAwareEntity($entity, $postfix + 1);
67
        }
68
69
        $converter = new CamelCaseToSnakeCaseNameConverter();
70
        $generatedName = $converter->normalize(str_replace(' ', '', $entity->getDefaultRouteName()));
71
        $name = $generatedName;
72
        $counter = 0;
73
        while ($repository->findOneBy(['name' => $name])) {
74
            $counter++;
75
            $name = sprintf('%s-%s', $generatedName, $counter);
76
        }
77
78
        $route = new Route();
79
        $route->setName($name)->setRoute($fullRoute);
80
        if ($entity instanceof DynamicContent) {
81
            $route->setDynamicContent($entity);
82
        }
83
        if ($entity instanceof StaticPage) {
84
            $route->setStaticPage($entity);
85
        }
86
87
        $entity->addRoute($route);
88
        return $route;
89
    }
90
91
    public function createRedirectFromOldRoute(Route $oldRoute, Route $newRoute): Route
92
    {
93
        $oldRoute
94
            ->setName($oldRoute->getName() . '_redirect')
95
            ->setDynamicContent(null)
96
            ->setRedirect($newRoute)
97
        ;
98
        return $oldRoute;
99
    }
100
101
    /**
102
     * @param RouteAwareInterface $entity
103
     * @param EntityManagerInterface|null $entityManager
104
     * @return null|ArrayCollection|Route[]
105
     */
106
    public function createPageRoute(RouteAwareInterface $entity, ?EntityManagerInterface $entityManager = null): ?ArrayCollection
107
    {
108
        $em = $entityManager ?: $this->manager;
109
110
        $entityRoutes = $entity->getRoutes();
111
        if (($routeCount = $entityRoutes->count()) === 0 || $entity->getRegenerateRoute()) {
112
            $newRoutes = new ArrayCollection();
113
            $entity->setRegenerateRoute(false);
114
115
            $newRoute = $this->createFromRouteAwareEntity($entity);
116
            $this->validator->validate($newRoute);
117
            $em->persist($newRoute);
118
119
            if ($routeCount > 0 && ($defaultRoute = $entityRoutes->first())) {
120
                $this->createRedirectFromOldRoute($defaultRoute, $newRoute);
121
                $newRoutes->add($defaultRoute);
122
                $entity->removeRoute($defaultRoute);
123
            }
124
125
            $newRoutes->add($newRoute);
126
            return $newRoutes;
127
        }
128
        return null;
129
    }
130
131
    /**
132
     * @param ChildRouteInterface $entity
133
     * @return string
134
     */
135
    private function getRoutePrefix(ChildRouteInterface $entity): string
136
    {
137
        $parent = $entity->getParentRoute();
138
        if ($parent) {
139
            return $parent->getRoute() . '/';
140
        }
141
        return '/';
142
    }
143
}
144