Completed
Push — master ( afd157...91e79e )
by Damian
05:02 queued 04:46
created

FormAction::getAttributes()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
nc 3
nop 0
dl 0
loc 18
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Forms;
4
5
use SilverStripe\ORM\FieldType\DBHTMLText;
6
7
/**
8
 * The action buttons are <input type="submit"> as well as <button> tags.
9
 *
10
 * Upon clicking the button below will redirect the user to doAction under the current controller.
11
 *
12
 * <code>
13
 * new FormAction (
14
 *    // doAction has to be a defined controller member
15
 *    $action = "doAction",
16
 *    $title = "Submit button"
17
 * )
18
 * </code>
19
 */
20
class FormAction extends FormField
21
{
22
23
    /**
24
     * @config
25
     * @var array
26
     */
27
    private static $casting = [
28
        'ButtonContent' => 'HTMLFragment',
29
    ];
30
31
    /**
32
     * Action name, normally prefixed with 'action_'
33
     *
34
     * @var string
35
     */
36
    protected $action;
37
38
    /**
39
     * Identifier of icon, if supported on the frontend
40
     *
41
     * @var string
42
     */
43
    protected $icon = null;
44
45
    /**
46
     * @skipUpgrade
47
     * @var string
48
     */
49
    protected $schemaComponent = 'FormAction';
50
51
    /**
52
     * Enables the use of <button> instead of <input>
53
     * in {@link Field()} - for more customisable styling.
54
     *
55
     * @var boolean
56
     */
57
    public $useButtonTag = false;
58
59
    /**
60
     * Literal button content, used when useButtonTag is true.
61
     *
62
     * @var string
63
     */
64
    protected $buttonContent = null;
65
66
    /**
67
     * Should validation be skipped when performing this action?
68
     *
69
     * @var bool
70
     */
71
    protected $validationExempt = false;
72
73
    /**
74
     * Create a new action button.
75
     *
76
     * @param string $action The method to call when the button is clicked
77
     * @param string $title The label on the button. This should be plain text, not escaped as HTML.
78
     * @param Form form The parent form, auto-set when the field is placed inside a form
79
     */
80
    public function __construct($action, $title = "", $form = null)
81
    {
82
        $this->action = "action_$action";
83
        $this->setForm($form);
0 ignored issues
show
Bug introduced by
It seems like $form defined by parameter $form on line 80 can be null; however, SilverStripe\Forms\FormField::setForm() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
84
85
        parent::__construct($this->action, $title);
86
    }
87
88
    /**
89
     * Add extra options to data
90
     */
91
    public function getSchemaDataDefaults()
92
    {
93
        $defaults = parent::getSchemaDataDefaults();
94
        $defaults['attributes']['type'] = $this->getUseButtonTag() ? 'button' : 'submit';
95
        $defaults['data']['icon'] = $this->getIcon();
96
        return $defaults;
97
    }
98
99
    /**
100
     * Get button icon, if supported
101
     *
102
     * @return string
103
     */
104
    public function getIcon()
105
    {
106
        return $this->icon;
107
    }
108
109
    /**
110
     * Sets button icon
111
     *
112
     * @param string $icon Icon identifier (not path)
113
     * @return $this
114
     */
115
    public function setIcon($icon)
116
    {
117
        $this->icon = $icon;
118
        return $this;
119
    }
120
121
    /**
122
     * Get the action name
123
     *
124
     * @return string
125
     */
126
    public function actionName()
127
    {
128
        return substr($this->name, 7);
129
    }
130
131
    /**
132
     * Set the full action name, including action_
133
     * This provides an opportunity to replace it with something else
134
     *
135
     * @param string $fullAction
136
     * @return $this
137
     */
138
    public function setFullAction($fullAction)
139
    {
140
        $this->action = $fullAction;
141
        return $this;
142
    }
143
144
    /**
145
     * @param array $properties
146
     * @return DBHTMLText
147
     */
148
    public function Field($properties = array())
149
    {
150
        $properties = array_merge(
151
            $properties,
152
            array(
153
                'Name' => $this->action,
154
                'Title' => ($this->description && !$this->useButtonTag) ? $this->description : $this->Title(),
155
                'UseButtonTag' => $this->useButtonTag
156
            )
157
        );
158
159
        return parent::Field($properties);
160
    }
161
162
    /**
163
     * @param array $properties
164
     * @return DBHTMLText
165
     */
166
    public function FieldHolder($properties = array())
167
    {
168
        return $this->Field($properties);
169
    }
170
171
    public function Type()
172
    {
173
        return 'action';
174
    }
175
176
    public function getAttributes()
177
    {
178
        if (isset($this->attributes['type'])) {
179
            $type = $this->attributes['type'];
180
        } else {
181
            $type = (isset($this->attributes['src'])) ? 'image' : 'submit';
182
        }
183
184
        return array_merge(
185
            parent::getAttributes(),
186
            array(
187
                'disabled' => ($this->isReadonly() || $this->isDisabled()),
188
                'value' => $this->Title(),
189
                'type' => $type,
190
                'title' => ($this->useButtonTag) ? $this->description : null,
191
            )
192
        );
193
    }
194
195
    /**
196
     * Add content inside a button field. This should be pre-escaped raw HTML and should be used sparingly.
197
     *
198
     * @param string $content
199
     * @return $this
200
     */
201
    public function setButtonContent($content)
202
    {
203
        $this->buttonContent = (string) $content;
204
        return $this;
205
    }
206
207
    /**
208
     * Gets the content inside the button field. This is raw HTML, and should be used sparingly.
209
     *
210
     * @return string
211
     */
212
    public function getButtonContent()
213
    {
214
        return $this->buttonContent;
215
    }
216
217
    /**
218
     * Enable or disable the rendering of this action as a <button />
219
     *
220
     * @param boolean
221
     * @return $this
222
     */
223
    public function setUseButtonTag($bool)
224
    {
225
        $this->useButtonTag = $bool;
226
        return $this;
227
    }
228
229
    /**
230
     * Determine if this action is rendered as a <button />
231
     *
232
     * @return boolean
233
     */
234
    public function getUseButtonTag()
235
    {
236
        return $this->useButtonTag;
237
    }
238
239
    /**
240
     * Set whether this action can be performed without validating the data
241
     *
242
     * @param bool $exempt
243
     * @return $this
244
     */
245
    public function setValidationExempt($exempt = true)
246
    {
247
        $this->validationExempt = $exempt;
248
        return $this;
249
    }
250
251
    /**
252
     * Get whether this action can be performed without vaidating the data
253
     *
254
     * @return bool
255
     */
256
    public function getValidationExempt()
257
    {
258
        return $this->validationExempt;
259
    }
260
261
    /**
262
     * Does not transform to readonly by purpose.
263
     * Globally disabled buttons would break the CMS.
264
     */
265
    public function performReadonlyTransformation()
266
    {
267
        $clone = clone $this;
268
        $clone->setReadonly(true);
269
        return $clone;
270
    }
271
}
272