Completed
Push — master ( 9e9970...97ce03 )
by Oleg
03:21
created

Validator::run()   D

Complexity

Conditions 9
Paths 9

Size

Total Lines 38
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 1
Metric Value
c 5
b 0
f 1
dl 0
loc 38
rs 4.9091
cc 9
eloc 23
nc 9
nop 2
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
                return call_user_func([$model,$name], $this);
92
            } else {
93
                throw new Exception('Validator ' . $name . ' not defined.');
94
            }
95
        }
96
97
        /** @var IValidator $valid */
98
        $valid = new $className(['container' => $this->container, 'params' => $this->rule]);
99
        $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...
100
101
        if ($client && method_exists($valid, 'client')) {
102
            $result = $this->clientValidate($valid, $model);
103
        } else {
104
            $result = $valid->validate($model);
105
        }
106
107
        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...
108
            $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...
109
        }
110
111
        return $result;
112
    }
113
114
    /**
115
     * @param $name
116
     * @return bool|string
117
     */
118
    protected function getValidatorClass($name)
119
    {
120
        if (!empty(self::$validators[$name])) {
121
            return '\\Micro\\validator\\' . self::$validators[$name];
122
        } elseif (class_exists($name) && is_subclass_of($name, '\Micro\validator\IValidator')) {
123
            return $name;
124
        } 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...
125
            return '\\App\\validator\\' . $name;
126
        }
127
128
        return false;
129
    }
130
131
    /**
132
     * Client validation making
133
     *
134
     * @access public
135
     *
136
     * @param IValidator $validator
137
     * @param IFormModel $model
138
     *
139
     * @return string
140
     */
141
    public function clientValidate(IValidator $validator, IFormModel $model)
142
    {
143
        $object = substr(get_class($model), strrpos(get_class($model), '\\') + 1);
144
145
        $result = null;
146
        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...
147
            $id = $object . '_' . $element;
148
            /** @noinspection PhpUndefinedMethodInspection */
149
            $result .= 'jQuery("#' . $id . '").bind("change blur submit", function(e){ ';
150
            /** @noinspection DisconnectedForeachInstructionInspection */
151
            $result .= $validator->client($model);
152
            $result .= ' });';
153
        }
154
155
        return $result;
156
    }
157
158
    /**
159
     * Get errors after run validation
160
     *
161
     * @access public
162
     * @return array
163
     */
164
    public function getErrors()
165
    {
166
        return $this->errors;
167
    }
168
169
    /**
170
     * Check is empty property
171
     *
172
     * @access protected
173
     *
174
     * @param mixed $value check value is empty
175
     * @param bool $trim run trim?
176
     *
177
     * @return bool
178
     */
179
    protected function isEmpty($value, $trim = false)
180
    {
181
        return $value === null || $value === [] || $value === '' || $trim && is_scalar($value) && trim($value) === '';
182
    }
183
}
184