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

UserForm::getEmailRecipientRequiredFields()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 4
nop 0
dl 0
loc 18
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\UserForms\Form;
4
5
use ResetFormAction;
0 ignored issues
show
Bug introduced by
The type ResetFormAction was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SilverStripe\Control\Controller;
7
use SilverStripe\Control\Session;
8
use SilverStripe\Forms\FieldList;
9
use SilverStripe\Forms\Form;
10
use SilverStripe\Forms\FormAction;
11
use SilverStripe\Forms\RequiredFields;
12
use SilverStripe\UserForms\FormField\UserFormsStepField;
13
use SilverStripe\UserForms\FormField\UserFormsFieldList;
14
15
/**
16
 * @package userforms
17
 */
18
class UserForm extends Form
19
{
20
    /**
21
     * @config
22
     * @var string
23
     */
24
    private static $button_text = '';
25
26
    /**
27
     * @param Controller $controller
28
     * @param string $name
29
     */
30
    public function __construct(Controller $controller, $name = Form::class)
31
    {
32
        $this->controller = $controller;
33
        $this->setRedirectToFormOnValidationError(true);
34
35
        parent::__construct(
36
            $controller,
37
            $name,
38
            new FieldList(),
39
            new FieldList()
40
        );
41
42
        $this->setFields($fields = $this->getFormFields());
43
44
        $fields->setForm($this);
45
        $this->setActions($actions = $this->getFormActions());
46
        $actions->setForm($this);
47
        $this->setValidator($this->getRequiredFields());
48
49
        // This needs to be re-evaluated since fields have been assigned
50
        $this->restoreFormState();
51
52
        // Number each page
53
        $stepNumber = 1;
54
        foreach ($this->getSteps() as $step) {
55
            $step->setStepNumber($stepNumber++);
56
        }
57
58
        if ($controller->DisableCsrfSecurityToken) {
59
            $this->disableSecurityToken();
60
        }
61
62
        $data = $this->getRequest()->getSession()->get("FormInfo.{$this->FormName()}.data");
63
64
        if (is_array($data)) {
65
            $this->loadDataFrom($data);
66
        }
67
68
        $this->extend('updateForm');
69
    }
70
71
    public function restoreFormState()
72
    {
73
        // Suppress restoreFormState if fields haven't been bootstrapped
74
        if ($this->fields && $this->fields->exists()) {
75
            return parent::restoreFormState();
76
        }
77
78
        return $this;
79
    }
80
81
    /**
82
     * Used for partial caching in the template.
83
     *
84
     * @return string
85
     */
86
    public function getLastEdited()
87
    {
88
        return $this->controller->LastEdited;
89
    }
90
91
    /**
92
     * @return bool
93
     */
94
    public function getDisplayErrorMessagesAtTop()
95
    {
96
        return (bool)$this->controller->DisplayErrorMessagesAtTop;
97
    }
98
99
    /**
100
     * Return the fieldlist, filtered to only contain steps
101
     *
102
     * @return \SilverStripe\ORM\ArrayList
103
     */
104
    public function getSteps()
105
    {
106
        return $this->Fields()->filterByCallback(function ($field) {
107
            return $field instanceof UserFormsStepField;
108
        });
109
    }
110
111
    /**
112
     * Get the form fields for the form on this page. Can modify this FieldSet
113
     * by using {@link updateFormFields()} on an {@link Extension} subclass which
114
     * is applied to this controller.
115
     *
116
     * This will be a list of top level composite steps
117
     *
118
     * @return FieldList
119
     */
120
    public function getFormFields()
121
    {
122
        $fields = new UserFormsFieldList();
123
        $target = $fields;
124
125
        foreach ($this->controller->data()->Fields() as $field) {
126
            $target = $target->processNext($field);
127
        }
128
        $fields->clearEmptySteps();
129
        $this->extend('updateFormFields', $fields);
130
        $fields->setForm($this);
131
        return $fields;
132
    }
133
134
    /**
135
     * Generate the form actions for the UserDefinedForm. You
136
     * can manipulate these by using {@link updateFormActions()} on
137
     * a decorator.
138
     *
139
     * @todo Make form actions editable via their own field editor.
140
     *
141
     * @return FieldList
142
     */
143
    public function getFormActions()
144
    {
145
        $submitText = ($this->controller->SubmitButtonText)
146
            ? $this->controller->SubmitButtonText
147
            : _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SUBMITBUTTON', 'Submit');
148
        $clearText = ($this->controller->ClearButtonText)
149
            ? $this->controller->ClearButtonText
150
            : _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.CLEARBUTTON', 'Clear');
151
152
        $actions = FieldList::create(FormAction::create('process', $submitText));
0 ignored issues
show
Bug introduced by
'process' of type string is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

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

152
        $actions = FieldList::create(FormAction::create(/** @scrutinizer ignore-type */ 'process', $submitText));
Loading history...
153
154
        if ($this->controller->ShowClearButton) {
155
            $actions->push(FormAction::create('clearForm', $clearText)->setAttribute('type', 'reset'));
156
        }
157
158
        $this->extend('updateFormActions', $actions);
159
        $actions->setForm($this);
160
        return $actions;
161
    }
162
163
    /**
164
     * Get the required form fields for this form.
165
     *
166
     * @return RequiredFields
167
     */
168
    public function getRequiredFields()
169
    {
170
        // Generate required field validator
171
        $requiredNames = $this
172
            ->getController()
173
            ->data()
174
            ->Fields()
175
            ->filter('Required', true)
176
            ->column('Name');
177
        $requiredNames = array_merge($requiredNames, $this->getEmailRecipientRequiredFields());
178
        $required = new RequiredFields($requiredNames);
179
        $this->extend('updateRequiredFields', $required);
180
        $required->setForm($this);
181
        return $required;
182
    }
183
184
    /**
185
     * Override some we can add UserForm specific attributes to the form.
186
     *
187
     * @return array
188
     */
189
    public function getAttributes()
190
    {
191
        $attrs = parent::getAttributes();
192
193
        $attrs['class'] = $attrs['class'] . ' userform';
194
        $attrs['data-livevalidation'] = (bool)$this->controller->EnableLiveValidation;
195
        $attrs['data-toperrors'] = (bool)$this->controller->DisplayErrorMessagesAtTop;
196
197
        return $attrs;
198
    }
199
200
    /**
201
     * @return string
202
     */
203
    public function getButtonText()
204
    {
205
        return $this->config()->get('button_text');
206
    }
207
208
    /**
209
     * Push fields into the RequiredFields array if they are used by any Email recipients.
210
     * Ignore if there is a backup i.e. the plain string field is set
211
     *
212
     * @return array required fields names
213
     */
214
    protected function getEmailRecipientRequiredFields()
215
    {
216
        $requiredFields = [];
217
        $recipientFieldsMap = [
218
            'EmailAddress' => 'SendEmailToField',
219
            'EmailSubject' => 'SendEmailSubjectField',
220
            'EmailReplyTo' => 'SendEmailFromField'
221
        ];
222
223
        foreach ($this->getController()->data()->EmailRecipients() as $recipient) {
224
            foreach ($recipientFieldsMap as $textField => $dynamicFormField) {
225
                if (empty($recipient->$textField) && $recipient->getComponent($dynamicFormField)->exists()) {
226
                    $requiredFields[] = $recipient->getComponent($dynamicFormField)->Name;
227
                }
228
            }
229
        }
230
231
        return $requiredFields;
232
    }
233
}
234