Integer::__invoke()   B
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 41
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 41
ccs 16
cts 16
cp 1
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 16
nc 4
nop 2
crap 4
1
<?php
2
/**
3
 *
4
 * This file is part of Aura for PHP.
5
 *
6
 * @license http://opensource.org/licenses/bsd-license.php BSD
7
 *
8
 */
9
namespace Aura\Filter\Rule\Sanitize;
10
11
/**
12
 *
13
 * Forces the value to an integer.
14
 *
15
 * @package Aura.Filter
16
 *
17
 */
18
class Integer
19
{
20
    /**
21
     *
22
     * Forces the value to an integer.
23
     *
24
     * Attempts to extract a valid integer from the given value, using an
25
     * algorithm somewhat less naive that "remove all characters that are not
26
     * '0-9+-'".  The result may not be expected, but it will be a integer.
27
     *
28
     * @param object $subject The subject to be filtered.
29
     *
30
     * @param string $field The subject field name.
31
     *
32
     * @return bool True if the value was sanitized, false if not.
33
     *
34
     */
35 6
    public function __invoke($subject, $field)
36
    {
37 6
        $value = $subject->$field;
38
39
        // sanitize numerics
40 6
        if (is_numeric($value)) {
41
            // we double-cast here to honor scientific notation.
42
            // (int) 1E5 == 15, but (int) (float) 1E5 == 100000
43 1
            $value = (float) $value;
44 1
            $subject->$field = (int) $value;
45 1
            return true;
46
        }
47
48 5
        if (! is_string($value)) {
49
            // cannot sanitize a non-string
50 1
            return false;
51
        }
52
53
        // it's a non-numeric string, attempt to extract an integer from it.
54
55
        // remove all chars except digit and minus.
56
        // this removes all + signs; any - sign takes precedence because ...
57
        //     0 + -1 = -1
58
        //     0 - +1 = -1
59
        // ... at least it seems that way to me now.
60 4
        $value = preg_replace('/[^0-9-]/', '', $value);
61
62
        // remove all trailing minuses
63 4
        $value = rtrim($value, '-');
64
65
        // remove all minuses not at the front
66 4
        $is_negative = preg_match('/^-/', $value);
67 4
        $value = str_replace('-', '', $value);
68 4
        if ($is_negative) {
69 1
            $value = '-' . $value;
70
        }
71
72
        // looks like we're done
73 4
        $subject->$field = (int) $value;
74 4
        return true;
75
    }
76
}
77