Passed
Push — master ( edb80f...21c050 )
by Thomas
03:56
created

PureModalAction::setForm()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 3
eloc 4
c 1
b 1
f 0
nc 2
nop 1
dl 0
loc 9
rs 10
1
<?php
2
3
namespace LeKoala\PureModal;
4
5
use SilverStripe\Forms\Form;
6
use SilverStripe\Forms\FieldList;
7
use SilverStripe\Control\Controller;
8
use SilverStripe\Forms\DatalessField;
9
10
/**
11
 * Custom modal action
12
 * Requires cms-actions to work out of the box
13
 */
14
class PureModalAction extends DatalessField
15
{
16
    /**
17
     * Default classes applied in constructor by the FormField
18
     * @config
19
     * @var array
20
     */
21
    private static $default_classes = ["btn", "btn-info"];
0 ignored issues
show
introduced by
The private property $default_classes is not used, and could be removed.
Loading history...
22
23
    /**
24
     * @var FieldList
25
     */
26
    protected $fieldList;
27
28
    /**
29
     * A custom title for the dialog button
30
     * @var string
31
     */
32
    protected $dialogButtonTitle;
33
34
    /**
35
     * Should it show the dialog button
36
     * @var boolean
37
     */
38
    protected $showDialogButton = true;
39
40
    /**
41
     * An icon for this button
42
     * @var string
43
     */
44
    protected $buttonIcon;
45
46
    /**
47
     * @var boolean
48
     */
49
    protected $shouldRefresh = false;
50
51
    /**
52
     * Whether to place the button in a dot-menu.
53
     * @see https://github.com/lekoala/silverstripe-cms-actions
54
     * @var bool
55
     */
56
    protected $dropUp = false;
57
58
    /**
59
     * @var boolean
60
     */
61
    protected $fillHeight = false;
62
63
    public function __construct($name, $title)
64
    {
65
        $name = 'doCustomAction[' . $name . ']';
66
        $this->title = $title;
67
        $this->name = $name;
68
69
        parent::__construct($name, $title);
70
    }
71
72
    public function getOverlayTriggersClose()
73
    {
74
        return PureModal::getOverlayTriggersCloseConfig();
75
    }
76
77
    /**
78
     * If the modal is in the body, it needs to go back to the form to submit properly
79
     * @return string
80
     */
81
    public function SubmitOnClickScript()
82
    {
83
        if (!PureModal::getMoveModalScript()) {
84
            return '';
85
        }
86
        $formId = PureModal::config()->edit_form_id;
87
        return "event.stopPropagation();var f=document.getElementById('$formId');var m=this.closest('.pure-modal');m.style.display='none';f.appendChild(m);f.submit();";
88
    }
89
90
    /**
91
     * Move modal when clicking on the open button. Trigger only once.
92
     * @return string
93
     */
94
    public static function getMoveModalScript()
95
    {
96
        if (!PureModal::config()->move_modal_to_body) {
97
            return '';
98
        }
99
        $formId = PureModal::config()->edit_form_id;
100
        return "document.getElementById('$formId').appendChild(this.parentElement.querySelector('.pure-modal'));this.onclick=null;";
101
    }
102
103
    public function getAttributes()
104
    {
105
        $attrs = [];
106
        // Move modal to form to avoid nesting issues
107
        // We cannot append to body because this breaks form submission
108
        $attrs['onclick'] = self::getMoveModalScript();
109
        return $attrs;
110
    }
111
112
    /**
113
     * Get the title with icon if set
114
     *
115
     * @return string
116
     */
117
    protected function getButtonTitle()
118
    {
119
        $title = $this->title;
120
        if ($this->buttonIcon) {
121
            $title = '<span class="font-icon-' . $this->buttonIcon . '"></span> ' . $title;
122
        }
123
        return $title;
124
    }
125
126
    /**
127
     * Get the dialog button title with icon if set
128
     *
129
     * @return string
130
     */
131
    protected function getDialogButtonTitle()
132
    {
133
        $title = $this->dialogButtonTitle ?: $this->title;
134
        if ($this->buttonIcon) {
135
            $title = '<span class="font-icon-' . $this->buttonIcon . '"></span> ' . $title;
136
        }
137
        return $title;
138
    }
139
140
    /**
141
     * Set dialog button customised button title
142
     *
143
     * @return self
144
     */
145
    public function setDialogButtonTitle($value)
146
    {
147
        $this->dialogButtonTitle = $value;
148
        return $this;
149
    }
150
151
    /**
152
     * Get an icon for this button
153
     *
154
     * @return string
155
     */
156
    public function getButtonIcon()
157
    {
158
        return $this->buttonIcon;
159
    }
160
161
    /**
162
     * Set an icon for this button
163
     *
164
     * Feel free to use SilverStripeIcons constants
165
     *
166
     * @param string $buttonIcon An icon for this button
167
     * @return $this
168
     */
169
    public function setButtonIcon(string $buttonIcon)
170
    {
171
        $this->buttonIcon = $buttonIcon;
172
        return $this;
173
    }
174
175
    /**
176
     * Set a new type of btn-something. It will remove any existing btn- class
177
     * @param string $type Leave blank to simply remove default button type
178
     * @return $this
179
     */
180
    public function setButtonType($type = null)
181
    {
182
        if ($this->extraClasses) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->extraClasses 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...
183
            foreach ($this->extraClasses as $k => $v) {
184
                if (strpos($k, 'btn-') !== false) {
185
                    unset($this->extraClasses[$k]);
186
                }
187
            }
188
        }
189
        if ($type) {
190
            $btn = "btn-$type";
191
            $this->extraClasses[$btn] = $btn;
192
        }
193
        return $this;
194
    }
