UrlRewriteRepository::create()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
rs 9.456
c 0
b 0
f 0
cc 1
nc 1
nop 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace RuthgerIdema\UrlRewrite\Repositories;
6
7
use RuthgerIdema\UrlRewrite\Entities\UrlRewrite;
8
use RuthgerIdema\UrlRewrite\Exceptions\UrlRewriteAlreadyExistsException;
9
use RuthgerIdema\UrlRewrite\Exceptions\UrlRewriteRegenerationFailed;
10
use RuthgerIdema\UrlRewrite\Repositories\Interfaces\UrlRewriteInterface;
11
12
class UrlRewriteRepository implements UrlRewriteInterface
13
{
14
    /** @var array */
15
    public const allowedTypes = [0, 1, 2];
16
17
    /** @var UrlRewrite */
18
    protected $model;
19
20
    public function __construct(
21
       UrlRewrite $model
22
    ) {
23
        $this->model = $model;
24
    }
25
26
    public function getModel(): object
27
    {
28
        return $this->model;
29
    }
30
31
    public function setModel(object $model): object
32
    {
33
        $this->model = $model;
0 ignored issues
show
Documentation Bug introduced by
$model is of type object<RuthgerIdema\UrlR...te\Repositories\object>, but the property $model was declared to be of type object<RuthgerIdema\UrlR...te\Entities\UrlRewrite>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
34
35
        return $this;
36
    }
37
38
    public function find(int $id): ?object
39
    {
40
        return $this->model->find($id);
41
    }
42
43
    public function checkIfIdExists(int $id): bool
44
    {
45
        return $this->model->where('id', $id)->exists();
46
    }
47
48
    public function checkIfRequestPathExists(string $url): bool
49
    {
50
        return $this->model->where('request_path', $url)->exists();
51
    }
52
53
    public function getByRequestPath(string $url): ?object
54
    {
55
        return $this->model->where('request_path', $url)->first();
56
    }
57
58
    public function getByTypeAndAttributes(string $type, array $attributes): ?object
59
    {
60
        return $this->model->getByTypeAndAttributes($type, $attributes)->first();
61
    }
62
63
    public function getByTargetPath($url): ?object
64
    {
65
        return $this->model->where('target_path', $url)->first();
66
    }
67
68
    public function all(): ?object
69
    {
70
        return $this->model->all();
71
    }
72
73
    public function delete(int $id): bool
74
    {
75
        return $this->find($id)->delete();
76
    }
77
78
    public function regenerateAll(): void
79
    {
80
        if (empty($this->getTypes())) {
81
            throw UrlRewriteRegenerationFailed::noConfiguration();
82
        }
83
84
        foreach ($this->getTypes() as $type) {
85
            $this->regenerateRoutesFromType($type);
86
        }
87
    }
88
89
    public function regenerateRoutesFromType(string $type): void
90
    {
91
        if (! array_key_exists($type, $this->getTypes())) {
92
            throw UrlRewriteRegenerationFailed::invalidType($type);
93
        }
94
95
        $rewrites = $this->model->where('type', $type)->get();
96
97
        foreach ($rewrites as $rewrite) {
98
            $this->regenerateRoute($rewrite);
99
        }
100
    }
101
102
    public function regenerateRoute(object $urlRewrite): object
103
    {
104
        if (! array_key_exists($urlRewrite->type, $this->getTypes())) {
105
            throw UrlRewriteRegenerationFailed::invalidType($urlRewrite->type);
106
        }
107
108
        if (! \is_array($urlRewrite->type_attributes)) {
109
            throw UrlRewriteRegenerationFailed::columnNotSet($urlRewrite, 'type_attributes');
110
        }
111
112
        return $this->update(
113
            ['target_path' => $this->targetPathFromRoute($urlRewrite->type, $urlRewrite->type_attributes)],
114
            $urlRewrite->id
115
        );
116
    }
117
118
    public function create(
119
        string $requestPath,
120
        ?string $targetPath,
121
        ?string $type = null,
122
        ?array $typeAttributes = null,
123
        int $redirectType = 0,
124
        ?string $description = null,
125
        ?bool $unique = false
126
    ): object {
127
        [$requestPath, $targetPath] = $this->validateCreate(
128
            $requestPath,
129
            $targetPath,
130
            $type,
131
            $typeAttributes,
132
            $redirectType,
133
            $unique
134
        );
135
136
        return $this->model->create(
137
            [
138
                'type' => $type,
139
                'type_attributes' => $typeAttributes,
140
                'request_path' => $requestPath,
141
                'target_path' => $targetPath,
142
                'redirect_type' => $redirectType,
143
                'description' => $description,
144
            ]
145
        );
146
    }
147
148
    public function update(array $data, int $id): object
149
    {
150
        $record = $this->find($id);
151
152
        $record->update($data);
153
154
        return $record;
155
    }
156
157
    protected function generateUnique(string $requestPath, int $id = 1): string
158
    {
159
        if ($this->checkIfRequestPathExists($requestPath.'-'.$id)) {
160
            return $this->generateUnique($requestPath, $id + 1);
161
        }
162
163
        return $requestPath.'-'.$id;
164
    }
165
166
    protected function getTypes(): array
167
    {
168
        return config('url-rewrite.types');
169
    }
170
171
    protected function targetPathFromRoute($type, $attributes): string
172
    {
173
        return route($type, $attributes, false);
174
    }
175
176
    protected function validateCreate(
177
        string $requestPath,
178
        ?string $targetPath,
179
        ?string $type,
180
        ?array $typeAttributes,
181
        int $redirectType,
182
        ?bool $unique
183
    ): array {
184
        if (! in_array($redirectType, self::allowedTypes, true)) {
185
            throw new \Exception('Redirect type must be 0, 1 or 2');
186
        }
187
188
        if ($this->checkIfRequestPathExists($requestPath)) {
189
            if (! $unique) {
190
                throw UrlRewriteAlreadyExistsException::requestPath($requestPath);
191
            }
192
193
            $requestPath = $this->generateUnique($requestPath);
194
        }
195
196
        if ($targetPath === null && isset($type, $typeAttributes)) {
197
            $targetPath = $this->targetPathFromRoute($type, $typeAttributes);
198
        }
199
200
        return [$requestPath, $targetPath];
201
    }
202
}
203