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