195
196
    /**
197
     * Get whether it must display the dialog button
198
     *
199
     * @return boolean
200
     */
201
    protected function getShowDialogButton()
202
    {
203
        return $this->showDialogButton;
204
    }
205
206
    /**
207
     * Set whether it must display the dialog button
208
     *
209
     * @return self
210
     */
211
    public function setShowDialogButton($value)
212
    {
213
        $this->showDialogButton = !!$value;
214
        return $this;
215
    }
216
217
    /**
218
     * Get the value of fieldList
219
     * @return FieldList
220
     */
221
    public function getFieldList()
222
    {
223
        return $this->fieldList;
224
    }
225
226
    /**
227
     * Set the value of fieldList
228
     *
229
     * @param FieldList $fieldList
230
     * @return $this
231
     */
232
    public function setFieldList(FieldList $fieldList)
233
    {
234
        $this->fieldList = $fieldList;
235
        foreach ($fieldList->dataFields() as $f) {
236
            $f->addExtraClass('no-change-track');
237
        }
238
        return $this;
239
    }
240
241
    /**
242
     * Make sure our nested fieldlist is bound to form
243
     *
244
     * @param Form $form
245
     * @return $this
246
     */
247
    public function setForm($form)
248
    {
249
        //@link https://github.com/unclecheese/silverstripe-display-logic/pull/155#issuecomment-1540966157
250
        if ($this->fieldList) {
251
            foreach ($this->fieldList as $field) {
252
                $field->setForm($form);
253
            }
254
        }
255
        return parent::setForm($form);
256
    }
257
258
    /**
259
     * Get the dropUp value
260
     * Called by ActionsGridFieldItemRequest to determine placement
261
     *
262
     * @see https://github.com/lekoala/silverstripe-cms-actions
263
     * @return bool
264
     */
265
    public function getDropUp()
266
    {
267
        return $this->dropUp;
268
    }
269
270
    /**
271
     * Set the value of dropUp
272
     * You might want to call also setButtonType(null) for better styles
273
     *
274
     * @see https://github.com/lekoala/silverstripe-cms-actions
275
     * @param bool $is
276
     * @return $this
277
     */
278
    public function setDropUp($is)
279
    {
280
        $this->dropUp = !!$is;
281
        return $this;
282
    }
283
284
    /**
285
     * Required for cms-actions
286
     * @return string
287
     */
288
    public function actionName()
289
    {
290
        return rtrim(str_replace('doCustomAction[', '', $this->name), ']');
291
    }
292
293
    /**
294
     * Get the value of shouldRefresh
295
     * @return mixed
296
     */
297
    public function getShouldRefresh()
298
    {
299
        return $this->shouldRefresh;
300
    }
301
302
    /**
303
     * Set the value of shouldRefresh
304
     *
305
     * @param mixed $shouldRefresh
306
     * @return $this
307
     */
308
    public function setShouldRefresh($shouldRefresh)
309
    {
310
        $this->shouldRefresh = $shouldRefresh;
311
        return $this;
312
    }
313
314
    public function getModalID()
315
    {
316
        return 'modal_' . $this->name;
317
    }
318
319
    public function getTitle()
320
    {
321
        return $this->title;
322
    }
323
324
    public function getFillHeight()
325
    {
326
        return $this->fillHeight;
327
    }
328
329
    public function setFillHeight($fillHeight)
330
    {
331
        $this->fillHeight = $fillHeight;
332
        return $this;
333
    }
334
}
335