Completed
Push — master ( 8f5c3e...5c04e2 )
by Jared
01:39
created

Errors::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * @author Jared King <[email protected]>
5
 *
6
 * @see http://jaredtking.com
7
 *
8
 * @copyright 2015 Jared King
9
 * @license MIT
10
 */
11
12
namespace Pulsar;
13
14
use ArrayAccess;
15
use ArrayIterator;
16
use Countable;
17
use Infuse\Locale;
18
use IteratorAggregate;
19
20
/**
21
 * Holds error messages generated by models, like validation errors.
22
 */
23
class Errors implements IteratorAggregate, Countable, ArrayAccess
24
{
25
    /**
26
     * @var array
27
     */
28
    private static $messages = [
29
        'pulsar.validation.alpha' => '{{field_name}} only allows letters',
30
        'pulsar.validation.alpha_numeric' => '{{field_name}} only allows letters and numbers',
31
        'pulsar.validation.alpha_dash' => '{{field_name}} only allows letters and dashes',
32
        'pulsar.validation.boolean' => '{{field_name}} must be yes or no',
33
        'pulsar.validation.custom' => '{{field_name}} validation failed',
34
        'pulsar.validation.email' => '{{field_name}} must be a valid email address',
35
        'pulsar.validation.enum' => '{{field_name}} must be one of the allowed values',
36
        'pulsar.validation.date' => '{{field_name}} must be a date',
37
        'pulsar.validation.failed' => '{{field_name}} is invalid',
38
        'pulsar.validation.ip' => '{{field_name}} only allows valid IP addresses',
39
        'pulsar.validation.matching' => '{{field_name}} must match',
40
        'pulsar.validation.numeric' => '{{field_name}} only allows numbers',
41
        'pulsar.validation.password' => '{{field_name}} must meet the password requirements',
42
        'pulsar.validation.range' => '{{field_name}} must be within the allowed range',
43
        'pulsar.validation.required' => '{{field_name}} is missing',
44
        'pulsar.validation.string' => '{{field_name}} must be a string of the proper length',
45
        'pulsar.validation.time_zone' => '{{field_name}} only allows valid time zones',
46
        'pulsar.validation.timestamp' => '{{field_name}} only allows timestamps',
47
        'pulsar.validation.unique' => 'The {{field_name}} you chose has already been taken. Please try a different {{field_name}}.',
48
        'pulsar.validation.url' => '{{field_name}} only allows valid URLs',
49
    ];
50
51
    /**
52
     * @var array
53
     */
54
    private $stack = [];
55
56
    /**
57
     * @var Locale|null
58
     */
59
    private $locale;
60
61
    /**
62
     * Sets the locale service.
63
     *
64
     * @param Locale $locale
65
     *
66
     * @return self
67
     */
68
    public function setLocale(Locale $locale)
69
    {
70
        $this->locale = $locale;
71
72
        return $this;
73
    }
74
75
    /**
76
     * Gets the locale service.
77
     *
78
     * @return Locale
79
     */
80
    public function getLocale()
81
    {
82
        if (!$this->locale) {
83
            $this->locale = new Locale();
84
        }
85
86
        return $this->locale;
87
    }
88
89
    /**
90
     * Adds an error message to the stack.
91
     *
92
     * @param $error
93
     * @param array $parameters
94
     *
95
     * @return $this
96
     */
97
    public function add($error, array $parameters = [])
98
    {
99
        $this->stack[] = [
100
            'error' => $error,
101
            'params' => $parameters,
102
        ];
103
104
        return $this;
105
    }
106
107
    /**
108
     * @deprecated
109
     *
110
     * Adds an error message to the stack
111
     *
112
     * @param array|string $error
113
     *                            - error: error code
114
     *                            - params: array of parameters to be passed to message
115
     *
116
     * @return self
117
     */
118
    public function push($error)
119
    {
120
        $this->stack[] = $this->sanitize($error);
121
122
        return $this;
123
    }
124
125
    /**
126
     * Gets all of the errors on the stack and also attempts
127
     * translation using the Locale class.
128
     *
129
     * @param string $locale optional locale
130
     *
131
     * @return array error messages
132
     */
133
    public function all($locale = '')
134
    {
135
        $messages = [];
136
        foreach ($this->stack as $error) {
137
            $messages[] = $this->parse($error['error'], $locale, $error['params']);
138
        }
139
140
        return $messages;
141
    }
142
143
    /**
144
     * @deprecated
145
     *
146
     * Gets all of the errors on the stack and also attempts
147
     * translation using the Locale class
148
     *
149
     * @param string $locale optional locale
150
     *
151
     * @return array errors
152
     */
153
    public function errors($locale = '')
0 ignored issues
show
Coding Style Best Practice introduced by
Please use __construct() instead of a PHP4-style constructor that is named after the class.
Loading history...
154
    {
155
        $errors = [];
156
        foreach ($this->stack as $error) {
157
            if (!isset($error['message'])) {
158
                $error['message'] = $this->parse($error['error'], $locale, $error['params']);
159
            }
160
161
            $errors[] = $error;
162
        }
163
164
        return $errors;
165
    }
166
167
    /**
168
     * @deprecated
169
     *
170
     * Gets the messages of errors on the stack
171
     *
172
     * @param string $locale optional locale
173
     *
174
     * @return array errors
175
     */
176
    public function messages($locale = '')
177
    {
178
        return $this->all($locale);
179
    }
180
181
    /**
182
     * Gets an error for a specific parameter on the stack.
183
     *
184
     * @param string $value value we are searching for
185
     * @param string $param parameter name
186
     *
187
     * @return array|bool
188
     */
189
    public function find($value, $param = 'field')
190
    {
191
        foreach ($this->errors() as $error) {
0 ignored issues
show
Deprecated Code introduced by
The method Pulsar\Errors::errors() has been deprecated with message: Gets all of the errors on the stack and also attempts
translation using the Locale class

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
192
            if (array_value($error['params'], $param) === $value) {
193
                return $error;
194
            }
195
        }
196
197
        return false;
198
    }
199
200
    /**
201
     * Checks if an error exists with a specific parameter on the stack.
202
     *
203
     * @param string $value value we are searching for
204
     * @param string $param parameter name
205
     *
206
     * @return bool
207
     */
208
    public function has($value, $param = 'field')
209
    {
210
        return $this->find($value, $param) !== false;
211
    }
212
213
    /**
214
     * Clears the error stack.
215
     *
216
     * @return self
217
     */
218
    public function clear()
219
    {
220
        $this->stack = [];
221
222
        return $this;
223
    }
224
225
    /**
226
     * Formats an incoming error message.
227
     *
228
     * @param array|string $error
229
     *
230
     * @return array
231
     */
232
    private function sanitize($error)
233
    {
234
        if (!is_array($error)) {
235
            $error = ['error' => $error];
236
        }
237
238
        if (!isset($error['params'])) {
239
            $error['params'] = [];
240
        }
241
242
        return $error;
243
    }
244
245
    /**
246
     * Parses an error message before displaying it.
247
     *
248
     * @param string       $error
249
     * @param string|false $locale
250
     * @param array        $parameters
251
     *
252
     * @return string
253
     */
254
    private function parse($error, $locale, array $parameters)
255
    {
256
        // try to supply a fallback message in case
257
        // the user does not have one specified
258
        $fallback = array_value(self::$messages, $error);
259
260
        return $this->getLocale()->t($error, $parameters, $locale, $fallback);
261
    }
262
263
    //////////////////////////
264
    // IteratorAggregate Interface
265
    //////////////////////////
266
267
    public function getIterator()
268
    {
269
        return new ArrayIterator($this->stack);
270
    }
271
272
    //////////////////////////
273
    // Countable Interface
274
    //////////////////////////
275
276
    /**
277
     * Get total number of models matching query.
278
     *
279
     * @return int
280
     */
281
    public function count()
282
    {
283
        return count($this->stack);
284
    }
285
286
    /////////////////////////////
287
    // ArrayAccess Interface
288
    /////////////////////////////
289
290
    public function offsetExists($offset)
291
    {
292
        return isset($this->stack[$offset]);
293
    }
294
295
    public function offsetGet($offset)
296
    {
297
        if (!$this->offsetExists($offset)) {
298
            throw new \OutOfBoundsException("$offset does not exist on this ErrorStack");
299
        }
300
301
        return $this->stack[$offset];
302
    }
303
304
    public function offsetSet($offset, $error)
305
    {
306
        if (!is_numeric($offset)) {
307
            throw new \Exception('Can only perform set on numeric indices');
308
        }
309
310
        $this->stack[$offset] = $this->sanitize($error);
311
    }
312
313
    public function offsetUnset($offset)
314
    {
315
        unset($this->stack[$offset]);
316
    }
317
}
318