PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.4.2
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.4.2
4.6.1 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 / Core / AssetManager.php
embedpress / Core Last commit date
AssetManager.php 9 months ago LocalizationManager.php 9 months ago init.php 10 months ago
AssetManager.php
781 lines
1 <?php
2
3 namespace EmbedPress\Core;
4
5 // Include LocalizationManager
6 // require_once __DIR__ . '/LocalizationManager.php';
7
8 use Embedpress\Core\LocalizationManager;
9
10 /**
11 * EmbedPress Asset Manager
12 *
13 * Centralized asset management for JS/CSS files across blocks, Elementor, admin, and frontend
14 * Handles new build files from Vite build system
15 */
16 class AssetManager
17 {
18 /**
19 * Track which handles should be treated as ES modules
20 */
21 private static $module_handles = [];
22
23 /**
24 * Track if the global module filter has been added
25 */
26 private static $module_filter_added = false;
27
28 /**
29 * Asset definitions with context-based loading
30 */
31 private static $assets = [
32
33 // 🔧 Scripts (Ordered by Priority)
34 // ----------------------------------
35
36 // Vendor assets (copied to assets folder for consistency)
37 // Priority 1-5: Core vendor libraries
38 'plyr-css' => [
39 'file' => 'css/plyr.css',
40 'deps' => [],
41 'contexts' => ['frontend', 'elementor', 'editor'],
42 'type' => 'style',
43 'handle' => 'embedpress-plyr-css',
44 'priority' => 1,
45 ],
46 'carousel-vendor-css' => [
47 'file' => 'css/carousel.min.css',
48 'deps' => [],
49 'contexts' => ['frontend', 'elementor'],
50 'type' => 'style',
51 'handle' => 'embedpress-carousel-vendor-css',
52 'priority' => 1,
53 ],
54 'glider-css' => [
55 'file' => 'css/glider.min.css',
56 'deps' => [],
57 'contexts' => ['frontend', 'elementor'],
58 'type' => 'style',
59 'handle' => 'embedpress-glider-css',
60 'priority' => 1,
61 ],
62 'plyr-js' => [
63 'file' => 'js/vendor/plyr.js',
64 'deps' => ['jquery'],
65 'contexts' => ['frontend', 'elementor', 'editor'],
66 'type' => 'script',
67 'footer' => true,
68 'handle' => 'embedpress-plyr',
69 'priority' => 2,
70 ],
71 'plyr-polyfilled-js' => [
72 'file' => 'js/vendor/plyr.polyfilled.js',
73 'deps' => ['jquery'],
74 'contexts' => ['frontend', 'elementor', 'editor'],
75 'type' => 'script',
76 'footer' => true,
77 'handle' => 'embedpress-plyr-polyfilled',
78 'priority' => 2,
79 ],
80 'carousel-vendor-js' => [
81 'file' => 'js/vendor/carousel.min.js',
82 'deps' => ['jquery'],
83 'contexts' => ['frontend', 'elementor'],
84 'type' => 'script',
85 'footer' => true,
86 'handle' => 'embedpress-carousel-vendor',
87 'priority' => 2,
88 ],
89 'glider-js' => [
90 'file' => 'js/vendor/glider.min.js',
91 'deps' => ['jquery'],
92 'contexts' => ['frontend', 'elementor'],
93 'type' => 'script',
94 'footer' => true,
95 'handle' => 'embedpress-glider',
96 'priority' => 2,
97 ],
98 'pdfobject-js' => [
99 'file' => 'js/vendor/pdfobject.js',
100 'deps' => [],
101 'contexts' => ['frontend', 'elementor', 'editor'],
102 'type' => 'script',
103 'footer' => true,
104 'handle' => 'embedpress-pdfobject',
105 'priority' => 2,
106 ],
107 'vimeo-player-js' => [
108 'file' => 'js/vendor/vimeo-player.js',
109 'deps' => [],
110 'contexts' => ['frontend', 'elementor'],
111 'type' => 'script',
112 'footer' => true,
113 'handle' => 'embedpress-vimeo-player',
114 'priority' => 2,
115 ],
116 'ytiframeapi-js' => [
117 'file' => 'js/vendor/ytiframeapi.js',
118 'deps' => [],
119 'contexts' => ['frontend', 'elementor'],
120 'type' => 'script',
121 'footer' => true,
122 'handle' => 'embedpress-ytiframeapi',
123 'priority' => 2,
124 ],
125 'bootstrap-js' => [
126 'file' => 'js/vendor/bootstrap/bootstrap.min.js',
127 'deps' => ['jquery'],
128 'contexts' => ['editor'],
129 'type' => 'script',
130 'footer' => true,
131 'handle' => 'embedpress-bootstrap',
132 'priority' => 2,
133 ],
134 'bootbox-js' => [
135 'file' => 'js/vendor/bootbox.min.js',
136 'deps' => ['jquery', 'embedpress-bootstrap'],
137 'contexts' => ['editor'],
138 'type' => 'script',
139 'footer' => true,
140 'handle' => 'embedpress-bootbox',
141 'priority' => 3,
142 ],
143 // Priority 5-6: Main application build assets
144 'admin-js' => [
145 'file' => 'js/admin.build.js',
146 'deps' => [],
147 'contexts' => ['admin'],
148 'type' => 'script',
149 'footer' => true,
150 'handle' => 'embedpress-admin',
151 'priority' => 5,
152 'page' => 'embedpress'
153 ],
154 // Priority 7-10: Blocks
155 'blocks-js' => [
156 'file' => 'js/blocks.build.js',
157 'deps' => ['wp-blocks', 'wp-i18n', 'wp-element', 'wp-api-fetch', 'wp-is-shallow-equal', 'wp-editor', 'wp-components'],
158 'contexts' => ['editor', 'frontend'],
159 'type' => 'script',
160 'footer' => true,
161 'handle' => 'embedpress-blocks-editor',
162 'priority' => 10,
163 ],
164 'blocks-editor-style' => [
165 'file' => 'css/blocks.build.css',
166 'deps' => [],
167 'contexts' => ['editor'],
168 'type' => 'style',
169 'handle' => 'embedpress-blocks-editor-style',
170 'priority' => 10,
171 ],
172 'blocks-style' => [
173 'file' => 'css/blocks.build.css',
174 'deps' => [],
175 'contexts' => ['frontend', 'editor'],
176 'type' => 'style',
177 'handle' => 'embedpress-blocks-style',
178 'priority' => 10,
179 ],
180
181 // Priority 15-20: Legacy JS files
182 'admin-legacy-js' => [
183 'file' => 'js/admin.js',
184 'deps' => ['jquery'],
185 'contexts' => ['admin'],
186 'type' => 'script',
187 'footer' => true,
188 'handle' => 'embedpress-admin-legacy',
189 'priority' => 15,
190 'page' => 'embedpress'
191 ],
192 'ads-js' => [
193 'file' => 'js/sponsored.js',
194 'deps' => ['jquery', 'embedpress-front'],
195 'contexts' => ['editor', 'frontend', 'elementor'],
196 'type' => 'script',
197 'footer' => true,
198 'handle' => 'embedpress-ads',
199 'priority' => 16,
200 ],
201 'analytics-tracker-js' => [
202 'file' => 'js/analytics-tracker.js',
203 'deps' => ['jquery'],
204 'contexts' => ['frontend', 'elementor'],
205 'type' => 'script',
206 'footer' => true,
207 'handle' => 'embedpress-analytics-tracker',
208 'priority' => 15,
209 ],
210 'carousel-js' => [
211 'file' => 'js/carousel.js',
212 'deps' => ['jquery', 'embedpress-carousel-vendor'],
213 'contexts' => ['frontend', 'elementor'],
214 'type' => 'script',
215 'footer' => true,
216 'handle' => 'embedpress-carousel',
217 'priority' => 15,
218 ],
219 'documents-viewer-js' => [
220 'file' => 'js/documents-viewer-script.js',
221 'deps' => ['jquery'],
222 'contexts' => ['frontend', 'elementor'],
223 'type' => 'script',
224 'footer' => true,
225 'handle' => 'embedpress-documents-viewer',
226 'priority' => 15,
227 ],
228 'front-js' => [
229 'file' => 'js/front.js',
230 'deps' => ['jquery'],
231 'contexts' => ['frontend', 'editor', 'elementor'],
232 'type' => 'script',
233 'footer' => true,
234 'handle' => 'embedpress-front',
235 'priority' => 15,
236 ],
237 'gallery-justify-js' => [
238 'file' => 'js/gallery-justify.js',
239 'deps' => ['jquery'],
240 'contexts' => ['editor', 'frontend', 'elementor'],
241 'type' => 'script',
242 'footer' => true,
243 'handle' => 'embedpress-gallery-justify',
244 'priority' => 15,
245 ],
246 'gutenberg-script-js' => [
247 'file' => 'js/gutneberg-script.js',
248 'deps' => ['wp-blocks', 'wp-element'],
249 'contexts' => ['editor'],
250 'type' => 'script',
251 'footer' => true,
252 'handle' => 'embedpress-gutenberg-script',
253 'priority' => 15,
254 ],
255 'init-plyr-js' => [
256 'file' => 'js/initplyr.js',
257 'deps' => ['jquery', 'embedpress-plyr'],
258 'contexts' => ['frontend', 'elementor'],
259 'type' => 'script',
260 'footer' => true,
261 'handle' => 'embedpress-init-plyr',
262 'priority' => 15,
263 ],
264 'instafeed-js' => [
265 'file' => 'js/instafeed.js',
266 'deps' => ['jquery'],
267 'contexts' => ['frontend', 'elementor'],
268 'type' => 'script',
269 'footer' => true,
270 'handle' => 'embedpress-instafeed',
271 'priority' => 15,
272 ],
273 'license-js' => [
274 'file' => 'js/license.js',
275 'deps' => ['jquery'],
276 'contexts' => ['admin'],
277 'type' => 'script',
278 'footer' => true,
279 'handle' => 'embedpress-license',
280 'priority' => 15,
281 'page' => 'embedpress'
282 ],
283 'preview-js' => [
284 'file' => 'js/preview.js',
285 'deps' => ['jquery', 'embedpress-bootbox'],
286 'contexts' => ['editor'],
287 'type' => 'script',
288 'footer' => true,
289 'handle' => 'embedpress-preview',
290 'priority' => 15,
291 'page' => 'embedpress'
292 ],
293 'settings-js' => [
294 'file' => 'js/settings.js',
295 'deps' => ['jquery', 'wp-color-picker'],
296 'contexts' => ['admin'],
297 'type' => 'script',
298 'footer' => true,
299 'handle' => 'embedpress-settings',
300 'priority' => 15,
301 'page' => 'embedpress'
302 ],
303
304 // 🎨 Styles (Ordered by Priority)
305 // ----------------------------------
306
307 // Build CSS files (analytics.build.css is handled by Analytics.php)
308
309 // Legacy CSS files
310 'admin-notices-css' => [
311 'file' => 'css/admin-notices.css',
312 'deps' => [],
313 'contexts' => ['admin'],
314 'type' => 'style',
315 'handle' => 'embedpress-admin-notices',
316 'priority' => 5,
317 'page' => 'embedpress'
318 ],
319
320 'el-icon-css' => [
321 'file' => 'css/el-icon.css',
322 'deps' => [],
323 'contexts' => ['elementor-editor'],
324 'type' => 'style',
325 'handle' => 'embedpress-el-icon',
326 'priority' => 5,
327 ],
328 'embedpress-elementor-css' => [
329 'file' => 'css/embedpress-elementor.css',
330 'deps' => [],
331 'contexts' => ['elementor'],
332 'type' => 'style',
333 'handle' => 'embedpress-elementor-css',
334 'priority' => 5,
335 ],
336 'embedpress-css' => [
337 'file' => 'css/embedpress.css',
338 'deps' => [],
339 'contexts' => ['editor', 'frontend', 'elementor'],
340 'type' => 'style',
341 'handle' => 'embedpress-css',
342 'priority' => 5,
343 ],
344 'settings-icons-css' => [
345 'file' => 'css/settings-icons.css',
346 'deps' => [],
347 'contexts' => ['admin'],
348 'type' => 'style',
349 'handle' => 'embedpress-settings-icons',
350 'priority' => 5,
351 'page' => 'embedpress'
352 ],
353 'settings-css' => [
354 'file' => 'css/settings.css',
355 'deps' => [],
356 'contexts' => ['admin'],
357 'type' => 'style',
358 'handle' => 'embedpress-settings-css',
359 'priority' => 5,
360 'page' => 'embedpress'
361 ],
362 'admin-css' => [
363 'file' => 'css/admin.css',
364 'deps' => [],
365 'contexts' => ['admin'],
366 'type' => 'style',
367 'handle' => 'embedpress-admin-css',
368 'priority' => 5,
369 'page' => 'embedpress'
370 ],
371 ];
372
373 /**
374 * Initialize asset manager
375 */
376 public static function init()
377 {
378
379
380 // Use proper priorities to ensure correct load order
381 add_action('wp_enqueue_scripts', [__CLASS__, 'enqueue_frontend_assets'], 5);
382 add_action('admin_enqueue_scripts', [__CLASS__, 'enqueue_admin_assets'], 5);
383 add_action('enqueue_block_assets', [__CLASS__, 'enqueue_block_assets'], 5);
384
385 add_action('enqueue_block_editor_assets', [__CLASS__, 'enqueue_editor_assets'], 5);
386
387 add_action('elementor/frontend/after_enqueue_styles', [__CLASS__, 'enqueue_elementor_assets'], 5);
388
389 add_action('elementor/editor/after_enqueue_styles', [__CLASS__, 'enqueue_elementor_editor_assets'], 5);
390 }
391
392 /**
393 * Enqueue frontend assets
394 */
395 public static function enqueue_frontend_assets()
396 {
397 self::enqueue_assets_for_context('frontend');
398
399 // Setup frontend localization
400 LocalizationManager::setup_frontend_localization();
401 }
402
403 /**
404 * Enqueue admin assets
405 */
406 public static function enqueue_admin_assets($hook = '')
407 {
408 self::enqueue_assets_for_context('admin', $hook);
409
410 // Load settings assets only on EmbedPress settings pages
411 if (strpos($hook, 'embedpress') !== false) {
412 self::enqueue_assets_for_context('settings', $hook);
413
414 // Ensure wp-color-picker is loaded for settings page
415 wp_enqueue_style('wp-color-picker');
416
417 // Ensure media scripts are loaded
418 if (!did_action('wp_enqueue_media')) {
419 wp_enqueue_media();
420 }
421 }
422
423 // Setup admin localization
424 LocalizationManager::setup_admin_localization($hook);
425 }
426
427 /**
428 * Enqueue block assets (both editor and frontend)
429 */
430 public static function enqueue_block_assets()
431 {
432 // This runs on both frontend and editor for blocks
433 // For frontend, we don't need the editor scripts
434 if (is_admin()) {
435 self::enqueue_assets_for_context('editor');
436 }
437 }
438
439 /**
440 * Enqueue editor-only assets
441 */
442 public static function enqueue_editor_assets()
443 {
444 // Ensure editor assets are loaded
445 self::enqueue_assets_for_context('editor');
446
447 // Setup editor localization
448 LocalizationManager::setup_editor_localization();
449 }
450
451 /**
452 * Enqueue Elementor frontend assets
453 */
454 public static function enqueue_elementor_assets()
455 {
456 self::enqueue_assets_for_context('elementor');
457
458 // Setup Elementor localization
459 LocalizationManager::setup_elementor_localization();
460 }
461
462 /**
463 * Enqueue Elementor editor assets
464 */
465 public static function enqueue_elementor_editor_assets()
466 {
467 // In Elementor editor, load elementor, editor, and elementor-editor contexts
468 self::enqueue_assets_for_context('elementor');
469 self::enqueue_assets_for_context('editor');
470 self::enqueue_assets_for_context('elementor-editor');
471
472 // Setup Elementor editor localization
473 LocalizationManager::setup_elementor_localization();
474 }
475
476 /**
477 * Enqueue assets for a specific context
478 */
479 private static function enqueue_assets_for_context($context, $hook = '')
480 {
481
482 $assets_to_enqueue = [];
483
484 // Collect assets for this context
485 foreach (self::$assets as $key => $asset) {
486 if (in_array($context, $asset['contexts'])) {
487 // Check if asset has page restriction
488 if (isset($asset['page']) && !empty($asset['page'])) {
489 // Only enqueue if we're on the specified page
490 if (strpos($hook, $asset['page']) !== false) {
491 $assets_to_enqueue[] = array_merge($asset, ['key' => $key]);
492 }
493 // If page doesn't match, don't enqueue this asset
494 } else {
495 // No page restriction, enqueue normally
496 $assets_to_enqueue[] = array_merge($asset, ['key' => $key]);
497 }
498 }
499 }
500
501 // Sort by priority
502 usort($assets_to_enqueue, function ($a, $b) {
503 return $a['priority'] - $b['priority'];
504 });
505
506 // Enqueue assets
507 foreach ($assets_to_enqueue as $asset) {
508 self::enqueue_single_asset($asset);
509 }
510 }
511
512 /**
513 * Enqueue a single asset
514 */
515 private static function enqueue_single_asset($asset)
516 {
517 $file_url = EMBEDPRESS_PLUGIN_DIR_URL . 'assets/' . $asset['file'];
518 $file_path = EMBEDPRESS_PLUGIN_DIR_PATH . '/assets/' . $asset['file'];
519
520 if (! file_exists($file_path)) {
521 return;
522 }
523
524 $version = filemtime($file_path);
525
526 // Check if we should load this asset based on current context
527 if (!self::should_load_asset($asset)) {
528 return;
529 }
530
531 // Enqueue asset
532 if ($asset['type'] === 'script') {
533 wp_enqueue_script(
534 $asset['handle'],
535 $file_url,
536 $asset['deps'],
537 $version,
538 ! empty($asset['footer'])
539 );
540
541 // Add module attribute for ES modules (only build files)
542 if (strpos($asset['file'], '.build.js') !== false) {
543 // Track this handle as a module
544 self::$module_handles[] = $asset['handle'];
545
546 // Add the global filter only once
547 if (!self::$module_filter_added) {
548 self::$module_filter_added = true;
549 add_filter('script_loader_tag', [__CLASS__, 'add_module_attribute'], 10, 2);
550 }
551 }
552 } elseif ($asset['type'] === 'style') {
553
554 wp_enqueue_style(
555 $asset['handle'],
556 $file_url,
557 $asset['deps'],
558 $version,
559 $asset['media'] ?? 'all'
560 );
561 }
562 }
563
564 /**
565 * Determine if an asset should be loaded based on current context
566 */
567 private static function should_load_asset($asset)
568 {
569 // Get current environment state
570 $is_admin = is_admin();
571 $is_elementor_editor = false;
572 $is_elementor_preview = false;
573 $is_gutenberg_editor = false;
574
575 // Check Elementor states
576 if (class_exists('\Elementor\Plugin')) {
577 $elementor = \Elementor\Plugin::$instance;
578
579 if (isset($elementor->editor)) {
580 $is_elementor_editor = $elementor->editor->is_edit_mode();
581 }
582
583 if (isset($elementor->preview)) {
584 $is_elementor_preview = $elementor->preview->is_preview_mode();
585 }
586 }
587
588 // Check if we're in Gutenberg editor
589 if ($is_admin) {
590 global $pagenow;
591 $is_gutenberg_editor = (
592 $pagenow === 'post.php' ||
593 $pagenow === 'post-new.php' ||
594 $pagenow === 'site-editor.php'
595 ) && function_exists('use_block_editor_for_post_type');
596 }
597
598 // Asset loading logic based on contexts
599 foreach ($asset['contexts'] as $context) {
600 switch ($context) {
601 case 'frontend':
602 // Load on frontend (not in any editor or admin)
603 if (!$is_admin && !$is_elementor_editor && !$is_elementor_preview) {
604 return true;
605 }
606 break;
607
608 case 'admin':
609 // Load in WordPress admin (but not in Elementor editor)
610 if ($is_admin && !$is_elementor_editor && !$is_elementor_preview) {
611 // Check if asset has page restriction
612 if (isset($asset['page'])) {
613 return self::is_embedpress_admin_page($asset['page']);
614 }
615 return true;
616 }
617 break;
618
619 case 'editor':
620 // Load in Gutenberg editor or when editing posts
621 if ($is_gutenberg_editor || ($is_admin && !$is_elementor_editor)) {
622 return true;
623 }
624 break;
625
626 case 'elementor':
627 // Load in Elementor editor, preview, or frontend when Elementor is rendering
628 if ($is_elementor_editor || $is_elementor_preview) {
629 return true;
630 }
631 // Also load on frontend if Elementor content is present
632 if (!$is_admin && self::has_elementor_content()) {
633 return true;
634 }
635 break;
636
637 case 'elementor-editor':
638 // Load only in Elementor editor (not preview or frontend)
639 if ($is_elementor_editor) {
640 return true;
641 }
642 break;
643
644 case 'settings':
645 // Load only on EmbedPress settings pages
646 if ($is_admin && !$is_elementor_editor && !$is_elementor_preview) {
647 return true;
648 }
649 break;
650 }
651 }
652
653 // Check if this is an individual block script and if it should be loaded
654 if (strpos($asset['handle'], 'embedpress-block-') === 0) {
655 return self::should_load_individual_block($asset['handle']);
656 }
657
658 return false;
659 }
660
661 /**
662 * Check if we're on an EmbedPress admin page
663 */
664 private static function is_embedpress_admin_page($page_type)
665 {
666 global $pagenow;
667
668 // Get current page
669 $current_page = isset($_GET['page']) ? $_GET['page'] : '';
670
671 switch ($page_type) {
672 case 'embedpress':
673 // Check if we're on any EmbedPress admin page
674 return (
675 strpos($current_page, 'embedpress') !== false ||
676 $pagenow === 'admin.php' && strpos($current_page, 'embedpress') !== false
677 );
678 case 'embedpress-analytics':
679 return $current_page === 'embedpress-analytics';
680 default:
681 return false;
682 }
683 }
684
685 /**
686 * Check if individual block should be loaded based on active blocks
687 */
688 private static function should_load_individual_block($handle)
689 {
690 // Get active blocks from settings
691 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ":elements", []);
692 $active_blocks = isset($elements['gutenberg']) ? (array) $elements['gutenberg'] : [];
693
694 // Map handles to block names
695 $block_map = [
696 'embedpress-block-embedpress' => 'embedpress',
697 'embedpress-block-document' => 'document',
698 'embedpress-block-pdf' => 'embedpress-pdf',
699 'embedpress-block-calendar' => 'embedpress-calendar',
700 'embedpress-block-google-docs' => 'google-docs',
701 'embedpress-block-google-drawings' => 'google-drawings',
702 'embedpress-block-google-forms' => 'google-forms',
703 'embedpress-block-google-maps' => 'google-maps',
704 'embedpress-block-google-sheets' => 'google-sheets',
705 'embedpress-block-google-slides' => 'google-slides',
706 'embedpress-block-twitch' => 'twitch',
707 'embedpress-block-wistia' => 'wistia',
708 'embedpress-block-youtube' => 'youtube'
709 ];
710
711 $block_name = isset($block_map[$handle]) ? $block_map[$handle] : '';
712
713 // If no block name found or no active blocks set, load all blocks (default behavior)
714 if (empty($block_name) || empty($active_blocks)) {
715 return true;
716 }
717
718 // Check if this specific block is active
719 return in_array($block_name, $active_blocks);
720 }
721
722 /**
723 * Check if current page has Elementor content
724 */
725 private static function has_elementor_content()
726 {
727 if (! class_exists('\Elementor\Plugin')) {
728 return false;
729 }
730
731 if (is_singular()) {
732 $post_id = get_the_ID();
733 if (empty($post_id) || ! is_numeric($post_id)) {
734 return false;
735 }
736
737 $document = \Elementor\Plugin::$instance->documents->get($post_id);
738
739 if ($document && method_exists($document, 'is_built_with_elementor')) {
740 return (bool) $document->is_built_with_elementor();
741 }
742 }
743
744 return false;
745 }
746
747
748 /**
749 * Get asset URL
750 */
751 public static function get_asset_url($file)
752 {
753 return EMBEDPRESS_PLUGIN_DIR_URL . 'assets/' . $file;
754 }
755
756
757
758 /**
759 * Add module attribute to script tags for ES modules
760 */
761 public static function add_module_attribute($tag, $handle)
762 {
763 if (in_array($handle, self::$module_handles)) {
764 // Only add type="module" if it doesn't already exist
765 if (strpos($tag, 'type="module"') === false) {
766 return str_replace('<script ', '<script type="module" ', $tag);
767 }
768 }
769 return $tag;
770 }
771
772 /**
773 * Check if asset exists
774 */
775 public static function asset_exists($file)
776 {
777 $plugin_path = dirname(dirname(dirname(__DIR__)));
778 return file_exists($plugin_path . '/assets/' . $file);
779 }
780 }
781