PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.6.0
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.6.0
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 2 weeks ago Embedpress_Elementor.php 1 month ago Embedpress_Google_Reviews.php 5 days ago Embedpress_Pdf.php 5 days ago Embedpress_Pdf_Gallery.php 5 days ago
Embedpress_Pdf_Gallery.php
986 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->add_control(
666 'flipbook_rtl',
667 [
668 'label' => sprintf(__('RTL Page Flip %s', 'embedpress'), $this->pro_text),
669 'description' => __('Reverse the page-turn direction so the flipbook opens and flips from right to left.', 'embedpress'),
670 'type' => Controls_Manager::SWITCHER,
671 'default' => '',
672 'classes' => $this->pro_class,
673 'condition' => ['viewer_style' => 'flip-book'],
674 ]
675 );
676
677 $this->add_control(
678 'flipbook_highlight_links',
679 [
680 'label' => __('Highlight Links', 'embedpress'),
681 'description' => __('Show a colored background behind hyperlinks in the flipbook.', 'embedpress'),
682 'type' => Controls_Manager::SWITCHER,
683 'default' => '',
684 'condition' => ['viewer_style' => 'flip-book'],
685 ]
686 );
687
688 $this->add_control(
689 'flipbook_highlight_color',
690 [
691 'label' => __('Highlight Color', 'embedpress'),
692 'type' => Controls_Manager::COLOR,
693 'default' => 'rgba(255, 255, 0, 0.1)',
694 'condition' => [
695 'viewer_style' => 'flip-book',
696 'flipbook_highlight_links' => 'yes',
697 ],
698 ]
699 );
700
701 $this->end_controls_section();
702
703 // Watermark Controls Section
704 $this->start_controls_section(
705 'watermark_section',
706 [
707 'label' => __('Watermark', 'embedpress'),
708 ]
709 );
710
711 $this->add_control(
712 'watermark_text',
713 [
714 'label' => sprintf(__('Watermark Text %s', 'embedpress'), $this->pro_text),
715 'type' => Controls_Manager::TEXT,
716 'default' => '',
717 'placeholder' => __('e.g. CONFIDENTIAL', 'embedpress'),
718 'classes' => $this->pro_class,
719 ]
720 );
721
722 $this->add_control(
723 'watermark_style',
724 [
725 'label' => __('Watermark Style', 'embedpress'),
726 'type' => Controls_Manager::SELECT,
727 'options' => [
728 'center' => __('Center Diagonal', 'embedpress'),
729 'tiled' => __('Tiled / Repeated', 'embedpress'),
730 ],
731 'default' => 'center',
732 'condition' => defined('EMBEDPRESS_SL_ITEM_SLUG') ? ['watermark_text!' => ''] : [],
733 'classes' => $this->pro_class,
734 ]
735 );
736
737 $this->add_control(
738 'watermark_font_size',
739 [
740 'label' => __('Font Size (px)', 'embedpress'),
741 'type' => Controls_Manager::NUMBER,
742 'default' => 48,
743 'min' => 10,
744 'max' => 200,
745 'condition' => defined('EMBEDPRESS_SL_ITEM_SLUG') ? ['watermark_text!' => ''] : [],
746 'classes' => $this->pro_class,
747 ]
748 );
749
750 $this->add_control(
751 'watermark_color',
752 [
753 'label' => __('Color', 'embedpress'),
754 'type' => Controls_Manager::COLOR,
755 'default' => '#000000',
756 'global' => [
757 'default' => Global_Colors::COLOR_PRIMARY,
758 ],
759 'condition' => defined('EMBEDPRESS_SL_ITEM_SLUG') ? ['watermark_text!' => ''] : [],
760 'classes' => $this->pro_class,
761 ]
762 );
763
764 $this->add_control(
765 'watermark_opacity',
766 [
767 'label' => __('Opacity (%)', 'embedpress'),
768 'type' => Controls_Manager::NUMBER,
769 'default' => 15,
770 'min' => 1,
771 'max' => 100,
772 'condition' => defined('EMBEDPRESS_SL_ITEM_SLUG') ? ['watermark_text!' => ''] : [],
773 'classes' => $this->pro_class,
774 ]
775 );
776
777 $this->end_controls_section();
778 }
779
780 /**
781 * Generate base64 viewer params
782 */
783 private function getParamData($settings)
784 {
785 $theme_mode = !empty($settings['theme_mode']) ? $settings['theme_mode'] : 'default';
786
787 $params = [
788 'themeMode' => $theme_mode,
789 'toolbar' => defined('EMBEDPRESS_PRO_PLUGIN_VERSION') ? (!empty($settings['pdf_toolbar']) ? 'true' : 'false') : 'true',
790 'position' => !empty($settings['toolbar_position']) ? $settings['toolbar_position'] : 'top',
791 'flipbook_toolbar_position' => !empty($settings['toolbar_position']) ? $settings['toolbar_position'] : 'bottom',
792 'presentation' => !empty($settings['presentation']) ? 'true' : 'false',
793 'download' => defined('EMBEDPRESS_PRO_PLUGIN_VERSION') ? (!empty($settings['download']) ? 'true' : 'false') : 'true',
794 'copy_text' => defined('EMBEDPRESS_PRO_PLUGIN_VERSION') ? (!empty($settings['copy_text']) ? 'true' : 'false') : 'true',
795 'add_text' => !empty($settings['add_text']) ? 'true' : 'false',
796 'draw' => defined('EMBEDPRESS_PRO_PLUGIN_VERSION') ? (!empty($settings['draw']) ? 'true' : 'false') : 'true',
797 'doc_rotation' => !empty($settings['doc_rotation']) ? 'true' : 'false',
798 'doc_details' => !empty($settings['doc_details']) ? 'true' : 'false',
799 'add_image' => !empty($settings['add_image']) ? 'true' : 'false',
800 'zoom_in' => !empty($settings['zoom_in']) ? 'true' : 'false',
801 'zoom_out' => !empty($settings['zoom_out']) ? 'true' : 'false',
802 'fit_view' => !empty($settings['fit_view']) ? 'true' : 'false',
803 'bookmark' => !empty($settings['bookmark']) ? 'true' : 'false',
804 'flipbook_rtl' => defined('EMBEDPRESS_SL_ITEM_SLUG') && !empty($settings['flipbook_rtl']) && $settings['flipbook_rtl'] === 'yes' ? 'true' : 'false',
805 'flipbook_highlight_links' => !empty($settings['flipbook_highlight_links']) && $settings['flipbook_highlight_links'] === 'yes' ? 'true' : 'false',
806 'flipbook_highlight_color' => !empty($settings['flipbook_highlight_color']) ? esc_attr($settings['flipbook_highlight_color']) : '',
807 'watermark_text' => defined('EMBEDPRESS_SL_ITEM_SLUG') && !empty($settings['watermark_text']) ? $settings['watermark_text'] : '',
808 'watermark_font_size' => defined('EMBEDPRESS_SL_ITEM_SLUG') && !empty($settings['watermark_font_size']) ? $settings['watermark_font_size'] : '48',
809 'watermark_color' => defined('EMBEDPRESS_SL_ITEM_SLUG') && !empty($settings['watermark_color']) ? Helper::get_elementor_global_color($settings, 'watermark_color') : '#000000',
810 'watermark_opacity' => defined('EMBEDPRESS_SL_ITEM_SLUG') && isset($settings['watermark_opacity']) ? $settings['watermark_opacity'] : '15',
811 'watermark_style' => defined('EMBEDPRESS_SL_ITEM_SLUG') && !empty($settings['watermark_style']) ? $settings['watermark_style'] : 'center',
812 ];
813
814 if ($theme_mode === 'custom') {
815 $params['customColor'] = !empty($settings['custom_color']) ? Helper::get_elementor_global_color($settings, 'custom_color') : '#403A81';
816 }
817
818 $query_string = http_build_query($params);
819 if (function_exists('mb_convert_encoding')) {
820 $query_string = mb_convert_encoding($query_string, 'UTF-8');
821 }
822
823 return base64_encode($query_string);
824 }
825
826 /**
827 * Parse PDF items from JSON control
828 */
829 private function get_pdf_items($settings)
830 {
831 $raw = !empty($settings['pdf_items_json']) ? $settings['pdf_items_json'] : '[]';
832 $items = json_decode($raw, true);
833 return is_array($items) ? $items : [];
834 }
835
836 protected function render()
837 {
838 $settings = $this->get_settings_for_display();
839 $pdf_items = $this->get_pdf_items($settings);
840
841 if (empty($pdf_items)) {
842 if (\Elementor\Plugin::$instance->editor->is_edit_mode()) {
843 echo '<div style="padding:40px;text-align:center;background:#f5f5f5;border-radius:8px;color:#999;">';
844 echo esc_html__('Click "Select PDF Files" to add PDFs to the gallery.', 'embedpress');
845 echo '</div>';
846 }
847 return;
848 }
849
850 $layout = !empty($settings['layout']) ? esc_attr($settings['layout']) : 'grid';
851
852 // Pro gate: bookshelf requires Pro
853 if (($layout === 'bookshelf' || $layout === 'carousel') && !defined('EMBEDPRESS_SL_ITEM_SLUG')) {
854 $layout = 'grid';
855 }
856
857 $columns = !empty($settings['columns']) ? intval($settings['columns']) : 3;
858 $columns_tablet = !empty($settings['columns_tablet']) ? intval($settings['columns_tablet']) : 2;
859 $columns_mobile = !empty($settings['columns_mobile']) ? intval($settings['columns_mobile']) : 1;
860 $gap = isset($settings['gap']['size']) ? intval($settings['gap']['size']) : 20;
861 $border_radius = isset($settings['border_radius']['size']) ? intval($settings['border_radius']['size']) : 8;
862 $aspect_ratio = !empty($settings['aspect_ratio']) ? esc_attr($settings['aspect_ratio']) : '4:3';
863 $viewer_style = !empty($settings['viewer_style']) ? esc_attr($settings['viewer_style']) : 'modern';
864
865 $viewer_params = $this->getParamData($settings);
866 $gallery_id = 'ep-gallery-' . $this->get_id();
867
868 $carousel_options = '';
869 if ($layout === 'carousel' || $layout === 'bookshelf') {
870 $carousel_options = wp_json_encode([
871 'autoplay' => !empty($settings['carousel_autoplay']),
872 'autoplaySpeed' => !empty($settings['carousel_speed']) ? intval($settings['carousel_speed']) : 3000,
873 'loop' => $settings['carousel_loop'] !== '',
874 'arrows' => $settings['carousel_arrows'] !== '',
875 'dots' => !empty($settings['carousel_dots']),
876 'slidesPerView' => !empty($settings['slides_per_view']) ? intval($settings['slides_per_view']) : 3,
877 ]);
878 }
879
880 // Play button settings
881 $show_play_btn = !empty($settings['show_play_button']) && $settings['show_play_button'] === 'yes';
882 $play_icon = !empty($settings['play_button_icon']) ? $settings['play_button_icon'] : 'play';
883 $play_shape = !empty($settings['play_button_shape']) ? $settings['play_button_shape'] : 'circle';
884 $always_show = !empty($settings['play_button_always_show']) && $settings['play_button_always_show'] === 'yes';
885
886 // Icon SVG paths
887 $icon_paths = [
888 'play' => 'M8 5v14l11-7z',
889 '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',
890 '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',
891 ];
892 $icon_path = isset($icon_paths[$play_icon]) ? $icon_paths[$play_icon] : $icon_paths['play'];
893
894 // Icon inline style — only shape and always-show (colors/size handled by Elementor selectors)
895 $icon_style_parts = [];
896 if ($play_shape === 'circle') {
897 $icon_style_parts[] = 'border-radius:50%';
898 } elseif ($play_shape === 'rounded-square') {
899 $icon_style_parts[] = 'border-radius:12px';
900 } else {
901 $icon_style_parts[] = 'border-radius:0';
902 }
903 if ($always_show) {
904 $icon_style_parts[] = 'opacity:1';
905 $icon_style_parts[] = 'transform:scale(1)';
906 }
907 $icon_style = implode(';', $icon_style_parts);
908
909 $item_class = 'ep-pdf-gallery__item' . ($always_show ? ' ep-pdf-gallery__item--always-show' : '');
910
911 $style = sprintf(
912 '--ep-gallery-gap:%dpx;--ep-gallery-radius:%dpx;',
913 $gap, $border_radius
914 );
915 ?>
916 <div class="ep-pdf-gallery"
917 data-layout="<?php echo $layout; ?>"
918 data-shelf-style="<?php echo esc_attr(!empty($settings['bookshelf_style']) ? $settings['bookshelf_style'] : 'dark-wood'); ?>"
919 data-columns="<?php echo $columns; ?>"
920 data-columns-tablet="<?php echo $columns_tablet; ?>"
921 data-columns-mobile="<?php echo $columns_mobile; ?>"
922 data-gap="<?php echo $gap; ?>"
923 data-border-radius="<?php echo $border_radius; ?>"
924 data-viewer-style="<?php echo $viewer_style; ?>"
925 data-viewer-params="<?php echo esc_attr($viewer_params); ?>"
926 data-gallery-id="<?php echo esc_attr($gallery_id); ?>"
927 <?php if ($carousel_options): ?>data-carousel-options="<?php echo esc_attr($carousel_options); ?>"<?php endif; ?>
928 style="<?php echo esc_attr($style); ?>">
929
930 <?php if ($layout === 'carousel' || $layout === 'bookshelf'): ?>
931 <div class="ep-pdf-gallery__carousel">
932 <div class="ep-pdf-gallery__carousel-track">
933 <?php else: ?>
934 <div class="ep-pdf-gallery__grid">
935 <?php endif; ?>
936
937 <?php foreach ($pdf_items as $index => $item):
938 $pdf_url = !empty($item['url']) ? esc_url($item['url']) : '';
939 if (empty($pdf_url)) continue;
940 $pdf_name = !empty($item['fileName']) ? $item['fileName'] : basename(parse_url($pdf_url, PHP_URL_PATH));
941 $custom_thumb = !empty($item['customThumbnailUrl']) ? esc_url($item['customThumbnailUrl']) : '';
942 $auto_thumb = !empty($item['autoThumbnailUrl']) ? esc_url($item['autoThumbnailUrl']) : '';
943 $thumb_url = $custom_thumb ?: $auto_thumb;
944 ?>
945 <div class="<?php echo esc_attr($item_class); ?>"
946 data-pdf-url="<?php echo $pdf_url; ?>"
947 data-pdf-index="<?php echo intval($index); ?>"
948 data-pdf-name="<?php echo esc_attr($pdf_name); ?>">
949 <div class="ep-pdf-gallery__thumbnail-wrap" data-ratio="<?php echo $aspect_ratio; ?>">
950 <?php if ($thumb_url): ?>
951 <img src="<?php echo $thumb_url; ?>" alt="<?php echo esc_attr($pdf_name); ?>" />
952 <?php else: ?>
953 <canvas class="ep-pdf-gallery__canvas" data-pdf-src="<?php echo $pdf_url; ?>" data-loading="true"></canvas>
954 <?php endif; ?>
955 <?php if ($show_play_btn): ?>
956 <div class="ep-pdf-gallery__overlay">
957 <?php if ($play_icon !== 'none'): ?>
958 <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); ?>">
959 <path d="<?php echo $icon_path; ?>"/>
960 </svg>
961 <?php endif; ?>
962 </div>
963 <?php endif; ?>
964 </div>
965 <div class="ep-pdf-gallery__book-title"><?php echo esc_html($pdf_name); ?></div>
966 </div>
967 <?php endforeach; ?>
968
969 <?php if ($layout === 'carousel' || $layout === 'bookshelf'): ?>
970 </div>
971 <button class="ep-pdf-gallery__carousel-prev" aria-label="Previous">
972 <svg viewBox="0 0 24 24"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>
973 </button>
974 <button class="ep-pdf-gallery__carousel-next" aria-label="Next">
975 <svg viewBox="0 0 24 24"><path d="M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z"/></svg>
976 </button>
977 <div class="ep-pdf-gallery__carousel-dots"></div>
978 </div>
979 <?php else: ?>
980 </div>
981 <?php endif; ?>
982 </div>
983 <?php
984 }
985 }
986