PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.5.4
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.5.4
4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 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.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / EmbedPress / Elementor / Widgets / Embedpress_Pdf_Gallery.php
embedpress / EmbedPress / Elementor / Widgets Last commit date
Embedpress_Calendar.php 1 month ago Embedpress_Document.php 1 month ago Embedpress_Elementor.php 2 months ago Embedpress_Pdf.php 1 month ago Embedpress_Pdf_Gallery.php 2 months ago
Embedpress_Pdf_Gallery.php
947 lines
1 <?php
2
3 namespace EmbedPress\Elementor\Widgets;
4
5 use \Elementor\Controls_Manager;
6 use \Elementor\Widget_Base;
7 use \Elementor\Core\Kits\Documents\Tabs\Global_Colors;
8 use \EmbedPress\Includes\Classes\Helper;
9
10 (defined('ABSPATH')) or die("No direct script access allowed.");
11
12 class Embedpress_Pdf_Gallery extends Widget_Base
13 {
14 protected $pro_class = '';
15 protected $pro_text = '';
16
17 public function __construct($data = [], $args = null)
18 {
19 parent::__construct($data, $args);
20
21 // Enqueue editor script for multi-select media library
22 add_action('elementor/editor/after_enqueue_scripts', [$this, 'enqueue_editor_scripts']);
23 }
24
25 public function enqueue_editor_scripts()
26 {
27 $file_path = EMBEDPRESS_URL_ASSETS . 'js/pdf-gallery-elementor-editor.js';
28 wp_enqueue_script(
29 'embedpress-pdf-gallery-editor',
30 $file_path,
31 ['jquery', 'elementor-editor'],
32 EMBEDPRESS_VERSION,
33 true
34 );
35
36 wp_localize_script('embedpress-pdf-gallery-editor', 'epPdfGallery', [
37 'ajaxUrl' => admin_url('admin-ajax.php'),
38 'nonce' => wp_create_nonce('ep_pdf_gallery_nonce'),
39 'assetsUrl' => EMBEDPRESS_URL_ASSETS,
40 'isProActive' => defined('EMBEDPRESS_SL_ITEM_SLUG') ? true : false,
41 ]);
42 }
43
44 /**
45 * AJAX handler: generate a thumbnail for a PDF attachment.
46 * Checks WordPress-generated preview first, then falls back to Imagick.
47 */
48 public static function ajax_generate_pdf_thumbnail()
49 {
50 \EmbedPress\Includes\Classes\Pdf_Thumbnail_Handler::ajax_generate_pdf_thumbnail();
51 }
52
53 public static function ajax_upload_pdf_thumbnail()
54 {
55 \EmbedPress\Includes\Classes\Pdf_Thumbnail_Handler::ajax_upload_pdf_thumbnail();
56 }
57
58 public function get_name()
59 {
60 return 'embedpress_pdf_gallery';
61 }
62
63 public function get_title()
64 {
65 return esc_html__('EmbedPress PDF Gallery', 'embedpress');
66 }
67
68 public function get_categories()
69 {
70 return ['embedpress'];
71 }
72
73 public function get_icon()
74 {
75 return 'icon-pdf-gallery';
76 }
77
78 public function get_style_depends()
79 {
80 return [
81 'embedpress-pdf-gallery-css',
82 'embedpress-css',
83 ];
84 }
85
86 public function get_script_depends()
87 {
88 return [
89 'embedpress-pdf-gallery',
90 ];
91 }
92
93 public function get_keywords()
94 {
95 return ['embedpress', 'pdf', 'gallery', 'pdf gallery', 'document gallery'];
96 }
97
98 protected function register_controls()
99 {
100 $this->pro_class = apply_filters('embedpress/pro_class', 'embedpress-pro-control not-active');
101 $this->pro_text = apply_filters('embedpress/pro_text', '<sup class="embedpress-pro-label" style="color:red">' . __('Pro', 'embedpress') . '</sup>');
102
103 // ======== Content: PDF Files ========
104 $this->start_controls_section(
105 'section_pdf_files',
106 [
107 'label' => __('PDF Files', 'embedpress'),
108 ]
109 );
110
111 $this->add_control(
112 'pdf_items_json',
113 [
114 'type' => Controls_Manager::HIDDEN,
115 'default' => '[]',
116 ]
117 );
118
119 $this->add_control(
120 'pdf_selector_ui',
121 [
122 'type' => Controls_Manager::RAW_HTML,
123 'raw' => '<div class="ep-pdf-gallery-selector">'
124 . '<div class="ep-pdf-gallery-repeater" style="margin-bottom:10px;max-height:400px;overflow-y:auto;"></div>'
125 . '<div class="ep-pdf-gallery-actions">'
126 . '<button class="elementor-button elementor-button-default ep-pdf-gallery-select-btn" type="button">'
127 . '<i class="eicon-plus-circle"></i> ' . __('Add PDF Files', 'embedpress')
128 . '</button>'
129 . '<button class="elementor-button ep-pdf-gallery-clear-btn" type="button" style="margin-left:5px;color:#fff;background:#d63638;border-color:#d63638;">'
130 . __('Clear All', 'embedpress')
131 . '</button>'
132 . '</div>'
133 . '</div>'
134 . '<style>'
135 . '.ep-pdf-gallery-repeater-item{display:flex;align-items:flex-start;padding:10px;background:var(--e-a-bg-default,#fff);border:1px solid var(--e-a-border-color-bold,#dcdcde);border-radius:4px;margin-bottom:8px;gap:10px;position:relative;transition:border-color .2s;}'
136 . '.ep-pdf-gallery-repeater-item:hover{border-color:var(--e-a-color-primary-bold,#2271b1);}'
137 . '.ep-pdf-gallery-repeater-item__thumb{flex-shrink:0;width:60px;height:75px;border-radius:3px;overflow:hidden;background:var(--e-a-bg-hover,#f0f0f1);display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;border:1px dashed var(--e-a-border-color,#c3c4c7);}'
138 . '.ep-pdf-gallery-repeater-item__thumb:hover{border-color:var(--e-a-color-primary-bold,#2271b1);}'
139 . '.ep-pdf-gallery-repeater-item__thumb img{width:100%;height:100%;object-fit:cover;}'
140 . '.ep-pdf-gallery-repeater-item__thumb canvas{width:100%;height:100%;object-fit:cover;}'
141 . '.ep-pdf-gallery-repeater-item__thumb-overlay{position:absolute;inset:0;background:rgba(0,0,0,.4);display:none;align-items:center;justify-content:center;color:#fff;font-size:16px;border-radius:3px;}'
142 . '.ep-pdf-gallery-repeater-item__thumb:hover .ep-pdf-gallery-repeater-item__thumb-overlay{display:flex;}'
143 . '.ep-pdf-gallery-repeater-item__thumb-placeholder{color:var(--e-a-color-txt-muted,#a7aaad);}'
144 . '.ep-pdf-gallery-repeater-item__content{flex:1;min-width:0;}'
145 . '.ep-pdf-gallery-repeater-item__name{font-size:12px;font-weight:500;color:var(--e-a-color-txt,#1e1e1e);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-bottom:6px;}'
146 . '.ep-pdf-gallery-repeater-item__thumb-label{font-size:10px;color:var(--e-a-color-txt-muted,#757575);margin-bottom:4px;}'
147 . '.ep-pdf-gallery-repeater-item__thumb-actions{display:flex;gap:4px;margin-bottom:6px;}'
148 . '.ep-pdf-gallery-repeater-item__thumb-btn{font-size:11px;padding:2px 8px;border:1px solid var(--e-a-border-color,#c3c4c7);border-radius:3px;background:var(--e-a-bg-default,#fff);cursor:pointer;color:var(--e-a-color-primary-bold,#2271b1);line-height:1.6;}'
149 . '.ep-pdf-gallery-repeater-item__thumb-btn:hover{background:var(--e-a-bg-hover,#f0f0f1);border-color:var(--e-a-color-primary-bold,#2271b1);}'
150 . '.ep-pdf-gallery-repeater-item__thumb-btn--remove{color:var(--e-a-color-danger,#d63638);}'
151 . '.ep-pdf-gallery-repeater-item__thumb-btn--remove:hover{color:var(--e-a-color-danger-bold,#a00);border-color:var(--e-a-color-danger,#d63638);}'
152 . '.ep-pdf-gallery-repeater-item__order-actions{display:flex;gap:3px;}'
153 . '.ep-pdf-gallery-repeater-item__order-btn{width:24px;height:24px;border:1px solid var(--e-a-border-color,#c3c4c7);border-radius:3px;background:var(--e-a-bg-default,#fff);cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--e-a-color-txt-muted,#50575e);padding:0;}'
154 . '.ep-pdf-gallery-repeater-item__order-btn:hover{background:var(--e-a-bg-hover,#f0f0f1);border-color:var(--e-a-color-primary-bold,#2271b1);color:var(--e-a-color-primary-bold,#2271b1);}'
155 . '.ep-pdf-gallery-repeater-item__order-btn:disabled{opacity:.3;cursor:default;}'
156 . '.ep-pdf-gallery-repeater-item__remove-btn{position:absolute;top:6px;right:6px;width:20px;height:20px;border:none;background:none;cursor:pointer;color:var(--e-a-color-danger,#d63638);font-size:18px;line-height:1;padding:0;display:flex;align-items:center;justify-content:center;border-radius:50%;}'
157 . '.ep-pdf-gallery-repeater-item__remove-btn:hover{background:var(--e-a-bg-danger,rgba(214,54,56,.1));}'
158 . '.ep-pdf-gallery-empty{padding:20px;text-align:center;color:var(--e-a-color-txt-muted,#757575);font-size:12px;background:var(--e-a-bg-hover,#f6f7f7);border:1px dashed var(--e-a-border-color,#c3c4c7);border-radius:4px;}'
159 . '.ep-pdf-gallery-select-btn{width:auto!important;}'
160 . '.ep-pdf-gallery-actions{display:flex;align-items:center;}'
161 . '.ep-pdf-gallery-repeater-item__spinner{width:24px;height:24px;border:3px solid var(--e-a-border-color,#c3c4c7);border-top-color:var(--e-a-color-primary-bold,#2271b1);border-radius:50%;animation:ep-spin .8s linear infinite;}'
162 . '@keyframes ep-spin{to{transform:rotate(360deg);}}'
163 . '.ep-pdf-gallery-repeater-item__thumb.is-generating{border-style:solid;}'
164 . '.ep-pdf-gallery-repeater-item__status{font-size:9px;color:var(--e-a-color-txt-muted,#999);font-style:italic;}'
165 . '</style>',
166 ]
167 );
168
169 $this->end_controls_section();
170
171 // ======== Layout ========
172 $this->start_controls_section(
173 'section_layout',
174 [
175 'label' => __('Layout', 'embedpress'),
176 ]
177 );
178
179 $this->add_control(
180 'layout',
181 [
182 'label' => __('Layout Type', 'embedpress'),
183 'type' => Controls_Manager::SELECT,
184 'default' => 'grid',
185 'options' => [
186 'grid' => __('Grid', 'embedpress'),
187 'masonry' => __('Masonry', 'embedpress'),
188 'carousel' => __('Carousel', 'embedpress') . ' ' . $this->pro_text,
189 'bookshelf' => __('Bookshelf', 'embedpress') . ' ' . $this->pro_text,
190 ],
191 ]
192 );
193
194 $this->add_control(
195 'bookshelf_style',
196 [
197 'label' => __('Shelf Style', 'embedpress'),
198 'type' => Controls_Manager::SELECT,
199 'default' => 'dark-wood',
200 'options' => [
201 'dark-wood' => __('Dark Wood', 'embedpress'),
202 'light-wood' => __('Light Wood', 'embedpress'),
203 'glass' => __('Glass', 'embedpress'),
204 ],
205 'condition' => [
206 'layout' => 'bookshelf',
207 ],
208 ]
209 );
210
211 $this->add_responsive_control(
212 'columns',
213 [
214 'label' => __('Columns', 'embedpress'),
215 'type' => Controls_Manager::SELECT,
216 'default' => '3',
217 'tablet_default' => '2',
218 'mobile_default' => '1',
219 'options' => [
220 '1' => '1',
221 '2' => '2',
222 '3' => '3',
223 '4' => '4',
224 '5' => '5',
225 '6' => '6',
226 ],
227 'selectors' => [
228 '{{WRAPPER}} .ep-pdf-gallery' => '--ep-gallery-columns: {{VALUE}};',
229 ],
230 'render_type' => 'template',
231 'condition' => [
232 'layout!' => 'carousel',
233 ],
234 ]
235 );
236
237 $this->add_control(
238 'gap',
239 [
240 'label' => __('Gap', 'embedpress'),
241 'type' => Controls_Manager::SLIDER,
242 'default' => ['size' => 20],
243 'range' => [
244 'px' => ['min' => 0, 'max' => 60],
245 ],
246 ]
247 );
248
249 $this->add_control(
250 'aspect_ratio',
251 [
252 'label' => __('Thumbnail Aspect Ratio', 'embedpress'),
253 'type' => Controls_Manager::SELECT,
254 'default' => '4:3',
255 'options' => [
256 '4:3' => '4:3',
257 '1:1' => '1:1',
258 '3:4' => '3:4',
259 '16:9' => '16:9',
260 ],
261 ]
262 );
263
264 $this->add_control(
265 'border_radius',
266 [
267 'label' => __('Border Radius', 'embedpress'),
268 'type' => Controls_Manager::SLIDER,
269 'default' => ['size' => 8],
270 'range' => [
271 'px' => ['min' => 0, 'max' => 30],
272 ],
273 ]
274 );
275
276 $this->end_controls_section();
277
278 // ======== Play Button ========
279 $this->start_controls_section(
280 'section_play_button',
281 [
282 'label' => __('Play Button', 'embedpress'),
283 ]
284 );
285
286 $this->add_control(
287 'show_play_button',
288 [
289 'label' => __('Show Play Button', 'embedpress'),
290 'type' => Controls_Manager::SWITCHER,
291 'default' => 'yes',
292 ]
293 );
294
295 $this->add_control(
296 'play_button_icon',
297 [
298 'label' => __('Icon', 'embedpress'),
299 'type' => Controls_Manager::SELECT,
300 'default' => 'play',
301 'options' => [
302 'play' => __('Play', 'embedpress'),
303 'eye' => __('View / Eye', 'embedpress'),
304 'document' => __('Document', 'embedpress'),
305 'none' => __('None (Background Only)', 'embedpress'),
306 ],
307 'condition' => ['show_play_button' => 'yes'],
308 ]
309 );
310
311 $this->add_control(
312 'play_button_color',
313 [
314 'label' => __('Icon Color', 'embedpress'),
315 'type' => Controls_Manager::COLOR,
316 'default' => '#ffffff',
317 'selectors' => [
318 '{{WRAPPER}} .ep-pdf-gallery__view-icon' => 'fill: {{VALUE}};',
319 ],
320 'condition' => [
321 'show_play_button' => 'yes',
322 'play_button_icon!' => 'none',
323 ],
324 ]
325 );
326
327 $this->add_control(
328 'play_button_size',
329 [
330 'label' => __('Icon Size', 'embedpress'),
331 'type' => Controls_Manager::SLIDER,
332 'default' => ['size' => 44],
333 'range' => [
334 'px' => ['min' => 24, 'max' => 80],
335 ],
336 'selectors' => [
337 '{{WRAPPER}} .ep-pdf-gallery__view-icon' => 'width: {{SIZE}}px; height: {{SIZE}}px;',
338 ],
339 'condition' => [
340 'show_play_button' => 'yes',
341 'play_button_icon!' => 'none',
342 ],
343 ]
344 );
345
346 $this->add_control(
347 'play_button_bg',
348 [
349 'label' => __('Background Color', 'embedpress'),
350 'type' => Controls_Manager::COLOR,
351 'default' => 'rgba(0, 0, 0, 0.6)',
352 'selectors' => [
353 '{{WRAPPER}} .ep-pdf-gallery__view-icon' => 'background-color: {{VALUE}};',
354 ],
355 'condition' => ['show_play_button' => 'yes'],
356 ]
357 );
358
359 $this->add_control(
360 'play_button_shape',
361 [
362 'label' => __('Background Shape', 'embedpress'),
363 'type' => Controls_Manager::SELECT,
364 'default' => 'circle',
365 'options' => [
366 'circle' => __('Circle', 'embedpress'),
367 'rounded-square' => __('Rounded Square', 'embedpress'),
368 'none' => __('None', 'embedpress'),
369 ],
370 'condition' => [
371 'show_play_button' => 'yes',
372 ],
373 ]
374 );
375
376 $this->add_control(
377 'hover_overlay_color',
378 [
379 'label' => __('Hover Overlay Color', 'embedpress'),
380 'type' => Controls_Manager::COLOR,
381 'default' => 'rgba(0, 0, 0, 0.35)',
382 'selectors' => [
383 '{{WRAPPER}} .ep-pdf-gallery__item:hover .ep-pdf-gallery__overlay' => 'background: {{VALUE}};',
384 '{{WRAPPER}} .ep-pdf-gallery__item--always-show .ep-pdf-gallery__overlay' => 'background: {{VALUE}};',
385 ],
386 'condition' => ['show_play_button' => 'yes'],
387 ]
388 );
389
390 $this->add_control(
391 'play_button_always_show',
392 [
393 'label' => __('Always Visible', 'embedpress'),
394 'description' => __('Show button without hover', 'embedpress'),
395 'type' => Controls_Manager::SWITCHER,
396 'default' => '',
397 'condition' => ['show_play_button' => 'yes'],
398 ]
399 );
400
401 $this->end_controls_section();
402
403 // ======== Carousel ========
404 $this->start_controls_section(
405 'section_carousel',
406 [
407 'label' => __('Carousel', 'embedpress'),
408 'condition' => ['layout' => 'carousel'],
409 ]
410 );
411
412 $this->add_control(
413 'slides_per_view',
414 [
415 'label' => __('Slides Per View', 'embedpress'),
416 'type' => Controls_Manager::NUMBER,
417 'default' => 3,
418 'min' => 1,
419 'max' => 6,
420 ]
421 );
422
423 $this->add_control(
424 'carousel_autoplay',
425 [
426 'label' => __('Autoplay', 'embedpress'),
427 'type' => Controls_Manager::SWITCHER,
428 'default' => '',
429 ]
430 );
431
432 $this->add_control(
433 'carousel_speed',
434 [
435 'label' => __('Autoplay Speed (ms)', 'embedpress'),
436 'type' => Controls_Manager::NUMBER,
437 'default' => 3000,
438 'min' => 1000,
439 'max' => 10000,
440 'step' => 500,
441 'condition' => ['carousel_autoplay' => 'yes'],
442 ]
443 );
444
445 $this->add_control(
446 'carousel_loop',
447 [
448 'label' => __('Loop', 'embedpress'),
449 'type' => Controls_Manager::SWITCHER,
450 'default' => 'yes',
451 ]
452 );
453
454 $this->add_control(
455 'carousel_arrows',
456 [
457 'label' => __('Arrows', 'embedpress'),
458 'type' => Controls_Manager::SWITCHER,
459 'default' => 'yes',
460 ]
461 );
462
463 $this->add_control(
464 'carousel_dots',
465 [
466 'label' => __('Dots', 'embedpress'),
467 'type' => Controls_Manager::SWITCHER,
468 'default' => '',
469 ]
470 );
471
472 $this->end_controls_section();
473
474 // ======== PDF Viewer ========
475 $this->start_controls_section(
476 'section_viewer',
477 [
478 'label' => __('PDF Viewer (Popup)', 'embedpress'),
479 ]
480 );
481
482 $this->add_control(
483 'viewer_style',
484 [
485 'label' => __('Viewer Style', 'embedpress'),
486 'type' => Controls_Manager::SELECT,
487 'default' => 'modern',
488 'options' => [
489 'modern' => __('Modern', 'embedpress'),
490 'flip-book' => __('Flip Book', 'embedpress'),
491 ],
492 ]
493 );
494
495 $this->add_control(
496 'theme_mode',
497 [
498 'label' => __('Theme', 'embedpress'),
499 'type' => Controls_Manager::SELECT,
500 'default' => 'default',
501 'options' => [
502 'default' => __('System Default', 'embedpress'),
503 'dark' => __('Dark', 'embedpress'),
504 'light' => __('Light', 'embedpress'),
505 'custom' => __('Custom', 'embedpress'),
506 ],
507 ]
508 );
509
510 $this->add_control(
511 'custom_color',
512 [
513 'label' => __('Custom Color', 'embedpress'),
514 'type' => Controls_Manager::COLOR,
515 'default' => '#403A81',
516 'condition' => ['theme_mode' => 'custom'],
517 ]
518 );
519
520 $this->add_control(
521 'pdf_toolbar',
522 [
523 'label' => sprintf(__('Toolbar %s', 'embedpress'), $this->pro_text),
524 'type' => Controls_Manager::SWITCHER,
525 'default' => 'yes',
526 'classes' => $this->pro_class,
527 ]
528 );
529
530 $this->add_control(
531 'toolbar_position',
532 [
533 'label' => __('Toolbar Position', 'embedpress'),
534 'type' => Controls_Manager::SELECT,
535 'default' => 'top',
536 'options' => [
537 'top' => __('Top', 'embedpress'),
538 'bottom' => __('Bottom', 'embedpress'),
539 ],
540 'condition' => ['pdf_toolbar' => 'yes'],
541 ]
542 );
543
544 $this->add_control(
545 'presentation',
546 [
547 'label' => __('Presentation Mode', 'embedpress'),
548 'type' => Controls_Manager::SWITCHER,
549 'default' => 'yes',
550 ]
551 );
552
553 $this->add_control(
554 'download',
555 [
556 'label' => sprintf(__('Print/Download %s', 'embedpress'), $this->pro_text),
557 'type' => Controls_Manager::SWITCHER,
558 'default' => 'yes',
559 'classes' => $this->pro_class,
560 ]
561 );
562
563 $this->add_control(
564 'copy_text',
565 [
566 'label' => sprintf(__('Copy Text %s', 'embedpress'), $this->pro_text),
567 'type' => Controls_Manager::SWITCHER,
568 'default' => 'yes',
569 'condition' => ['viewer_style' => 'modern'],
570 'classes' => $this->pro_class,
571 ]
572 );
573
574 $this->add_control(
575 'draw',
576 [
577 'label' => sprintf(__('Draw %s', 'embedpress'), $this->pro_text),
578 'type' => Controls_Manager::SWITCHER,
579 'default' => 'yes',
580 'condition' => ['viewer_style' => 'modern'],
581 'classes' => $this->pro_class,
582 ]
583 );
584
585 $this->add_control(
586 'add_text',
587 [
588 'label' => __('Add Text', 'embedpress'),
589 'type' => Controls_Manager::SWITCHER,
590 'default' => 'yes',
591 'condition' => ['viewer_style' => 'modern'],
592 ]
593 );
594
595 $this->add_control(
596 'add_image',
597 [
598 'label' => __('Add Image', 'embedpress'),
599 'type' => Controls_Manager::SWITCHER,
600 'default' => 'yes',
601 'condition' => ['viewer_style' => 'modern'],
602 ]
603 );
604
605 $this->add_control(
606 'doc_rotation',
607 [
608 'label' => __('Rotation', 'embedpress'),
609 'type' => Controls_Manager::SWITCHER,
610 'default' => 'yes',
611 'condition' => ['viewer_style' => 'modern'],
612 ]
613 );
614
615 $this->add_control(
616 'doc_details',
617 [
618 'label' => __('Properties', 'embedpress'),
619 'type' => Controls_Manager::SWITCHER,
620 'default' => 'yes',
621 'condition' => ['viewer_style' => 'modern'],
622 ]
623 );
624
625 $this->add_control(
626 'zoom_in',
627 [
628 'label' => __('Zoom In', 'embedpress'),
629 'type' => Controls_Manager::SWITCHER,
630 'default' => 'yes',
631 'condition' => ['viewer_style' => 'flip-book'],
632 ]
633 );
634
635 $this->add_control(
636 'zoom_out',
637 [
638 'label' => __('Zoom Out', 'embedpress'),
639 'type' => Controls_Manager::SWITCHER,
640 'default' => 'yes',
641 'condition' => ['viewer_style' => 'flip-book'],
642 ]
643 );
644
645 $this->add_control(
646 'fit_view',
647 [
648 'label' => __('Fit View', 'embedpress'),
649 'type' => Controls_Manager::SWITCHER,
650 'default' => 'yes',
651 'condition' => ['viewer_style' => 'flip-book'],
652 ]
653 );
654
655 $this->add_control(
656 'bookmark',
657 [
658 'label' => __('Bookmark', 'embedpress'),
659 'type' => Controls_Manager::SWITCHER,
660 'default' => 'yes',
661 'condition' => ['viewer_style' => 'flip-book'],
662 ]
663 );
664
665 $this->end_controls_section();
666
667 // Watermark Controls Section
668 $this->start_controls_section(
669 'watermark_section',
670 [
671 'label' => __('Watermark', 'embedpress'),
672 ]
673 );
674
675 $this->add_control(
676 'watermark_text',
677 [
678 'label' => sprintf(__('Watermark Text %s', 'embedpress'), $this->pro_text),
679 'type' => Controls_Manager::TEXT,
680 'default' => '',
681 'placeholder' => __('e.g. CONFIDENTIAL', 'embedpress'),
682 'classes' => $this->pro_class,
683 ]
684 );
685
686 $this->add_control(
687 'watermark_style',
688 [
689 'label' => __('Watermark Style', 'embedpress'),
690 'type' => Controls_Manager::SELECT,
691 'options' => [
692 'center' => __('Center Diagonal', 'embedpress'),
693 'tiled' => __('Tiled / Repeated', 'embedpress'),
694 ],
695 'default' => 'center',
696 'condition' => defined('EMBEDPRESS_SL_ITEM_SLUG') ? ['watermark_text!' => ''] : [],
697 'classes' => $this->pro_class,
698 ]
699 );
700
701 $this->add_control(
702 'watermark_font_size',
703 [
704 'label' => __('Font Size (px)', 'embedpress'),
705 'type' => Controls_Manager::NUMBER,
706 'default' => 48,
707 'min' => 10,
708 'max' => 200,
709 'condition' => defined('EMBEDPRESS_SL_ITEM_SLUG') ? ['watermark_text!' => ''] : [],
710 'classes' => $this->pro_class,
711 ]
712 );
713
714 $this->add_control(
715 'watermark_color',
716 [
717 'label' => __('Color', 'embedpress'),
718 'type' => Controls_Manager::COLOR,
719 'default' => '#000000',
720 'global' => [
721 'default' => Global_Colors::COLOR_PRIMARY,
722 ],
723 'condition' => defined('EMBEDPRESS_SL_ITEM_SLUG') ? ['watermark_text!' => ''] : [],
724 'classes' => $this->pro_class,
725 ]
726 );
727
728 $this->add_control(
729 'watermark_opacity',
730 [
731 'label' => __('Opacity (%)', 'embedpress'),
732 'type' => Controls_Manager::NUMBER,
733 'default' => 15,
734 'min' => 1,
735 'max' => 100,
736 'condition' => defined('EMBEDPRESS_SL_ITEM_SLUG') ? ['watermark_text!' => ''] : [],
737 'classes' => $this->pro_class,
738 ]
739 );
740
741 $this->end_controls_section();
742 }
743
744 /**
745 * Generate base64 viewer params
746 */
747 private function getParamData($settings)
748 {
749 $theme_mode = !empty($settings['theme_mode']) ? $settings['theme_mode'] : 'default';
750
751 $params = [
752 'themeMode' => $theme_mode,
753 'toolbar' => defined('EMBEDPRESS_PRO_PLUGIN_VERSION') ? (!empty($settings['pdf_toolbar']) ? 'true' : 'false') : 'true',
754 'position' => !empty($settings['toolbar_position']) ? $settings['toolbar_position'] : 'top',
755 'flipbook_toolbar_position' => !empty($settings['toolbar_position']) ? $settings['toolbar_position'] : 'bottom',
756 'presentation' => !empty($settings['presentation']) ? 'true' : 'false',
757 'download' => defined('EMBEDPRESS_PRO_PLUGIN_VERSION') ? (!empty($settings['download']) ? 'true' : 'false') : 'true',
758 'copy_text' => defined('EMBEDPRESS_PRO_PLUGIN_VERSION') ? (!empty($settings['copy_text']) ? 'true' : 'false') : 'true',
759 'add_text' => !empty($settings['add_text']) ? 'true' : 'false',
760 'draw' => defined('EMBEDPRESS_PRO_PLUGIN_VERSION') ? (!empty($settings['draw']) ? 'true' : 'false') : 'true',
761 'doc_rotation' => !empty($settings['doc_rotation']) ? 'true' : 'false',
762 'doc_details' => !empty($settings['doc_details']) ? 'true' : 'false',
763 'add_image' => !empty($settings['add_image']) ? 'true' : 'false',
764 'zoom_in' => !empty($settings['zoom_in']) ? 'true' : 'false',
765 'zoom_out' => !empty($settings['zoom_out']) ? 'true' : 'false',
766 'fit_view' => !empty($settings['fit_view']) ? 'true' : 'false',
767 'bookmark' => !empty($settings['bookmark']) ? 'true' : 'false',
768 'watermark_text' => defined('EMBEDPRESS_SL_ITEM_SLUG') && !empty($settings['watermark_text']) ? $settings['watermark_text'] : '',
769 'watermark_font_size' => defined('EMBEDPRESS_SL_ITEM_SLUG') && !empty($settings['watermark_font_size']) ? $settings['watermark_font_size'] : '48',
770 'watermark_color' => defined('EMBEDPRESS_SL_ITEM_SLUG') && !empty($settings['watermark_color']) ? Helper::get_elementor_global_color($settings, 'watermark_color') : '#000000',
771 'watermark_opacity' => defined('EMBEDPRESS_SL_ITEM_SLUG') && isset($settings['watermark_opacity']) ? $settings['watermark_opacity'] : '15',
772 'watermark_style' => defined('EMBEDPRESS_SL_ITEM_SLUG') && !empty($settings['watermark_style']) ? $settings['watermark_style'] : 'center',
773 ];
774
775 if ($theme_mode === 'custom') {
776 $params['customColor'] = !empty($settings['custom_color']) ? Helper::get_elementor_global_color($settings, 'custom_color') : '#403A81';
777 }
778
779 $query_string = http_build_query($params);
780 if (function_exists('mb_convert_encoding')) {
781 $query_string = mb_convert_encoding($query_string, 'UTF-8');
782 }
783
784 return base64_encode($query_string);
785 }
786
787 /**
788 * Parse PDF items from JSON control
789 */
790 private function get_pdf_items($settings)
791 {
792 $raw = !empty($settings['pdf_items_json']) ? $settings['pdf_items_json'] : '[]';
793 $items = json_decode($raw, true);
794 return is_array($items) ? $items : [];
795 }
796
797 protected function render()
798 {
799 $settings = $this->get_settings_for_display();
800 $pdf_items = $this->get_pdf_items($settings);
801
802 if (empty($pdf_items)) {
803 if (\Elementor\Plugin::$instance->editor->is_edit_mode()) {
804 echo '<div style="padding:40px;text-align:center;background:#f5f5f5;border-radius:8px;color:#999;">';
805 echo esc_html__('Click "Select PDF Files" to add PDFs to the gallery.', 'embedpress');
806 echo '</div>';
807 }
808 return;
809 }
810
811 $layout = !empty($settings['layout']) ? esc_attr($settings['layout']) : 'grid';
812
813 // Pro gate: bookshelf requires Pro
814 if (($layout === 'bookshelf' || $layout === 'carousel') && !defined('EMBEDPRESS_SL_ITEM_SLUG')) {
815 $layout = 'grid';
816 }
817
818 $columns = !empty($settings['columns']) ? intval($settings['columns']) : 3;
819 $columns_tablet = !empty($settings['columns_tablet']) ? intval($settings['columns_tablet']) : 2;
820 $columns_mobile = !empty($settings['columns_mobile']) ? intval($settings['columns_mobile']) : 1;
821 $gap = isset($settings['gap']['size']) ? intval($settings['gap']['size']) : 20;
822 $border_radius = isset($settings['border_radius']['size']) ? intval($settings['border_radius']['size']) : 8;
823 $aspect_ratio = !empty($settings['aspect_ratio']) ? esc_attr($settings['aspect_ratio']) : '4:3';
824 $viewer_style = !empty($settings['viewer_style']) ? esc_attr($settings['viewer_style']) : 'modern';
825
826 $viewer_params = $this->getParamData($settings);
827 $gallery_id = 'ep-gallery-' . $this->get_id();
828
829 $carousel_options = '';
830 if ($layout === 'carousel' || $layout === 'bookshelf') {
831 $carousel_options = wp_json_encode([
832 'autoplay' => !empty($settings['carousel_autoplay']),
833 'autoplaySpeed' => !empty($settings['carousel_speed']) ? intval($settings['carousel_speed']) : 3000,
834 'loop' => $settings['carousel_loop'] !== '',
835 'arrows' => $settings['carousel_arrows'] !== '',
836 'dots' => !empty($settings['carousel_dots']),
837 'slidesPerView' => !empty($settings['slides_per_view']) ? intval($settings['slides_per_view']) : 3,
838 ]);
839 }
840
841 // Play button settings
842 $show_play_btn = !empty($settings['show_play_button']) && $settings['show_play_button'] === 'yes';
843 $play_icon = !empty($settings['play_button_icon']) ? $settings['play_button_icon'] : 'play';
844 $play_shape = !empty($settings['play_button_shape']) ? $settings['play_button_shape'] : 'circle';
845 $always_show = !empty($settings['play_button_always_show']) && $settings['play_button_always_show'] === 'yes';
846
847 // Icon SVG paths
848 $icon_paths = [
849 'play' => 'M8 5v14l11-7z',
850 'eye' => 'M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z',
851 'document' => 'M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z',
852 ];
853 $icon_path = isset($icon_paths[$play_icon]) ? $icon_paths[$play_icon] : $icon_paths['play'];
854
855 // Icon inline style — only shape and always-show (colors/size handled by Elementor selectors)
856 $icon_style_parts = [];
857 if ($play_shape === 'circle') {
858 $icon_style_parts[] = 'border-radius:50%';
859 } elseif ($play_shape === 'rounded-square') {
860 $icon_style_parts[] = 'border-radius:12px';
861 } else {
862 $icon_style_parts[] = 'border-radius:0';
863 }
864 if ($always_show) {
865 $icon_style_parts[] = 'opacity:1';
866 $icon_style_parts[] = 'transform:scale(1)';
867 }
868 $icon_style = implode(';', $icon_style_parts);
869
870 $item_class = 'ep-pdf-gallery__item' . ($always_show ? ' ep-pdf-gallery__item--always-show' : '');
871
872 $style = sprintf(
873 '--ep-gallery-gap:%dpx;--ep-gallery-radius:%dpx;',
874 $gap, $border_radius
875 );
876 ?>
877 <div class="ep-pdf-gallery"
878 data-layout="<?php echo $layout; ?>"
879 data-shelf-style="<?php echo esc_attr(!empty($settings['bookshelf_style']) ? $settings['bookshelf_style'] : 'dark-wood'); ?>"
880 data-columns="<?php echo $columns; ?>"
881 data-columns-tablet="<?php echo $columns_tablet; ?>"
882 data-columns-mobile="<?php echo $columns_mobile; ?>"
883 data-gap="<?php echo $gap; ?>"
884 data-border-radius="<?php echo $border_radius; ?>"
885 data-viewer-style="<?php echo $viewer_style; ?>"
886 data-viewer-params="<?php echo esc_attr($viewer_params); ?>"
887 data-gallery-id="<?php echo esc_attr($gallery_id); ?>"
888 <?php if ($carousel_options): ?>data-carousel-options="<?php echo esc_attr($carousel_options); ?>"<?php endif; ?>
889 style="<?php echo esc_attr($style); ?>">
890
891 <?php if ($layout === 'carousel' || $layout === 'bookshelf'): ?>
892 <div class="ep-pdf-gallery__carousel">
893 <div class="ep-pdf-gallery__carousel-track">
894 <?php else: ?>
895 <div class="ep-pdf-gallery__grid">
896 <?php endif; ?>
897
898 <?php foreach ($pdf_items as $index => $item):
899 $pdf_url = !empty($item['url']) ? esc_url($item['url']) : '';
900 if (empty($pdf_url)) continue;
901 $pdf_name = !empty($item['fileName']) ? $item['fileName'] : basename(parse_url($pdf_url, PHP_URL_PATH));
902 $custom_thumb = !empty($item['customThumbnailUrl']) ? esc_url($item['customThumbnailUrl']) : '';
903 $auto_thumb = !empty($item['autoThumbnailUrl']) ? esc_url($item['autoThumbnailUrl']) : '';
904 $thumb_url = $custom_thumb ?: $auto_thumb;
905 ?>
906 <div class="<?php echo esc_attr($item_class); ?>"
907 data-pdf-url="<?php echo $pdf_url; ?>"
908 data-pdf-index="<?php echo intval($index); ?>"
909 data-pdf-name="<?php echo esc_attr($pdf_name); ?>">
910 <div class="ep-pdf-gallery__thumbnail-wrap" data-ratio="<?php echo $aspect_ratio; ?>">
911 <?php if ($thumb_url): ?>
912 <img src="<?php echo $thumb_url; ?>" alt="<?php echo esc_attr($pdf_name); ?>" />
913 <?php else: ?>
914 <canvas class="ep-pdf-gallery__canvas" data-pdf-src="<?php echo $pdf_url; ?>" data-loading="true"></canvas>
915 <?php endif; ?>
916 <?php if ($show_play_btn): ?>
917 <div class="ep-pdf-gallery__overlay">
918 <?php if ($play_icon !== 'none'): ?>
919 <svg class="ep-pdf-gallery__view-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" style="<?php echo esc_attr($icon_style); ?>">
920 <path d="<?php echo $icon_path; ?>"/>
921 </svg>
922 <?php endif; ?>
923 </div>
924 <?php endif; ?>
925 </div>
926 <div class="ep-pdf-gallery__book-title"><?php echo esc_html($pdf_name); ?></div>
927 </div>
928 <?php endforeach; ?>
929
930 <?php if ($layout === 'carousel' || $layout === 'bookshelf'): ?>
931 </div>
932 <button class="ep-pdf-gallery__carousel-prev" aria-label="Previous">
933 <svg viewBox="0 0 24 24"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>
934 </button>
935 <button class="ep-pdf-gallery__carousel-next" aria-label="Next">
936 <svg viewBox="0 0 24 24"><path d="M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z"/></svg>
937 </button>
938 <div class="ep-pdf-gallery__carousel-dots"></div>
939 </div>
940 <?php else: ?>
941 </div>
942 <?php endif; ?>
943 </div>
944 <?php
945 }
946 }
947