RecordValidator   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 62
c 0
b 0
f 0
dl 0
loc 150
ccs 60
cts 60
cp 1
rs 10
wmc 29

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getErrors() 0 8 3
A hasErrors() 0 8 3
A resolveValue() 0 9 2
C validate() 0 59 12
A __construct() 0 14 3
A resetErrors() 0 3 1
A trimArray() 0 7 4
A addError() 0 3 1
1
<?php
2
/**
3
 * This file is part of the Divergence package.
4
 *
5
 * (c) Henry Paradiz <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Divergence\Models;
12
13
use Exception;
14
15
use Divergence\Helpers\Validate;
16
17
/**
18
 * RecordValidator.
19
 *
20
 * @package Divergence
21
 * @author  Henry Paradiz <[email protected]>
22
 * @author  Chris Alfano <[email protected]>
23
 *
24
 */
25
class RecordValidator
26
{
27
    // configurables
28
    public static $autoTrim = true;
29
30
    // protected properties
31
    protected $_record;
32
    protected $_errors = [];
33
34
35
    // magic methods
36 44
    public function __construct(&$record, $autoTrim = null)
37
    {
38
        //init autoTrim option to static default
39 44
        if (!isset($autoTrim)) {
40 44
            $autoTrim = self::$autoTrim;
41
        }
42
43
        // apply autotrim
44 44
        if ($autoTrim) {
45 44
            self::trimArray($record);
46
        }
47
48
        // store record
49 44
        $this->_record = &$record;
50
    }
51
52
53
    // public instance methods
54 6
    public function resetErrors()
55
    {
56 6
        $this->_errors = [];
57
    }
58
59 21
    public function getErrors($id = false)
60
    {
61 21
        if ($id === false) {
62 21
            return $this->_errors;
63 2
        } elseif (array_key_exists($id, $this->_errors)) {
64 2
            return $this->_errors[$id];
65
        } else {
66 1
            return false;
67
        }
68
    }
69
70
71 21
    public function hasErrors($id = false)
72
    {
73 21
        if ($id === false) {
74 21
            return (count($this->_errors) > 0);
75 1
        } elseif (array_key_exists($id, $this->_errors)) {
76 1
            return true;
77
        } else {
78 1
            return false;
79
        }
80
    }
81
82
83 1
    public function addError($id, $errorMessage)
84
    {
85 1
        $this->_errors[$id] = $errorMessage;
86
    }
87
88
89 22
    public function validate($options)
90
    {
91
        // apply default
92 22
        $options = array_merge([
93 22
            'validator' => 'string',
94 22
            'required' => true,
95 22
        ], $options);
96
97
98
        // check 'field'
99 22
        if (empty($options['field'])) {
100 1
            throw new Exception('Required option "field" missing');
101
        }
102
103
        // check 'id' and default to 'field'
104 21
        if (empty($options['id'])) {
105 21
            $options['id'] = $options['field'];
106
        }
107
108
109
        // get validator
110 21
        if (is_string($options['validator'])) {
111 17
            $validator = [Validate::class, $options['validator']];
112
        } else {
113 4
            $validator = $options['validator'];
114
        }
115
116
        // check validator
117 21
        if (!is_callable($validator)) {
118 1
            throw new Exception('Validator for field ' . $options['id'] . ' is not callable');
119
        }
120
121
122
        // return false if any errors are already registered under 'id'
123 20
        if (array_key_exists($options['id'], $this->_errors)) {
124 1
            return false;
125
        }
126
127
128 20
        $value = $this->resolveValue($options['field']);
129
130
        // skip validation for empty fields that aren't required
131 20
        if (!$options['required'] && empty($value)) {
132 1
            return true;
133
        }
134
135
        // call validator
136 19
        $isValid = call_user_func($validator, $value, $options);
137
138 19
        if ($isValid == false) {
139 11
            if (!empty($options['errorMessage'])) {
140 9
                $this->_errors[$options['id']] = gettext($options['errorMessage']);
141
            } else {
142
                // default 'errorMessage' built from 'id'
143 2
                $this->_errors[$options['id']] = sprintf($options['required'] && empty($value) ? _('%s is missing.') : _('%s is invalid.'), $options['id']);
144
            }
145 11
            return false;
146
        } else {
147 8
            return true;
148
        }
149
    }
150
151
152
153
    // protected instance methods
154 20
    protected function resolveValue($field)
155
    {
156 20
        $cur = &$this->_record;
157 20
        if (array_key_exists($field, $cur)) {
158 18
            $cur = &$cur[$field];
159
        } else {
160 2
            return null;
161
        }
162 18
        return $cur;
163
    }
164
165
166
167
    // protected static methods
168 44
    protected static function trimArray(&$array)
169
    {
170 44
        foreach ($array as &$var) {
171 40
            if (is_string($var)) {
172 33
                $var = trim($var);
173 29
            } elseif (is_array($var)) {
174 14
                self::trimArray($var);
175
            }
176
        }
177
    }
178
}
179