PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 4.5.4
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v4.5.4
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 / Gutenberg / BlockManager.php
embedpress / EmbedPress / Gutenberg Last commit date
BlockManager.php 2 months ago EmbedPressBlockRenderer.php 1 month ago FallbackHandler.php 9 months ago InitBlocks.php 9 months ago
BlockManager.php
1938 lines
1 <?php
2
3 namespace EmbedPress\Gutenberg;
4
5 use EmbedPress\Includes\Classes\Helper;
6 use EmbedPress\Core\AssetManager;
7
8 /**
9 * Block Manager for EmbedPress
10 *
11 * Handles registration and management of all EmbedPress Gutenberg blocks
12 * using the new centralized structure.
13 */
14 class BlockManager
15 {
16
17 /**
18 * Instance of this class
19 */
20 private static $instance = null;
21
22 /**
23 * Blocks directory path
24 */
25 private $blocks_path;
26
27 /**
28 * Blocks directory URL
29 */
30 private $blocks_url;
31
32 /**
33 * Available blocks
34 */
35 private $available_blocks = [
36 'EmbedPress' => [
37 'name' => 'embedpress/embedpress',
38 'render_callback' => [EmbedPressBlockRenderer::class, 'render'],
39 'setting_key' => 'embedpress',
40 'supports_save_function' => true
41 ],
42 'embedpress-pdf' => [
43 'name' => 'embedpress/embedpress-pdf',
44 'render_callback' => [EmbedPressBlockRenderer::class, 'render_embedpress_pdf'],
45 'setting_key' => 'embedpress-pdf',
46 'supports_save_function' => true
47 ],
48 'document' => [
49 'name' => 'embedpress/document',
50 'render_callback' => [EmbedPressBlockRenderer::class, 'render_document'],
51 'setting_key' => 'document',
52 'supports_save_function' => true
53 ],
54 'embedpress-calendar' => [
55 'name' => 'embedpress/embedpress-calendar',
56 'render_callback' => [EmbedPressBlockRenderer::class, 'render_embedpress_calendar'],
57 'setting_key' => 'embedpress-calendar',
58 'supports_save_function' => true
59 ],
60 'youtube-block' => [
61 'name' => 'embedpress/youtube-block',
62 'render_callback' => [EmbedPressBlockRenderer::class, 'render_youtube_block'],
63 'setting_key' => 'youtube-block',
64 'supports_save_function' => false
65 ],
66 'wistia-block' => [
67 'name' => 'embedpress/wistia-block',
68 'render_callback' => [EmbedPressBlockRenderer::class, 'render_wistia_block'],
69 'setting_key' => 'wistia-block',
70 'supports_save_function' => false
71 ],
72 'pdf-gallery' => [
73 'name' => 'embedpress/pdf-gallery',
74 'render_callback' => [EmbedPressBlockRenderer::class, 'render_pdf_gallery'],
75 'setting_key' => 'pdf-gallery',
76 'supports_save_function' => true
77 ],
78 ];
79
80 /**
81 * Get instance
82 */
83 public static function get_instance()
84 {
85 if (null === self::$instance) {
86 self::$instance = new self();
87 }
88 return self::$instance;
89 }
90
91 /**
92 * Constructor
93 */
94 private function __construct()
95 {
96 // Use src directory if it exists (development), otherwise use built assets (production/distribution)
97 if (file_exists(EMBEDPRESS_PATH_BASE . 'src/Blocks/')) {
98 $this->blocks_path = EMBEDPRESS_PATH_BASE . 'src/Blocks/';
99 $this->blocks_url = EMBEDPRESS_URL_STATIC . '../src/Blocks/';
100 } else {
101 // Fallback to built assets directory when src is not available (distribution)
102 $this->blocks_path = EMBEDPRESS_PATH_BASE . 'assets/blocks/';
103 $this->blocks_url = EMBEDPRESS_URL_ASSETS . 'blocks/';
104 }
105
106
107 // AssetManager is initialized in Core/init.php
108
109 add_action('init', [$this, 'register_blocks']);
110 add_action('admin_enqueue_scripts', [$this, 'enqueue_block_assets']);
111 add_action('admin_enqueue_scripts', [$this, 'enqueue_editor_assets']);
112
113 // Register PDF gallery thumbnail AJAX handlers
114 // Uses Pdf_Thumbnail_Handler (no Elementor dependency) so this works with Gutenberg-only setups
115 add_action('wp_ajax_ep_upload_pdf_thumbnail', ['EmbedPress\Includes\Classes\Pdf_Thumbnail_Handler', 'ajax_upload_pdf_thumbnail']);
116 add_action('wp_ajax_ep_generate_pdf_thumbnail', ['EmbedPress\Includes\Classes\Pdf_Thumbnail_Handler', 'ajax_generate_pdf_thumbnail']);
117 }
118
119 /**
120 * Register all blocks
121 */
122 public function register_blocks()
123 {
124 if (!function_exists('register_block_type')) {
125 return;
126 }
127
128 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ":elements", []);
129 $g_blocks = isset($elements['gutenberg']) ? (array) $elements['gutenberg'] : [];
130
131
132 // Ensure embedpress block is enabled by default if no settings exist
133 if (empty($elements) || !isset($elements['gutenberg'])) {
134 $this->ensure_default_blocks_enabled();
135 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ":elements", []);
136 $g_blocks = isset($elements['gutenberg']) ? (array) $elements['gutenberg'] : [];
137 }
138
139 foreach ($this->available_blocks as $block_folder => $block_config) {
140 $setting_key = $block_config['setting_key'];
141
142 // Check if block is enabled in settings
143 if (!empty($g_blocks[$setting_key])) {
144 $this->register_single_block($block_folder, $block_config);
145 } else {
146 // Unregister if disabled
147 if (\WP_Block_Type_Registry::get_instance()->is_registered($block_config['name'])) {
148 unregister_block_type($block_config['name']);
149 }
150 }
151 }
152 }
153
154 /**
155 * Register a single block
156 */
157 private function register_single_block($block_folder, $block_config)
158 {
159 $block_path = $this->blocks_path . $block_folder;
160 $block_json_path = $block_path . '/block.json';
161
162 // Check if we're in development mode (src directory exists) or distribution mode
163 $is_development_mode = file_exists(EMBEDPRESS_PATH_BASE . 'src/Blocks/');
164
165 if ($is_development_mode && file_exists($block_json_path)) {
166 // Development mode: Use block.json files
167 $block_args = [];
168
169 // For blocks that support save function, render_callback is only used for dynamic content
170 if (isset($block_config['render_callback'])) {
171 $block_args['render_callback'] = $block_config['render_callback'];
172 }
173
174 // Add attributes from the old system for compatibility
175 if ($block_config['name'] === 'embedpress/embedpress') {
176 $block_args['attributes'] = $this->get_embedpress_block_attributes();
177 } else if ($block_config['name'] === 'embedpress/embedpress-pdf') {
178 $block_args['attributes'] = $this->get_embedpress_pdf_attributes();
179 } else if ($block_config['name'] === 'embedpress/document') {
180 $block_args['attributes'] = $this->get_embedpress_doc_attributes();
181 } else if ($block_config['name'] === 'embedpress/youtube-block') {
182 $block_args['attributes'] = $this->get_youtube_block_attributes();
183 } else if ($block_config['name'] === 'embedpress/wistia-block') {
184 $block_args['attributes'] = $this->get_wistia_block_attributes();
185 } else if ($block_config['name'] === 'embedpress/pdf-gallery') {
186 $block_args['attributes'] = $this->get_pdf_gallery_attributes();
187 }
188
189 register_block_type($block_json_path, $block_args);
190 } else {
191 // Distribution mode: Register blocks directly without block.json
192 // The JavaScript registration is handled by the bundled blocks.build.js file
193 // We only need to register the server-side render callbacks
194
195 $block_args = [
196 'render_callback' => $block_config['render_callback'] ?? null,
197 ];
198
199 // Add attributes for server-side rendering
200 if ($block_config['name'] === 'embedpress/embedpress') {
201 $block_args['attributes'] = $this->get_embedpress_block_attributes();
202 } else if ($block_config['name'] === 'embedpress/embedpress-pdf') {
203 $block_args['attributes'] = $this->get_embedpress_pdf_attributes();
204 } else if ($block_config['name'] === 'embedpress/document') {
205 $block_args['attributes'] = $this->get_embedpress_doc_attributes();
206 } else if ($block_config['name'] === 'embedpress/youtube-block') {
207 $block_args['attributes'] = $this->get_youtube_block_attributes();
208 } else if ($block_config['name'] === 'embedpress/wistia-block') {
209 $block_args['attributes'] = $this->get_wistia_block_attributes();
210 } else if ($block_config['name'] === 'embedpress/pdf-gallery') {
211 $block_args['attributes'] = $this->get_pdf_gallery_attributes();
212 }
213
214 // Only register if not already registered by JavaScript
215 if (!\WP_Block_Type_Registry::get_instance()->is_registered($block_config['name'])) {
216 register_block_type($block_config['name'], $block_args);
217 } else {
218 // Block already registered by JavaScript, just update the render callback
219 $block_type = \WP_Block_Type_Registry::get_instance()->get_registered($block_config['name']);
220 if ($block_type && isset($block_config['render_callback'])) {
221 $block_type->render_callback = $block_config['render_callback'];
222 }
223 }
224 }
225 }
226
227 /**
228 * Get EmbedPress block attributes for compatibility
229 */
230 private function get_embedpress_block_attributes()
231 {
232 // Base attributes for all embeds
233 $attributes = [
234 // Core attributes
235 'clientId' => [
236 'type' => 'string',
237 ],
238 'url' => [
239 'type' => 'string',
240 'default' => ''
241 ],
242 'providerName' => [
243 'type' => 'string',
244 'default' => ''
245 ],
246 'embedHTML' => [
247 'type' => 'string',
248 'default' => ''
249 ],
250 'height' => [
251 'type' => 'string',
252 'default' => '600'
253 ],
254 'width' => [
255 'type' => 'string',
256 'default' => '600'
257 ],
258
259 // State attributes
260 'editingURL' => [
261 'type' => 'boolean',
262 'default' => false
263 ],
264 'fetching' => [
265 'type' => 'boolean',
266 'default' => false
267 ],
268 'cannotEmbed' => [
269 'type' => 'boolean',
270 'default' => false
271 ],
272 'interactive' => [
273 'type' => 'boolean',
274 'default' => false
275 ],
276 'align' => [
277 'type' => 'string',
278 'default' => 'center'
279 ],
280
281
282 // Custom Player
283 'customPlayer' => [
284 'type' => 'boolean',
285 'default' => false
286 ],
287 'playerPreset' => [
288 'type' => 'string',
289 'default' => 'preset-default'
290 ],
291 'playerColor' => [
292 'type' => 'string',
293 'default' => '#5b4e96',
294 ],
295 'autoPause' => [
296 'type' => 'boolean',
297 'default' => false
298 ],
299 'posterThumbnail' => [
300 'type' => 'string',
301 'default' => ''
302 ],
303 'playerPip' => [
304 'type' => 'boolean',
305 'default' => true
306 ],
307 'playerRestart' => [
308 'type' => 'boolean',
309 'default' => true
310 ],
311 'playerRewind' => [
312 'type' => 'boolean',
313 'default' => false
314 ],
315 'playerFastForward' => [
316 'type' => 'boolean',
317 'default' => false
318 ],
319 'playerTooltip' => [
320 'type' => 'boolean',
321 'default' => true
322 ],
323 'playerHideControls' => [
324 'type' => 'boolean',
325 'default' => false
326 ],
327 'playerDownload' => [
328 'type' => 'boolean',
329 'default' => true
330 ],
331 // Pro Custom Player features (PRD #81243). These MUST mirror
332 // attributes.js or the render_callback receives stripped values
333 // and the Pro filter (AdvancedPlayerHandlers::build_options)
334 // falls back to schema defaults — e.g. "Show Replay" stays on
335 // even when the editor toggle is off, because the false value
336 // never reaches PHP.
337 'playerAutoResume' => [
338 'type' => 'boolean',
339 'default' => false
340 ],
341 'playerAutoResumeThreshold' => [
342 'type' => 'number',
343 'default' => 30
344 ],
345 'playerEndScreen' => [
346 'type' => 'boolean',
347 'default' => false
348 ],
349 'playerEndScreenMode' => [
350 'type' => 'string',
351 'default' => 'message'
352 ],
353 'playerEndScreenMessage' => [
354 'type' => 'string',
355 'default' => 'Thanks for watching!'
356 ],
357 'playerEndScreenButtonText' => [
358 'type' => 'string',
359 'default' => 'Learn more'
360 ],
361 'playerEndScreenButtonUrl' => [
362 'type' => 'string',
363 'default' => ''
364 ],
365 'playerEndScreenRedirectUrl' => [
366 'type' => 'string',
367 'default' => ''
368 ],
369 'playerEndScreenRedirectNewWindow' => [
370 'type' => 'boolean',
371 'default' => false
372 ],
373 'playerEndScreenCountdown' => [
374 'type' => 'number',
375 'default' => 5
376 ],
377 'playerEndScreenShowReplay' => [
378 'type' => 'boolean',
379 'default' => true
380 ],
381 'playerPrivacyMode' => [
382 'type' => 'boolean',
383 'default' => false
384 ],
385 'playerPrivacyMessage' => [
386 'type' => 'string',
387 'default' => 'Click to load. By playing, you accept third-party cookies.'
388 ],
389 'playerTimedCTA' => [
390 'type' => 'boolean',
391 'default' => false
392 ],
393 'playerTimedCTAItems' => [
394 'type' => 'array',
395 'default' => []
396 ],
397 'playerChapters' => [
398 'type' => 'boolean',
399 'default' => false
400 ],
401 'playerChaptersItems' => [
402 'type' => 'array',
403 'default' => []
404 ],
405 'playerChaptersShowTitle' => [
406 'type' => 'boolean',
407 'default' => true
408 ],
409 'playerEmailCapture' => [
410 'type' => 'boolean',
411 'default' => false
412 ],
413 'playerEmailCaptureTime' => [
414 'type' => 'number',
415 'default' => 30
416 ],
417 'playerEmailCaptureUnit' => [
418 'type' => 'string',
419 'default' => 'seconds'
420 ],
421 'playerEmailCaptureHeadline' => [
422 'type' => 'string',
423 'default' => 'Enter your email to keep watching'
424 ],
425 'playerEmailCaptureRequireName' => [
426 'type' => 'boolean',
427 'default' => false
428 ],
429 'playerEmailCaptureAllowSkip' => [
430 'type' => 'boolean',
431 'default' => false
432 ],
433 'playerEmailCaptureButtonText' => [
434 'type' => 'string',
435 'default' => 'Continue'
436 ],
437 'playerActionLock' => [
438 'type' => 'boolean',
439 'default' => false
440 ],
441 'playerActionLockType' => [
442 'type' => 'string',
443 'default' => 'share'
444 ],
445 'playerActionLockHeadline' => [
446 'type' => 'string',
447 'default' => 'Unlock this video'
448 ],
449 'playerActionLockMessage' => [
450 'type' => 'string',
451 'default' => 'Complete the action below to continue watching.'
452 ],
453 'playerActionLockShareNetworks' => [
454 'type' => 'array',
455 'default' => ['facebook', 'twitter', 'linkedin']
456 ],
457 'playerActionLockShareUrl' => [
458 'type' => 'string',
459 'default' => ''
460 ],
461 'playerActionLockLinkUrl' => [
462 'type' => 'string',
463 'default' => ''
464 ],
465 'playerActionLockLinkText' => [
466 'type' => 'string',
467 'default' => 'Open link'
468 ],
469 'playerActionLockBypassAdmins' => [
470 'type' => 'boolean',
471 'default' => true
472 ],
473 'playerAdaptiveStreaming' => [
474 'type' => 'boolean',
475 'default' => false
476 ],
477 'playerCountryRestriction' => [
478 'type' => 'boolean',
479 'default' => false
480 ],
481 'playerCountryMode' => [
482 'type' => 'string',
483 'default' => 'block'
484 ],
485 'playerCountryList' => [
486 'type' => 'string',
487 'default' => ''
488 ],
489 'playerCountryMessage' => [
490 'type' => 'string',
491 'default' => 'Sorry, this video is not available in your country.'
492 ],
493 'playerLmsTracking' => [
494 'type' => 'boolean',
495 'default' => false
496 ],
497 'playerLmsThreshold' => [
498 'type' => 'number',
499 'default' => 90
500 ],
501 'playerHeatmap' => [
502 'type' => 'boolean',
503 'default' => false
504 ],
505 'playerCdnEnabled' => [
506 'type' => 'boolean',
507 'default' => true
508 ],
509 'powered_by' => [
510 'type' => 'boolean',
511 'default' => true
512 ],
513 ];
514
515 // Add provider-specific attributes
516 $attributes = array_merge($attributes, $this->get_youtube_attributes());
517 $attributes = array_merge($attributes, $this->get_vimeo_attributes());
518 $attributes = array_merge($attributes, $this->get_wistia_attributes());
519 $attributes = array_merge($attributes, $this->get_instagram_attributes());
520 $attributes = array_merge($attributes, $this->get_calendly_attributes());
521 $attributes = array_merge($attributes, $this->get_podcast_attributes());
522 $attributes = array_merge($attributes, $this->get_google_photos_attributes());
523 $attributes = array_merge($attributes, $this->get_nft_attributes());
524 $attributes = array_merge($attributes, $this->get_ad_manager_attributes());
525 $attributes = array_merge($attributes, $this->get_content_protection_attributes());
526 $attributes = array_merge($attributes, $this->get_social_sharing_attributes());
527 $attributes = array_merge($attributes, $this->get_custom_branding_attributes());
528
529 return $attributes;
530 }
531
532 /**
533 * Get PDF-specific attributes
534 */
535 private function get_embedpress_pdf_attributes()
536 {
537 $attributes = [
538 'clientId' => [
539 'type' => 'string',
540 ],
541 'id' => [
542 'type' => 'string'
543 ],
544 'href' => [
545 'type' => 'string'
546 ],
547 'fileName' => [
548 'type' => 'string',
549 ],
550 'mime' => [
551 'type' => 'string',
552 ],
553 'url' => [
554 'type' => 'string',
555 'default' => ''
556 ],
557 'height' => [
558 'type' => 'string',
559 'default' => '600'
560 ],
561 'width' => [
562 'type' => 'string',
563 'default' => '600'
564 ],
565 'pageNumber' => [
566 'type' => 'number',
567 'default' => 1
568 ],
569 'viewerStyle' => [
570 'type' => 'string',
571 'default' => 'modern'
572 ],
573 'displayMode' => [
574 'type' => 'string',
575 'default' => 'inline'
576 ],
577 'lightboxThumbnail' => [
578 'type' => 'string',
579 'default' => ''
580 ],
581 'lightboxAlign' => [
582 'type' => 'string',
583 'default' => 'left'
584 ],
585 'triggerText' => [
586 'type' => 'string',
587 'default' => 'View PDF'
588 ],
589 'triggerColor' => [
590 'type' => 'string',
591 'default' => ''
592 ],
593 'triggerBgColor' => [
594 'type' => 'string',
595 'default' => ''
596 ],
597 'triggerFontSize' => [
598 'type' => 'string',
599 'default' => ''
600 ],
601 'triggerBorderRadius' => [
602 'type' => 'string',
603 'default' => ''
604 ],
605 'themeMode' => [
606 'type' => 'string',
607 'default' => 'default'
608 ],
609 'customColor' => [
610 'type' => 'string',
611 'default' => '#403A81'
612 ],
613 'toolbar' => [
614 'type' => 'boolean',
615 'default' => true
616 ],
617 'presentation' => [
618 'type' => 'boolean',
619 'default' => true
620 ],
621 'lazyLoad' => [
622 'type' => 'boolean',
623 'default' => false
624 ],
625 'position' => [
626 'type' => 'string',
627 'default' => 'top'
628 ],
629 'flipbook_toolbar_position' => [
630 'type' => 'string',
631 'default' => 'bottom'
632 ],
633 'download' => [
634 'type' => 'boolean',
635 'default' => true
636 ],
637 'open' => [
638 'type' => 'boolean',
639 'default' => false
640 ],
641 'copy_text' => [
642 'type' => 'boolean',
643 'default' => true
644 ],
645 'add_text' => [
646 'type' => 'boolean',
647 'default' => true
648 ],
649 'draw' => [
650 'type' => 'boolean',
651 'default' => true
652 ],
653 'add_image' => [
654 'type' => 'boolean',
655 'default' => true
656 ],
657 'zoomIn' => [
658 'type' => 'boolean',
659 'default' => true
660 ],
661 'zoomOut' => [
662 'type' => 'boolean',
663 'default' => true
664 ],
665 'fitView' => [
666 'type' => 'boolean',
667 'default' => true
668 ],
669 'bookmark' => [
670 'type' => 'boolean',
671 'default' => true
672 ],
673 'doc_details' => [
674 'type' => 'boolean',
675 'default' => true
676 ],
677 'doc_rotation' => [
678 'type' => 'boolean',
679 'default' => true
680 ],
681 'unitoption' => [
682 'type' => 'string',
683 'default' => '%'
684 ],
685 'powered_by' => [
686 'type' => 'boolean',
687 'default' => true
688 ],
689 'watermarkText' => [
690 'type' => 'string',
691 'default' => ''
692 ],
693 'watermarkFontSize' => [
694 'type' => 'number',
695 'default' => 48
696 ],
697 'watermarkColor' => [
698 'type' => 'string',
699 'default' => '#000000'
700 ],
701 'watermarkOpacity' => [
702 'type' => 'number',
703 'default' => 15
704 ],
705 'watermarkStyle' => [
706 'type' => 'string',
707 'default' => 'center'
708 ],
709
710 ];
711
712 $attributes = array_merge($attributes, $this->get_content_protection_attributes());
713 $attributes = array_merge($attributes, $this->get_social_sharing_attributes());
714 $attributes = array_merge($attributes, $this->get_custom_branding_attributes());
715
716 return $attributes;
717 }
718
719 /**
720 * Get PDF Gallery block attributes
721 */
722 private function get_pdf_gallery_attributes()
723 {
724 return [
725 'clientId' => ['type' => 'string'],
726 'pdfItems' => ['type' => 'array', 'default' => []],
727 'layout' => ['type' => 'string', 'default' => 'grid'],
728 'columns' => ['type' => 'number', 'default' => 3],
729 'columnsTablet' => ['type' => 'number', 'default' => 2],
730 'columnsMobile' => ['type' => 'number', 'default' => 1],
731 'gap' => ['type' => 'number', 'default' => 20],
732 'thumbnailAspectRatio' => ['type' => 'string', 'default' => '4:3'],
733 'thumbnailBorderRadius' => ['type' => 'number', 'default' => 8],
734 'carouselAutoplay' => ['type' => 'boolean', 'default' => false],
735 'carouselAutoplaySpeed' => ['type' => 'number', 'default' => 3000],
736 'carouselLoop' => ['type' => 'boolean', 'default' => true],
737 'carouselArrows' => ['type' => 'boolean', 'default' => true],
738 'carouselDots' => ['type' => 'boolean', 'default' => false],
739 'slidesPerView' => ['type' => 'number', 'default' => 3],
740 'viewerStyle' => ['type' => 'string', 'default' => 'modern'],
741 'themeMode' => ['type' => 'string', 'default' => 'default'],
742 'customColor' => ['type' => 'string', 'default' => '#403A81'],
743 'toolbar' => ['type' => 'boolean', 'default' => true],
744 'position' => ['type' => 'string', 'default' => 'top'],
745 'flipbook_toolbar_position' => ['type' => 'string', 'default' => 'bottom'],
746 'presentation' => ['type' => 'boolean', 'default' => true],
747 'download' => ['type' => 'boolean', 'default' => true],
748 'copy_text' => ['type' => 'boolean', 'default' => true],
749 'draw' => ['type' => 'boolean', 'default' => true],
750 'add_text' => ['type' => 'boolean', 'default' => true],
751 'add_image' => ['type' => 'boolean', 'default' => true],
752 'doc_rotation' => ['type' => 'boolean', 'default' => true],
753 'doc_details' => ['type' => 'boolean', 'default' => true],
754 'zoomIn' => ['type' => 'boolean', 'default' => true],
755 'zoomOut' => ['type' => 'boolean', 'default' => true],
756 'fitView' => ['type' => 'boolean', 'default' => true],
757 'bookmark' => ['type' => 'boolean', 'default' => true],
758 'powered_by' => ['type' => 'boolean', 'default' => true],
759 'watermarkText' => ['type' => 'string', 'default' => ''],
760 'watermarkFontSize' => ['type' => 'number', 'default' => 48],
761 'watermarkColor' => ['type' => 'string', 'default' => '#000000'],
762 'watermarkOpacity' => ['type' => 'number', 'default' => 15],
763 'watermarkStyle' => ['type' => 'string', 'default' => 'center'],
764 ];
765 }
766
767 private function get_embedpress_doc_attributes()
768 {
769 $attributes = [
770 'clientId' => [
771 'type' => 'string',
772 ],
773
774 'id' => [
775 'type' => 'string',
776 ],
777 'href' => [
778 'type' => 'string',
779 ],
780 'height' => [
781 'type' => 'string',
782 'default' => '600'
783 ],
784 'width' => [
785 'type' => 'string',
786 'default' => '600'
787 ],
788 'fileName' => [
789 'type' => 'string',
790 ],
791 'mime' => [
792 'type' => 'string',
793 ],
794 'powered_by' => [
795 'type' => 'boolean',
796 'default' => true,
797 ],
798 'presentation' => [
799 'type' => 'boolean',
800 'default' => true,
801 ],
802 'docViewer' => [
803 'type' => 'string',
804 'default' => 'custom',
805 ],
806 'themeMode' => [
807 'type' => 'string',
808 'default' => 'default',
809 ],
810 'customColor' => [
811 'type' => 'string',
812 'default' => '#403A81',
813 ],
814 'position' => [
815 'type' => 'string',
816 'default' => 'top',
817 ],
818 'download' => [
819 'type' => 'boolean',
820 'default' => true,
821 ],
822 'open' => [
823 'type' => 'boolean',
824 'default' => false,
825 ],
826 'copy_text' => [
827 'type' => 'boolean',
828 'default' => true,
829 ],
830 'draw' => [
831 'type' => 'boolean',
832 'default' => true,
833 ],
834 'toolbar' => [
835 'type' => 'boolean',
836 'default' => true,
837 ],
838 'doc_rotation' => [
839 'type' => 'boolean',
840 'default' => true,
841 ],
842 ];
843
844 $attributes = array_merge($attributes, $this->get_content_protection_attributes());
845 $attributes = array_merge($attributes, $this->get_social_sharing_attributes());
846 $attributes = array_merge($attributes, $this->get_custom_branding_attributes());
847
848 return $attributes;
849 }
850
851 /**
852 * Get YouTube block-specific attributes (for legacy youtube-block)
853 */
854 private function get_youtube_block_attributes()
855 {
856 return [
857 'url' => [
858 'type' => 'string',
859 'default' => ''
860 ],
861 'iframeSrc' => [
862 'type' => 'string',
863 'default' => ''
864 ],
865 'mediaId' => [
866 'type' => 'string',
867 'default' => ''
868 ],
869 'align' => [
870 'type' => 'string',
871 'default' => 'center'
872 ]
873 ];
874 }
875
876 /**
877 * Get Wistia block-specific attributes (for legacy wistia-block)
878 */
879 private function get_wistia_block_attributes()
880 {
881 return [
882 'url' => [
883 'type' => 'string',
884 'default' => ''
885 ],
886 'iframeSrc' => [
887 'type' => 'string',
888 'default' => ''
889 ],
890 'align' => [
891 'type' => 'string',
892 'default' => 'center'
893 ]
894 ];
895 }
896
897 /**
898 * Get ContenProtection-specific attributes
899 */
900 private function get_content_protection_attributes()
901 {
902 return [
903 'lockContent' => [
904 'type' => 'boolean',
905 'default' => false
906 ],
907 'protectionType' => [
908 'type' => 'string',
909 'default' => 'password'
910 ],
911 'userRole' => [
912 'type' => 'array',
913 'default' => []
914 ],
915 'protectionMessage' => [
916 'type' => 'string',
917 'default' => 'You do not have access to this content. Only users with the following roles can view it: [user_roles]'
918 ],
919 'contentPassword' => [
920 'type' => 'string',
921 'default' => ''
922 ],
923 'lockHeading' => [
924 'type' => 'string',
925 'default' => 'Content Locked'
926 ],
927 'lockSubHeading' => [
928 'type' => 'string',
929 'default' => 'Content is locked and requires password to access it.'
930 ],
931 'lockErrorMessage' => [
932 'type' => 'string',
933 'default' => 'Oops, that wasn\'t the right password. Try again.'
934 ],
935 'passwordPlaceholder' => [
936 'type' => 'string',
937 'default' => 'Password'
938 ],
939 'submitButtonText' => [
940 'type' => 'string',
941 'default' => 'Unlock'
942 ],
943 'submitUnlockingText' => [
944 'type' => 'string',
945 'default' => 'Unlocking'
946 ],
947 'enableFooterMessage' => [
948 'type' => 'boolean',
949 'default' => false
950 ],
951 'footerMessage' => [
952 'type' => 'string',
953 'default' => 'In case you don\'t have the password, kindly reach out to content owner or administrator to request access.'
954 ],
955 ];
956 }
957
958 /**
959 * Get SocialSharing-specific attributes
960 */
961 private function get_social_sharing_attributes()
962 {
963 return [
964 'contentShare' => [
965 'type' => 'boolean',
966 'default' => false
967 ],
968 'sharePosition' => [
969 'type' => 'string',
970 'default' => 'right'
971 ],
972 'customTitle' => [
973 'type' => 'string',
974 'default' => ''
975 ],
976 'customDescription' => [
977 'type' => 'string',
978 'default' => ''
979 ],
980 'customThumbnail' => [
981 'type' => 'string',
982 'default' => ''
983 ],
984 'shareFacebook' => [
985 'type' => 'boolean',
986 'default' => true
987 ],
988 'shareTwitter' => [
989 'type' => 'boolean',
990 'default' => true
991 ],
992 'sharePinterest' => [
993 'type' => 'boolean',
994 'default' => true
995 ],
996 'shareLinkedin' => [
997 'type' => 'boolean',
998 'default' => true
999 ],
1000 ];
1001 }
1002
1003 /**
1004 * Get CustomBranding-specific attributes
1005 */
1006 private function get_custom_branding_attributes()
1007 {
1008 return [
1009 'customlogo' => [
1010 'type' => 'string',
1011 'default' => ''
1012 ],
1013 'logoX' => [
1014 'type' => 'number',
1015 'default' => 5
1016 ],
1017 'logoY' => [
1018 'type' => 'number',
1019 'default' => 10
1020 ],
1021 'customlogoUrl' => [
1022 'type' => 'string',
1023 ],
1024 'logoOpacity' => [
1025 'type' => 'number',
1026 'default' => 0.6
1027 ],
1028 ];
1029 }
1030
1031
1032 /**
1033 * Get YouTube-specific attributes
1034 */
1035 private function get_youtube_attributes()
1036 {
1037 return [
1038 // YouTube specific attributes
1039 'ispagination' => [
1040 'type' => 'boolean',
1041 'default' => true
1042 ],
1043 'ytChannelLayout' => [
1044 'type' => 'string',
1045 'default' => 'gallery'
1046 ],
1047 'pagesize' => [
1048 'type' => 'string',
1049 'default' => '6'
1050 ],
1051 'columns' => [
1052 'type' => 'string',
1053 'default' => '3'
1054 ],
1055 'gapbetweenvideos' => [
1056 'type' => 'number',
1057 'default' => 30
1058 ],
1059 'videosize' => [
1060 'type' => 'string',
1061 'default' => 'fixed',
1062 ],
1063 'starttime' => [
1064 'type' => 'string',
1065 ],
1066 'endtime' => [
1067 'type' => 'string',
1068 ],
1069 'autoplay' => [
1070 'type' => 'boolean',
1071 'default' => false,
1072 ],
1073 'muteVideo' => [
1074 'type' => 'boolean',
1075 'default' => true,
1076 ],
1077 'controls' => [
1078 'type' => 'string',
1079 ],
1080 'fullscreen' => [
1081 'type' => 'boolean',
1082 'default' => true,
1083 ],
1084 'videoannotations' => [
1085 'type' => 'boolean',
1086 'default' => true,
1087 ],
1088 'progressbarcolor' => [
1089 'type' => 'string',
1090 'default' => 'red'
1091 ],
1092 'closedcaptions' => [
1093 'type' => 'boolean',
1094 'default' => true,
1095 ],
1096 'modestbranding' => [
1097 'type' => 'string',
1098 ],
1099 'relatedvideos' => [
1100 'type' => 'boolean',
1101 'default' => true,
1102 ],
1103 'showinfo' => [
1104 'type' => 'boolean',
1105 'default' => true,
1106 ],
1107 'showLoop' => [
1108 'type' => 'boolean',
1109 'default' => true,
1110 ],
1111 ];
1112 }
1113
1114 /**
1115 * Get Vimeo-specific attributes
1116 */
1117 private function get_vimeo_attributes()
1118 {
1119 return [
1120 'vimeoAutoplay' => [
1121 'type' => 'boolean',
1122 'default' => false,
1123 ],
1124 'vimeoLoop' => [
1125 'type' => 'boolean',
1126 'default' => false,
1127 ],
1128 'vimeoPortrait' => [
1129 'type' => 'boolean',
1130 'default' => true,
1131 ],
1132 'vimeoTitle' => [
1133 'type' => 'boolean',
1134 'default' => true,
1135 ],
1136 'vimeoByline' => [
1137 'type' => 'boolean',
1138 'default' => true,
1139 ],
1140 'vimeoColor' => [
1141 'type' => 'string',
1142 'default' => '#00adef'
1143 ],
1144 'vimeoDnt' => [
1145 'type' => 'boolean',
1146 'default' => false,
1147 ],
1148 // Additional Vimeo attributes
1149 'vstarttime' => [
1150 'type' => 'string',
1151 ],
1152 'vautoplay' => [
1153 'type' => 'boolean',
1154 'default' => false
1155 ],
1156 'vscheme' => [
1157 'type' => 'string',
1158 ],
1159 'vtitle' => [
1160 'type' => 'boolean',
1161 'default' => true
1162 ],
1163 'vauthor' => [
1164 'type' => 'boolean',
1165 'default' => true
1166 ],
1167 'vavatar' => [
1168 'type' => 'boolean',
1169 'default' => true
1170 ],
1171 'vloop' => [
1172 'type' => 'boolean',
1173 'default' => false
1174 ],
1175 'vautopause' => [
1176 'type' => 'boolean',
1177 'default' => false
1178 ],
1179 'vdnt' => [
1180 'type' => 'boolean',
1181 'default' => false
1182 ],
1183 ];
1184 }
1185
1186 /**
1187 * Get Wistia-specific attributes
1188 */
1189 private function get_wistia_attributes()
1190 {
1191 return [
1192 'wstarttime' => [
1193 'type' => 'string',
1194 ],
1195 'wautoplay' => [
1196 'type' => 'boolean',
1197 'default' => true
1198 ],
1199 'scheme' => [
1200 'type' => 'string',
1201 ],
1202 'captions' => [
1203 'type' => 'boolean',
1204 'default' => true
1205 ],
1206 'playbutton' => [
1207 'type' => 'boolean',
1208 'default' => true
1209 ],
1210 'smallplaybutton' => [
1211 'type' => 'boolean',
1212 'default' => true
1213 ],
1214 'playbar' => [
1215 'type' => 'boolean',
1216 'default' => true
1217 ],
1218 'resumable' => [
1219 'type' => 'boolean',
1220 'default' => true
1221 ],
1222 'wistiafocus' => [
1223 'type' => 'boolean',
1224 'default' => true
1225 ],
1226 'volumecontrol' => [
1227 'type' => 'boolean',
1228 'default' => true
1229 ],
1230 'volume' => [
1231 'type' => 'number',
1232 'default' => 100
1233 ],
1234 'rewind' => [
1235 'type' => 'boolean',
1236 'default' => false
1237 ],
1238 'wfullscreen' => [
1239 'type' => 'boolean',
1240 'default' => true
1241 ],
1242 ];
1243 }
1244
1245 /**
1246 * Get Instagram-specific attributes
1247 */
1248 private function get_instagram_attributes()
1249 {
1250 return [
1251 'instaLayout' => [
1252 'type' => 'string',
1253 'default' => 'insta-grid'
1254 ],
1255 'carouselArrows' => [
1256 'type' => 'boolean',
1257 'default' => true
1258 ],
1259 'carouselSpacing' => [
1260 'type' => 'string',
1261 'default' => '0'
1262 ],
1263 'carouselDots' => [
1264 'type' => 'boolean',
1265 'default' => false
1266 ],
1267 // Instagram Feed attributes
1268 'instafeedFeedType' => [
1269 'type' => 'string',
1270 'default' => 'user_account_type',
1271 ],
1272 'instafeedAccountType' => [
1273 'type' => 'string',
1274 'default' => 'personal',
1275 ],
1276 'instafeedProfileImage' => [
1277 'type' => 'boolean',
1278 'default' => true,
1279 ],
1280 'instafeedProfileImageUrl' => [
1281 'type' => 'string',
1282 'default' => '',
1283 ],
1284 'instafeedFollowBtn' => [
1285 'type' => 'boolean',
1286 'default' => true,
1287 ],
1288 'instafeedFollowBtnLabel' => [
1289 'type' => 'string',
1290 'default' => 'Follow',
1291 ],
1292 'instafeedPostsCount' => [
1293 'type' => 'boolean',
1294 'default' => true,
1295 ],
1296 'instafeedPostsCountText' => [
1297 'type' => 'string',
1298 'default' => '[count] posts',
1299 ],
1300 'instafeedFollowersCount' => [
1301 'type' => 'boolean',
1302 'default' => true,
1303 ],
1304 'instafeedFollowersCountText' => [
1305 'type' => 'string',
1306 'default' => '[count] followers',
1307 ],
1308 'instafeedAccName' => [
1309 'type' => 'boolean',
1310 'default' => true,
1311 ],
1312 'instafeedColumns' => [
1313 'type' => 'string',
1314 'default' => '3'
1315 ],
1316 'instafeedColumnsGap' => [
1317 'type' => 'string',
1318 'default' => '5'
1319 ],
1320 'instafeedPostsPerPage' => [
1321 'type' => 'string',
1322 'default' => '12'
1323 ],
1324 'instafeedTab' => [
1325 'type' => 'boolean',
1326 'default' => true,
1327 ],
1328 'instafeedLikesCount' => [
1329 'type' => 'boolean',
1330 'default' => true,
1331 ],
1332 'instafeedCommentsCount' => [
1333 'type' => 'boolean',
1334 'default' => true,
1335 ],
1336 'instafeedPopup' => [
1337 'type' => 'boolean',
1338 'default' => true,
1339 ],
1340 'instafeedPopupFollowBtn' => [
1341 'type' => 'boolean',
1342 'default' => true,
1343 ],
1344 'instafeedPopupFollowBtnLabel' => [
1345 'type' => 'string',
1346 'default' => 'Follow',
1347 ],
1348 'instafeedLoadmore' => [
1349 'type' => 'boolean',
1350 'default' => true,
1351 ],
1352 'instafeedLoadmoreLabel' => [
1353 'type' => 'string',
1354 'default' => 'Load More',
1355 ],
1356 'slidesShow' => [
1357 'type' => 'string',
1358 'default' => '4'
1359 ],
1360 'slidesScroll' => [
1361 'type' => 'string',
1362 'default' => '4'
1363 ],
1364 'carouselAutoplay' => [
1365 'type' => 'boolean',
1366 'default' => false
1367 ],
1368 'autoplaySpeed' => [
1369 'type' => 'string',
1370 'default' => '3000'
1371 ],
1372 'transitionSpeed' => [
1373 'type' => 'string',
1374 'default' => '1000'
1375 ],
1376 'carouselLoop' => [
1377 'type' => 'boolean',
1378 'default' => true
1379 ],
1380 ];
1381 }
1382
1383 /**
1384 * Get Calendly-specific attributes
1385 */
1386 private function get_calendly_attributes()
1387 {
1388 return [
1389 'cEmbedType' => [
1390 'type' => 'string',
1391 'default' => 'inline'
1392 ],
1393 'calendlyData' => [
1394 'type' => 'boolean',
1395 'default' => false
1396 ],
1397 'hideCookieBanner' => [
1398 'type' => 'boolean',
1399 'default' => false
1400 ],
1401 'hideEventTypeDetails' => [
1402 'type' => 'boolean',
1403 'default' => false
1404 ],
1405 'cBackgroundColor' => [
1406 'type' => 'string',
1407 'default' => 'ffffff'
1408 ],
1409 'cTextColor' => [
1410 'type' => 'string',
1411 'default' => '1A1A1A'
1412 ],
1413 'cButtonLinkColor' => [
1414 'type' => 'string',
1415 'default' => '0000FF'
1416 ],
1417 'cPopupButtonText' => [
1418 'type' => 'string',
1419 'default' => 'Schedule time with me'
1420 ],
1421 'cPopupButtonBGColor' => [
1422 'type' => 'string',
1423 'default' => '0000FF'
1424 ],
1425 'cPopupButtonTextColor' => [
1426 'type' => 'string',
1427 'default' => 'FFFFFF'
1428 ],
1429 'cPopupLinkText' => [
1430 'type' => 'string',
1431 'default' => 'Schedule time with me'
1432 ],
1433 ];
1434 }
1435
1436 /**
1437 * Get Podcast-specific attributes (Spreaker)
1438 */
1439 private function get_podcast_attributes()
1440 {
1441 return [
1442 // Spreaker attributes
1443 'theme' => [
1444 'type' => 'string',
1445 'default' => 'light'
1446 ],
1447 'color' => [
1448 'type' => 'string',
1449 'default' => ''
1450 ],
1451 'coverImageUrl' => [
1452 'type' => 'string',
1453 'default' => ''
1454 ],
1455 'playlist' => [
1456 'type' => 'boolean',
1457 'default' => false
1458 ],
1459 'playlistContinuous' => [
1460 'type' => 'boolean',
1461 'default' => false
1462 ],
1463 'playlistLoop' => [
1464 'type' => 'boolean',
1465 'default' => false
1466 ],
1467 'playlistAutoupdate' => [
1468 'type' => 'boolean',
1469 'default' => true
1470 ],
1471 'chaptersImage' => [
1472 'type' => 'boolean',
1473 'default' => true
1474 ],
1475 'episodeImagePosition' => [
1476 'type' => 'string',
1477 'default' => 'right'
1478 ],
1479 'hideLikes' => [
1480 'type' => 'boolean',
1481 'default' => false
1482 ],
1483 'hideComments' => [
1484 'type' => 'boolean',
1485 'default' => false
1486 ],
1487 'hideSharing' => [
1488 'type' => 'boolean',
1489 'default' => false
1490 ],
1491 'hideLogo' => [
1492 'type' => 'boolean',
1493 'default' => false
1494 ],
1495 'hideEpisodeDescription' => [
1496 'type' => 'boolean',
1497 'default' => false
1498 ],
1499 'hidePlaylistDescriptions' => [
1500 'type' => 'boolean',
1501 'default' => false
1502 ],
1503 'hidePlaylistImages' => [
1504 'type' => 'boolean',
1505 'default' => false
1506 ],
1507 'hideDownload' => [
1508 'type' => 'boolean',
1509 'default' => false
1510 ],
1511 ];
1512 }
1513
1514 /**
1515 * Get Google Photos-specific attributes
1516 */
1517 private function get_google_photos_attributes()
1518 {
1519 return [
1520 'mode' => [
1521 'type' => 'string',
1522 'default' => 'carousel'
1523 ],
1524 'imageWidth' => [
1525 'type' => 'number',
1526 'default' => 800
1527 ],
1528 'imageHeight' => [
1529 'type' => 'number',
1530 'default' => 600
1531 ],
1532 'showTitle' => [
1533 'type' => 'boolean',
1534 'default' => true
1535 ],
1536 'playerAutoplay' => [
1537 'type' => 'boolean',
1538 'default' => false
1539 ],
1540 'delay' => [
1541 'type' => 'number',
1542 'default' => 5
1543 ],
1544 'repeat' => [
1545 'type' => 'boolean',
1546 'default' => true
1547 ],
1548 'mediaitemsAspectRatio' => [
1549 'type' => 'boolean',
1550 'default' => true
1551 ],
1552 'mediaitemsEnlarge' => [
1553 'type' => 'boolean',
1554 'default' => false
1555 ],
1556 'mediaitemsStretch' => [
1557 'type' => 'boolean',
1558 'default' => false
1559 ],
1560 'mediaitemsCover' => [
1561 'type' => 'boolean',
1562 'default' => false
1563 ],
1564 'backgroundColor' => [
1565 'type' => 'string',
1566 'default' => '#000000'
1567 ],
1568 'expiration' => [
1569 'type' => 'number',
1570 'default' => 60
1571 ],
1572 ];
1573 }
1574
1575 /**
1576 * Get NFT/OpenSea-specific attributes
1577 */
1578 private function get_nft_attributes()
1579 {
1580 return [
1581 'limit' => [
1582 'type' => 'number',
1583 'default' => 20
1584 ],
1585 'itemperpage' => [
1586 'type' => 'number',
1587 'default' => 9
1588 ],
1589 'loadmore' => [
1590 'type' => 'boolean',
1591 'default' => false
1592 ],
1593 'loadmorelabel' => [
1594 'type' => 'text',
1595 'default' => 'Load More'
1596 ],
1597 'orderby' => [
1598 'type' => 'string',
1599 'default' => 'desc'
1600 ],
1601 'gapbetweenitem' => [
1602 'type' => 'number',
1603 'default' => 30
1604 ],
1605 'layout' => [
1606 'type' => 'string',
1607 'default' => 'ep-grid'
1608 ],
1609 'preset' => [
1610 'type' => 'string',
1611 'default' => 'preset-default'
1612 ],
1613 'nftperrow' => [
1614 'type' => 'number',
1615 'default' => 3
1616 ],
1617 'collectionname' => [
1618 'type' => 'boolean',
1619 'default' => true
1620 ],
1621 'nftimage' => [
1622 'type' => 'boolean',
1623 'default' => true
1624 ],
1625 'nfttitle' => [
1626 'type' => 'boolean',
1627 'default' => true
1628 ],
1629 'nftcreator' => [
1630 'type' => 'boolean',
1631 'default' => true
1632 ],
1633 'prefix_nftcreator' => [
1634 'type' => 'string',
1635 'default' => 'Created By'
1636 ],
1637 'nftprice' => [
1638 'type' => 'boolean',
1639 'default' => true
1640 ],
1641 'prefix_nftprice' => [
1642 'type' => 'string',
1643 'default' => 'Current Price'
1644 ],
1645 'nftlastsale' => [
1646 'type' => 'boolean',
1647 'default' => true
1648 ],
1649 'prefix_nftlastsale' => [
1650 'type' => 'string',
1651 'default' => 'Last Sale'
1652 ],
1653 'nftbutton' => [
1654 'type' => 'boolean',
1655 'default' => true
1656 ],
1657 'nftrank' => [
1658 'type' => 'boolean',
1659 'default' => true
1660 ],
1661 'label_nftrank' => [
1662 'type' => 'string',
1663 'default' => 'Rank'
1664 ],
1665 'nftdetails' => [
1666 'type' => 'boolean',
1667 'default' => true
1668 ],
1669 'label_nftdetails' => [
1670 'type' => 'string',
1671 'default' => 'Details'
1672 ],
1673 'label_nftbutton' => [
1674 'type' => 'string',
1675 'default' => 'See Details'
1676 ],
1677 'alignment' => [
1678 'type' => 'string',
1679 'default' => 'ep-item-center'
1680 ],
1681 // Color and Typography for NFT
1682 'itemBGColor' => [
1683 'type' => 'string',
1684 ],
1685 'collectionNameColor' => [
1686 'type' => 'string',
1687 ],
1688 'collectionNameFZ' => [
1689 'type' => 'number',
1690 ],
1691 'titleColor' => [
1692 'type' => 'string',
1693 ],
1694 'titleFontsize' => [
1695 'type' => 'number',
1696 ],
1697 'creatorColor' => [
1698 'type' => 'string',
1699 ],
1700 'creatorFontsize' => [
1701 'type' => 'number',
1702 ],
1703 'creatorLinkColor' => [
1704 'type' => 'string',
1705 ],
1706 'creatorLinkFontsize' => [
1707 'type' => 'number',
1708 ],
1709 'priceLabelColor' => [
1710 'type' => 'string',
1711 ],
1712 'priceLabelFontsize' => [
1713 'type' => 'number',
1714 ],
1715 'priceColor' => [
1716 'type' => 'string',
1717 ],
1718 'priceFontsize' => [
1719 'type' => 'number',
1720 ],
1721 'priceUSDColor' => [
1722 'type' => 'string',
1723 ],
1724 'priceUSDFontsize' => [
1725 'type' => 'number',
1726 ],
1727 'lastSaleLabelColor' => [
1728 'type' => 'string',
1729 ],
1730 'lastSaleLabelFontsize' => [
1731 'type' => 'number',
1732 ],
1733 'lastSaleColor' => [
1734 'type' => 'string',
1735 ],
1736 'lastSaleFontsize' => [
1737 'type' => 'number',
1738 ],
1739 'lastSaleUSDColor' => [
1740 'type' => 'string',
1741 ],
1742 'lastSaleUSDFontsize' => [
1743 'type' => 'number',
1744 ],
1745 'buttonTextColor' => [
1746 'type' => 'string',
1747 ],
1748 'buttonBackgroundColor' => [
1749 'type' => 'string',
1750 ],
1751 'buttonTextFontsize' => [
1752 'type' => 'number',
1753 ],
1754 'loadmoreTextColor' => [
1755 'type' => 'string',
1756 ],
1757 'loadmoreBackgroundColor' => [
1758 'type' => 'string',
1759 ],
1760 'loadmoreTextFontsize' => [
1761 'type' => 'number',
1762 ],
1763 'rankBtnColor' => [
1764 'type' => 'string',
1765 ],
1766 'rankBtnBorderColor' => [
1767 'type' => 'string',
1768 ],
1769 'rankBtnFZ' => [
1770 'type' => 'number',
1771 ],
1772 'rankLabelColor' => [
1773 'type' => 'string',
1774 ],
1775 'rankLabelFZ' => [
1776 'type' => 'number',
1777 ],
1778 'detialTitleColor' => [
1779 'type' => 'string',
1780 ],
1781 'detialTitleFZ' => [
1782 'type' => 'number',
1783 ],
1784 'detailTextColor' => [
1785 'type' => 'string',
1786 ],
1787 'detailTextLinkColor' => [
1788 'type' => 'string',
1789 ],
1790 'detailTextFZ' => [
1791 'type' => 'number',
1792 ],
1793 ];
1794 }
1795
1796 /**
1797 * Get Ad Manager-specific attributes
1798 */
1799 private function get_ad_manager_attributes()
1800 {
1801 return [
1802 'adManager' => [
1803 'type' => 'boolean',
1804 'default' => false
1805 ],
1806 'adSource' => [
1807 'type' => 'string',
1808 'default' => 'video'
1809 ],
1810 'adContent' => [
1811 'type' => 'object',
1812 ],
1813 'adFileUrl' => [
1814 'type' => 'string',
1815 'default' => ''
1816 ],
1817 'adWidth' => [
1818 'type' => 'string',
1819 'default' => '300'
1820 ],
1821 'adHeight' => [
1822 'type' => 'string',
1823 'default' => '200'
1824 ],
1825 'adXPosition' => [
1826 'type' => 'number',
1827 'default' => 25
1828 ],
1829 'adYPosition' => [
1830 'type' => 'number',
1831 'default' => 10
1832 ],
1833 'adUrl' => [
1834 'type' => 'string',
1835 'default' => ''
1836 ],
1837 'adStart' => [
1838 'type' => 'string',
1839 'default' => '10'
1840 ],
1841 'adSkipButton' => [
1842 'type' => 'boolean',
1843 'default' => true
1844 ],
1845 'adSkipButtonAfter' => [
1846 'type' => 'string',
1847 'default' => '5'
1848 ],
1849 ];
1850 }
1851
1852 /**
1853 * Enqueue block assets for both frontend and backend
1854 * Now handled by AssetManager
1855 */
1856 public function enqueue_block_assets()
1857 {
1858 // Assets are now handled by the centralized AssetManager
1859 // This method is kept for backward compatibility
1860 }
1861
1862 /**
1863 * Enqueue editor assets
1864 */
1865 public function enqueue_editor_assets()
1866 {
1867 // Assets are now handled by AssetManager, but we still need to localize the script
1868 $this->localize_editor_script();
1869 }
1870
1871 /**
1872 * Localize editor script with necessary data
1873 * Note: Localization is now handled by LocalizationManager
1874 */
1875 private function localize_editor_script()
1876 {
1877 // Localization is now handled by LocalizationManager
1878 // This method is kept for backward compatibility but functionality has been moved
1879 }
1880
1881 /**
1882 * Add a new block to the available blocks list
1883 */
1884 public function add_block($folder_name, $config)
1885 {
1886 $this->available_blocks[$folder_name] = $config;
1887 }
1888
1889 /**
1890 * Ensure default blocks are enabled if no settings exist
1891 */
1892 private function ensure_default_blocks_enabled()
1893 {
1894 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ":elements", []);
1895
1896 // If no gutenberg settings exist, create default ones
1897 if (!isset($elements['gutenberg'])) {
1898 $elements['gutenberg'] = [];
1899 }
1900
1901 // Enable embedpress block by default
1902 if (!isset($elements['gutenberg']['embedpress'])) {
1903 $elements['gutenberg']['embedpress'] = 'embedpress';
1904 }
1905
1906 // Enable embedpress-pdf block by default
1907 if (!isset($elements['gutenberg']['embedpress-pdf'])) {
1908 $elements['gutenberg']['embedpress-pdf'] = 'embedpress-pdf';
1909 }
1910
1911 // Enable youtube-block by default for legacy support
1912 if (!isset($elements['gutenberg']['youtube-block'])) {
1913 $elements['gutenberg']['youtube-block'] = 'youtube-block';
1914 }
1915
1916 // Enable wistia-block by default for legacy support
1917 if (!isset($elements['gutenberg']['wistia-block'])) {
1918 $elements['gutenberg']['wistia-block'] = 'wistia-block';
1919 }
1920
1921 // Enable pdf-gallery block by default
1922 if (!isset($elements['gutenberg']['pdf-gallery'])) {
1923 $elements['gutenberg']['pdf-gallery'] = 'pdf-gallery';
1924 }
1925
1926 // Update options if any changes were made
1927 update_option(EMBEDPRESS_PLG_NAME . ":elements", $elements);
1928 }
1929
1930 /**
1931 * Get available blocks
1932 */
1933 public function get_available_blocks()
1934 {
1935 return $this->available_blocks;
1936 }
1937 }
1938