Completed
Pull Request — master (#2)
by James Ekow Abaka
01:17
created

Input::getFileObjects()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
ccs 0
cts 11
cp 0
rs 9.4285
cc 2
eloc 11
nc 2
nop 1
crap 6
1
<?php
2
3
/*
4
 * Ntentan Framework
5
 * Copyright (c) 2008-2015 James Ekow Abaka Ainooson
6
 * 
7
 * Permission is hereby granted, free of charge, to any person obtaining
8
 * a copy of this software and associated documentation files (the
9
 * "Software"), to deal in the Software without restriction, including
10
 * without limitation the rights to use, copy, modify, merge, publish,
11
 * distribute, sublicense, and/or sell copies of the Software, and to
12
 * permit persons to whom the Software is furnished to do so, subject to
13
 * the following conditions:
14
 * 
15
 * The above copyright notice and this permission notice shall be
16
 * included in all copies or substantial portions of the Software.
17
 * 
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
25
 * 
26
 */
27
28
namespace ntentan\utils;
29
30
/**
31
 * An input filter class which is wraped around PHP's `filter_input` and
32
 * `filter_input_array` classes. This class provides methods which allow safe
33
 * and secure access to data passed to an application. 
34
 *
35
 * @author James Ainooson
36
 */
37
class Input 
38
{
39
    /**
40
     * Constant for POST request.
41
     */
42
    const POST = INPUT_POST;
43
44
    /**
45
     * Constant for GET request.
46
     */
47
    const GET = INPUT_GET;
48
49
    /**
50
     * Constant for INPUT request.
51
     */
52
    const REQUEST = INPUT_REQUEST;
53
54
    /**
55
     * Cache or arrays which hold decoded query strings.
56
     *
57
     * @var array
58
     */
59
    private static $arrays = [];
60
    
61
    /**
62
     * Decodes and returns the value of a given item in an HTTP query.
63
     * Although PHP decodes query strings automatically, it converts periods to underscores. This method makes it 
64
     * possible to decode query strings that contain underscores.
65
     * Based on code from http://stackoverflow.com/a/14432765
66
     * 
67
     * @param string $method The HTTP method of the query (GET, POST ...)
68
     * @param string $key The key of the item in the query to retrieve.
69
     * @return mixed
70
     */
71
    private static function decode(string $method, string $key)
72
    {
73
        if(!isset(self::$arrays[$method])) {
74
            $query = $method == self::GET 
75
                ? filter_input(INPUT_SERVER, 'QUERY_STRING') 
76
                : file_get_contents('php://input');
77
            $query = preg_replace_callback('/(?:^|(?<=&))[^=[]+/', 
78
                function($match) {
79
                    return bin2hex($match[0]);
80
                }, urldecode($query));
81
            parse_str($query, $data);
82
            self::$arrays[$method] = array_combine(array_map('hex2bin', array_keys($data)), $data);        
83
        }
84
        return $key ? (self::$arrays[$method][$key] ?? null) : (self::$arrays[$method] ?? null);
85
    }
86
    
87
    /**
88
     * Does the actual work of calling either the filter_input of 
89
     * filter_input_array. Calls the filter_input when a data key is provided
90
     * and callse the filte_input_array when a data key is absent.
91
     * 
92
     * @param string $input Input type
93
     * @param string $key The data key
94
     * @return string|array The value.
95
     */
96
    private static function getVariable(string $input, string $key)
97
    {
98
        if ($key === null) {
99
            if (!isset(self::$arrays[$input])) {
100
                self::$arrays[$input] = filter_input_array($input);
101
            }
102
            $return = self::$arrays[$input];
103
        } else {
104
            $return = filter_input($input, $key);
105
        }
106
107
        if ($return === null && $key === null) {
108
            $return = array();
109
        }
110
111
        return $return;
112
    }
113
    
114
    /**
115
     * Retrieves GET request variables.
116
     * 
117
     * @param string $key
118
     * @return string|array
119
     */
120
    public static function get(string $key = null)
121
    {
122
        return self::decode(self::GET, $key);
123
    }
124
125
    /**
126
     * Retrieves post request variables.
127
     * 
128
     * @param string $key
129
     * @return string|array
130
     */
131
    public static function post(string $key = null)
132
    {
133
        return self::decode(self::POST, $key);
134
    }
135
136
    /**
137
     * Retrieves server variables.
138
     * 
139
     * @param string $key
140
     * @return string|array
141
     */
142
    public static function server(string $key = null)
143
    {
144
        return self::getVariable(INPUT_SERVER, $key);
145
    }
146
147
    /**
148
     * Retrieves cookie variables.
149
     * 
150
     * @param string $key
151
     * @return string|array
152
     */
153
    public static function cookie(string $key = null)
154
    {
155
        return self::getVariable(INPUT_COOKIE, $key);
156
    }
157
158
    /**
159
     * Checks if a particular key exists in a given request query.
160
     *
161
     * @param string $input
162
     * @param string $key
163
     * @return bool
164
     */
165
    public static function exists(string $input, string $key) : bool
166
    {
167
        return isset(self::getVariable($input, null)[$key]);
168
    }
169
170
    /**
171
     * Retrieves uploaded files as instances of UploadedFile or an array of UploadedFile if multiples exist.
172
     *
173
     * @param string $key
174
     * @return array|filesystem\UploadedFile|null
175
     */
176
    public static function files(string $key = null)
177
    {
178
        if (!isset($_FILES[$key])) {
179
            return null;
180
        }
181
        if (is_array($_FILES[$key]['name'])) {
182
            return self::getFileObjects($key);
183
        } else {
184
            return new filesystem\UploadedFile($_FILES);
185
        }
186
    }
187
188
    private static function getFileObjects($key)
189
    {
190
        $files = [];
191
        $numFiles = count($_FILES[$key]['name']);
192
        for ($i = 0; $i < $numFiles; $i++) {
193
            $files[] = new filesystem\UploadedFile([
194
                'name' => $_FILES[$key]['name'][$i],
195
                'type' => $_FILES[$key]['type'][$i],
196
                'tmp_name' => $_FILES[$key]['tmp_name'][$i],
197
                'error' => $_FILES[$key]['error'][$i],
198
                'size' => $_FILES[$key]['size'][$i],
199
            ]);
200
        }
201
        return $files;
202
    }
203
204
}
205