Completed
Push — master ( ff13dd...500912 )
by Jared
02:35
created

Errors::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * @author Jared King <[email protected]>
5
 *
6
 * @link http://jaredtking.com
7
 *
8
 * @copyright 2015 Jared King
9
 * @license MIT
10
 */
11
namespace Pulsar;
12
13
use ArrayAccess;
14
use ArrayIterator;
15
use Countable;
16
use IteratorAggregate;
17
use Infuse\Locale;
18
19
class Errors implements IteratorAggregate, Countable, ArrayAccess
20
{
21
    /**
22
     * @var array
23
     */
24
    private $stack = [];
25
26
    /**
27
     * @var Model
28
     */
29
    private $model;
30
31
    /**
32
     * @var Locale
33
     */
34
    private $locale;
35
36
    /**
37
     * @var int
38
     */
39
    private $pointer = 0;
0 ignored issues
show
Unused Code introduced by
The property $pointer is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
40
41
    /**
42
     * @param string $model class name of model
43
     *
44
     * @var Locale
45
     */
46
    public function __construct($model, Locale $locale = null)
47
    {
48
        if (!$locale) {
49
            $locale = new Locale();
50
        }
51
52
        $this->locale = $locale;
53
        $this->model = $model;
0 ignored issues
show
Documentation Bug introduced by
It seems like $model of type string is incompatible with the declared type object<Pulsar\Model> of property $model.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
54
    }
55
56
    /**
57
     * Gets the locale instance.
58
     *
59
     * @return Locale
60
     */
61
    public function getLocale()
62
    {
63
        return $this->locale;
64
    }
65
66
    /**
67
     * Adds an error message to the stack.
68
     *
69
     * @param string $property name of property the error is about
70
     * @param string $error    error code or message
71
     *
72
     * @return self
73
     */
74
    public function add($property, $error)
75
    {
76
        if (!isset($this->stack[$property])) {
77
            $this->stack[$property] = [];
78
        }
79
80
        $this->stack[$property][] = $error;
81
82
        return $this;
83
    }
84
85
    /**
86
     * Gets all of the errors on the stack and also attempts
87
     * translation using the Locale class.
88
     *
89
     * @param string|false $property property to filter by
90
     * @param string|false $locale   locale name to translate to
91
     *
92
     * @return array errors
93
     */
94
    public function all($property = false, $locale = false)
95
    {
96
        $errors = $this->stack;
97
        if ($property) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $property of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
98
            if (!isset($errors[$property])) {
99
                return [];
100
            }
101
102
            $errors = [$property => $this->stack[$property]];
103
        }
104
105
        // convert errors into messages
106
        $messages = [];
107
        foreach ($errors as $property => $errors2) {
108
            foreach ($errors2 as $error) {
109
                $messages[] = $this->parse($property, $error, $locale);
110
            }
111
        }
112
113
        return $messages;
114
    }
115
116
    /**
117
     * Checks if a property has an error.
118
     *
119
     * @param string $property
120
     *
121
     * @return bool
122
     */
123
    public function has($property)
124
    {
125
        return isset($this->stack[$property]);
126
    }
127
128
    /**
129
     * Clears all errors.
130
     *
131
     * @return self
132
     */
133
    public function clear()
134
    {
135
        $this->stack = [];
136
137
        return $this;
138
    }
139
140
    /**
141
     * Parses an error message before displaying it.
142
     *
143
     * @param string       $property
144
     * @param string       $error
145
     * @param string|false $locale
146
     *
147
     * @return array
148
     */
149
    private function parse($property, $error, $locale)
150
    {
151
        $model = $this->model;
152
153
        $parameters = [
154
            'property' => $model::getPropertyTitle($property),
155
        ];
156
157
        return $this->locale->t($error, $parameters, $locale);
0 ignored issues
show
Bug introduced by
It seems like $locale defined by parameter $locale on line 149 can also be of type string; however, Infuse\Locale::t() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
158
    }
159
160
    //////////////////////////
161
    // IteratorAggregate Interface
162
    //////////////////////////
163
164
    public function getIterator()
165
    {
166
        return new ArrayIterator($this->stack);
167
    }
168
169
    //////////////////////////
170
    // Countable Interface
171
    //////////////////////////
172
173
    /**
174
     * Get total number of errors.
175
     *
176
     * @return int
177
     */
178
    public function count()
179
    {
180
        return count($this->all());
181
    }
182
183
    /////////////////////////////
184
    // ArrayAccess Interface
185
    /////////////////////////////
186
187
    public function offsetExists($offset)
188
    {
189
        return $this->has($offset);
190
    }
191
192
    public function offsetGet($offset)
193
    {
194
        return $this->all($offset);
195
    }
196
197
    public function offsetSet($offset, $error)
198
    {
199
        $this->add($offset, $error);
200
    }
201
202
    public function offsetUnset($offset)
203
    {
204
        if ($this->has($offset)) {
205
            unset($this->stack[$offset]);
206
        }
207
    }
208
}
209