Passed
Push — master ( ebdfbb...20570e )
by
unknown
02:32
created

code/Extension/UserFormValidator.php (4 issues)

1
<?php
2
3
namespace SilverStripe\UserForms\Extension;
4
5
use SilverStripe\Forms\RequiredFields;
6
use SilverStripe\UserForms\Model\EditableFormField\EditableFieldGroup;
7
use SilverStripe\UserForms\Model\EditableFormField\EditableFieldGroupEnd;
8
use SilverStripe\UserForms\Model\EditableFormField;
9
use SilverStripe\UserForms\Model\EditableFormField\EditableFormStep;
10
11
class UserFormValidator extends RequiredFields
12
{
13
    public function php($data)
14
    {
15
        if (!parent::php($data)) {
16
            return false;
17
        }
18
19
        // Skip unsaved records
20
        if (empty($data['ID']) || !is_numeric($data['ID'])) {
21
            return true;
22
        }
23
24
        $fields = EditableFormField::get()->filter('ParentID', $data['ID'])->sort('"Sort" ASC');
25
26
        // Current nesting
27
        $stack = array();
28
        $conditionalStep = false; // Is the current step conditional?
29
        foreach ($fields as $field) {
30
            if ($field instanceof EditableFormStep) {
31
                // Page at top level, or after another page is ok
32
                if (empty($stack) || (count($stack) === 1 && $stack[0] instanceof EditableFormStep)) {
33
                    $stack = array($field);
34
                    $conditionalStep = $field->EffectiveDisplayRules()->count() > 0;
35
                    continue;
36
                }
37
38
                $this->validationError(
39
                    'FormFields',
40
                    _t(
41
                        __CLASS__.".UNEXPECTED_BREAK",
42
                        "Unexpected page break '{name}' inside nested field '{group}'",
43
                        array(
44
                            'name' => $field->CMSTitle,
0 ignored issues
show
Bug Best Practice introduced by
The property CMSTitle does not exist on SilverStripe\UserForms\M...mField\EditableFormStep. Since you implemented __get, consider adding a @property annotation.
Loading history...
45
                            'group' => end($stack)->CMSTitle
46
                        )
47
                    ),
48
                    'error'
49
                );
50
                return false;
51
            }
52
53
            // Validate no pages
54
            if (empty($stack)) {
55
                $this->validationError(
56
                    'FormFields',
57
                    _t(
58
                        __CLASS__.".NO_PAGE",
59
                        "Field '{name}' found before any pages",
60
                        array(
61
                            'name' => $field->CMSTitle
62
                        )
63
                    ),
64
                    'error'
65
                );
66
                return false;
67
            }
68
69
            // Nest field group
70
            if ($field instanceof EditableFieldGroup) {
71
                $stack[] = $field;
72
                continue;
73
            }
74
75
            // Unnest field group
76
            if ($field instanceof EditableFieldGroupEnd) {
77
                $top = end($stack);
78
79
                // Check that the top is a group at all
80
                if (!$top instanceof EditableFieldGroup) {
81
                    $this->validationError(
82
                        'FormFields',
83
                        _t(
84
                            __CLASS__.".UNEXPECTED_GROUP_END",
85
                            "'{name}' found without a matching group",
86
                            array(
87
                                'name' => $field->CMSTitle
0 ignored issues
show
Bug Best Practice introduced by
The property CMSTitle does not exist on SilverStripe\UserForms\M...d\EditableFieldGroupEnd. Since you implemented __get, consider adding a @property annotation.
Loading history...
88
                            )
89
                        ),
90
                        'error'
91
                    );
92
                    return false;
93
                }
94
95
                // Check that the top is the right group
96
                if ($top->EndID != $field->ID) {
0 ignored issues
show
Bug Best Practice introduced by
The property EndID does not exist on SilverStripe\UserForms\M...ield\EditableFieldGroup. Since you implemented __get, consider adding a @property annotation.
Loading history...
97
                    $this->validationError(
98
                        'FormFields',
99
                        _t(
100
                            __CLASS__.".WRONG_GROUP_END",
101
                            "'{name}' found closes the wrong group '{group}'",
102
                            array(
103
                                'name' => $field->CMSTitle,
104
                                'group' => $top->CMSTitle
0 ignored issues
show
Bug Best Practice introduced by
The property CMSTitle does not exist on SilverStripe\UserForms\M...ield\EditableFieldGroup. Since you implemented __get, consider adding a @property annotation.
Loading history...
105
                            )
106
                        ),
107
                        'error'
108
                    );
109
                    return false;
110
                }
111
112
                // Unnest group
113
                array_pop($stack);
114
            }
115
116
            // Normal field type
117
            if ($conditionalStep && $field->Required) {
118
                $this->validationError(
119
                    'FormFields',
120
                    _t(
121
                        __CLASS__.".CONDITIONAL_REQUIRED",
122
                        "Required field '{name}' cannot be placed within a conditional page",
123
                        array(
124
                            'name' => $field->CMSTitle
125
                        )
126
                    ),
127
                    'error'
128
                );
129
                return false;
130
            }
131
        }
132
133
        return true;
134
    }
135
}
136