Passed
Push — master ( ea4f63...197c27 )
by Paul
20:35 queued 09:52
created

Sanitizer::sanitizeNumeric()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Modules;
4
5
use GeminiLabs\SiteReviews\Helper;
6
use GeminiLabs\SiteReviews\Helpers\Arr;
7
use GeminiLabs\SiteReviews\Helpers\Cast;
8
use GeminiLabs\SiteReviews\Helpers\Str;
9
use GeminiLabs\SiteReviews\Modules\Multilingual;
10
11
class Sanitizer
12
{
13
    const JSON_ERROR_CODES = [
14
        JSON_ERROR_DEPTH => 'JSON Error: The maximum stack depth has been exceeded',
15
        JSON_ERROR_STATE_MISMATCH => 'JSON Error: Invalid or malformed JSON',
16
        JSON_ERROR_CTRL_CHAR => 'JSON Error: Control character error, possibly incorrectly encoded',
17
        JSON_ERROR_SYNTAX => 'JSON Error: Syntax error',
18
        JSON_ERROR_UTF8 => 'JSON Error: Malformed UTF-8 characters, possibly incorrectly encoded',
19
        JSON_ERROR_RECURSION => 'JSON Error: One or more recursive references in the value to be encoded',
20
        JSON_ERROR_INF_OR_NAN => 'JSON Error: One or more NAN or INF values in the value to be encoded',
21
        JSON_ERROR_UNSUPPORTED_TYPE => 'JSON Error: A value of a type that cannot be encoded was given',
22
        JSON_ERROR_INVALID_PROPERTY_NAME => 'JSON Error: A property name that cannot be encoded was given',
23
        JSON_ERROR_UTF16 => 'JSON Error: Malformed UTF-16 characters, possibly incorrectly encoded',
24
    ];
25
26
    /**
27
     * @var array
28
     */
29
    public $sanitizers;
30
31
    /**
32
     * @var array
33
     */
34
    public $values;
35
36 40
    public function __construct(array $values = [], array $sanitizers = [])
37
    {
38 40
        $this->sanitizers = $this->buildSanitizers(Arr::consolidate($sanitizers));
39 40
        $this->values = Arr::consolidate($values);
40 40
    }
41
42
    /**
43
     * @return array|bool|string
44
     */
45 40
    public function run()
46
    {
47 40
        $result = $this->values;
48 40
        foreach ($this->values as $key => $value) {
49 40
            if (array_key_exists($key, $this->sanitizers)) {
50 40
                $result[$key] = call_user_func([$this, $this->sanitizers[$key]], $value);
51
            }
52
        }
53 40
        return $result;
54
    }
55
56
    /**
57
     * @param mixed $value
58
     * @return array
59
     */
60 17
    public function sanitizeArray($value)
61
    {
62 17
        return Arr::consolidate($value);
63
    }
64
65
    /**
66
     * @param mixed $value
67
     * @return int[]
68
     */
69 25
    public function sanitizeArrayInt($value)
70
    {
71 25
        return Arr::uniqueInt(Cast::toArray($value));
72
    }
73
74
    /**
75
     * @param mixed $value
76
     * @return string[]
77
     */
78 1
    public function sanitizeArrayString($value)
79
    {
80 1
        $sanitized = array_filter(Cast::toArray($value), 'is_string');
81
        array_walk($sanitized, function (&$value) {
82 1
            $value = $this->sanitizeText($value);
83 1
        });
84 1
        return $sanitized;
85
    }
86
87
    /**
88
     * @param mixed $value
89
     * @return bool
90
     */
91 16
    public function sanitizeBool($value)
92
    {
93 16
        return Cast::toBool($value);
94
    }
95
96
    /**
97
     * If date is invalid then return an empty string.
98
     * @param mixed $value
99
     * @param string $fallback
100
     * @return string
101
     */
102 24
    public function sanitizeDate($value, $fallback = '')
103
    {
104 24
        $date = strtotime(trim(Cast::toString($value)));
105 24
        if (false !== $date) {
106 15
            return wp_date('Y-m-d H:i:s', $date);
107
        }
108 24
        return $fallback;
109
    }
110
111
    /**
112
     * @param mixed $value
113
     * @return string
114
     */
115 25
    public function sanitizeEmail($value)
116
    {
117 25
        return sanitize_email(trim(Cast::toString($value)));
118
    }
119
120
    /**
121
     * @param mixed $value
122
     * @return string
123
     */
124 9
    public function sanitizeId($value)
125
    {
126 9
        require_once ABSPATH.WPINC.'/pluggable.php';
127 9
        $value = sanitize_key($this->sanitizeText($value));
128 9
        $value = substr($value, 0, 32); // limit the id to 32 characters
129 9
        if (empty($value)) {
130 9
            $value = glsr()->prefix.substr(wp_hash(serialize($this->values), 'nonce'), -12, 8);
131
        }
132 9
        return $value;
133
    }
134
135
    /**
136
     * @param mixed $value
137
     * @return int
138
     */
139 16
    public function sanitizeInt($value)
140
    {
141 16
        return Cast::toInt($value);
142
    }
143
144
    /**
145
     * @param mixed $value
146
     * @return array
147
     */
148
    public function sanitizeJson($value)
149
    {
150
        $result = '';
151
        if (is_scalar($value) && !Helper::isEmpty($value)) {
152
            $result = trim((string) $value);
153
            $result = htmlspecialchars_decode($result);
154
            $result = json_decode($result, true);
155
            $error = json_last_error();
156
            if (array_key_exists($error, static::JSON_ERROR_CODES)) {
157
                glsr_log()->error(static::JSON_ERROR_CODES[$error])->debug($value);
158
            }
159
        }
160
        return wp_unslash(Arr::consolidate($result));
161
    }
162
163
    /**
164
     * This allows lowercase alphannumeric and underscore characters
165
     * @param mixed $value
166
     * @return string
167
     */
168 25
    public function sanitizeKey($value)
169
    {
170 25
        $value = sanitize_key($this->sanitizeText($value));
171 25
        return substr(Str::snakeCase($value), 0, 32); // limit the key to 32 characters
172
    }
173
174
    /**
175
     * This allows lowercase alpha and underscore characters
176
     * @param mixed $value
177
     * @return string
178
     */
179 22
    public function sanitizeName($value)
180
    {
181 22
        $value = Str::snakeCase($this->sanitizeText($value));
182 22
        return preg_replace('/[^a-z_]/', '', $value);
183
    }
184
185
    /**
186
     * @param mixed $value
187
     * @return int|string
188
     */
189 1
    public function sanitizeNumeric($value)
190
    {
191 1
        return is_numeric($value) ? Cast::toInt($value) : '';
192
    }
193
194
    /**
195
     * @param mixed $value
196
     * @return int[]
197
     */
198 24
    public function sanitizePostIds($value)
199
    {
200 24
        $postIds = Cast::toArray($value);
201 24
        $postIds = array_map('\GeminiLabs\SiteReviews\Helper::getPostId', $postIds);
202 24
        return Arr::uniqueInt($postIds);
203
    }
204
205
    /**
206
     * @param mixed $value
207
     * @return string
208
     */
209 1
    public function sanitizeSlug($value)
210
    {
211 1
        return sanitize_title($this->sanitizeText($value));
212
    }
213
214
    /**
215
     * @param mixed $value
216
     * @return int[]
217
     */
218 24
    public function sanitizeTermIds($value)
219
    {
220 24
        $termIds = Cast::toArray($value);
221 24
        $termIds = array_map('\GeminiLabs\SiteReviews\Helper::getTermTaxonomyId', $termIds);
222 24
        return Arr::uniqueInt($termIds);
223
    }
224
225
    /**
226
     * @param mixed $value
227
     * @return string
228
     */
229 30
    public function sanitizeText($value)
230
    {
231 30
        return sanitize_text_field(trim(Cast::toString($value)));
232
    }
233
234
    /**
235
     * @param mixed $value
236
     * @return string
237
     */
238
    public function sanitizeTextHtml($value)
239
    {
240
        $allowedHtmlPost = wp_kses_allowed_html('post');
241
        $allowedHtml = [
242
            'a' => glsr_get($allowedHtmlPost, 'a'),
243
            'em' => glsr_get($allowedHtmlPost, 'em'),
244
            'strong' => glsr_get($allowedHtmlPost, 'strong'),
245
        ];
246
        $allowedHtml = glsr()->filterArray('sanitize/allowed-html', $allowedHtml, $this);
247
        return wp_kses(trim(Cast::toString($value)), $allowedHtml);
248
    }
249
250
    /**
251
     * @param mixed $value
252
     * @return string
253
     */
254 16
    public function sanitizeTextMultiline($value)
255
    {
256 16
        return sanitize_textarea_field(trim(Cast::toString($value)));
257
    }
258
259
    /**
260
     * Returns slashed data!
261
     * @param mixed $value
262
     * @return string
263
     */
264
    public function sanitizeTextPost($value)
265
    {
266
        return wp_filter_post_kses(trim(Cast::toString($value)));
267
    }
268
269
    /**
270
     * @param mixed $value
271
     * @return string
272
     */
273 16
    public function sanitizeUrl($value)
274
    {
275 16
        $value = trim(Cast::toString($value));
276 16
        if (!Str::startsWith('http://, https://', $value)) {
277 16
            $value = Str::prefix($value, 'https://');
278
        }
279 16
        $url = esc_url_raw($value);
280 16
        if (mb_strtolower($value) === mb_strtolower($url) && filter_var($url, FILTER_VALIDATE_URL) !== false) {
281 15
            return $url;
282
        }
283 16
        return '';
284
    }
285
286
    /**
287
     * @param mixed $value
288
     * @return string
289
     */
290 15
    public function sanitizeUserEmail($value)
291
    {
292 15
        $user = wp_get_current_user();
293 15
        $value = $this->sanitizeEmail($value);
294 15
        if ($user->exists() && !glsr()->retrieveAs('bool', 'import', false)) {
295 2
            return Helper::ifEmpty($value, $user->user_email);
296
        }
297 15
        return $value;
298
    }
299
300
    /**
301
     * @param mixed $value
302
     * @return int
303
     */
304 15
    public function sanitizeUserId($value)
305
    {
306 15
        $user = get_user_by('ID', Cast::toInt($value));
307 15
        if (false !== $user) {
308 2
            return (int) $user->ID;
309
        }
310 15
        if (glsr()->retrieveAs('bool', 'import', false)) {
311
            return 0;
312
        }
313 15
        return get_current_user_id();
314
    }
315
316
    /**
317
     * @param mixed $value
318
     * @return int[]
319
     */
320 24
    public function sanitizeUserIds($value)
321
    {
322 24
        $userIds = Cast::toArray($value);
323 24
        $userIds = array_map('\GeminiLabs\SiteReviews\Helper::getUserId', $userIds);
324 24
        return Arr::uniqueInt($userIds);
325
    }
326
327
    /**
328
     * @param mixed $value
329
     * @return string
330
     */
331 15
    public function sanitizeUserName($value)
332
    {
333 15
        $user = wp_get_current_user();
334 15
        $value = $this->sanitizeText($value);
335 15
        if ($user->exists() && !glsr()->retrieveAs('bool', 'import', false)) {
336 2
            return Helper::ifEmpty($value, $user->display_name);
337
        }
338 15
        return $value;
339
    }
340
341
    /**
342
     * @return array
343
     */
344 40
    protected function buildSanitizers(array $sanitizers)
345
    {
346 40
        foreach ($sanitizers as $key => &$type) {
347 40
            $method = Helper::buildMethodName($type, 'sanitize');
348 40
            $type = method_exists($this, $method)
349 40
                ? $method
350 40
                : 'sanitizeText';
351
        }
352 40
        return $sanitizers;
353
    }
354
}
355