-
Notifications
You must be signed in to change notification settings - Fork 811
Expand file tree
/
Copy pathFormMessage.php
More file actions
189 lines (170 loc) · 5.41 KB
/
Copy pathFormMessage.php
File metadata and controls
189 lines (170 loc) · 5.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
<?php
namespace SilverStripe\Forms;
use InvalidArgumentException;
use SilverStripe\Core\XssSanitiser;
use SilverStripe\ORM\ValidationResult;
use SilverStripe\View\ViewableData;
/**
* Form component which contains a castable message
*
* @mixin ViewableData
*/
trait FormMessage
{
/**
* @var string
*/
protected $message = '';
/**
* @var string
*/
protected $messageType = '';
/**
* Casting for message
*
* @var string
*/
protected $messageCast = null;
/**
* Returns the field message, used by form validation.
* If the current cast is ValidationResult::CAST_HTML, the message will be sanitised.
*
* Use {@link setError()} to set this property.
*
* @return string
*/
public function getMessage()
{
$message = $this->message;
if ($this->getMessageCast() === ValidationResult::CAST_HTML) {
$message = XssSanitiser::create()->sanitiseString($message);
}
return $message;
}
/**
* Returns the field message type.
*
* Arbitrary value which is mostly used for CSS classes in the rendered HTML, e.g "required".
*
* Use {@link setError()} to set this property.
*
* @return string
*/
public function getMessageType()
{
return $this->messageType;
}
/**
* Casting type for this message. Will be 'text' or 'html'
*
* @return string
*/
public function getMessageCast()
{
return $this->messageCast;
}
/**
* Sets the error message to be displayed on the form field.
*
* Allows HTML content, so remember to use Convert::raw2xml().
*
* @param string $message Message string
* @param string $messageType Message type
* @param string $messageCast
* @return $this
*/
public function setMessage(
$message,
$messageType = ValidationResult::TYPE_ERROR,
$messageCast = ValidationResult::CAST_TEXT
) {
if (!in_array($messageCast, [ValidationResult::CAST_TEXT, ValidationResult::CAST_HTML])) {
throw new InvalidArgumentException("Invalid message cast type");
}
$this->message = $message;
$this->messageType = $messageType;
$this->messageCast = $messageCast;
return $this;
}
/**
* Appends a message to the existing message if the types and casts match.
* If either is different, the $force argument determines the behaviour.
*
* Note: to prevent duplicates, we check for the $message string in the existing message.
* If the existing message contains $message as a substring, it won't be added.
*
* @param bool $force if true, and the new message cannot be appended to the existing one, the existing message will be overridden.
* @throws InvalidArgumentException if $force is false and the messages can't be merged because of a mismatched type or cast.
*/
public function appendMessage(
string $message,
string $messageType = ValidationResult::TYPE_ERROR,
string $messageCast = ValidationResult::CAST_TEXT,
bool $force = false,
): static {
if (empty($message)) {
return $this;
}
if (empty($this->message)) {
return $this->setMessage($message, $messageType, $messageCast);
}
$canBeMerged = ($messageType === $this->getMessageType() && $messageCast === $this->getMessageCast());
if (!$canBeMerged && !$force) {
throw new InvalidArgumentException(
sprintf(
"Couldn't append message of type %s and cast %s to existing message of type %s and cast %s",
$messageType,
$messageCast,
$this->getMessageType(),
$this->getMessageCast(),
)
);
}
// Checks that the exact message string is not already contained before appending
$messageContainsString = strpos($this->message, $message) !== false;
if ($canBeMerged && $messageContainsString) {
return $this;
}
if ($canBeMerged) {
$separator = $messageCast === ValidationResult::CAST_HTML ? '<br />' : PHP_EOL;
$message = $this->message . $separator . $message;
}
return $this->setMessage($message, $messageType, $messageCast);
}
/**
* Get casting helper for message cast, or null if not known
*
* @return string
*/
protected function getMessageCastingHelper()
{
switch ($this->getMessageCast()) {
case ValidationResult::CAST_TEXT:
return 'Text';
case ValidationResult::CAST_HTML:
return 'HTMLFragment';
default:
return null;
}
}
/**
* Get form schema encoded message
*
* @return array|null Message in array format, or null if no message
*/
public function getSchemaMessage()
{
$message = $this->getMessage();
if (!$message) {
return null;
}
// Form schema messages treat simple strings as plain text, so nest for html messages
if ($this->getMessageCast() === ValidationResult::CAST_HTML) {
$message = ['html' => $message];
}
return [
'value' => $message,
'type' => $this->getMessageType(),
];
}
}