-
Notifications
You must be signed in to change notification settings - Fork 227
/
UserFormValidator.php
135 lines (120 loc) · 4.5 KB
/
UserFormValidator.php
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
<?php
namespace SilverStripe\UserForms\Extension;
use SilverStripe\Forms\RequiredFields;
use SilverStripe\UserForms\Model\EditableFormField\EditableFieldGroup;
use SilverStripe\UserForms\Model\EditableFormField\EditableFieldGroupEnd;
use SilverStripe\UserForms\Model\EditableFormField;
use SilverStripe\UserForms\Model\EditableFormField\EditableFormStep;
class UserFormValidator extends RequiredFields
{
public function php($data)
{
if (!parent::php($data)) {
return false;
}
// Skip unsaved records
if (empty($data['ID']) || !is_numeric($data['ID'])) {
return true;
}
$fields = EditableFormField::get()->filter('ParentID', $data['ID'])->sort('"Sort" ASC');
// Current nesting
$stack = array();
$conditionalStep = false; // Is the current step conditional?
foreach ($fields as $field) {
if ($field instanceof EditableFormStep) {
// Page at top level, or after another page is ok
if (empty($stack) || (count($stack ?? []) === 1 && $stack[0] instanceof EditableFormStep)) {
$stack = array($field);
$conditionalStep = $field->DisplayRules()->count() > 0;
continue;
}
$this->validationError(
'FormFields',
_t(
__CLASS__.".UNEXPECTED_BREAK",
"Unexpected page break '{name}' inside nested field '{group}'",
array(
'name' => $field->CMSTitle,
'group' => end($stack)->CMSTitle
)
),
'error'
);
return false;
}
// Validate no pages
if (empty($stack)) {
$this->validationError(
'FormFields',
_t(
__CLASS__.".NO_PAGE",
"Field '{name}' found before any pages",
array(
'name' => $field->CMSTitle
)
),
'error'
);
return false;
}
// Nest field group
if ($field instanceof EditableFieldGroup) {
$stack[] = $field;
continue;
}
// Unnest field group
if ($field instanceof EditableFieldGroupEnd) {
$top = end($stack);
// Check that the top is a group at all
if (!$top instanceof EditableFieldGroup) {
$this->validationError(
'FormFields',
_t(
__CLASS__.".UNEXPECTED_GROUP_END",
"'{name}' found without a matching group",
array(
'name' => $field->CMSTitle
)
),
'error'
);
return false;
}
// Check that the top is the right group
if ($top->EndID != $field->ID) {
$this->validationError(
'FormFields',
_t(
__CLASS__.".WRONG_GROUP_END",
"'{name}' found closes the wrong group '{group}'",
array(
'name' => $field->CMSTitle,
'group' => $top->CMSTitle
)
),
'error'
);
return false;
}
// Unnest group
array_pop($stack);
}
// Normal field type
if ($conditionalStep && $field->Required) {
$this->validationError(
'FormFields',
_t(
__CLASS__.".CONDITIONAL_REQUIRED",
"Required field '{name}' cannot be placed within a conditional page",
array(
'name' => $field->CMSTitle
)
),
'error'
);
return false;
}
}
return true;
}
}