Passed
Push — 4 ( 34eb17...84b405 )
by Robbie
08:27 queued 12s
created

RequiredFields::canBeCached()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Forms;
4
5
use SilverStripe\ORM\ArrayLib;
6
7
/**
8
 * Required Fields allows you to set which fields need to be present before
9
 * submitting the form. Submit an array of arguments or each field as a separate
10
 * argument.
11
 *
12
 * Validation is performed on a field by field basis through
13
 * {@link FormField::validate}.
14
 */
15
class RequiredFields extends Validator
16
{
17
18
    /**
19
     * List of required fields
20
     *
21
     * @var array
22
     */
23
    protected $required;
24
25
    /**
26
     * Pass each field to be validated as a seperate argument to the constructor
27
     * of this object. (an array of elements are ok).
28
     */
29
    public function __construct()
30
    {
31
        $required = func_get_args();
32
        if (isset($required[0]) && is_array($required[0])) {
33
            $required = $required[0];
34
        }
35
        if (!empty($required)) {
36
            $this->required = ArrayLib::valuekey($required);
37
        } else {
38
            $this->required = [];
39
        }
40
41
        parent::__construct();
42
    }
43
44
    /**
45
     * Clears all the validation from this object.
46
     *
47
     * @return $this
48
     */
49
    public function removeValidation()
50
    {
51
        parent::removeValidation();
52
        $this->required = [];
53
54
        return $this;
55
    }
56
57
    /**
58
     * Debug helper
59
     * @return string
60
     */
61
    public function debug()
62
    {
63
        if (!is_array($this->required)) {
0 ignored issues
show
introduced by
The condition is_array($this->required) is always true.
Loading history...
64
            return false;
65
        }
66
67
        $result = "<ul>";
68
        foreach ($this->required as $name) {
69
            $result .= "<li>$name</li>";
70
        }
71
72
        $result .= "</ul>";
73
        return $result;
74
    }
75
76
    /**
77
     * Allows validation of fields via specification of a php function for
78
     * validation which is executed after the form is submitted.
79
     *
80
     * @param array $data
81
     *
82
     * @return boolean
83
     */
84
    public function php($data)
85
    {
86
        $valid = true;
87
        $fields = $this->form->Fields();
88
89
        foreach ($fields as $field) {
90
            $valid = ($field->validate($this) && $valid);
91
        }
92
93
        if (!$this->required) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->required of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
94
            return $valid;
95
        }
96
97
        foreach ($this->required as $fieldName) {
98
            if (!$fieldName) {
99
                continue;
100
            }
101
102
            if ($fieldName instanceof FormField) {
103
                $formField = $fieldName;
104
                $fieldName = $fieldName->getName();
105
            } else {
106
                $formField = $fields->dataFieldByName($fieldName);
107
            }
108
109
            // submitted data for file upload fields come back as an array
110
            $value = isset($data[$fieldName]) ? $data[$fieldName] : null;
111
112
            if (is_array($value)) {
113
                if ($formField instanceof FileField && isset($value['error']) && $value['error']) {
114
                    $error = true;
115
                } else {
116
                    $error = (count($value)) ? false : true;
117
                }
118
            } else {
119
                // assume a string or integer
120
                $error = (strlen($value)) ? false : true;
121
            }
122
123
            if ($formField && $error) {
124
                $errorMessage = _t(
125
                    'SilverStripe\\Forms\\Form.FIELDISREQUIRED',
126
                    '{name} is required',
127
                    [
128
                        'name' => strip_tags(
129
                            '"' . ($formField->Title() ? $formField->Title() : $fieldName) . '"'
130
                        )
131
                    ]
132
                );
133
134
                if ($msg = $formField->getCustomValidationMessage()) {
135
                    $errorMessage = $msg;
136
                }
137
138
                $this->validationError(
139
                    $fieldName,
140
                    $errorMessage,
141
                    "required"
142
                );
143
144
                $valid = false;
145
            }
146
        }
147
148
        return $valid;
149
    }
150
151
    /**
152
     * Adds a single required field to required fields stack.
153
     *
154
     * @param string $field
155
     *
156
     * @return $this
157
     */
158
    public function addRequiredField($field)
159
    {
160
        $this->required[$field] = $field;
161
162
        return $this;
163
    }
164
165
    /**
166
     * Removes a required field
167
     *
168
     * @param string $field
169
     *
170
     * @return $this
171
     */
172
    public function removeRequiredField($field)
173
    {
174
        unset($this->required[$field]);
175
176
        return $this;
177
    }
178
179
    /**
180
     * Add {@link RequiredField} objects together
181
     *
182
     * @param RequiredFields $requiredFields
183
     * @return $this
184
     */
185
    public function appendRequiredFields($requiredFields)
186
    {
187
        $this->required = $this->required + ArrayLib::valuekey(
188
            $requiredFields->getRequired()
189
        );
190
191
        return $this;
192
    }
193
194
    /**
195
     * Returns true if the named field is "required".
196
     *
197
     * Used by {@link FormField} to return a value for FormField::Required(),
198
     * to do things like show *s on the form template.
199
     *
200
     * @param string $fieldName
201
     *
202
     * @return boolean
203
     */
204
    public function fieldIsRequired($fieldName)
205
    {
206
        return isset($this->required[$fieldName]);
207
    }
208
209
    /**
210
     * Return the required fields
211
     *
212
     * @return array
213
     */
214
    public function getRequired()
215
    {
216
        return array_values($this->required);
217
    }
218
219
    /**
220
     * @return bool
221
     */
222
    public function canBeCached(): bool
223
    {
224
        return count($this->getRequired()) === 0;
225
    }
226
}
227