PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 4.4.6
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v4.4.6
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 / LocalizationManager.php
embedpress / Core Last commit date
AssetManager.php 7 months ago LocalizationManager.php 7 months ago init.php 9 months ago
LocalizationManager.php
565 lines
1 <?php
2
3 namespace EmbedPress\Core;
4
5 use EmbedPress\Includes\Classes\Helper;
6
7 /**
8 * EmbedPress Localization Manager
9 *
10 * Handles all JavaScript localization for EmbedPress blocks, admin, and frontend
11 * Provides clean separation of concerns from AssetManager
12 */
13 class LocalizationManager
14 {
15 /**
16 * Setup admin localization scripts
17 *
18 * @param string $hook Current admin page hook
19 */
20 public static function setup_admin_localization($hook)
21 {
22 global $pagenow;
23
24 self::setup_license_localization();
25 self::setup_feature_notices_localization();
26
27 // Setup settings page localization if on EmbedPress settings page
28 if (strpos($hook, 'embedpress') !== false) {
29 self::setup_settings_localization();
30 self::setup_preview_localization();
31 }
32
33 // Only setup localization on post edit pages
34 if (!in_array($pagenow, ['post.php', 'post-new.php'])) {
35 return;
36 }
37 }
38
39 /**
40 * Setup editor localization scripts
41 */
42 public static function setup_editor_localization()
43 {
44 self::setup_frontend_script_localization();
45 self::setup_gutenberg_localization();
46 self::setup_new_blocks_localization();
47 self::setup_preview_localization();
48 }
49
50 /**
51 * Setup frontend localization scripts
52 */
53 public static function setup_frontend_localization()
54 {
55 self::setup_frontend_script_localization();
56 self::setup_gutenberg_localization();
57 self::setup_preview_localization();
58 self::setup_analytics_localization();
59 }
60
61 /**
62 * Setup Elementor widget localization
63 */
64 public static function setup_elementor_localization()
65 {
66 self::setup_frontend_script_localization();
67 self::setup_calendar_widget_localization();
68 self::setup_analytics_localization();
69 }
70
71 /**
72 * Setup preview localization (attached to preview script)
73 */
74 private static function setup_preview_localization()
75 {
76 // Try both admin and preview script handles
77 $script_handles = ['embedpress-admin', 'embedpress-preview'];
78
79 $url_schemes = apply_filters('embedpress:getAdditionalURLSchemes', self::get_url_schemes());
80
81 // Ensure required constants are defined with fallbacks
82 $version = defined('EMBEDPRESS_VERSION') ? EMBEDPRESS_VERSION : '1.0.0';
83 $shortcode = defined('EMBEDPRESS_SHORTCODE') ? EMBEDPRESS_SHORTCODE : 'embedpress';
84 $assets_url = defined('EMBEDPRESS_URL_ASSETS') ? EMBEDPRESS_URL_ASSETS : '';
85
86 $localization_data = [
87 'previewSettings' => [
88 'baseUrl' => get_site_url() . '/',
89 'versionUID' => $version,
90 'debug' => defined('WP_DEBUG') && WP_DEBUG,
91 ],
92 'shortcode' => $shortcode,
93 'assetsUrl' => $assets_url,
94 'urlSchemes' => $url_schemes,
95 ];
96
97 foreach ($script_handles as $script_handle) {
98 if (wp_script_is($script_handle, 'enqueued') || wp_script_is($script_handle, 'registered')) {
99 wp_localize_script($script_handle, 'embedpressPreviewData', $localization_data);
100 }
101 }
102
103 wp_localize_script($script_handle, 'embedpressAdminParams', [
104 'ajaxUrl' => admin_url('admin-ajax.php'),
105 'nonce' => wp_create_nonce('embedpress')
106 ]);
107 }
108
109 /**
110 * Setup license script localization
111 */
112 private static function setup_license_localization()
113 {
114 $script_handle = 'embedpress-admin';
115
116 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
117 return;
118 }
119
120 $item_id = defined('EMBEDPRESS_SL_ITEM_ID') ? EMBEDPRESS_SL_ITEM_ID : 'embedpress';
121
122 wp_localize_script($script_handle, 'embedpressLicenseData', [
123 'nonce' => wp_create_nonce('wpdeveloper_sl_' . $item_id . '_nonce')
124 ]);
125 }
126
127 /**
128 * Setup feature notices script localization
129 */
130 private static function setup_feature_notices_localization()
131 {
132 $script_handle = 'embedpress-feature-notices';
133
134 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
135 return;
136 }
137
138 wp_localize_script($script_handle, 'embedpressFeatureNotices', [
139 'ajaxurl' => admin_url('admin-ajax.php'),
140 'nonce' => wp_create_nonce('embedpress_feature_notice'),
141 ]);
142 }
143
144 /**
145 * Setup Gutenberg blocks localization (embedpressObj variable)
146 */
147 private static function setup_gutenberg_localization()
148 {
149 $script_handle = 'embedpress-blocks-editor';
150
151 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
152 return;
153 }
154
155 // Ensure required constants are defined
156 if (!defined('EMBEDPRESS_PLG_NAME')) {
157 return;
158 }
159
160 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ":elements", []);
161 $active_blocks = isset($elements['gutenberg']) ? (array) $elements['gutenberg'] : [];
162
163 $wistia_labels = self::get_wistia_labels();
164 $wistia_options = self::get_wistia_options();
165 $pars_url = wp_parse_url(get_site_url());
166 $documents_cta_options = (array) get_option(EMBEDPRESS_PLG_NAME . ':document');
167 $current_user = wp_get_current_user();
168 $assets_url = defined('EMBEDPRESS_URL_ASSETS') ? EMBEDPRESS_URL_ASSETS : '';
169 $static_url = defined('EMBEDPRESS_URL_STATIC') ? EMBEDPRESS_URL_STATIC : '';
170
171 // Get global powered_by setting
172 $g_settings = get_option(EMBEDPRESS_PLG_NAME, []);
173 $powered_by_default = isset($g_settings['embedpress_document_powered_by']) && $g_settings['embedpress_document_powered_by'] === 'yes';
174
175 wp_localize_script($script_handle, 'embedpressGutenbergData', [
176
177
178 // Keep only the variables that are actually used in JavaScript
179 'wistiaLabels' => json_encode($wistia_labels),
180 'wistiaOptions' => $wistia_options,
181 'poweredBy' => apply_filters('embedpress_document_block_powered_by', $powered_by_default),
182 'isProVersion' => defined('EMBEDPRESS_PRO_PLUGIN_FILE'),
183 'twitchHost' => !empty($pars_url['host']) ? $pars_url['host'] : '',
184 'siteUrl' => site_url(),
185 'activeBlocks' => $active_blocks,
186 'documentCta' => $documents_cta_options,
187 'pdfRenderer' => Helper::get_pdf_renderer(),
188 'isProPluginActive' => defined('EMBEDPRESS_SL_ITEM_SLUG'),
189 'ajaxUrl' => admin_url('admin-ajax.php'),
190 'adminUrl' => admin_url(),
191 'sourceNonce' => wp_create_nonce('source_nonce_embedpress'),
192 'canUploadMedia' => current_user_can('upload_files'),
193 'assetsUrl' => $assets_url,
194 'staticUrl' => $static_url,
195 // Use underscore naming for consistency with block attributes
196 'iframe_width' => Helper::get_options_value('enableEmbedResizeWidth', '600'),
197 'iframe_height' => Helper::get_options_value('enableEmbedResizeHeight', '400'),
198 'iframeWidth' => Helper::get_options_value('enableEmbedResizeWidth', '600'), // Keep camelCase for backward compatibility
199 'iframeHeight' => Helper::get_options_value('enableEmbedResizeHeight', '400'), // Keep camelCase for backward compatibility
200 'pdfCustomColor' => Helper::get_options_value('custom_color', '#403A81'),
201 'brandingLogos' => [
202 'youtube' => Helper::get_branding_value('logo_url', 'youtube'),
203 'vimeo' => Helper::get_branding_value('logo_url', 'vimeo'),
204 'wistia' => Helper::get_branding_value('logo_url', 'wistia'),
205 'twitch' => Helper::get_branding_value('logo_url', 'twitch'),
206 'dailymotion' => Helper::get_branding_value('logo_url', 'dailymotion'),
207 ],
208 'userRoles' => Helper::get_user_roles(),
209 'currentUser' => $current_user->data,
210 'feedbackSubmitted' => get_option('embedpress_feedback_submited'),
211 'ratingHelpDisabled' => Helper::get_options_value('turn_off_rating_help', false),
212
213 // Legacy support
214 'wistia_labels' => json_encode($wistia_labels),
215 'wisita_options' => $wistia_options,
216 'embedpress_powered_by' => apply_filters('embedpress_document_block_powered_by', $powered_by_default),
217 'embedpress_pro' => defined('EMBEDPRESS_PRO_PLUGIN_FILE'),
218 'twitch_host' => !empty($pars_url['host']) ? $pars_url['host'] : '',
219 'site_url' => site_url(),
220 'rest_url' => get_rest_url(),
221 'embedpress_rest_url' => get_rest_url(null, 'embedpress/v1/oembed/embedpress'),
222 'active_blocks' => $active_blocks,
223 'document_cta' => $documents_cta_options,
224 'pdf_renderer' => Helper::get_pdf_renderer(),
225 'is_pro_plugin_active' => defined('EMBEDPRESS_SL_ITEM_SLUG'),
226 'ajaxurl' => admin_url('admin-ajax.php'),
227 'source_nonce' => wp_create_nonce('source_nonce_embedpress'),
228 'can_upload_media' => current_user_can('upload_files'),
229 'permalink_structure' => get_option('permalink_structure'),
230 'EMBEDPRESS_URL_ASSETS' => EMBEDPRESS_URL_ASSETS,
231 'iframe_width' => Helper::get_options_value('enableEmbedResizeWidth'),
232 'iframe_height' => Helper::get_options_value('enableEmbedResizeHeight'),
233 'pdf_custom_color' => Helper::get_options_value('custom_color'),
234 'pdf_custom_color' => Helper::get_options_value('custom_color'),
235 'youtube_brand_logo_url' => Helper::get_branding_value('logo_url', 'youtube'),
236 'vimeo_brand_logo_url' => Helper::get_branding_value('logo_url', 'vimeo'),
237 'wistia_brand_logo_url' => Helper::get_branding_value('logo_url', 'wistia'),
238 'twitch_brand_logo_url' => Helper::get_branding_value('logo_url', 'twitch'),
239 'dailymotion_brand_logo_url' => Helper::get_branding_value('logo_url', 'dailymotion'),
240 'user_roles' => Helper::get_user_roles(),
241 'current_user' => $current_user->data,
242 'is_embedpress_feedback_submited' => get_option('embedpress_feedback_submited'),
243 'turn_off_rating_help' => Helper::get_options_value('turn_off_rating_help'),
244 ]);
245 }
246
247 /**
248 * Setup frontend script localization (embedpressFrontendData variable)
249 */
250 private static function setup_frontend_script_localization()
251 {
252 // The embedpressFrontendData variable should be attached to multiple frontend scripts
253 $script_handles = ['embedpress-front', 'embedpress-ads'];
254
255 $localization_data = [
256 'ajaxurl' => admin_url('admin-ajax.php'),
257 'isProPluginActive' => defined('EMBEDPRESS_SL_ITEM_SLUG'),
258 'nonce' => wp_create_nonce('ep_nonce'),
259 ];
260
261 foreach ($script_handles as $script_handle) {
262 if (wp_script_is($script_handle, 'enqueued') || wp_script_is($script_handle, 'registered')) {
263 wp_localize_script($script_handle, 'embedpressFrontendData', $localization_data);
264 }
265 }
266 }
267
268 /**
269 * Setup settings page localization (attached to admin script)
270 */
271 private static function setup_settings_localization()
272 {
273 $script_handle = 'embedpress-admin';
274
275 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
276 return;
277 }
278
279 wp_localize_script($script_handle, 'embedpressSettingsData', [
280 'nonce' => wp_create_nonce('embedpress_elements_action'),
281 'ajaxNonce' => wp_create_nonce('embedpress_ajax_nonce'),
282 ]);
283 }
284
285 /**
286 * Setup new blocks localization (for new block system)
287 */
288 private static function setup_new_blocks_localization()
289 {
290 // Try multiple possible handles for new blocks
291 $possible_handles = [
292 'embedpress-blocks-editor', // Current handle from AssetManager
293 'embedpress-blocks', // Old handle
294 'embedpress_blocks-cgb-block-js', // Legacy handle
295 'embedpress-blocks-js', // Alternative handle
296 ];
297
298 $script_handle = null;
299 foreach ($possible_handles as $handle) {
300 if (wp_script_is($handle, 'enqueued') || wp_script_is($handle, 'registered')) {
301 $script_handle = $handle;
302 break;
303 }
304 }
305
306 if (!$script_handle) {
307 return;
308 }
309
310 // Ensure required constants are defined
311 if (!defined('EMBEDPRESS_PLG_NAME')) {
312 return;
313 }
314
315 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ":elements", []);
316 $active_blocks = isset($elements['gutenberg']) ? (array) $elements['gutenberg'] : [];
317
318 wp_localize_script($script_handle, 'embedpressNewBlocksData', [
319 'pluginDirPath' => defined('EMBEDPRESS_PATH_BASE') ? EMBEDPRESS_PATH_BASE : '',
320 'pluginDirUrl' => defined('EMBEDPRESS_URL_STATIC') ? EMBEDPRESS_URL_STATIC . '../' : '',
321 'activeBlocks' => $active_blocks,
322 'canUploadMedia' => current_user_can('upload_files'),
323 'ajaxUrl' => admin_url('admin-ajax.php'),
324 'nonce' => wp_create_nonce('embedpress_nonce'),
325 'restUrl' => rest_url('embedpress/v1/'),
326 'siteUrl' => site_url(),
327 ]);
328 }
329
330
331
332
333
334 /**
335 * Setup analytics tracker localization
336 */
337 private static function setup_analytics_localization()
338 {
339 $script_handle = 'embedpress-analytics-tracker';
340
341 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
342 return;
343 }
344
345 // Get analytics manager instance to check for embedded content
346 $has_embedded_content = false;
347 if (class_exists('EmbedPress\Includes\Classes\Analytics\Analytics_Manager')) {
348 $analytics_manager = \EmbedPress\Includes\Classes\Analytics\Analytics_Manager::get_instance();
349 $has_embedded_content = $analytics_manager->has_embedded_content();
350 }
351
352 // Get tracking enabled setting
353 $tracking_enabled = get_option('embedpress_analytics_tracking_enabled', true);
354
355 // Get original referrer if available
356 $original_referrer = '';
357 if (defined('EMBEDPRESS_ORIGINAL_REFERRER') && !empty(EMBEDPRESS_ORIGINAL_REFERRER)) {
358 $original_referrer = EMBEDPRESS_ORIGINAL_REFERRER;
359 }
360
361 // Get session ID safely
362 $session_id = self::get_analytics_session_id();
363
364 wp_localize_script($script_handle, 'embedpress_analytics', [
365 'ajax_url' => admin_url('admin-ajax.php'),
366 'rest_url' => rest_url('embedpress/v1/analytics/'),
367 'nonce' => wp_create_nonce('wp_rest'),
368 'session_id' => $session_id,
369 'page_url' => get_permalink(),
370 'post_id' => get_the_ID(),
371 'tracking_enabled' => (bool) $tracking_enabled,
372 'original_referrer' => $original_referrer,
373 'has_embedded_content' => $has_embedded_content
374 ]);
375 }
376
377 /**
378 * Setup Google Calendar widget localization
379 */
380 private static function setup_calendar_widget_localization()
381 {
382 $script_handle = 'epgc';
383
384 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
385 return;
386 }
387
388 $nonce = wp_create_nonce('epgc_nonce');
389 wp_localize_script($script_handle, 'embedpressCalendarData', [
390 'ajaxUrl' => admin_url('admin-ajax.php'),
391 'nonce' => $nonce,
392 'translations' => [
393 'allDay' => __('All day', 'embedpress'),
394 'createdBy' => __('Created by', 'embedpress'),
395 'goToEvent' => __('Go to event', 'embedpress'),
396 'unknownError' => __('Unknown error', 'embedpress'),
397 'requestError' => __('Request error', 'embedpress'),
398 'loading' => __('Loading', 'embedpress')
399 ]
400 ]);
401 }
402
403 /**
404 * Load plugin text domain for translations
405 */
406 public static function load_text_domain()
407 {
408 $locale = determine_locale();
409 $locale = apply_filters('plugin_locale', $locale, 'embedpress');
410
411 // Load from WordPress languages directory first
412 if (file_exists(WP_LANG_DIR . "/embedpress-" . $locale . '.mo')) {
413 unload_textdomain('embedpress');
414 load_textdomain('embedpress', WP_LANG_DIR . "/embedpress-" . $locale . '.mo');
415 }
416
417 // Load from plugin languages directory
418 load_plugin_textdomain('embedpress', false, plugin_basename(dirname(EMBEDPRESS_FILE)) . '/languages');
419 }
420
421 /**
422 * Get Wistia labels for localization
423 *
424 * @return array
425 */
426 private static function get_wistia_labels()
427 {
428 return [
429 'watch_from_beginning' => __('Watch from the beginning', 'embedpress'),
430 'skip_to_where_you_left_off' => __('Skip to where you left off', 'embedpress'),
431 'you_have_watched_it_before' => __('It looks like you\'ve watched<br />part of this video before!', 'embedpress'),
432 ];
433 }
434
435 /**
436 * Get Wistia options safely
437 *
438 * @return mixed|null
439 */
440 private static function get_wistia_options()
441 {
442 if (!function_exists('embedpress_wisita_pro_get_options')) {
443 return null;
444 }
445
446 try {
447 // return embedpress_wisita_pro_get_options();
448 } catch (\Exception $e) {
449 // Silently fail if function throws an error
450 return null;
451 }
452 }
453
454 /**
455 * Get branding value safely
456 *
457 * @param string $type
458 * @param string $provider
459 * @return string
460 */
461 private static function get_branding_value($type, $provider)
462 {
463 if (!function_exists('get_branding_value')) {
464 return '';
465 }
466
467 try {
468 return self::get_branding_value($type, $provider);
469 } catch (\Exception $e) {
470 return '';
471 }
472 }
473
474 /**
475 * Get analytics session ID safely
476 *
477 * @return string
478 */
479 private static function get_analytics_session_id()
480 {
481 // Prefer cookie-based session IDs to avoid server PHP session configuration issues
482 if (isset($_COOKIE['ep_session_id'])) {
483 $cookie = $_COOKIE['ep_session_id'];
484 // Allow only safe characters and a minimum length
485 if (is_string($cookie) && preg_match('/^[A-Za-z0-9._:-]{8,}$/', $cookie)) {
486 return sanitize_text_field($cookie);
487 }
488 }
489
490 // Generate a new ephemeral session ID
491 $id = 'ep-sess-' . time() . '-' . wp_generate_password(8, false);
492
493 // Set a session cookie (expires when the browser closes)
494 if (!headers_sent()) {
495 $path = defined('COOKIEPATH') ? COOKIEPATH : '/';
496 $domain = (defined('COOKIE_DOMAIN') && COOKIE_DOMAIN) ? COOKIE_DOMAIN : '';
497 $secure = is_ssl();
498 $httponly = true;
499 setcookie('ep_session_id', $id, 0, $path, $domain, $secure, $httponly);
500 }
501
502 return $id;
503 }
504
505 /**
506 * Get URL schemes for preview script
507 *
508 * @return array
509 */
510 private static function get_url_schemes()
511 {
512 return [
513 // Apple podcasts
514 'podcasts.apple.com/*',
515 // YouTube
516 'youtube.com/watch\\?*',
517 'youtube.com/playlist\\?*',
518 'youtube.com/channel/*',
519 'youtube.com/c/*',
520 'youtube.com/user/*',
521 'youtube.com/(\w+)[^?\/]*$',
522 // Vimeo
523 'vimeo.com/*',
524 'vimeo.com/groups/*/videos/*',
525 // Twitter
526 'twitter.com/*/status/*',
527 'twitter.com/i/moments/*',
528 'twitter.com/*/timelines/*',
529 // Facebook
530 'facebook.com/*',
531 'fb.watch/*',
532 // Instagram
533 'instagram.com/p/*',
534 'instagr.am/p/*',
535 // SoundCloud
536 'soundcloud.com/*',
537 // Twitch
538 '*.twitch.tv/*',
539 'twitch.tv/*',
540 // Wistia
541 '*.wistia.com/medias/*',
542 'fast.wistia.com/embed/medias/*.jsonp',
543 // Google services
544 'google.com/*',
545 'google.com.*/*',
546 'google.co.*/*',
547 'maps.google.com/*',
548 'docs.google.com/presentation/*',
549 'docs.google.com/document/*',
550 'docs.google.com/spreadsheets/*',
551 'docs.google.com/forms/*',
552 'docs.google.com/drawings/*',
553 ];
554 }
555
556 /**
557 * Initialize localization manager hooks
558 */
559 public static function init()
560 {
561 // Load text domain early
562 add_action('plugins_loaded', [__CLASS__, 'load_text_domain'], 1);
563 }
564 }
565