Completed
Push — master ( c61969...df1bf5 )
by Marcus
02:35
created

FloatVal::__invoke()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 57
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 57
c 0
b 0
f 0
ccs 26
cts 26
cp 1
rs 8.7433
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
namespace Mbright\Validation\Rule\Sanitize;
4
5
class FloatVal
6
{
7
    /**
8
     * Forces the value to a float.
9
     *
10
     * Attempts to extract a valid float from the given value, using an
11
     * algorithm somewhat less naive that "remove all characters that are not
12
     * '0-9.,eE+-'".  The result may not be expected, but it will be a float.
13
     *
14
     * @param object $subject The subject to be filtered.
15
     * @param string $field The subject field name.
16
     *
17
     * @return bool True if the value was sanitized, false if not.
18
     */
19 15
    public function __invoke($subject, string $field): bool
20
    {
21 15
        $value = $subject->$field;
22
23 15
        if (is_float($value)) {
24 3
            return true;
25
        }
26
27 12
        if (is_numeric($value)) {
28 3
            $subject->$field = (float) $value;
29
30 3
            return true;
31
        }
32
33 9
        if (!is_string($value)) {
34 3
            return false;
35
        }
36
37
        // it's a non-numeric string, attempt to extract a float from it.
38
        // remove all + signs; any - sign takes precedence because ...
39
        //     0 + -1 = -1
40
        //     0 - +1 = -1
41
        // ... at least it seems that way to me now.
42 6
        $value = str_replace('+', '', $value);
43
44
        // reduce multiple decimals and minuses
45 6
        $value = preg_replace('/[\.-]{2,}/', '.', $value);
46
47
        // remove all decimals without a digit or minus next to them
48 6
        $value = preg_replace('/([^0-9-]\.[^0-9])/', '', $value);
49
50
        // remove all chars except digit, decimal, and minus
51 6
        $value = preg_replace('/[^0-9\.-]/', '', $value);
52
53
        // remove all trailing decimals and minuses
54 6
        $value = rtrim($value, '.-');
55
56
        // remove all minuses not at the front
57 6
        $is_negative = ($value[0] == '-');
58 6
        $value = str_replace('-', '', $value);
59 6
        if ($is_negative) {
60 3
            $value = '-' . $value;
61
        }
62
63
        // remove all decimals but the first
64 6
        $pos = strpos($value, '.');
65 6
        $value = str_replace('.', '', $value);
66 6
        if ($pos !== false) {
67 6
            $value = substr($value, 0, $pos)
68 6
                . '.'
69 6
                . substr($value, $pos);
70
        }
71
72 6
        $subject->$field = (float) $value;
73
74 6
        return true;
75
    }
76
}
77