PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.0
Tutor LMS – eLearning and online course solution v4.0.0
4.0.0 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / components / ConfirmationModal.php
tutor / components Last commit date
Constants 22 hours ago Accordion.php 22 hours ago Alert.php 22 hours ago AttachmentCard.php 22 hours ago Avatar.php 22 hours ago Badge.php 22 hours ago BaseComponent.php 22 hours ago Button.php 22 hours ago ConfirmationModal.php 22 hours ago CourseFilter.php 22 hours ago DateFilter.php 22 hours ago DropdownFilter.php 22 hours ago EmptyState.php 22 hours ago FileUploader.php 22 hours ago InputField.php 22 hours ago Modal.php 22 hours ago Nav.php 22 hours ago Pagination.php 22 hours ago Popover.php 22 hours ago PreviewTrigger.php 22 hours ago Progress.php 22 hours ago SearchFilter.php 22 hours ago Sorting.php 22 hours ago StarRating.php 22 hours ago StarRatingInput.php 22 hours ago StatusSelect.php 22 hours ago SvgIcon.php 22 hours ago Table.php 22 hours ago Tabs.php 22 hours ago Tooltip.php 22 hours ago WPEditor.php 22 hours ago
ConfirmationModal.php
479 lines
1 <?php
2 /**
3 * Tutor Component: Confirmation Modal
4 *
5 * Provides a reusable confirmation modal with Alpine.js integration.
6 *
7 * @package Tutor\Components
8 * @author Themeum
9 * @link https://themeum.com
10 * @since 4.0.0
11 */
12
13 namespace Tutor\Components;
14
15 use TUTOR\Icon;
16
17 defined( 'ABSPATH' ) || exit;
18
19 /**
20 * Confirmation Modal Component Class.
21 *
22 * ```
23 * // Example usage:
24 *
25 * ConfirmationModal::make()
26 * ->id( 'delete-course-modal' )
27 * ->title( 'Delete This Course?' )
28 * ->message( 'Are you sure you want to delete this course permanently? Please confirm your choice.' )
29 * ->confirm_handler( 'handleDeleteCourse(payload?.courseId)' )
30 * ->mutation_state( 'deleteMutation' )
31 * ->render();
32 *
33 * // With custom icon
34 * ConfirmationModal::make()
35 * ->id( 'delete-announcement-modal' )
36 * ->title( 'Delete This Announcement?' )
37 * ->message( 'This action cannot be undone.' )
38 * ->icon( Icon::DELETE_2, 80 )
39 * ->confirm_handler( 'handleDeleteAnnouncement(payload?.announcementId)' )
40 * ->render();
41 * ```
42 *
43 * @since 4.0.0
44 */
45 class ConfirmationModal extends BaseComponent {
46 const ICON_TYPE_HTML = 'html';
47
48 /**
49 * Modal unique ID.
50 *
51 * @since 4.0.0
52 *
53 * @var string
54 */
55 protected $id = '';
56
57 /**
58 * Modal title.
59 *
60 * @since 4.0.0
61 *
62 * @var string
63 */
64 protected $title;
65
66 /**
67 * Confirmation message.
68 *
69 * @since 4.0.0
70 *
71 * @var string
72 */
73 protected $message;
74
75 /**
76 * Allowed HTML tags and attributes. Keys are tag names and values are allowed attributes.
77 *
78 * @since 4.0.0
79 *
80 * @var array
81 */
82 protected $allowed_html_tags = array(
83 'span' => array(
84 'class' => true,
85 'x-text' => true,
86 ),
87 'b' => array(),
88 'strong' => array(),
89 'i' => array(),
90 'em' => array(),
91 'br' => array(),
92 );
93
94 /**
95 * Icon name from Icon class.
96 *
97 * @since 4.0.0
98 *
99 * @var string
100 */
101 protected $icon = '';
102
103 /**
104 * Icon width.
105 *
106 * @since 4.0.0
107 *
108 * @var int
109 */
110 protected $icon_width = 100;
111
112 /**
113 * Icon height.
114 *
115 * @since 4.0.0
116 *
117 * @var int
118 */
119 protected $icon_height = 100;
120
121 /**
122 * Icon type.
123 *
124 * @since 4.0.0
125 *
126 * @var string|null
127 */
128 protected $icon_type = null;
129
130 /**
131 * Confirm handler function name (Alpine.js method).
132 *
133 * @since 4.0.0
134 *
135 * @var string
136 */
137 protected $confirm_handler = '';
138
139 /**
140 * Mutation state variable name (e.g., 'deleteMutation').
141 *
142 * @since 4.0.0
143 *
144 * @var string
145 */
146 protected $mutation_state = 'confirmMutation';
147
148 /**
149 * Cancel button text.
150 *
151 * @since 4.0.0
152 *
153 * @var string
154 */
155 protected $cancel_text = '';
156
157 /**
158 * Confirm button text.
159 *
160 * @since 4.0.0
161 *
162 * @var string
163 */
164 protected $confirm_text = '';
165
166 /**
167 * Custom width for modal content.
168 *
169 * @since 4.0.0
170 *
171 * @var string
172 */
173 protected $width = '426px';
174
175 /**
176 * Custom confirm button HTML.
177 *
178 * @since 4.0.0
179 *
180 * @var string
181 */
182 protected $confirm_btn = '';
183
184 /**
185 * Custom cancel button HTML.
186 *
187 * @since 4.0.0
188 *
189 * @var string
190 */
191 protected $cancel_btn = '';
192
193 /**
194 * Set modal ID.
195 *
196 * @since 4.0.0
197 *
198 * @param string $id Modal unique ID.
199 *
200 * @return $this
201 */
202 public function id( $id ) {
203 $this->id = sanitize_key( $id );
204 return $this;
205 }
206
207 /**
208 * Set modal title.
209 *
210 * @since 4.0.0
211 *
212 * @param string $title Modal title.
213 *
214 * @return $this
215 */
216 public function title( string $title ) {
217 $this->title = $title;
218 return $this;
219 }
220
221 /**
222 * Sets the confirmation message.
223 *
224 * @since 4.0.0
225 *
226 * @param string $message The confirmation message text.
227 * @param array $allowed_html_tags Optional. Allowed HTML tags and attributes. Keys are tag names and values are allowed attributes.
228 *
229 * @return $this
230 */
231 public function message( string $message, array $allowed_html_tags = array() ) {
232 $this->message = $message;
233 $this->allowed_html_tags = wp_parse_args( $allowed_html_tags, $this->allowed_html_tags );
234 return $this;
235 }
236
237 /**
238 * Set icon.
239 *
240 * @since 4.0.0
241 *
242 * @param string $icon Icon name from Icon class.
243 * @param int $width Icon width.
244 * @param int $height Icon height.
245 * @param string $type Icon type.
246 *
247 * @return $this
248 */
249 public function icon( string $icon, int $width = 100, int $height = 100, $type = null ) {
250 $this->icon = $icon;
251 $this->icon_width = $width;
252 $this->icon_height = $height;
253 $this->icon_type = $type;
254 return $this;
255 }
256
257 /**
258 * Set confirm handler function name.
259 *
260 * @since 4.0.0
261 *
262 * @param string $handler Alpine.js method name.
263 *
264 * @return $this
265 */
266 public function confirm_handler( string $handler ) {
267 $this->confirm_handler = $handler;
268 return $this;
269 }
270
271 /**
272 * Set mutation state variable name.
273 *
274 * @since 4.0.0
275 *
276 * @param string $state Mutation state variable name.
277 *
278 * @return $this
279 */
280 public function mutation_state( string $state ) {
281 $this->mutation_state = $state;
282 return $this;
283 }
284
285 /**
286 * Set cancel button text.
287 *
288 * @since 4.0.0
289 *
290 * @param string $text Cancel button text.
291 *
292 * @return $this
293 */
294 public function cancel_text( string $text ) {
295 $this->cancel_text = $text;
296 return $this;
297 }
298
299 /**
300 * Set confirm button text.
301 *
302 * @since 4.0.0
303 *
304 * @param string $text Confirm button text.
305 *
306 * @return $this
307 */
308 public function confirm_text( string $text ) {
309 $this->confirm_text = $text;
310 return $this;
311 }
312
313 /**
314 * Set custom width for modal content.
315 *
316 * @since 4.0.0
317 *
318 * @param string $width Width value (e.g., '426px', '50%').
319 *
320 * @return $this
321 */
322 public function width( string $width ) {
323 $this->width = $width;
324 return $this;
325 }
326
327 /**
328 * Set custom confirm button HTML.
329 *
330 * @since 4.0.0
331 *
332 * @param string $html Button HTML.
333 *
334 * @return $this
335 */
336 public function confirm_button( string $html ) {
337 $this->confirm_btn = $html;
338 return $this;
339 }
340
341 /**
342 * Set custom cancel button HTML.
343 *
344 * @since 4.0.0
345 *
346 * @param string $html Button HTML.
347 *
348 * @return $this
349 */
350 public function cancel_button( string $html ) {
351 $this->cancel_btn = $html;
352 return $this;
353 }
354
355 /**
356 * Get the modal HTML.
357 *
358 * @since 4.0.0
359 *
360 * @return string HTML output.
361 */
362 public function get(): string {
363 if ( empty( $this->id ) ) {
364 return '';
365 }
366
367 if ( empty( $this->icon ) ) {
368 $this->icon = tutor_utils()->get_themed_svg( 'images/illustrations/delete.svg' );
369 $this->icon_type = self::ICON_TYPE_HTML;
370 }
371
372 // Set default button texts if not provided.
373 if ( empty( $this->cancel_text ) ) {
374 $this->cancel_text = __( 'Cancel', 'tutor' );
375 }
376 if ( empty( $this->confirm_text ) ) {
377 $this->confirm_text = __( 'Yes', 'tutor' );
378 }
379
380 // Build Alpine.js x-data.
381 $alpine_data = array( 'id' => $this->id );
382 $alpine_json = wp_json_encode( $alpine_data );
383
384 // Build style attribute for custom width.
385 $style_attr = $this->width
386 ? sprintf( ' style="max-width: %s;"', esc_attr( $this->width ) )
387 : '';
388
389 // Build icon HTML.
390 $icon_html = '';
391 if ( ! empty( $this->icon ) ) {
392 if ( self::ICON_TYPE_HTML === $this->icon_type ) {
393 $icon_html = $this->icon;
394 } elseif ( filter_var( $this->icon, FILTER_VALIDATE_URL ) !== false ) {
395 $icon_html = sprintf( '<img src="%s" style="width:%spx;height:%spx;"/>', $this->icon, $this->icon_width, $this->icon_height );
396 } else {
397 ob_start();
398 SvgIcon::make()->name( $this->icon )->width( $this->icon_width )->height( $this->icon_height )->render();
399 $icon_html = ob_get_clean();
400 }
401 }
402
403 // Prepare message HTML with allowed HTML tags.
404 $message_html = wp_kses( $this->message ?? __( 'Are you sure you want to perform this action? Please confirm your choice.', 'tutor' ), $this->allowed_html_tags );
405
406 // Prepare confirm button HTML.
407 $confirm_html = $this->confirm_btn;
408 if ( empty( $confirm_html ) ) {
409 $confirm_html = sprintf(
410 '<button
411 class="tutor-btn tutor-btn-destructive tutor-btn-small"
412 :class="%s?.isPending ? \'tutor-btn-loading\' : \'\'"
413 @click="%s"
414 :disabled="%s?.isPending"
415 >
416 %s
417 </button>',
418 esc_js( $this->mutation_state ),
419 $this->confirm_handler,
420 esc_js( $this->mutation_state ),
421 esc_html( $this->confirm_text )
422 );
423 }
424
425 // Prepare cancel button HTML.
426 $cancel_html = $this->cancel_btn;
427 if ( empty( $cancel_html ) ) {
428 $cancel_html = sprintf(
429 '<button
430 class="tutor-btn tutor-btn-secondary tutor-btn-small"
431 @click="TutorCore.modal.closeModal(\'%s\')"
432 >
433 %s
434 </button>',
435 esc_js( $this->id ),
436 esc_html( $this->cancel_text )
437 );
438 }
439
440 $this->component_string = sprintf(
441 '<div x-data="tutorModal(%s)" x-cloak style="display: none;">
442 <template x-teleport="body">
443 <div x-bind="getModalBindings()">
444 <div x-bind="getBackdropBindings()"></div>
445 <div x-bind="getModalContentBindings()"%s>
446 <button x-data="tutorIcon({ name: \'cross\', width: 16, height: 16})" x-bind="getCloseButtonBindings()" aria-label="%s"></button>
447
448 <div class="tutor-p-7 tutor-pt-10 tutor-flex tutor-flex-column tutor-items-center">
449 %s
450 <h5 class="tutor-h5 tutor-font-medium tutor-mt-7">
451 %s
452 </h5>
453 <p class="tutor-p3 tutor-text-secondary tutor-mt-2 tutor-text-center">
454 %s
455 </p>
456 </div>
457
458 <div class="tutor-grid tutor-grid-cols-2 tutor-gap-4 tutor-px-7 tutor-pb-6">
459 %s
460 %s
461 </div>
462 </div>
463 </div>
464 </template>
465 </div>',
466 esc_attr( $alpine_json ),
467 $style_attr,
468 esc_attr__( 'Close', 'tutor' ),
469 $icon_html,
470 esc_html( $this->title ?? __( 'Are you sure?', 'tutor' ) ),
471 $message_html,
472 $cancel_html,
473 $confirm_html,
474 );
475
476 return $this->component_string;
477 }
478 }
479