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