Completed
Push — master ( a88030...fd03b7 )
by Tomas
10s
created

InputParam::getValue()   C

Complexity

Conditions 19
Paths 22

Size

Total Lines 55
Code Lines 37

Duplication

Lines 18
Ratio 32.73 %

Code Coverage

Tests 32
CRAP Score 19.495

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 18
loc 55
ccs 32
cts 36
cp 0.8889
rs 6.6276
c 2
b 0
f 0
cc 19
eloc 37
nc 22
nop 0
crap 19.495

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 Tomaj\NetteApi\Params;
4
5
use Exception;
6
7
class InputParam implements ParamInterface
8
{
9
    const TYPE_POST      = 'POST';
10
    const TYPE_GET       = 'GET';
11
    const TYPE_PUT       = 'PUT';
12
    const TYPE_FILE      = 'FILE';
13
    const TYPE_COOKIE    = 'COOKIE';
14
    const TYPE_POST_RAW  = 'POST_RAW';
15
    const TYPE_POST_JSON_KEY  = 'POST_JSON_KEY';
16
17
    const OPTIONAL = false;
18
    const REQUIRED = true;
19
20
    /**
21
     * @var string
22
     */
23
    private $type;
24
25
    /**
26
     * @var string
27
     */
28
    private $key;
29
30
    /**
31
     * @var bool
32
     */
33
    private $required;
34
35
    /**
36
     * @var array|null
37
     */
38
    private $availableValues;
39
40
    /**
41
     * @var bool
42
     */
43
    private $multi;
44 48
45
    public function __construct($type, $key, $required = self::OPTIONAL, $availableValues = null, $multi = false)
46 48
    {
47 48
        $this->type = $type;
48 48
        $this->key = $key;
49 48
        $this->required = $required;
50 48
        $this->availableValues = $availableValues;
51 48
        $this->multi = $multi;
52
    }
53
54
    /**
55
     * @return string
56 9
     */
57
    public function getType()
58 9
    {
59
        return $this->type;
60
    }
61
62
    /**
63
     * @return string
64 21
     */
65
    public function getKey()
66 21
    {
67
        return $this->key;
68
    }
69
70
    /**
71
     * @return boolean
72 6
     */
73
    public function isRequired()
74 6
    {
75
        return $this->required;
76
    }
77 6
78
    public function getAvailableValues()
79 6
    {
80
        return $this->availableValues;
81
    }
82
83
    /**
84
     * @return bool
85 21
     */
86
    public function isMulti()
87 21
    {
88
        return $this->multi;
89
    }
90
91
    /**
92
     * Check if actual value from environment is valid
93
     *
94
     * @return bool
95
     *
96
     * @throws Exception if actual InputParam has unsupported type
97 18
     */
98
    public function isValid()
99 18
    {
100 6
        if ($this->required == self::OPTIONAL) {
101
            return true;
102
        }
103 18
104 18
        $value = $this->getValue();
105 9
        if ($this->availableValues !== null) {
106 6
            if (is_array($this->availableValues)) {
107
                return empty(array_diff(($this->isMulti() ? $value : [$value]), $this->availableValues));
108 1
            }
109
        }
110 15
111 15
        if ($this->required) {
112 6
            if ($value === null || $value == '') {
113
                return false;
114 9
            }
115 3
            if (is_string($this->availableValues)) {
116
                return $value == $this->availableValues;
117 2
            }
118 6
        }
119
        return true;
120
    }
121
122
    /**
123
     * Process environment variables like POST|GET|etc.. and return actual value
124
     *
125
     * @return mixed
126
     *
127
     * @throws Exception if actual InputParam has unsupported type
128 39
     */
129
    public function getValue()
0 ignored issues
show
Coding Style introduced by
getValue uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getValue uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getValue uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getValue uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
130 39
    {
131 15 View Code Duplication
        if ($this->type == self::TYPE_GET) {
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...
132 6
            if (!filter_has_var(INPUT_GET, $this->key) && isset($_GET[$this->key])) {
133
                return $_GET[$this->key];
134 9
            }
135
            if ($this->isMulti()) {
136
                return filter_input(INPUT_GET, $this->key, FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
137 9
            }
138
            return filter_input(INPUT_GET, $this->key);
139 33
        }
140 12 View Code Duplication
        if ($this->type == self::TYPE_POST) {
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...
141 6
            if (!filter_has_var(INPUT_POST, $this->key) && isset($_POST[$this->key])) {
142
                return $_POST[$this->key];
143 9
            }
144
            if ($this->isMulti()) {
145
                return filter_input(INPUT_POST, $this->key, FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
146 9
            }
147
            return filter_input(INPUT_POST, $this->key);
148 24
        }
149 9
        if ($this->type == self::TYPE_FILE) {
150 6
            if (isset($_FILES[$this->key])) {
151 3
                if ($this->isMulti()) {
152
                    return $this->processMultiFileUploads($_FILES[$this->key]);
153 3
                } else {
154
                    return $_FILES[$this->key];
155
                }
156 3
            }
157
            return null;
158 15
        }
159 3
        if ($this->type == self::TYPE_COOKIE) {
160 3
            if (isset($_COOKIE[$this->key])) {
161
                return $_COOKIE[$this->key];
162
            }
163 12
        }
164 3
        if ($this->type == self::TYPE_POST_RAW) {
165
            return file_get_contents("php://input");
166 9
        }
167 6
        if ($this->type == self::TYPE_PUT) {
168 6
            parse_str(file_get_contents("php://input"), $params);
169
            if (isset($params[$this->key])) {
170
                return $params[$this->key];
171 6
            }
172
            return '';
173
        }
174 3
        if ($this->type == self::TYPE_POST_JSON_KEY) {
175
            $params = file_get_contents("php://input");
176
            $params = @json_decode($params, true);
177 3
            if (isset($params[$this->key])) {
178
                return $params[$this->key];
179 3
            }
180 3
            return '';
181 3
        }
182 3
        throw new Exception('Invalid type');
183 1
    }
184 1
185 3
    private function processMultiFileUploads($files)
186
    {
187
        $result = [];
188
        foreach ($files as $key => $values) {
189
            foreach ($values as $index => $value) {
190
                $result[$index][$key] = $value;
191
            }
192
        }
193
        return $result;
194
    }
195
}
196