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 / Core / LocalizationManager.php
embedpress / Core Last commit date
AssetManager.php 1 month ago LocalizationManager.php 1 month ago init.php 9 months ago
LocalizationManager.php
686 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 self::setup_onboarding_localization($hook);
32 }
33
34 // Only setup localization on post edit pages
35 if (!in_array($pagenow, ['post.php', 'post-new.php'])) {
36 return;
37 }
38 }
39
40 /**
41 * Setup editor localization scripts
42 */
43 public static function setup_editor_localization()
44 {
45 self::setup_frontend_script_localization();
46 self::setup_gutenberg_localization();
47 self::setup_new_blocks_localization();
48 self::setup_preview_localization();
49 // Needed for the Calendar block's editor ServerSideRender preview
50 // to authenticate AJAX requests via the epgc_nonce.
51 self::setup_calendar_widget_localization();
52 }
53
54 /**
55 * Setup frontend localization scripts
56 */
57 public static function setup_frontend_localization()
58 {
59 self::setup_frontend_script_localization();
60 self::setup_gutenberg_localization();
61 self::setup_preview_localization();
62 self::setup_analytics_localization();
63 self::setup_pdf_gallery_localization();
64 self::setup_pdf_lightbox_localization();
65 }
66
67 /**
68 * Setup Elementor widget localization
69 */
70 public static function setup_elementor_localization()
71 {
72 self::setup_frontend_script_localization();
73 self::setup_calendar_widget_localization();
74 self::setup_analytics_localization();
75 self::setup_pdf_gallery_localization();
76 self::setup_pdf_lightbox_localization();
77 }
78
79 /**
80 * Setup preview localization (attached to preview script)
81 */
82 private static function setup_preview_localization()
83 {
84 // Try both admin and preview script handles
85 $script_handles = ['embedpress-admin', 'embedpress-preview'];
86
87 $url_schemes = apply_filters('embedpress:getAdditionalURLSchemes', self::get_url_schemes());
88
89 // Ensure required constants are defined with fallbacks
90 $version = defined('EMBEDPRESS_VERSION') ? EMBEDPRESS_VERSION : '1.0.0';
91 $shortcode = defined('EMBEDPRESS_SHORTCODE') ? EMBEDPRESS_SHORTCODE : 'embedpress';
92 $assets_url = defined('EMBEDPRESS_URL_ASSETS') ? EMBEDPRESS_URL_ASSETS : '';
93
94 $localization_data = [
95 'previewSettings' => [
96 'baseUrl' => get_site_url() . '/',
97 'versionUID' => $version,
98 'debug' => defined('WP_DEBUG') && WP_DEBUG,
99 ],
100 'shortcode' => $shortcode,
101 'assetsUrl' => $assets_url,
102 'urlSchemes' => $url_schemes,
103 ];
104
105 foreach ($script_handles as $script_handle) {
106 if (wp_script_is($script_handle, 'enqueued') || wp_script_is($script_handle, 'registered')) {
107 wp_localize_script($script_handle, 'embedpressPreviewData', $localization_data);
108 }
109 }
110
111 wp_localize_script($script_handle, 'embedpressAdminParams', [
112 'ajaxUrl' => admin_url('admin-ajax.php'),
113 'nonce' => wp_create_nonce('embedpress')
114 ]);
115 }
116
117 /**
118 * Setup license script localization
119 */
120 private static function setup_license_localization()
121 {
122 $script_handle = 'embedpress-admin';
123
124 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
125 return;
126 }
127
128 $item_id = defined('EMBEDPRESS_SL_ITEM_ID') ? EMBEDPRESS_SL_ITEM_ID : 'embedpress';
129
130 wp_localize_script($script_handle, 'embedpressLicenseData', [
131 'nonce' => wp_create_nonce('wpdeveloper_sl_' . $item_id . '_nonce')
132 ]);
133 }
134
135 /**
136 * Setup feature notices script localization
137 */
138 private static function setup_feature_notices_localization()
139 {
140 $script_handle = 'embedpress-feature-notices';
141
142 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
143 return;
144 }
145
146 wp_localize_script($script_handle, 'embedpressFeatureNotices', [
147 'ajaxurl' => admin_url('admin-ajax.php'),
148 'nonce' => wp_create_nonce('embedpress_feature_notice'),
149 ]);
150 }
151
152 /**
153 * Setup Gutenberg blocks localization (embedpressObj variable)
154 */
155 private static function setup_gutenberg_localization()
156 {
157 $script_handle = 'embedpress-blocks-editor';
158
159 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
160 return;
161 }
162
163 // Ensure required constants are defined
164 if (!defined('EMBEDPRESS_PLG_NAME')) {
165 return;
166 }
167
168 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ":elements", []);
169 $active_blocks = isset($elements['gutenberg']) ? (array) $elements['gutenberg'] : [];
170
171 $wistia_labels = self::get_wistia_labels();
172 $wistia_options = self::get_wistia_options();
173 $pars_url = wp_parse_url(get_site_url());
174 $documents_cta_options = (array) get_option(EMBEDPRESS_PLG_NAME . ':document');
175 $current_user = wp_get_current_user();
176 $assets_url = defined('EMBEDPRESS_URL_ASSETS') ? EMBEDPRESS_URL_ASSETS : '';
177 $static_url = defined('EMBEDPRESS_URL_STATIC') ? EMBEDPRESS_URL_STATIC : '';
178
179 // Get global powered_by setting
180 $g_settings = get_option(EMBEDPRESS_PLG_NAME, []);
181 $powered_by_default = isset($g_settings['embedpress_document_powered_by']) && $g_settings['embedpress_document_powered_by'] === 'yes';
182 $lazy_load_default = isset($g_settings['g_lazyload']) && $g_settings['g_lazyload'] == 1;
183
184 wp_localize_script($script_handle, 'embedpressGutenbergData', [
185
186
187 // Keep only the variables that are actually used in JavaScript
188 'wistiaLabels' => json_encode($wistia_labels),
189 'wistiaOptions' => $wistia_options,
190 'poweredBy' => apply_filters('embedpress_document_block_powered_by', $powered_by_default),
191 'isProVersion' => defined('EMBEDPRESS_PRO_PLUGIN_FILE'),
192 'twitchHost' => !empty($pars_url['host']) ? $pars_url['host'] : '',
193 'twitchSettings' => self::get_twitch_settings(),
194 'siteUrl' => site_url(),
195 // Permalink-aware REST base. Plain permalinks serve REST under
196 // ?rest_route=/ instead of /wp-json/, so always derive from
197 // rest_url() rather than concatenating site_url() + '/wp-json/'.
198 'restUrl' => esc_url_raw(rest_url('embedpress/v1/')),
199 'activeBlocks' => $active_blocks,
200 'documentCta' => $documents_cta_options,
201 'pdfRenderer' => Helper::get_pdf_renderer(),
202 'flipbookRenderer' => Helper::get_flipbook_renderer(),
203 'isProPluginActive' => defined('EMBEDPRESS_SL_ITEM_SLUG'),
204 'ajaxUrl' => admin_url('admin-ajax.php'),
205 'adminUrl' => admin_url(),
206 'sourceNonce' => wp_create_nonce('source_nonce_embedpress'),
207 'canUploadMedia' => current_user_can('upload_files'),
208 'pdfGalleryNonce' => wp_create_nonce('ep_pdf_gallery_nonce'),
209 'assetsUrl' => $assets_url,
210 'staticUrl' => $static_url,
211 // Use underscore naming for consistency with block attributes
212 'iframe_width' => Helper::get_options_value('enableEmbedResizeWidth', '600'),
213 'iframe_height' => Helper::get_options_value('enableEmbedResizeHeight', '400'),
214 'iframeWidth' => Helper::get_options_value('enableEmbedResizeWidth', '600'), // Keep camelCase for backward compatibility
215 'iframeHeight' => Helper::get_options_value('enableEmbedResizeHeight', '400'), // Keep camelCase for backward compatibility
216 'pdfCustomColor' => Helper::get_options_value('custom_color', '#403A81'),
217 'lazyLoad' => $lazy_load_default,
218 'brandingLogos' => [
219 'youtube' => Helper::get_branding_value('logo_url', 'youtube'),
220 'vimeo' => Helper::get_branding_value('logo_url', 'vimeo'),
221 'wistia' => Helper::get_branding_value('logo_url', 'wistia'),
222 'twitch' => Helper::get_branding_value('logo_url', 'twitch'),
223 'dailymotion' => Helper::get_branding_value('logo_url', 'dailymotion'),
224 'document' => Helper::get_branding_value('logo_url', 'document'),
225 ],
226 'userRoles' => Helper::get_user_roles(),
227 'currentUser' => $current_user->data,
228 'feedbackSubmitted' => get_option('embedpress_feedback_submited'),
229 'ratingHelpDisabled' => Helper::get_options_value('turn_off_rating_help', false),
230 'milestoneDisabled' => Helper::get_options_value('turn_off_milestone', false),
231
232 // Legacy support
233 'wistia_labels' => json_encode($wistia_labels),
234 'wisita_options' => $wistia_options,
235 'embedpress_powered_by' => apply_filters('embedpress_document_block_powered_by', $powered_by_default),
236 'embedpress_pro' => defined('EMBEDPRESS_PRO_PLUGIN_FILE'),
237 'twitch_host' => !empty($pars_url['host']) ? $pars_url['host'] : '',
238 'site_url' => site_url(),
239 'rest_url' => get_rest_url(),
240 'embedpress_rest_url' => get_rest_url(null, 'embedpress/v1/oembed/embedpress'),
241 'active_blocks' => $active_blocks,
242 'document_cta' => $documents_cta_options,
243 'pdf_renderer' => Helper::get_pdf_renderer(),
244 'flipbook_renderer' => Helper::get_flipbook_renderer(),
245 'is_pro_plugin_active' => defined('EMBEDPRESS_SL_ITEM_SLUG'),
246 'ajaxurl' => admin_url('admin-ajax.php'),
247 'source_nonce' => wp_create_nonce('source_nonce_embedpress'),
248 'can_upload_media' => current_user_can('upload_files'),
249 'permalink_structure' => get_option('permalink_structure'),
250 'EMBEDPRESS_URL_ASSETS' => EMBEDPRESS_URL_ASSETS,
251 'iframe_width' => Helper::get_options_value('enableEmbedResizeWidth'),
252 'iframe_height' => Helper::get_options_value('enableEmbedResizeHeight'),
253 'pdf_custom_color' => Helper::get_options_value('custom_color'),
254 'pdf_custom_color' => Helper::get_options_value('custom_color'),
255 'youtube_brand_logo_url' => Helper::get_branding_value('logo_url', 'youtube'),
256 'vimeo_brand_logo_url' => Helper::get_branding_value('logo_url', 'vimeo'),
257 'wistia_brand_logo_url' => Helper::get_branding_value('logo_url', 'wistia'),
258 'twitch_brand_logo_url' => Helper::get_branding_value('logo_url', 'twitch'),
259 'dailymotion_brand_logo_url' => Helper::get_branding_value('logo_url', 'dailymotion'),
260 'user_roles' => Helper::get_user_roles(),
261 'current_user' => $current_user->data,
262 'is_embedpress_feedback_submited' => get_option('embedpress_feedback_submited'),
263 'turn_off_rating_help' => Helper::get_options_value('turn_off_rating_help'),
264 'turn_off_milestone' => Helper::get_options_value('turn_off_milestone'),
265 ]);
266 }
267
268 /**
269 * Setup frontend script localization (embedpressFrontendData variable)
270 */
271 private static function setup_frontend_script_localization()
272 {
273 // The embedpressFrontendData variable should be attached to multiple frontend scripts
274 $script_handles = ['embedpress-front', 'embedpress-ads'];
275
276 $localization_data = [
277 'ajaxurl' => admin_url('admin-ajax.php'),
278 'isProPluginActive' => defined('EMBEDPRESS_SL_ITEM_SLUG'),
279 'nonce' => wp_create_nonce('ep_nonce'),
280 ];
281
282 foreach ($script_handles as $script_handle) {
283 if (wp_script_is($script_handle, 'enqueued') || wp_script_is($script_handle, 'registered')) {
284 wp_localize_script($script_handle, 'embedpressFrontendData', $localization_data);
285 }
286 }
287 }
288
289 /**
290 * Setup settings page localization (attached to admin script)
291 */
292 private static function setup_settings_localization()
293 {
294 $script_handle = 'embedpress-admin';
295
296 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
297 return;
298 }
299
300 wp_localize_script($script_handle, 'embedpressSettingsData', [
301 'nonce' => wp_create_nonce('embedpress_elements_action'),
302 'ajaxNonce' => wp_create_nonce('embedpress_ajax_nonce'),
303 ]);
304 }
305
306 /**
307 * Setup onboarding wizard localization
308 *
309 * @param string $hook Current admin page hook
310 */
311 private static function setup_onboarding_localization($hook)
312 {
313 if (strpos($hook, 'embedpress-onboarding') === false) {
314 return;
315 }
316
317 $script_handle = 'embedpress-onboarding';
318
319 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
320 return;
321 }
322
323 $settings = (array) get_option(EMBEDPRESS_PLG_NAME, []);
324 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ':elements', []);
325 $pro_active = apply_filters('embedpress/is_allow_rander', false);
326
327 wp_localize_script($script_handle, 'embedpressOnboardingData', [
328 'ajaxUrl' => admin_url('admin-ajax.php'),
329 'nonce' => wp_create_nonce('embedpress_onboarding_nonce'),
330 'settingsUrl' => admin_url('admin.php?page=embedpress&page_type=settings'),
331 'dashboardUrl' => admin_url('admin.php?page=embedpress'),
332 'proActive' => $pro_active,
333 'upgradeUrl' => 'https://wpdeveloper.com/in/upgrade-embedpress',
334 'settings' => $settings,
335 'elements' => $elements,
336 'assetsUrl' => EMBEDPRESS_URL_ASSETS,
337 ]);
338 }
339
340 /**
341 * Setup new blocks localization (for new block system)
342 */
343 private static function setup_new_blocks_localization()
344 {
345 // Try multiple possible handles for new blocks
346 $possible_handles = [
347 'embedpress-blocks-editor', // Current handle from AssetManager
348 'embedpress-blocks', // Old handle
349 'embedpress_blocks-cgb-block-js', // Legacy handle
350 'embedpress-blocks-js', // Alternative handle
351 ];
352
353 $script_handle = null;
354 foreach ($possible_handles as $handle) {
355 if (wp_script_is($handle, 'enqueued') || wp_script_is($handle, 'registered')) {
356 $script_handle = $handle;
357 break;
358 }
359 }
360
361 if (!$script_handle) {
362 return;
363 }
364
365 // Ensure required constants are defined
366 if (!defined('EMBEDPRESS_PLG_NAME')) {
367 return;
368 }
369
370 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ":elements", []);
371 $active_blocks = isset($elements['gutenberg']) ? (array) $elements['gutenberg'] : [];
372
373 wp_localize_script($script_handle, 'embedpressNewBlocksData', [
374 'pluginDirPath' => defined('EMBEDPRESS_PATH_BASE') ? EMBEDPRESS_PATH_BASE : '',
375 'pluginDirUrl' => defined('EMBEDPRESS_URL_STATIC') ? EMBEDPRESS_URL_STATIC . '../' : '',
376 'activeBlocks' => $active_blocks,
377 'canUploadMedia' => current_user_can('upload_files'),
378 'ajaxUrl' => admin_url('admin-ajax.php'),
379 'nonce' => wp_create_nonce('embedpress_nonce'),
380 'restUrl' => rest_url('embedpress/v1/'),
381 'siteUrl' => site_url(),
382 ]);
383 }
384
385
386
387
388
389 /**
390 * Setup analytics tracker localization
391 */
392 private static function setup_analytics_localization()
393 {
394 $script_handle = 'embedpress-analytics-tracker';
395
396 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
397 return;
398 }
399
400 // Get analytics manager instance to check for embedded content
401 $has_embedded_content = false;
402 if (class_exists('EmbedPress\Includes\Classes\Analytics\Analytics_Manager')) {
403 $analytics_manager = \EmbedPress\Includes\Classes\Analytics\Analytics_Manager::get_instance();
404 $has_embedded_content = $analytics_manager->has_embedded_content();
405 }
406
407 // Get tracking enabled setting
408 $tracking_enabled = get_option('embedpress_analytics_tracking_enabled', true);
409
410 // Get original referrer if available
411 $original_referrer = '';
412 if (defined('EMBEDPRESS_ORIGINAL_REFERRER') && !empty(EMBEDPRESS_ORIGINAL_REFERRER)) {
413 $original_referrer = EMBEDPRESS_ORIGINAL_REFERRER;
414 }
415
416 // Get session ID safely
417 $session_id = self::get_analytics_session_id();
418
419 wp_localize_script($script_handle, 'embedpress_analytics', [
420 'ajax_url' => admin_url('admin-ajax.php'),
421 'rest_url' => rest_url('embedpress/v1/analytics/'),
422 'nonce' => wp_create_nonce('wp_rest'),
423 'session_id' => $session_id,
424 'page_url' => get_permalink(),
425 'post_id' => get_the_ID(),
426 'tracking_enabled' => (bool) $tracking_enabled,
427 'original_referrer' => $original_referrer,
428 'has_embedded_content' => $has_embedded_content
429 ]);
430 }
431
432 /**
433 * Setup Google Calendar widget localization
434 */
435 private static function setup_calendar_widget_localization()
436 {
437 $script_handle = 'epgc';
438
439 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
440 return;
441 }
442
443 $nonce = wp_create_nonce('epgc_nonce');
444 wp_localize_script($script_handle, 'embedpressCalendarData', [
445 'ajaxUrl' => admin_url('admin-ajax.php'),
446 'nonce' => $nonce,
447 'translations' => [
448 'allDay' => __('All day', 'embedpress'),
449 'createdBy' => __('Created by', 'embedpress'),
450 'goToEvent' => __('Go to event', 'embedpress'),
451 'unknownError' => __('Unknown error', 'embedpress'),
452 'requestError' => __('Request error', 'embedpress'),
453 'loading' => __('Loading', 'embedpress')
454 ]
455 ]);
456 }
457
458 /**
459 * Load plugin text domain for translations
460 */
461 public static function load_text_domain()
462 {
463 $locale = determine_locale();
464 $locale = apply_filters('plugin_locale', $locale, 'embedpress');
465
466 // Load from WordPress languages directory first
467 if (file_exists(WP_LANG_DIR . "/embedpress-" . $locale . '.mo')) {
468 unload_textdomain('embedpress');
469 load_textdomain('embedpress', WP_LANG_DIR . "/embedpress-" . $locale . '.mo');
470 }
471
472 // Load from plugin languages directory
473 load_plugin_textdomain('embedpress', false, plugin_basename(dirname(EMBEDPRESS_FILE)) . '/languages');
474 }
475
476 /**
477 * Get Wistia labels for localization
478 *
479 * @return array
480 */
481 private static function get_wistia_labels()
482 {
483 return [
484 'watch_from_beginning' => __('Watch from the beginning', 'embedpress'),
485 'skip_to_where_you_left_off' => __('Skip to where you left off', 'embedpress'),
486 'you_have_watched_it_before' => __('It looks like you\'ve watched<br />part of this video before!', 'embedpress'),
487 ];
488 }
489
490 /**
491 * Get Wistia options safely
492 *
493 * @return mixed|null
494 */
495 private static function get_wistia_options()
496 {
497 if (!function_exists('embedpress_wisita_pro_get_options')) {
498 return null;
499 }
500
501 try {
502 // return embedpress_wisita_pro_get_options();
503 } catch (\Exception $e) {
504 // Silently fail if function throws an error
505 return null;
506 }
507 }
508
509 /**
510 * Get branding value safely
511 *
512 * @param string $type
513 * @param string $provider
514 * @return string
515 */
516 private static function get_branding_value($type, $provider)
517 {
518 if (!function_exists('get_branding_value')) {
519 return '';
520 }
521
522 try {
523 return self::get_branding_value($type, $provider);
524 } catch (\Exception $e) {
525 return '';
526 }
527 }
528
529 /**
530 * Get analytics session ID safely
531 *
532 * @return string
533 */
534 private static function get_analytics_session_id()
535 {
536 // Prefer cookie-based session IDs to avoid server PHP session configuration issues
537 if (isset($_COOKIE['ep_session_id'])) {
538 $cookie = $_COOKIE['ep_session_id'];
539 // Allow only safe characters and a minimum length
540 if (is_string($cookie) && preg_match('/^[A-Za-z0-9._:-]{8,}$/', $cookie)) {
541 return sanitize_text_field($cookie);
542 }
543 }
544
545 // Generate a new ephemeral session ID
546 $id = 'ep-sess-' . time() . '-' . wp_generate_password(8, false);
547
548 // Set a session cookie (expires when the browser closes)
549 if (!headers_sent()) {
550 $path = defined('COOKIEPATH') ? COOKIEPATH : '/';
551 $domain = (defined('COOKIE_DOMAIN') && COOKIE_DOMAIN) ? COOKIE_DOMAIN : '';
552 $secure = is_ssl();
553 $httponly = true;
554 setcookie('ep_session_id', $id, 0, $path, $domain, $secure, $httponly);
555 }
556
557 return $id;
558 }
559
560 /**
561 * Get URL schemes for preview script
562 *
563 * @return array
564 */
565 private static function get_url_schemes()
566 {
567 return [
568 // Apple podcasts
569 'podcasts.apple.com/*',
570 // YouTube
571 'youtube.com/watch\\?*',
572 'youtube.com/playlist\\?*',
573 'youtube.com/channel/*',
574 'youtube.com/c/*',
575 'youtube.com/user/*',
576 'youtube.com/(\w+)[^?\/]*$',
577 // Vimeo
578 'vimeo.com/*',
579 'vimeo.com/groups/*/videos/*',
580 // Twitter
581 'twitter.com/*/status/*',
582 'twitter.com/i/moments/*',
583 'twitter.com/*/timelines/*',
584 // Facebook
585 'facebook.com/*',
586 'fb.watch/*',
587 // Instagram
588 'instagram.com/p/*',
589 'instagr.am/p/*',
590 // SoundCloud
591 'soundcloud.com/*',
592 // Twitch
593 '*.twitch.tv/*',
594 'twitch.tv/*',
595 // Wistia
596 '*.wistia.com/medias/*',
597 'fast.wistia.com/embed/medias/*.jsonp',
598 // Google services
599 'google.com/*',
600 'google.com.*/*',
601 'google.co.*/*',
602 'maps.google.com/*',
603 'docs.google.com/presentation/*',
604 'docs.google.com/document/*',
605 'docs.google.com/spreadsheets/*',
606 'docs.google.com/forms/*',
607 'docs.google.com/drawings/*',
608 ];
609 }
610
611 /**
612 * Setup PDF gallery frontend localization
613 */
614 private static function setup_pdf_gallery_localization()
615 {
616 $script_handle = 'embedpress-pdf-gallery';
617
618 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
619 return;
620 }
621
622 $plugin_url = defined('EMBEDPRESS_URL_ASSETS') ? str_replace('assets/', '', EMBEDPRESS_URL_ASSETS) : '';
623
624 wp_localize_script($script_handle, 'embedpressObj', [
625 'pdfRenderer' => Helper::get_pdf_renderer(),
626 'flipbookRenderer' => Helper::get_flipbook_renderer(),
627 'pluginUrl' => $plugin_url,
628 ]);
629 }
630
631 /**
632 * Setup PDF lightbox frontend localization
633 */
634 private static function setup_pdf_lightbox_localization()
635 {
636 $script_handle = 'embedpress-pdf-lightbox';
637
638 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
639 return;
640 }
641
642 // Only localize if not already done by gallery
643 if (wp_script_is('embedpress-pdf-gallery', 'enqueued')) {
644 return;
645 }
646
647 $plugin_url = defined('EMBEDPRESS_URL_ASSETS') ? str_replace('assets/', '', EMBEDPRESS_URL_ASSETS) : '';
648
649 wp_localize_script($script_handle, 'embedpressObj', [
650 'pdfRenderer' => Helper::get_pdf_renderer(),
651 'flipbookRenderer' => Helper::get_flipbook_renderer(),
652 'pluginUrl' => $plugin_url,
653 ]);
654 }
655
656 /**
657 * Initialize localization manager hooks
658 */
659 /**
660 * Get Twitch settings for Gutenberg localization
661 */
662 private static function get_twitch_settings()
663 {
664 $twitch_settings = get_option(EMBEDPRESS_PLG_NAME . ':twitch', []);
665
666 return [
667 'autoplay' => isset($twitch_settings['embedpress_pro_twitch_autoplay']) ? $twitch_settings['embedpress_pro_twitch_autoplay'] : 'no',
668 'mute' => isset($twitch_settings['embedpress_pro_twitch_mute']) ? $twitch_settings['embedpress_pro_twitch_mute'] : 'yes',
669 'theme' => isset($twitch_settings['embedpress_pro_twitch_theme']) ? $twitch_settings['embedpress_pro_twitch_theme'] : 'dark',
670 'fullscreen' => isset($twitch_settings['embedpress_pro_fs']) ? $twitch_settings['embedpress_pro_fs'] : 'yes',
671 'chat' => isset($twitch_settings['embedpress_pro_twitch_chat']) ? $twitch_settings['embedpress_pro_twitch_chat'] : 'no',
672 'startTime' => isset($twitch_settings['start_time']) ? intval($twitch_settings['start_time']) : 0,
673 ];
674 }
675
676 public static function init()
677 {
678 // Load directly: init() is called from an `init` priority-5 callback in
679 // Core/init.php, so `plugins_loaded` has already fired and registering a
680 // hook on it here is a no-op. Since WP 4.6 `init` is the recommended
681 // hook for load_plugin_textdomain anyway, and WPML's `gettext` filter
682 // is registered well before this point.
683 self::load_text_domain();
684 }
685 }
686