Completed
Push — master ( 97ce03...3c04c2 )
by Oleg
03:16
created

Validator::run()   C

Complexity

Conditions 12
Paths 11

Size

Total Lines 44
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 1
Metric Value
c 6
b 0
f 1
dl 0
loc 44
rs 5.1612
cc 12
eloc 26
nc 11
nop 2

How to fix   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 /** MicroValidator */
2
3
namespace Micro\validator;
4
5
use Micro\base\Exception;
6
use Micro\base\IContainer;
7
use Micro\form\IFormModel;
8
9
/**
10
 * Validator is a runner validation process
11
 *
12
 * @author Oleg Lunegov <[email protected]>
13
 * @link https://github.com/lugnsk/micro
14
 * @copyright Copyright &copy; 2013 Oleg Lunegov
15
 * @license /LICENSE
16
 * @package micro
17
 * @subpackage
18
 * @version 1.0
19
 * @since 1.0
20
 */
21
class Validator
22
{
23
    /** @var array $validators supported validations */
24
    protected static $validators = [
25
        'required' => 'RequiredValidator',
26
        'captcha' => 'CaptchaValidator',
27
        'boolean' => 'BooleanValidator',
28
        'compare' => 'CompareValidator',
29
        'string' => 'StringValidator',
30
        'regexp' => 'RegexpValidator',
31
        'number' => 'NumberValidator',
32
        'unique' => 'UniqueValidator',
33
        'range' => 'RangeValidator',
34
        'email' => 'EmailValidator',
35
        'url' => 'UrlValidator',
36
        'file' => 'FileValidator'
37
    ];
38
    /** @var array $errors errors summary */
39
    public $errors = [];
40
    /** @var array $elements validation elements */
41
    public $elements = [];
42
    /** @var array $params validation parameters */
43
    public $params = [];
44
    /** @var IContainer $container Container */
45
    protected $container;
46
    /** @var array $rule current rule */
47
    protected $rule = [];
48
49
    /**
50
     * Constructor validator object
51
     *
52
     * @access public
53
     *
54
     * @param array $params configuration array
55
     *
56
     * @result void
57
     */
58
    public function __construct(array $params)
59
    {
60
        $this->container = $params['container'];
61
        $this->rule = $params['rule'];
62
    }
63
64
    /**
65
     * Running validation process
66
     *
67
     * @access public
68
     *
69
     * @param IFormModel $model model
70
     * @param bool $client run on client side?
71
     *
72
     * @return bool|string
73
     * @throws Exception
74
     */
75
    public function run($model, $client = false)
76
    {
77
        $elements = explode(',', str_replace(' ', '', array_shift($this->rule)));
78
        $name = array_shift($this->rule);
79
80
        $className = $this->getValidatorClass($name);
81
        if (!$className) {
82
            if (function_exists($name)) {
83
                foreach ($elements AS $element) {
84
                    if (property_exists($model, $element)) {
85
                        $model->$element = call_user_func($name, $model->$element);
86
                    }
87
                }
88
89
                return true;
90
            } elseif (method_exists($model, $name)) {
91
                foreach ($elements AS $element) {
92
                    if (property_exists($model, $element) && !call_user_func([$model, $name], $element)) {
93
                        return false;
94
                    }
95
                }
96
97
                return true;
98
            } else {
99
                throw new Exception('Validator ' . $name . ' not defined.');
100
            }
101
        }
102
103
        /** @var IValidator $valid */
104
        $valid = new $className(['container' => $this->container, 'params' => $this->rule]);
105
        $valid->elements = $elements;
0 ignored issues
show
Bug introduced by
Accessing elements on the interface Micro\validator\IValidator suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
106
107
        if ($client && method_exists($valid, 'client')) {
108
            $result = $this->clientValidate($valid, $model);
109
        } else {
110
            $result = $valid->validate($model);
111
        }
112
113
        if ($valid->errors) {
0 ignored issues
show
Bug introduced by
Accessing errors on the interface Micro\validator\IValidator suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
114
            $this->errors[] = $valid->errors;
0 ignored issues
show
Bug introduced by
Accessing errors on the interface Micro\validator\IValidator suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
115
        }
116
117
        return $result;
118
    }
119
120
    /**
121
     * @param $name
122
     * @return bool|string
123
     */
124
    protected function getValidatorClass($name)
125
    {
126
        if (!empty(self::$validators[$name])) {
127
            return '\\Micro\\validator\\' . self::$validators[$name];
128
        } elseif (class_exists($name) && is_subclass_of($name, '\Micro\validator\IValidator')) {
129
            return $name;
130
        } elseif (file_exists($this->container->kernel->getAppDir() . '/validator/' . $name . '.php')) {
0 ignored issues
show
Bug introduced by
Accessing kernel on the interface Micro\base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
131
            return '\\App\\validator\\' . $name;
132
        }
133
134
        return false;
135
    }
136
137
    /**
138
     * Client validation making
139
     *
140
     * @access public
141
     *
142
     * @param IValidator $validator
143
     * @param IFormModel $model
144
     *
145
     * @return string
146
     */
147
    public function clientValidate(IValidator $validator, IFormModel $model)
148
    {
149
        $object = substr(get_class($model), strrpos(get_class($model), '\\') + 1);
150
151
        $result = null;
152
        foreach ($validator->elements AS $element) {
0 ignored issues
show
Bug introduced by
Accessing elements on the interface Micro\validator\IValidator suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
153
            $id = $object . '_' . $element;
154
            /** @noinspection PhpUndefinedMethodInspection */
155
            $result .= 'jQuery("#' . $id . '").bind("change blur submit", function(e){ ';
156
            /** @noinspection DisconnectedForeachInstructionInspection */
157
            $result .= $validator->client($model);
158
            $result .= ' });';
159
        }
160
161
        return $result;
162
    }
163
164
    /**
165
     * Get errors after run validation
166
     *
167
     * @access public
168
     * @return array
169
     */
170
    public function getErrors()
171
    {
172
        return $this->errors;
173
    }
174
175
    /**
176
     * Check is empty property
177
     *
178
     * @access protected
179
     *
180
     * @param mixed $value check value is empty
181
     * @param bool $trim run trim?
182
     *
183
     * @return bool
184
     */
185
    protected function isEmpty($value, $trim = false)
186
    {
187
        return $value === null || $value === [] || $value === '' || $trim && is_scalar($value) && trim($value) === '';
188
    }
189
}
190