Completed
Push — fetcher_factories ( 10a56f...fd93ea )
by David
13:44
created

PhpVarsCheckRouter::__invoke()   C

Complexity

Conditions 22
Paths 134

Size

Total Lines 61
Code Lines 38

Duplication

Lines 39
Ratio 63.93 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 39
loc 61
rs 5.5823
cc 22
eloc 38
nc 134
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Mouf\Mvc\Splash\Routers;
4
5
use Mouf\Mvc\Splash\Utils\SplashException;
6
use Psr\Http\Message\ResponseInterface as Response;
7
use Psr\Http\Message\ServerRequestInterface as Request;
8
use Psr\Log\LoggerInterface;
9
use Zend\Stratigility\MiddlewareInterface;
10
11
/**
12
 * This router :
13
 *  - just checks that some PHP settings are not exeeded : max_input_vars, max_post_size
14
 *  - doesn't actually 'routes' the request. It's more like a filter to me applied and check the request.
15
 *  - should be placed BEFORE the effective applications router and AFTER the Exceptions handling routers.
16
 *
17
 * @author Kevin Nguyen
18
 */
19
class PhpVarsCheckRouter implements MiddlewareInterface
20
{
21
    /**
22
     * The logger used by Splash.
23
     *
24
     * @var LoggerInterface
25
     */
26
    private $log;
27
28
    /**
29
     * A simple counter to check requests' length (GET, POST, REQUEST).
30
     *
31
     * @var int
32
     */
33
    private $count;
34
35
    /**
36
     * @Important
37
     *
38
     * @param LoggerInterface $log The logger used by Splash
39
     */
40
    public function __construct(LoggerInterface $log = null)
41
    {
42
        $this->log = $log;
43
    }
44
45
    /**
46
     * Get the min in 2 values if there exist.
47
     *
48
     * @param int $val1
49
     * @param int $val2
50
     *
51
     * @return int|NULL
52
     */
53
    private function getMinInConfiguration($val1, $val2)
54
    {
55
        if ($val1 && $val2) {
56
            return min(array($val1, $val2));
57
        }
58
        if ($val1) {
59
            return $val1;
60
        }
61
        if ($val2) {
62
            return $val2;
63
        }
64
65
        return;
66
    }
67
68
    /**
69
     * Returns the number of bytes from php.ini parameter.
70
     *
71
     * @param $val
72
     *
73
     * @return int|string
74
     */
75
    private static function iniGetBytes($val)
76
    {
77
        $val = trim(ini_get($val));
78
        if ($val != '') {
79
            $last = strtolower(
80
                    $val{strlen($val) - 1}
81
            );
82
        } else {
83
            $last = '';
84
        }
85
        switch ($last) {
86
            // The 'G' modifier is available since PHP 5.1.0
87
            case 'g':
88
                $val *= 1024;
89
            case 'm':
90
                $val *= 1024;
91
            case 'k':
92
                $val *= 1024;
93
        }
94
95
        return $val;
96
    }
97
98
    /**
99
     * Count number of element in array.
100
     *
101
     * @param mixed $item
102
     * @param mixed $key
103
     */
104
    private function countRecursive($item, $key)
0 ignored issues
show
Unused Code introduced by
The parameter $item is not used and could be removed.

This check looks from 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 $key is not used and could be removed.

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

Loading history...
105
    {
106
        ++$this->count;
107
    }
108
109
    /**
110
     * Process an incoming request and/or response.
111
     *
112
     * Accepts a server-side request and a response instance, and does
113
     * something with them.
114
     *
115
     * If the response is not complete and/or further processing would not
116
     * interfere with the work done in the middleware, or if the middleware
117
     * wants to delegate to another process, it can use the `$out` callable
118
     * if present.
119
     *
120
     * If the middleware does not return a value, execution of the current
121
     * request is considered complete, and the response instance provided will
122
     * be considered the response to return.
123
     *
124
     * Alternately, the middleware may return a response instance.
125
     *
126
     * Often, middleware will `return $out();`, with the assumption that a
127
     * later middleware will return a response.
128
     *
129
     * @param Request       $request
130
     * @param Response      $response
131
     * @param null|callable $out
132
     *
133
     * @return null|Response
134
     *
135
     * @throws SplashException
136
     */
137
    public function __invoke(Request $request, Response $response, callable $out = null)
138
    {
139
        // Check if there is a limit of input number in php
140
        // Throw exception if the limit is reached
141 View Code Duplication
        if (ini_get('max_input_vars') || ini_get('suhosin.get.max_vars')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
142
            $maxGet = $this->getMinInConfiguration(ini_get('max_input_vars'), ini_get('suhosin.get.max_vars'));
143
            if ($maxGet !== null) {
144
                $this->count = 0;
145
                array_walk_recursive($_GET, array($this, 'countRecursive'));
146
                if ($this->count == $maxGet) {
147
                    if ($this->log != null) {
148
                        $this->log->error('Max input vars reaches for get parameters ({maxGet}). Check your variable max_input_vars in php.ini or suhosin module suhosin.get.max_vars.', ['maxGet' => $maxGet]);
149
                    }
150
                    throw new SplashException('Max input vars reaches for get parameters ('.$maxGet.'). Check your variable max_input_vars in php.ini or suhosin module suhosin.get.max_vars.');
151
                }
152
            }
153
        }
154 View Code Duplication
        if (ini_get('max_input_vars') || ini_get('suhosin.post.max_vars')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
            $maxPost = $this->getMinInConfiguration(ini_get('max_input_vars'), ini_get('suhosin.post.max_vars'));
156
            if ($maxPost !== null) {
157
                $this->count = 0;
158
                array_walk_recursive($_POST, array($this, 'countRecursive'));
159
                if ($this->count == $maxPost) {
160
                    if ($this->log != null) {
161
                        $this->log->error('Max input vars reaches for post parameters ({maxPost}). Check your variable max_input_vars in php.ini or suhosin module suhosin.post.max_vars.', ['maxPost' => $maxPost]);
162
                    }
163
                    throw new SplashException('Max input vars reaches for post parameters ('.$maxPost.'). Check your variable max_input_vars in php.ini or suhosin module suhosin.post.max_vars.');
164
                }
165
            }
166
        }
167 View Code Duplication
        if (ini_get('max_input_vars') || ini_get('suhosin.request.max_vars')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
            $maxRequest = $this->getMinInConfiguration(ini_get('max_input_vars'), ini_get('suhosin.request.max_vars'));
169
            if ($maxRequest !== null) {
170
                $this->count = 0;
171
                array_walk_recursive($_REQUEST, array($this, 'countRecursive'));
172
                if ($this->count == $maxRequest) {
173
                    if ($this->log != null) {
174
                        $this->log->error('Max input vars reaches for request parameters ({maxRequest}). Check your variable max_input_vars in php.ini or suhosin module suhosin.request.max_vars.', ['maxRequest' => $maxRequest]);
175
                    }
176
                    throw new SplashException('Max input vars reaches for request parameters ('.$maxRequest.'). Check your variable max_input_vars in php.ini or suhosin module suhosin.request.max_vars.');
177
                }
178
            }
179
        }
180
        if (isset($_SERVER['REQUEST_METHOD']) && strtolower($_SERVER['REQUEST_METHOD']) == 'post' && empty($_POST) && empty($_FILES)) {
181
            $maxPostSize = self::iniGetBytes('post_max_size');
182
            if ($_SERVER['CONTENT_LENGTH'] > $maxPostSize) {
183
                if ($this->log != null) {
184
                    $this->log->error('Max post size exceeded! Got {length} bytes, but limit is {maxPostSize} bytes. Edit post_max_size setting in your php.ini.', ['length' => $_SERVER['CONTENT_LENGTH'], 'maxPostSize' => $maxPostSize]);
185
                }
186
                throw new SplashException(
187
                    sprintf('Max post size exceeded! Got %s bytes, but limit is %s bytes. Edit post_max_size setting in your php.ini.',
188
                        $_SERVER['CONTENT_LENGTH'],
189
                        $maxPostSize
190
                    )
191
                );
192
            }
193
        }
194
195
        //If no Exception has been thrown, call next router
196
        return $out($request, $response);
197
    }
198
}
199