Route::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Components Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentsBundle\Entity\Core;
15
16
use ApiPlatform\Metadata\ApiResource;
17
use ApiPlatform\Metadata\Delete;
18
use ApiPlatform\Metadata\Get;
19
use ApiPlatform\Metadata\GetCollection;
20
use ApiPlatform\Metadata\Patch;
21
use ApiPlatform\Metadata\Post;
22
use ApiPlatform\Metadata\Put;
23
use Doctrine\Common\Collections\ArrayCollection;
24
use Doctrine\Common\Collections\Collection;
25
use Silverback\ApiComponentsBundle\Annotation as Silverback;
26
use Silverback\ApiComponentsBundle\DataProvider\StateProvider\RouteStateProvider;
27
use Silverback\ApiComponentsBundle\Entity\Utility\IdTrait;
28
use Silverback\ApiComponentsBundle\Entity\Utility\TimestampedTrait;
29
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
30
use Symfony\Component\Serializer\Annotation\Groups;
31
use Symfony\Component\Validator\Constraints as Assert;
32
33 1
const REQUIREMENTS = ['id' => '(.+)'];
34 1
const SECURITY = "is_granted('read_route', object)";
35
36
/**
37
 * Although a user will be able to get the routes and the tree of data down to getting the ID for a component
38
 * fetching a component will be restricted based on the route it is within.
39
 *
40
 * @author Daniel West <[email protected]>
41
 */
42
#[Assert\Expression(
43
    '!(this.getPage() == null & this.getPageData() == null & this.getRedirect() == null)',
44
    message: 'Please specify either page, pageData or redirect.',
45
    groups: ['Route:generate:write', 'Default']
46
)]
47
#[Assert\Expression(
48
    '!(this.getPage() != null & this.getPageData() != null)',
49
    message: 'Please specify either page or pageData, not both.',
50
    groups: ['Route:generate:write', 'Default']
51
)]
52
#[UniqueEntity('name', 'This route name is already in use.')]
53
#[UniqueEntity('path', 'This path is already in use.')]
54
#[ApiResource(
55
    mercure: true,
56
    provider: RouteStateProvider::class
57
)]
58
#[Post]
59
#[GetCollection]
60
#[Delete(requirements: REQUIREMENTS, security: SECURITY)]
61
#[Put(requirements: REQUIREMENTS, security: SECURITY)]
62
#[Patch(requirements: REQUIREMENTS, security: SECURITY)]
63
#[Get(requirements: ['id' => "(?!.+\/redirects$).+"], security: SECURITY)]
64
// Custom endpoints
65
#[Post(uriTemplate: '/routes/generate{._format}', validationContext: ['groups' => ['Route:generate:write']])]
66
#[Get(uriTemplate: '/routes/{id}/redirects{._format}', defaults: ['_api_item_operation_name' => 'route_redirects'], requirements: REQUIREMENTS, normalizationContext: ['groups' => ['Route:redirect:read']], security: SECURITY)]
67
#[Get(uriTemplate: '/routes_manifest/{id}{._format}', defaults: ['_api_item_operation_name' => 'route_resources'], requirements: REQUIREMENTS, normalizationContext: ['groups' => ['Route:manifest:read']], security: SECURITY)]
68
#[Silverback\Timestamped]
69
class Route
70
{
71
    use IdTrait;
72
    use TimestampedTrait;
73
74
    #[Assert\NotBlank]
75
    #[Groups(['Route:redirect:read'])]
76
    private string $path = '';
77
78
    #[Assert\NotNull]
79
    private string $name;
80
81
    private ?Route $redirect = null;
82
83
    #[Groups(['Route:redirect:read'])]
84
    private Collection $redirectedFrom;
85
86
    #[Groups(['Route:manifest:read'])]
87
    private ?Page $page = null;
88
89
    #[Groups(['Route:manifest:read'])]
90
    private ?AbstractPageData $pageData = null;
91
92
    public function __construct()
93
    {
94
        $this->redirectedFrom = new ArrayCollection();
95
    }
96
97
    public function getPath(): string
98
    {
99
        return $this->path;
100
    }
101
102
    public function setPath(string $path): self
103
    {
104
        $this->path = $path;
105
106
        return $this;
107
    }
108
109
    public function getName(): string
110
    {
111
        return $this->name;
112
    }
113
114
    public function setName(string $name): self
115
    {
116
        $this->name = $name;
117
118
        return $this;
119
    }
120
121
    public function getRedirect(): ?self
122
    {
123
        return $this->redirect;
124
    }
125
126
    public function setRedirect(?self $redirect): self
127
    {
128
        $this->redirect = $redirect;
129
        if ($redirect) {
130
            $redirect->addRedirectedFrom($this);
131
        }
132
133
        return $this;
134
    }
135
136
    /**
137
     * @return Collection|Route[]
138
     */
139
    public function getRedirectedFrom()
140
    {
141
        return $this->redirectedFrom;
142
    }
143
144
    /**
145
     * @param array|Collection $redirectedFrom
146
     */
147
    public function setRedirectedFrom($redirectedFrom): self
148
    {
149
        $isArray = \is_array($redirectedFrom);
150
        if (!$isArray && !$redirectedFrom instanceof Collection) {
0 ignored issues
show
introduced by
$redirectedFrom is always a sub-type of Doctrine\Common\Collections\Collection.
Loading history...
151
            throw new \InvalidArgumentException('setRedirectedFrom requires an array or Collection');
152
        }
153
        $this->redirectedFrom = $isArray ? new ArrayCollection($redirectedFrom) : $redirectedFrom;
0 ignored issues
show
Bug introduced by
It seems like $redirectedFrom can also be of type Doctrine\Common\Collections\Collection; however, parameter $elements of Doctrine\Common\Collecti...llection::__construct() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

153
        $this->redirectedFrom = $isArray ? new ArrayCollection(/** @scrutinizer ignore-type */ $redirectedFrom) : $redirectedFrom;
Loading history...
154
155
        return $this;
156
    }
157
158
    public function addRedirectedFrom(self $redirectedFrom): self
159
    {
160
        if (!$this->redirectedFrom->contains($redirectedFrom)) {
161
            $this->redirectedFrom->add($redirectedFrom);
162
        }
163
164
        return $this;
165
    }
166
167
    public function getPage(): ?Page
168
    {
169
        return $this->page;
170
    }
171
172
    public function setPage(?Page $page): self
173
    {
174
        $this->page = $page;
175
        if ($this->page) {
176
            $this->page->setRoute($this);
177
        }
178
179
        return $this;
180
    }
181
182
    public function getPageData(): ?AbstractPageData
183
    {
184
        return $this->pageData;
185
    }
186
187
    public function setPageData(?AbstractPageData $pageData): self
188
    {
189
        $this->pageData = $pageData;
190
        if ($this->pageData) {
191
            $this->pageData->setRoute($this);
192
        }
193
194
        return $this;
195
    }
196
}
197