Issues (6)

src/PureModal.php (1 issue)

1
<?php
2
3
namespace LeKoala\PureModal;
4
5
use SilverStripe\View\SSViewer;
6
use SilverStripe\Forms\FormField;
7
use SilverStripe\Admin\ModelAdmin;
8
use SilverStripe\Control\Controller;
9
use SilverStripe\Forms\DatalessField;
10
use SilverStripe\ORM\FieldType\DBHTMLText;
11
12
/**
13
 * A simple pure css modal for usage in the cms
14
 *
15
 * If your content contains a form, it should be loaded through an iframe
16
 * because you cannot nest forms (warning, this gets tricky with "move_modal_to_body")
17
 *
18
 * @author lekoala
19
 */
20
class PureModal extends DatalessField
21
{
22
    /**
23
     * @var string
24
     */
25
    protected $title;
26
27
    /**
28
     * @var string
29
     */
30
    protected $content;
31
32
    /**
33
     * @var string
34
     */
35
    protected $iframe;
36
37
    /**
38
     * @var bool
39
     */
40
    protected $iframeTop;
41
42
    /**
43
     * @var string|null
44
     */
45
    protected $buttonIcon = null;
46
47
    /**
48
     * @param string $name
49
     * @param string $title
50
     * @param string $content
51
     */
52
    public function __construct($name, $title, $content)
53
    {
54
        $this->setContent($content);
55
56
        // If you want, you can remove this and switch to another type
57
        $this->addExtraClass('btn-primary');
58
59
        parent::__construct($name, $title);
60
    }
61
62
    public function Type()
63
    {
64
        return 'pure-modal';
65
    }
66
67
    /**
68
     * @return string
69
     */
70
    public static function getMoveModalScript()
71
    {
72
        if (!self::config()->move_modal_to_body) {
73
            return '';
74
        }
75
        return "document.body.appendChild(this.parentElement.querySelector('.pure-modal'));this.onclick=null;";
76
    }
77
78
    /**
79
     * @return bool
80
     */
81
    public static function getOverlayTriggersCloseConfig()
82
    {
83
        return boolval(self::config()->overlay_triggers_close);
84
    }
85
86
    /**
87
     * For template usage
88
     * @return bool
89
     */
90
    public function getOverlayTriggersClose()
91
    {
92
        return PureModal::getOverlayTriggersCloseConfig();
93
    }
94
95
    /**
96
     * @return array<string,mixed>
97
     */
98
    public function getAttributes()
99
    {
100
        $attrs = [];
101
        // Move modal to body to avoid nesting issues
102
        $attrs['onclick'] = self::getMoveModalScript();
103
        // Since the frame is hidden, we need to compute size on click
104
        // TODO: fix this as it may report incorrect height
105
        if ($this->getIframe() && self::config()->compute_iframe_height) {
106
            $attrs['onclick'] .= "var i=document.querySelector('#" . $this->getIframeID() . "');i.style.height = 0; setTimeout(function() {i.style.height = i.contentWindow.document.body.scrollHeight + 'px';},100);";
107
        }
108
        return $attrs;
109
    }
110
111
    /**
112
     * Render a dialog
113
     *
114
     * @param Controller $controller
115
     * @param array<string,mixed> $customFields
116
     * @return string|DBHTMLText
117
     */
118
    public static function renderDialog($controller, $customFields = null)
119
    {
120
        // Set empty content by default otherwise it will render the full page
121
        if (empty($customFields['Content'])) {
122
            $customFields['Content'] = '';
123
        }
124
125
        $templatesWithSuffix = SSViewer::get_templates_by_class(static::class, '_Dialog', __CLASS__);
126
127
        return $controller->renderWith($templatesWithSuffix, $customFields);
0 ignored issues
show
It seems like $customFields can also be of type null; however, parameter $customFields of SilverStripe\Control\Controller::renderWith() does only seem to accept SilverStripe\Model\ModelData|array, maybe add an additional type check? ( Ignorable by Annotation )

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

127
        return $controller->renderWith($templatesWithSuffix, /** @scrutinizer ignore-type */ $customFields);
Loading history...
128
    }
129
130
    /**
131
     * Sets the content of this field to a new value.
132
     *
133
     * @param string|FormField $content
134
     * @return $this
135
     */
136
    public function setContent($content)
137
    {
138
        $this->content = $content;
139
        return $this;
140
    }
141
142
    /**
143
     * @return string
144
     */
145
    public function getContent()
146
    {
147
        return $this->content;
148
    }
149
150
    /**
151
     * Build an url for the current controller and pass along some parameters
152
     *
153
     * If you want to call actions on a model, use getModelLink
154
     *
155
     * @param string $action
156
     * @param array<string,mixed> $params
157
     * @return string
158
     */
159
    public function getControllerLink($action, array $params = null)
160
    {
161
        if ($params === null) {
162
            $params = [];
163
        }
164
        $ctrl = Controller::curr();
165
        if ($ctrl instanceof ModelAdmin) {
166
            $allParams = $ctrl->getRequest()->allParams();
167
            $modelClass = $ctrl->getRequest()->param('ModelClass');
168
            $action = $modelClass . '/' . $action;
169
            $params = array_merge($allParams, $params);
170
        }
171
        if (!empty($params)) {
172
            $action .= '?' . http_build_query($params);
173
        }
174
        return $ctrl->Link($action);
175
    }
176
177
    /**
178
     * @param array<string,mixed> $properties
179
     * @return DBHTMLText
180
     */
181
    public function Field($properties = [])
182
    {
183
        $icon = $this->buttonIcon;
184
        if ($icon) {
185
            $this->addExtraClass('font-icon');
186
            $this->addExtraClass('font-icon-' . $icon);
187
        }
188
        return parent::Field($properties);
189
    }
190
191
    /**
192
     * @return string
193
     */
194
    public function getTitle()
195
    {
196
        return $this->title;
197
    }
198
199
    /**
200
     * @param string $title
201
     * @return $this
202
     */
203
    public function setTitle($title)
204
    {
205
        $this->title = $title;
206
        return $this;
207
    }
208
209
    /**
210
     * @return string
211
     */
212
    public function getIframe()
213
    {
214
        return $this->iframe;
215
    }
216
217
    /**
218
     * Link to iframe src
219
     *
220
     * @param string $iframe
221
     * @return $this
222
     */
223
    public function setIframe($iframe)
224
    {
225
        $this->iframe = $iframe;
226
        return $this;
227
    }
228
229
    /**
230
     * Helper for setIframe link using conventions
231
     *
232
     * @param string $action
233
     * @return $this
234
     */
235
    public function setIframeAction($action)
236
    {
237
        return $this->setIframe($this->getControllerLink($action));
238
    }
239
240
    /**
241
     * @return bool
242
     */
243
    public function getIframeTop()
244
    {
245
        return $this->iframeTop;
246
    }
247
248
    /**
249
     * Should the iframe be above the content
250
     *
251
     * @param bool $iframeTop
252
     * @return $this
253
     */
254
    public function setIframeTop($iframeTop)
255
    {
256
        $this->iframeTop = $iframeTop;
257
        return $this;
258
    }
259
260
    /**
261
     * @return string
262
     */
263
    public function getModalID()
264
    {
265
        return 'modal_' . $this->name;
266
    }
267
268
    /**
269
     * @return string
270
     */
271
    public function getIframeID()
272
    {
273
        return $this->getModalID() . '_iframe';
274
    }
275
276
    /**
277
     * Get an icon for this button
278
     *
279
     * @return string|null
280
     */
281
    public function getButtonIcon()
282
    {
283
        return $this->buttonIcon;
284
    }
285
286
    /**
287
     * Set an icon for this button
288
     *
289
     * Feel free to use SilverStripeIcons constants
290
     *
291
     * @param string|null $buttonIcon An icon for this button
292
     * @return $this
293
     */
294
    public function setButtonIcon(string $buttonIcon = null)
295
    {
296
        $this->buttonIcon = $buttonIcon;
297
        return $this;
298
    }
299
}
300