Passed
Pull Request — master (#33)
by Melech
03:28
created

MessageCapableRouter::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
c 1
b 0
f 0
nc 1
nop 9
dl 0
loc 20
rs 9.9666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Routing\Dispatchers;
15
16
use Valkyrja\Container\Container;
17
use Valkyrja\Dispatcher\Dispatcher;
18
use Valkyrja\Event\Events;
19
use Valkyrja\Http\Request;
20
use Valkyrja\Http\ResponseFactory;
21
use Valkyrja\Routing\Collection;
22
use Valkyrja\Routing\Config\Config;
23
use Valkyrja\Routing\Matcher;
24
use Valkyrja\Routing\Message;
25
use Valkyrja\Routing\Route;
26
use Valkyrja\Routing\Support\Abort;
27
use Valkyrja\Validation\Validator;
28
29
use function assert;
30
31
/**
32
 * Class MessageCapableRouter.
33
 *
34
 * @author Melech Mizrachi
35
 */
36
class MessageCapableRouter extends Router
37
{
38
    /**
39
     * MessageCapableRouter constructor.
40
     */
41
    public function __construct(
42
        protected Validator $validator,
43
        Collection $collection,
44
        Container $container,
45
        Dispatcher $dispatcher,
46
        Events $events,
47
        Matcher $matcher,
48
        ResponseFactory $responseFactory,
49
        Config|array $config,
50
        bool $debug = false
51
    ) {
52
        parent::__construct(
53
            collection     : $collection,
54
            container      : $container,
55
            dispatcher     : $dispatcher,
56
            events         : $events,
57
            matcher        : $matcher,
58
            responseFactory: $responseFactory,
59
            config         : $config,
60
            debug          : $debug
61
        );
62
    }
63
64
    /**
65
     * @inheritDoc
66
     */
67
    public function getRouteFromRequest(Request $request): Route
68
    {
69
        $route = parent::getRouteFromRequest($request);
70
71
        foreach ($route->getMessages() ?? [] as $message) {
72
            $this->ensureIsMessage($message);
73
            $this->ensureRequestConformsToMessage($request, $message);
74
        }
75
76
        return $route;
77
    }
78
79
    /**
80
     * Ensure a message is a message.
81
     *
82
     * @param string $message The message
83
     *
84
     * @return void
85
     */
86
    protected function ensureIsMessage(string $message): void
87
    {
88
        assert($this->determineIsMessage($message));
89
    }
90
91
    /**
92
     * Determine if a dependency is a message.
93
     *
94
     * @param string $message The message
95
     *
96
     * @return bool
97
     */
98
    protected function determineIsMessage(string $message): bool
99
    {
100
        return is_a($message, Message::class, true);
101
    }
102
103
    /**
104
     * @param Request               $request The request
105
     * @param class-string<Message> $message The message class name
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Message> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Message>.
Loading history...
106
     *
107
     * @return void
108
     */
109
    protected function ensureRequestConformsToMessage(Request $request, string $message): void
110
    {
111
        $this->ensureRequestHasNoExtraData($request, $message);
112
        $this->ensureRequestIsValid($request, $message);
113
    }
114
115
    /**
116
     * @param Request               $request The request
117
     * @param class-string<Message> $message The message class name
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Message> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Message>.
Loading history...
118
     *
119
     * @return void
120
     */
121
    protected function ensureRequestHasNoExtraData(Request $request, string $message): void
122
    {
123
        // If there is extra data
124
        if ($message::determineIfRequestContainsExtraData($request)) {
125
            // Then the payload is too large
126
            $this->abortDueToExtraData($request, $message);
127
        }
128
    }
129
130
    /**
131
     * @param Request               $request The request
132
     * @param class-string<Message> $message The message class name
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Message> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Message>.
Loading history...
133
     *
134
     * @return void
135
     */
136
    protected function abortDueToExtraData(Request $request, string $message): void
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

136
    protected function abortDueToExtraData(/** @scrutinizer ignore-unused */ Request $request, string $message): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $message is not used and could be removed. ( Ignorable by Annotation )

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

136
    protected function abortDueToExtraData(Request $request, /** @scrutinizer ignore-unused */ string $message): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
137
    {
138
        Abort::abort413();
139
    }
140
141
    /**
142
     * @param Request               $request The request
143
     * @param class-string<Message> $message The message class name
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Message> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Message>.
Loading history...
144
     *
145
     * @return void
146
     */
147
    protected function ensureRequestIsValid(Request $request, string $message): void
148
    {
149
        if (($messageRules = $message::getValidationRules()) === null) {
150
            return;
151
        }
152
153
        $validator = $this->validator;
154
        $validator->setRules($this->getValidatorRules($message::getDataFromRequest($request), $messageRules));
155
156
        if (! $validator->validate()) {
157
            $this->abortDueToValidationErrors($request, $message);
158
        }
159
    }
160
161
    /**
162
     * @param Request               $request The request
163
     * @param class-string<Message> $message The message class name
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Message> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Message>.
Loading history...
164
     *
165
     * @return void
166
     */
167
    protected function abortDueToValidationErrors(Request $request, string $message): void
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

167
    protected function abortDueToValidationErrors(/** @scrutinizer ignore-unused */ Request $request, string $message): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $message is not used and could be removed. ( Ignorable by Annotation )

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

167
    protected function abortDueToValidationErrors(Request $request, /** @scrutinizer ignore-unused */ string $message): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
168
    {
169
        Abort::abort400();
170
    }
171
172
    /**
173
     * @param array                                                                        $data         The data
174
     * @param array<string, array<string, array{arguments: array, errorMessage?: string}>> $messageRules The message rules
175
     *
176
     * @return array
177
     */
178
    protected function getValidatorRules(array $data, array $messageRules): array
179
    {
180
        $rules = [];
181
182
        foreach ($messageRules as $param => $paramRule) {
183
            $rules[$param] = [
184
                'subject' => $data[$param],
185
                'rules'   => $paramRule,
186
            ];
187
        }
188
189
        return $rules;
190
    }
191
}
192