Passed
Pull Request — 4 (#10232)
by Steve
06:54
created

ValidationResult::__serialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\ORM;
4
5
use InvalidArgumentException;
6
use Serializable;
7
use SilverStripe\Core\Convert;
8
use SilverStripe\Core\Injector\Injectable;
9
use SilverStripe\Dev\Deprecation;
10
11
/**
12
 * A class that combined as a boolean result with an optional list of error messages.
13
 * This is used for returning validation results from validators
14
 *
15
 * Each message can have a code or field which will uniquely identify that message. However,
16
 * messages can be stored without a field or message as an "overall" message.
17
 */
18
class ValidationResult implements Serializable
19
{
20
    use Injectable;
21
22
    /**
23
     * Standard "error" type
24
     */
25
    const TYPE_ERROR = 'error';
26
27
    /**
28
     * Standard "good" message type
29
     */
30
    const TYPE_GOOD = 'good';
31
32
    /**
33
     * Non-error message type.
34
     */
35
    const TYPE_INFO = 'info';
36
37
    /**
38
     * Warning message type
39
     */
40
    const TYPE_WARNING = 'warning';
41
42
    /**
43
     * Message type is html
44
     */
45
    const CAST_HTML = 'html';
46
47
    /**
48
     * Message type is plain text
49
     */
50
    const CAST_TEXT = 'text';
51
52
    /**
53
     * Is the result valid or not.
54
     * Note that there can be non-error messages in the list.
55
     *
56
     * @var bool
57
     */
58
    protected $isValid = true;
59
60
    /**
61
     * List of messages
62
     *
63
     * @var array
64
     */
65
    protected $messages = [];
66
67
    /**
68
     * Create a new ValidationResult.
69
     * By default, it is a successful result.   Call $this->error() to record errors.
70
     */
71
    public function __construct()
72
    {
73
        if (func_num_args() > 0) {
74
            Deprecation::notice('3.2', '$valid parameter is deprecated please addError to mark the result as invalid', false);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type integer expected by parameter $scope of SilverStripe\Dev\Deprecation::notice(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

74
            Deprecation::notice('3.2', '$valid parameter is deprecated please addError to mark the result as invalid', /** @scrutinizer ignore-type */ false);
Loading history...
75
            $this->isValid = func_get_arg(0);
76
        }
77
        if (func_num_args() > 1) {
78
            Deprecation::notice('3.2', '$message parameter is deprecated please use addMessage or addError instead', false);
79
            $this->addError(func_get_arg(1));
80
        }
81
    }
82
83
    /**
84
     * Record an error against this validation result,
85
     *
86
     * @param string $message     The message string.
87
     * @param string $messageType Passed as a CSS class to the form, so other values can be used if desired.
88
     * Standard types are defined by the TYPE_ constant definitions.
89
     * @param string $code        A codename for this error. Only one message per codename will be added.
90
     *                            This can be usedful for ensuring no duplicate messages
91
     * @param string|bool $cast Cast type; One of the CAST_ constant definitions.
92
     * Bool values will be treated as plain text flag.
93
     * @return $this
94
     */
95
    public function addError($message, $messageType = self::TYPE_ERROR, $code = null, $cast = self::CAST_TEXT)
96
    {
97
        return $this->addFieldError(null, $message, $messageType, $code, $cast);
98
    }
99
100
    /**
101
     * Record an error against this validation result,
102
     *
103
     * @param string $fieldName   The field to link the message to.  If omitted; a form-wide message is assumed.
104
     * @param string $message     The message string.
105
     * @param string $messageType The type of message: e.g. "bad", "warning", "good", or "required". Passed as a CSS
106
     *                            class to the form, so other values can be used if desired.
107
     * @param string $code        A codename for this error. Only one message per codename will be added.
108
     *                            This can be usedful for ensuring no duplicate messages
109
     * @param string|bool $cast Cast type; One of the CAST_ constant definitions.
110
     * Bool values will be treated as plain text flag.
111
     * @return $this
112
     */
113
    public function addFieldError(
114
        $fieldName,
115
        $message,
116
        $messageType = self::TYPE_ERROR,
117
        $code = null,
118
        $cast = self::CAST_TEXT
119
    ) {
120
        $this->isValid = false;
121
        return $this->addFieldMessage($fieldName, $message, $messageType, $code, $cast);
122
    }
123
124
    /**
125
     * Add a message to this ValidationResult without necessarily marking it as an error
126
     *
127
     * @param string $message     The message string.
128
     * @param string $messageType The type of message: e.g. "bad", "warning", "good", or "required". Passed as a CSS
129
     *                            class to the form, so other values can be used if desired.
130
     * @param string $code        A codename for this error. Only one message per codename will be added.
131
     *                            This can be usedful for ensuring no duplicate messages
132
     * @param string|bool $cast Cast type; One of the CAST_ constant definitions.
133
     * Bool values will be treated as plain text flag.
134
     * @return $this
135
     */
136
    public function addMessage($message, $messageType = self::TYPE_ERROR, $code = null, $cast = self::CAST_TEXT)
137
    {
138
        return $this->addFieldMessage(null, $message, $messageType, $code, $cast);
139
    }
140
141
    /**
142
     * Add a message to this ValidationResult without necessarily marking it as an error
143
     *
144
     * @param string $fieldName   The field to link the message to.  If omitted; a form-wide message is assumed.
145
     * @param string $message     The message string.
146
     * @param string $messageType The type of message: e.g. "bad", "warning", "good", or "required". Passed as a CSS
147
     *                            class to the form, so other values can be used if desired.
148
     * @param string $code        A codename for this error. Only one message per codename will be added.
149
     *                            This can be usedful for ensuring no duplicate messages
150
     * @param string|bool $cast Cast type; One of the CAST_ constant definitions.
151
     * Bool values will be treated as plain text flag.
152
     * @return $this
153
     */
154
    public function addFieldMessage(
155
        $fieldName,
156
        $message,
157
        $messageType = self::TYPE_ERROR,
158
        $code = null,
159
        $cast = self::CAST_TEXT
160
    ) {
161
        if ($code && is_numeric($code)) {
162
            throw new InvalidArgumentException("Don't use a numeric code '$code'.  Use a string.");
163
        }
164
        if (is_bool($cast)) {
165
            $cast = $cast ? self::CAST_TEXT : self::CAST_HTML;
166
        }
167
        $metadata = [
168
            'message' => $message,
169
            'fieldName' => $fieldName,
170
            'messageType' => $messageType,
171
            'messageCast' => $cast,
172
        ];
173
174
        if ($code) {
175
            $this->messages[$code] = $metadata;
176
        } else {
177
            $this->messages[] = $metadata;
178
        }
179
180
        return $this;
181
    }
182
183
    /**
184
     * Returns true if the result is valid.
185
     * @return boolean
186
     */
187
    public function isValid()
188
    {
189
        return $this->isValid;
190
    }
191
192
    /**
193
     * Return the full error meta-data, suitable for combining with another ValidationResult.
194
     *
195
     * @return array Array of messages, where each item is an array of data for that message.
196
     */
197
    public function getMessages()
198
    {
199
        return $this->messages;
200
    }
201
202
    /**
203
     * Combine this Validation Result with the ValidationResult given in other.
204
     * It will be valid if both this and the other result are valid.
205
     * This object will be modified to contain the new validation information.
206
     *
207
     * @param ValidationResult $other the validation result object to combine
208
     * @return $this
209
     */
210
    public function combineAnd(ValidationResult $other)
211
    {
212
        $this->isValid = $this->isValid && $other->isValid();
213
        $this->messages = array_merge($this->messages, $other->getMessages());
214
        return $this;
215
    }
216
217
    public function __serialize(): array
218
    {
219
        return [
220
            'messages' => $this->messages,
221
            'isValid' => $this->isValid()
222
        ];
223
    }
224
225
    public function __unserialize(array $data): void
226
    {
227
        $this->messages = $data['messages'];
228
        $this->isValid = $data['isValid'];
229
    }
230
231
    /**
232
     * The __serialize() magic method will be automatically used instead of this
233
     *
234
     * @return string
235
     * @deprecated will be removed in 5.0
236
     */
237
    public function serialize()
238
    {
239
        return json_encode([$this->messages, $this->isValid]);
240
    }
241
242
    /**
243
     * The __unserialize() magic method will be automatically used instead of this almost all the time
244
     * This method will be automatically used if existing serialized data was not saved as an associative array
245
     * and the PHP version used in less than PHP 9.0
246
     *
247
     * @param string $serialized
248
     * @deprecated will be removed in 5.0
249
     */
250
    public function unserialize($serialized)
251
    {
252
        list($this->messages, $this->isValid) = json_decode($serialized, true);
253
    }
254
}
255