NumberValidator::validate()   F
last analyzed

Complexity

Conditions 27
Paths 261

Size

Total Lines 82
Code Lines 53

Duplication

Lines 8
Ratio 9.76 %

Importance

Changes 0
Metric Value
cc 27
eloc 53
nc 261
nop 0
dl 8
loc 82
rs 3.7724
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
namespace Agavi\Validator;
3
4
// +---------------------------------------------------------------------------+
5
// | This file is part of the Agavi package.                                   |
6
// | Copyright (c) 2005-2011 the Agavi Project.                                |
7
// |                                                                           |
8
// | For the full copyright and license information, please view the LICENSE   |
9
// | file that was distributed with this source code. You can also view the    |
10
// | LICENSE file online at http://www.agavi.org/LICENSE.txt                   |
11
// |   vi: set noexpandtab:                                                    |
12
// |   Local Variables:                                                        |
13
// |   indent-tabs-mode: t                                                     |
14
// |   End:                                                                    |
15
// +---------------------------------------------------------------------------+
16
use Agavi\Config\Config;
17
use Agavi\Util\DecimalFormatter;
18
19
/**
20
 * NumberValidator verifies that a parameter is a number and allows you to
21
 * apply size constraints.
22
 *
23
 * Parameters:
24
 *   'no_locale' do not use localized number format parsing with translation on
25
 *   'in_locale' locale to use for parsing rather than the current locale
26
 *   'type'      number type (int/integer or double/float)
27
 *   'cast_to'   type to cast to (int/integer or double/float)
28
 *   'min'       minimum value for the input
29
 *   'max'       maximum value for the input
30
 *
31
 * @package    agavi
32
 * @subpackage validator
33
 *
34
 * @author     Dominik del Bondio <[email protected]>
35
 * @copyright  Authors
36
 * @copyright  The Agavi Project
37
 *
38
 * @since      0.11.0
39
 *
40
 * @version    $Id$
41
 */
42
class NumberValidator extends Validator
43
{
44
    /**
45
     * Validates the input
46
     *
47
     * @return     bool The input is valid number according to given parameters.
48
     *
49
     * @author     Dominik del Bondio <[email protected]>
50
     * @author     David Zülke <[email protected]>
51
     * @since      0.11.0
52
     */
53
    protected function validate()
54
    {
55
        $value =& $this->getData($this->getArgument());
56
57
        if (!is_scalar($value)) {
58
            // non scalar values would cause notices
59
            $this->throwError();
60
            return false;
61
        }
62
63
        $hasExtraChars = false;
64
        if (!is_int($value) && !is_float($value)) {
65
            $locale = null;
66
            if (Config::get('core.use_translation') && !$this->getParameter('no_locale', false)) {
67
                if ($locale = $this->getParameter('in_locale')) {
68
                    $locale = $this->getContext()->getTranslationManager()->getLocale($locale);
69
                } else {
70
                    $locale = $this->getContext()->getTranslationManager()->getCurrentLocale();
71
                }
72
            }
73
            
74
            $parsedValue = DecimalFormatter::parse($value, $locale, $hasExtraChars);
0 ignored issues
show
Documentation introduced by
$value is of type string|boolean, but the function expects a object<Agavi\Util\The>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
It seems like $locale can also be of type object<Agavi\Translation\Locale>; however, Agavi\Util\DecimalFormatter::parse() does only seem to accept object<Agavi\Util\An>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
75
        } else {
76
            $parsedValue = $value;
77
        }
78
        
79
        switch (strtolower($this->getParameter('type'))) {
80
            case 'int':
81
            case 'integer':
82
                if (!is_int($parsedValue) || $hasExtraChars) {
83
                    $this->throwError('type');
84
                    return false;
85
                }
86
                
87
                break;
88
            
89
            case 'float':
90
            case 'double':
91
                if ((!is_float($parsedValue) && !is_int($parsedValue)) || $hasExtraChars) {
92
                    $this->throwError('type');
93
                    return false;
94
                }
95
                
96
                break;
97
            
98
            default:
99
                if ($parsedValue === false || $hasExtraChars) {
100
                    $this->throwError('type');
101
                    return false;
102
                }
103
        }
104
105 View Code Duplication
        if ($this->hasParameter('min') && $parsedValue < $this->getParameter('min')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
106
            $this->throwError('min');
107
            return false;
108
        }
109
110 View Code Duplication
        if ($this->hasParameter('max') && $parsedValue > $this->getParameter('max')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
111
            $this->throwError('max');
112
            return false;
113
        }
114
        
115
        switch (strtolower($this->getParameter('cast_to', $this->getParameter('type')))) {
116
            case 'int':
117
            case 'integer':
118
                $parsedValue = (int) $parsedValue;
119
                break;
120
            
121
            case 'float':
122
            case 'double':
123
                $parsedValue = (float) $parsedValue;
124
                break;
125
        }
126
127
        if ($this->hasParameter('export')) {
128
            $this->export($parsedValue);
129
        } else {
130
            $value = $parsedValue;
131
        }
132
        
133
        return true;
134
    }
135
}
136