Double::__invoke()   B
last analyzed

Complexity

Conditions 6
Paths 7

Size

Total Lines 59
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 59
ccs 26
cts 26
cp 1
rs 8.7117
c 0
b 0
f 0
cc 6
eloc 26
nc 7
nop 2
crap 6

How to fix   Long Method   

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
 *
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 a float.
14
 *
15
 * @package Aura.Filter
16
 *
17
 */
18
class Double
19
{
20
    /**
21
     *
22
     * Forces the value to a float.
23
     *
24
     * Attempts to extract a valid float from the given value, using an
25
     * algorithm somewhat less naive that "remove all characters that are not
26
     * '0-9.,eE+-'".  The result may not be expected, but it will be a float.
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
     * @todo Extract scientific notation from weird strings?
35
     *
36
     */
37 5
    public function __invoke($subject, $field)
38
    {
39 5
        $value = $subject->$field;
40
41 5
        if (is_float($value)) {
42
            // already a float, nothing to do
43 1
            return true;
44
        }
45
46 4
        if (is_numeric($value)) {
47
            // numeric string, cast to a float
48 1
            $subject->$field = (float) $value;
49 1
            return true;
50
        }
51
52 3
        if (! is_string($value)) {
53
            // not a string, cannot sanitize
54 1
            return false;
55
        }
56
57
        // it's a non-numeric string, attempt to extract a float from it.
58
        // remove all + signs; any - sign takes precedence because ...
59
        //     0 + -1 = -1
60
        //     0 - +1 = -1
61
        // ... at least it seems that way to me now.
62 2
        $value = str_replace('+', '', $value);
63
64
        // reduce multiple decimals and minuses
65 2
        $value = preg_replace('/[\.-]{2,}/', '.', $value);
66
67
        // remove all decimals without a digit or minus next to them
68 2
        $value = preg_replace('/([^0-9-]\.[^0-9])/', '', $value);
69
70
        // remove all chars except digit, decimal, and minus
71 2
        $value = preg_replace('/[^0-9\.-]/', '', $value);
72
73
        // remove all trailing decimals and minuses
74 2
        $value = rtrim($value, '.-');
75
76
        // remove all minuses not at the front
77 2
        $is_negative = ($value[0] == '-');
78 2
        $value = str_replace('-', '', $value);
79 2
        if ($is_negative) {
80 1
            $value = '-' . $value;
81
        }
82
83
        // remove all decimals but the first
84 2
        $pos = strpos($value, '.');
85 2
        $value = str_replace('.', '', $value);
86 2
        if ($pos !== false) {
87 2
            $value = substr($value, 0, $pos)
88 2
                   . '.'
89 2
                   . substr($value, $pos);
90
        }
91
92
        // done
93 2
        $subject->$field = (float) $value;
94 2
        return true;
95
    }
96
}
97