PhpVarsCheckRouter   A
last analyzed

Complexity

Total Complexity 34

Size/Duplication

Total Lines 181
Duplicated Lines 21.55 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 2
dl 39
loc 181
rs 9.2
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B getMinInConfiguration() 0 14 5
A countRecursive() 0 4 1
B iniGetBytes() 0 23 5
C __invoke() 39 61 22

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
        $val = (int) $val;
86
        switch ($last) {
87
            // The 'G' modifier is available since PHP 5.1.0
88
            case 'g':
89
                $val *= 1024;
90
            case 'm':
91
                $val *= 1024;
92
            case 'k':
93
                $val *= 1024;
94
        }
95
96
        return $val;
97
    }
98
99
    /**
100
     * Count number of element in array.
101
     *
102
     * @param mixed $item
103
     * @param mixed $key
104
     */
105
    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...
106
    {
107
        ++$this->count;
108
    }
109
110
    /**
111
     * Process an incoming request and/or response.
112
     *
113
     * Accepts a server-side request and a response instance, and does
114
     * something with them.
115
     *
116
     * If the response is not complete and/or further processing would not
117
     * interfere with the work done in the middleware, or if the middleware
118
     * wants to delegate to another process, it can use the `$out` callable
119
     * if present.
120
     *
121
     * If the middleware does not return a value, execution of the current
122
     * request is considered complete, and the response instance provided will
123
     * be considered the response to return.
124
     *
125
     * Alternately, the middleware may return a response instance.
126
     *
127
     * Often, middleware will `return $out();`, with the assumption that a
128
     * later middleware will return a response.
129
     *
130
     * @param Request       $request
131
     * @param Response      $response
132
     * @param null|callable $out
133
     *
134
     * @return null|Response
135
     *
136
     * @throws SplashException
137
     */
138
    public function __invoke(Request $request, Response $response, callable $out = null)
139
    {
140
        // Check if there is a limit of input number in php
141
        // Throw exception if the limit is reached
142 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...
143
            $maxGet = $this->getMinInConfiguration(ini_get('max_input_vars'), ini_get('suhosin.get.max_vars'));
144
            if ($maxGet !== null) {
145
                $this->count = 0;
146
                array_walk_recursive($_GET, array($this, 'countRecursive'));
147
                if ($this->count == $maxGet) {
148
                    if ($this->log != null) {
149
                        $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]);
150
                    }
151
                    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.');
152
                }
153
            }
154
        }
155 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...
156
            $maxPost = $this->getMinInConfiguration(ini_get('max_input_vars'), ini_get('suhosin.post.max_vars'));
157
            if ($maxPost !== null) {
158
                $this->count = 0;
159
                array_walk_recursive($_POST, array($this, 'countRecursive'));
160
                if ($this->count == $maxPost) {
161
                    if ($this->log != null) {
162
                        $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]);
163
                    }
164
                    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.');
165
                }
166
            }
167
        }
168 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...
169
            $maxRequest = $this->getMinInConfiguration(ini_get('max_input_vars'), ini_get('suhosin.request.max_vars'));
170
            if ($maxRequest !== null) {
171
                $this->count = 0;
172
                array_walk_recursive($_REQUEST, array($this, 'countRecursive'));
173
                if ($this->count == $maxRequest) {
174
                    if ($this->log != null) {
175
                        $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]);
176
                    }
177
                    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.');
178
                }
179
            }
180
        }
181
        if (isset($_SERVER['REQUEST_METHOD']) && strtolower($_SERVER['REQUEST_METHOD']) == 'post' && empty($_POST) && empty($_FILES)) {
182
            $maxPostSize = self::iniGetBytes('post_max_size');
183
            if ($_SERVER['CONTENT_LENGTH'] > $maxPostSize) {
184
                if ($this->log != null) {
185
                    $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]);
186
                }
187
                throw new SplashException(
188
                    sprintf('Max post size exceeded! Got %s bytes, but limit is %s bytes. Edit post_max_size setting in your php.ini.',
189
                        $_SERVER['CONTENT_LENGTH'],
190
                        $maxPostSize
191
                    )
192
                );
193
            }
194
        }
195
196
        //If no Exception has been thrown, call next router
197
        return $out($request, $response);
198
    }
199
}
200