Completed
Pull Request — master (#6)
by aguevaraIL
18:47
created

Composite::setNormalizer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2.864

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 8
ccs 2
cts 5
cp 0.4
crap 2.864
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace roaresearch\yii2\roa\urlRules;
4
5
use Yii;
6
use yii\{
7
    base\InvalidConfigException,
8
    web\NotFoundHttpException,
9
    web\UrlManager,
10
    web\UrlNormalizer
11
};
12
13
/**
14
 * Url rule that can call children rule when applicable.
15
 *
16
 * @author Angel (Faryshta) Guevara <[email protected]>
17
 */
18
abstract class Composite extends \yii\web\CompositeUrlRule
19
{
20
    /**
21
     * @var bool whether this rule must throw an `NotFoundHttpException` when
22
     * parse request fails.
23
     */
24
    public bool $strict = true;
25
26
    /**
27
     * @var string message used to create the `NotFoundHttpException` when
28
     * `$strict` equals `true` and no children rules could parse the request.
29
     */
30
    public string $notFoundMessage = 'Unknown route.';
31
32
    /**
33
     * @var ?UrlNormalizer|array
34
     */
35
    protected ?UrlNormalizer $normalizer;
36
37
    /**
38
     * @inheritdoc
39
     */
40 21
    public function setNormalizer(?UrlNormalizer|array $normalizer): void
41
    {
42 21
        $this->normalizer = is_array($normalizer)
0 ignored issues
show
introduced by
The condition is_array($normalizer) is always true.
Loading history...
43
            ? Yii::createObject(array_merge(
44
                ['class' => UrlNormalizer::class],
45
                $normalizer
46
            ))
47
            : $normalizer;
48 21
    }
49 21
50
    /**
51
     * @param UrlManager $manager the URL manager
52
     * @return ?UrlNormalizer
53
     */
54
    protected function getNormalizer(UrlManager $manager): ?UrlNormalizer
55 21
    {
56
        if ($this->normalizer === null
57
            && $manager->normalizer instanceof UrlNormalizer
58
        ) {
59
            return $manager->normalizer;
60
        }
61
62
        return $this->normalizer;
63
    }
64
65
    /**
66
     * Determines if this rule must parse the request using the children rules
67
     * or return `false` inmediately.
68
     *
69 21
     * @param string $route
70
     * @return bool
71 21
     */
72 21
    abstract protected function isApplicable(string $route): bool;
73
74 21
    /**
75
     * Ensures that `$rules` property is set
76
     */
77
    private function ensureRules()
78
    {
79 21
        $this->rules ??= $this->createRules();
80
    }
81
82 21
    /**
83 1
     * @inheritdoc
84
     */
85 21
    public function parseRequest($manager, $request)
86 21
    {
87 21
        // only parse rules applicable rules
88 21
        if (!$this->isApplicable($request->pathInfo)) {
89 21
            return false;
90 21
        }
91 21
        $normalized = false;
92
        if ($this->hasNormalizer($manager)) {
93
            $request->pathInfo = $this->getNormalizer($manager)
94 21
                ->normalizePathInfo(
95 21
                    $request->pathInfo,
96 21
                    '',
97
                    $normalized
98
                );
99
        }
100 21
        $this->ensureRules();
101 1
        $result = parent::parseRequest($manager, $request);
102 21
        if ($result === false && $this->strict === true) {
103
            throw $this->createNotFoundException();
104
        }
105
106
        return $normalized
107
            ? $this->getNormalizer($manager)->normalizeRoute($result)
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type false; however, parameter $route of yii\web\UrlNormalizer::normalizeRoute() 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

107
            ? $this->getNormalizer($manager)->normalizeRoute(/** @scrutinizer ignore-type */ $result)
Loading history...
108 17
            : $result;
109
    }
110
111 17
    /**
112 16
     * @inheritdoc
113
     */
114 17
    public function createUrl($manager, $route, $params)
115
    {
116 17
        // only parse rules applicable rules
117
        if (!$this->isApplicable($route)) {
118
            return false;
119
        }
120
        $this->ensureRules();
121
122
        return parent::createUrl($manager, $route, $params);
123 21
    }
124
125 21
    /**
126
     * @param UrlManager $manager the URL manager
127
     * @return bool
128
     */
129
    protected function hasNormalizer($manager): bool
130
    {
131
        return null !== $this->getNormalizer($manager);
132 21
    }
133
134 21
    /**
135 21
     * @return NotFoundHttpException
136
     */
137
    protected function createNotFoundException(): NotFoundHttpException
138
    {
139
        return new NotFoundHttpException($this->notFoundMessage);
140 21
    }
141
}
142