Completed
Pull Request — master (#7)
by Angel
08:45 queued 01:09
created

Composite   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Test Coverage

Coverage 79.55%

Importance

Changes 0
Metric Value
eloc 39
dl 0
loc 129
ccs 35
cts 44
cp 0.7955
rs 10
c 0
b 0
f 0
wmc 19

7 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 13 4
A ensureRules() 0 3 2
A getNormalizer() 0 9 3
A parseRequest() 0 24 6
A hasNormalizer() 0 3 1
A createUrl() 0 9 2
A createNotFoundException() 0 3 1
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 $strict = true;
25
26
    /**
27
     * @var UrlNormalizer|null
28
     */
29
    public $normalizer = null;
30
31
    /**
32
     * @var string message used to create the `NotFoundHttpException` when
33
     * `$strict` equals `true` and no children rules could parse the request.
34
     */
35
    public $notFoundMessage = 'Unknown route.';
36
37
    /**
38
     * @inheritdoc
39
     */
40 21
    public function init()
41
    {
42 21
        if (is_array($this->normalizer)) {
0 ignored issues
show
introduced by
The condition is_array($this->normalizer) is always false.
Loading history...
43
            $this->normalizer = Yii::createObject(array_merge(
44
                ['class' => UrlNormalizer::class],
45
                $this->normalizer
46
            ));
47
        }
48 21
        if (!empty($this->normalizer)
49 21
            && !$this->normalizer instanceof UrlNormalizer
0 ignored issues
show
introduced by
$this->normalizer is always a sub-type of yii\web\UrlNormalizer.
Loading history...
50
        ) {
51
            throw new InvalidConfigException(
52
                'Invalid config for `normalizer`.'
53
            );
54
        }
55 21
    }
56
57
    /**
58
     * Determines if this rule must parse the request using the children rules
59
     * or return `false` inmediately.
60
     *
61
     * @param string $route
62
     * @return bool
63
     */
64
    abstract protected function isApplicable(string $route): bool;
65
66
    /**
67
     * Ensures that `$rules` property is set
68
     */
69 21
    protected function ensureRules()
70
    {
71 21
        $this->rules = $this->rules ?: $this->createRules();
72 21
    }
73
74
    /**
75
     * @inheritdoc
76
     */
77 21
    public function parseRequest($manager, $request)
78
    {
79
        // only parse rules applicable rules
80 21
        if (!$this->isApplicable($request->pathInfo)) {
81 1
            return false;
82
        }
83 21
        $normalized = false;
84 21
        if ($this->hasNormalizer($manager)) {
85 21
            $request->pathInfo = $this->getNormalizer($manager)
86 21
                ->normalizePathInfo(
87 21
                    $request->pathInfo,
88 21
                    '',
89 21
                    $normalized
90
                );
91
        }
92 21
        $this->ensureRules();
93 21
        $result = parent::parseRequest($manager, $request);
94 21
        if ($result === false && $this->strict === true) {
95
            throw $this->createNotFoundException();
96
        }
97
98 21
        return $normalized
99 1
            ? $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

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