PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 4.5.5
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v4.5.5
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 3 weeks ago LocalizationManager.php 3 weeks ago init.php 3 weeks ago
LocalizationManager.php
705 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 'viewCount' => [
227 'restUrl' => esc_url_raw(get_rest_url(null, 'embedpress/v1/analytics/view-count')),
228 'downloadUrl' => esc_url_raw(get_rest_url(null, 'embedpress/v1/analytics/download-count')),
229 'viewEnabled' => \EmbedPress\Includes\Classes\View_Count_Display::is_enabled(),
230 'downloadEnabled' => \EmbedPress\Includes\Classes\View_Count_Display::is_download_enabled(),
231 'labels' => [
232 /* translators: %s: formatted number of views */
233 'singular' => __('%s view', 'embedpress'),
234 /* translators: %s: formatted number of views */
235 'plural' => __('%s views', 'embedpress'),
236 /* translators: %s: formatted number of downloads */
237 'downloadSingular' => __('%s download', 'embedpress'),
238 /* translators: %s: formatted number of downloads */
239 'downloadPlural' => __('%s downloads', 'embedpress'),
240 ],
241 ],
242 'userRoles' => Helper::get_user_roles(),
243 'currentUser' => $current_user->data,
244 'feedbackSubmitted' => get_option('embedpress_feedback_submited'),
245 'ratingHelpDisabled' => Helper::get_options_value('turn_off_rating_help', false),
246 'milestoneDisabled' => Helper::get_options_value('turn_off_milestone', false),
247
248 // Legacy support
249 'wistia_labels' => json_encode($wistia_labels),
250 'wisita_options' => $wistia_options,
251 'embedpress_powered_by' => apply_filters('embedpress_document_block_powered_by', $powered_by_default),
252 'embedpress_pro' => defined('EMBEDPRESS_PRO_PLUGIN_FILE'),
253 'twitch_host' => !empty($pars_url['host']) ? $pars_url['host'] : '',
254 'site_url' => site_url(),
255 'rest_url' => get_rest_url(),
256 'embedpress_rest_url' => get_rest_url(null, 'embedpress/v1/oembed/embedpress'),
257 'active_blocks' => $active_blocks,
258 'document_cta' => $documents_cta_options,
259 'pdf_renderer' => Helper::get_pdf_renderer(),
260 'flipbook_renderer' => Helper::get_flipbook_renderer(),
261 'is_pro_plugin_active' => defined('EMBEDPRESS_SL_ITEM_SLUG'),
262 'ajaxurl' => admin_url('admin-ajax.php'),
263 'source_nonce' => wp_create_nonce('source_nonce_embedpress'),
264 'can_upload_media' => current_user_can('upload_files'),
265 'permalink_structure' => get_option('permalink_structure'),
266 'EMBEDPRESS_URL_ASSETS' => EMBEDPRESS_URL_ASSETS,
267 'iframe_width' => Helper::get_options_value('enableEmbedResizeWidth'),
268 'iframe_height' => Helper::get_options_value('enableEmbedResizeHeight'),
269 'pdf_custom_color' => Helper::get_options_value('custom_color'),
270 'pdf_custom_color' => Helper::get_options_value('custom_color'),
271 'youtube_brand_logo_url' => Helper::get_branding_value('logo_url', 'youtube'),
272 'vimeo_brand_logo_url' => Helper::get_branding_value('logo_url', 'vimeo'),
273 'wistia_brand_logo_url' => Helper::get_branding_value('logo_url', 'wistia'),
274 'twitch_brand_logo_url' => Helper::get_branding_value('logo_url', 'twitch'),
275 'dailymotion_brand_logo_url' => Helper::get_branding_value('logo_url', 'dailymotion'),
276 'user_roles' => Helper::get_user_roles(),
277 'current_user' => $current_user->data,
278 'is_embedpress_feedback_submited' => get_option('embedpress_feedback_submited'),
279 'turn_off_rating_help' => Helper::get_options_value('turn_off_rating_help'),
280 'turn_off_milestone' => Helper::get_options_value('turn_off_milestone'),
281 ]);
282 }
283
284 /**
285 * Setup frontend script localization (embedpressFrontendData variable)
286 */
287 private static function setup_frontend_script_localization()
288 {
289 // The embedpressFrontendData variable should be attached to multiple frontend scripts
290 $script_handles = ['embedpress-front', 'embedpress-ads', 'embedpress-yt-queue'];
291
292 $localization_data = [
293 'ajaxurl' => admin_url('admin-ajax.php'),
294 'isProPluginActive' => defined('EMBEDPRESS_SL_ITEM_SLUG'),
295 'nonce' => wp_create_nonce('ep_nonce'),
296 'rest_url' => esc_url_raw(rest_url()),
297 'rest_nonce' => wp_create_nonce('wp_rest'),
298 ];
299
300 foreach ($script_handles as $script_handle) {
301 if (wp_script_is($script_handle, 'enqueued') || wp_script_is($script_handle, 'registered')) {
302 wp_localize_script($script_handle, 'embedpressFrontendData', $localization_data);
303 }
304 }
305 }
306
307 /**
308 * Setup settings page localization (attached to admin script)
309 */
310 private static function setup_settings_localization()
311 {
312 $script_handle = 'embedpress-admin';
313
314 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
315 return;
316 }
317
318 wp_localize_script($script_handle, 'embedpressSettingsData', [
319 'nonce' => wp_create_nonce('embedpress_elements_action'),
320 'ajaxNonce' => wp_create_nonce('embedpress_ajax_nonce'),
321 ]);
322 }
323
324 /**
325 * Setup onboarding wizard localization
326 *
327 * @param string $hook Current admin page hook
328 */
329 private static function setup_onboarding_localization($hook)
330 {
331 if (strpos($hook, 'embedpress-onboarding') === false) {
332 return;
333 }
334
335 $script_handle = 'embedpress-onboarding';
336
337 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
338 return;
339 }
340
341 $settings = (array) get_option(EMBEDPRESS_PLG_NAME, []);
342 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ':elements', []);
343 $pro_active = apply_filters('embedpress/is_allow_rander', false);
344
345 wp_localize_script($script_handle, 'embedpressOnboardingData', [
346 'ajaxUrl' => admin_url('admin-ajax.php'),
347 'nonce' => wp_create_nonce('embedpress_onboarding_nonce'),
348 'settingsUrl' => admin_url('admin.php?page=embedpress&page_type=settings'),
349 'dashboardUrl' => admin_url('admin.php?page=embedpress'),
350 'proActive' => $pro_active,
351 'upgradeUrl' => 'https://wpdeveloper.com/in/upgrade-embedpress',
352 'settings' => $settings,
353 'elements' => $elements,
354 'assetsUrl' => EMBEDPRESS_URL_ASSETS,
355 ]);
356 }
357
358 /**
359 * Setup new blocks localization (for new block system)
360 */
361 private static function setup_new_blocks_localization()
362 {
363 // Try multiple possible handles for new blocks
364 $possible_handles = [
365 'embedpress-blocks-editor', // Current handle from AssetManager
366 'embedpress-blocks', // Old handle
367 'embedpress_blocks-cgb-block-js', // Legacy handle
368 'embedpress-blocks-js', // Alternative handle
369 ];
370
371 $script_handle = null;
372 foreach ($possible_handles as $handle) {
373 if (wp_script_is($handle, 'enqueued') || wp_script_is($handle, 'registered')) {
374 $script_handle = $handle;
375 break;
376 }
377 }
378
379 if (!$script_handle) {
380 return;
381 }
382
383 // Ensure required constants are defined
384 if (!defined('EMBEDPRESS_PLG_NAME')) {
385 return;
386 }
387
388 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ":elements", []);
389 $active_blocks = isset($elements['gutenberg']) ? (array) $elements['gutenberg'] : [];
390
391 wp_localize_script($script_handle, 'embedpressNewBlocksData', [
392 'pluginDirPath' => defined('EMBEDPRESS_PATH_BASE') ? EMBEDPRESS_PATH_BASE : '',
393 'pluginDirUrl' => defined('EMBEDPRESS_URL_STATIC') ? EMBEDPRESS_URL_STATIC . '../' : '',
394 'activeBlocks' => $active_blocks,
395 'canUploadMedia' => current_user_can('upload_files'),
396 'ajaxUrl' => admin_url('admin-ajax.php'),
397 'nonce' => wp_create_nonce('embedpress_nonce'),
398 'restUrl' => rest_url('embedpress/v1/'),
399 'siteUrl' => site_url(),
400 ]);
401 }
402
403
404
405
406
407 /**
408 * Setup analytics tracker localization
409 */
410 private static function setup_analytics_localization()
411 {
412 $script_handle = 'embedpress-analytics-tracker';
413
414 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
415 return;
416 }
417
418 // Get analytics manager instance to check for embedded content
419 $has_embedded_content = false;
420 if (class_exists('EmbedPress\Includes\Classes\Analytics\Analytics_Manager')) {
421 $analytics_manager = \EmbedPress\Includes\Classes\Analytics\Analytics_Manager::get_instance();
422 $has_embedded_content = $analytics_manager->has_embedded_content();
423 }
424
425 // Get tracking enabled setting
426 $tracking_enabled = get_option('embedpress_analytics_tracking_enabled', true);
427
428 // Get original referrer if available
429 $original_referrer = '';
430 if (defined('EMBEDPRESS_ORIGINAL_REFERRER') && !empty(EMBEDPRESS_ORIGINAL_REFERRER)) {
431 $original_referrer = EMBEDPRESS_ORIGINAL_REFERRER;
432 }
433
434 // Get session ID safely — only when tracking is enabled, otherwise we'd
435 // set ep_session_id even though no events will ever be recorded.
436 $session_id = $tracking_enabled ? self::get_analytics_session_id() : '';
437
438 wp_localize_script($script_handle, 'embedpress_analytics', [
439 'ajax_url' => admin_url('admin-ajax.php'),
440 'rest_url' => rest_url('embedpress/v1/analytics/'),
441 'nonce' => wp_create_nonce('wp_rest'),
442 'session_id' => $session_id,
443 'page_url' => get_permalink(),
444 'post_id' => get_the_ID(),
445 'tracking_enabled' => (bool) $tracking_enabled,
446 'original_referrer' => $original_referrer,
447 'has_embedded_content' => $has_embedded_content
448 ]);
449 }
450
451 /**
452 * Setup Google Calendar widget localization
453 */
454 private static function setup_calendar_widget_localization()
455 {
456 $script_handle = 'epgc';
457
458 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
459 return;
460 }
461
462 $nonce = wp_create_nonce('epgc_nonce');
463 wp_localize_script($script_handle, 'embedpressCalendarData', [
464 'ajaxUrl' => admin_url('admin-ajax.php'),
465 'nonce' => $nonce,
466 'translations' => [
467 'allDay' => __('All day', 'embedpress'),
468 'createdBy' => __('Created by', 'embedpress'),
469 'goToEvent' => __('Go to event', 'embedpress'),
470 'unknownError' => __('Unknown error', 'embedpress'),
471 'requestError' => __('Request error', 'embedpress'),
472 'loading' => __('Loading', 'embedpress')
473 ]
474 ]);
475 }
476
477 /**
478 * Load plugin text domain for translations
479 */
480 public static function load_text_domain()
481 {
482 $locale = determine_locale();
483 $locale = apply_filters('plugin_locale', $locale, 'embedpress');
484
485 // Load from WordPress languages directory first
486 if (file_exists(WP_LANG_DIR . "/embedpress-" . $locale . '.mo')) {
487 unload_textdomain('embedpress');
488 load_textdomain('embedpress', WP_LANG_DIR . "/embedpress-" . $locale . '.mo');
489 }
490
491 // Load from plugin languages directory
492 load_plugin_textdomain('embedpress', false, plugin_basename(dirname(EMBEDPRESS_FILE)) . '/languages');
493 }
494
495 /**
496 * Get Wistia labels for localization
497 *
498 * @return array
499 */
500 private static function get_wistia_labels()
501 {
502 return [
503 'watch_from_beginning' => __('Watch from the beginning', 'embedpress'),
504 'skip_to_where_you_left_off' => __('Skip to where you left off', 'embedpress'),
505 'you_have_watched_it_before' => __('It looks like you\'ve watched<br />part of this video before!', 'embedpress'),
506 ];
507 }
508
509 /**
510 * Get Wistia options safely
511 *
512 * @return mixed|null
513 */
514 private static function get_wistia_options()
515 {
516 if (!function_exists('embedpress_wisita_pro_get_options')) {
517 return null;
518 }
519
520 try {
521 // return embedpress_wisita_pro_get_options();
522 } catch (\Exception $e) {
523 // Silently fail if function throws an error
524 return null;
525 }
526 }
527
528 /**
529 * Get branding value safely
530 *
531 * @param string $type
532 * @param string $provider
533 * @return string
534 */
535 private static function get_branding_value($type, $provider)
536 {
537 if (!function_exists('get_branding_value')) {
538 return '';
539 }
540
541 try {
542 return self::get_branding_value($type, $provider);
543 } catch (\Exception $e) {
544 return '';
545 }
546 }
547
548 /**
549 * Get analytics session ID safely
550 *
551 * @return string
552 */
553 private static function get_analytics_session_id()
554 {
555 // Prefer cookie-based session IDs to avoid server PHP session configuration issues
556 if (isset($_COOKIE['ep_session_id'])) {
557 $cookie = $_COOKIE['ep_session_id'];
558 // Allow only safe characters and a minimum length
559 if (is_string($cookie) && preg_match('/^[A-Za-z0-9._:-]{8,}$/', $cookie)) {
560 return sanitize_text_field($cookie);
561 }
562 }
563
564 // Generate a new ephemeral session ID
565 $id = 'ep-sess-' . time() . '-' . wp_generate_password(8, false);
566
567 // Set a session cookie (expires when the browser closes)
568 if (!headers_sent()) {
569 $path = defined('COOKIEPATH') ? COOKIEPATH : '/';
570 $domain = (defined('COOKIE_DOMAIN') && COOKIE_DOMAIN) ? COOKIE_DOMAIN : '';
571 $secure = is_ssl();
572 $httponly = true;
573 setcookie('ep_session_id', $id, 0, $path, $domain, $secure, $httponly);
574 }
575
576 return $id;
577 }
578
579 /**
580 * Get URL schemes for preview script
581 *
582 * @return array
583 */
584 private static function get_url_schemes()
585 {
586 return [
587 // Apple podcasts
588 'podcasts.apple.com/*',
589 // YouTube
590 'youtube.com/watch\\?*',
591 'youtube.com/playlist\\?*',
592 'youtube.com/channel/*',
593 'youtube.com/c/*',
594 'youtube.com/user/*',
595 'youtube.com/(\w+)[^?\/]*$',
596 // Vimeo
597 'vimeo.com/*',
598 'vimeo.com/groups/*/videos/*',
599 // Twitter
600 'twitter.com/*/status/*',
601 'twitter.com/i/moments/*',
602 'twitter.com/*/timelines/*',
603 // Facebook
604 'facebook.com/*',
605 'fb.watch/*',
606 // Instagram
607 'instagram.com/p/*',
608 'instagr.am/p/*',
609 // SoundCloud
610 'soundcloud.com/*',
611 // Twitch
612 '*.twitch.tv/*',
613 'twitch.tv/*',
614 // Wistia
615 '*.wistia.com/medias/*',
616 'fast.wistia.com/embed/medias/*.jsonp',
617 // Google services
618 'google.com/*',
619 'google.com.*/*',
620 'google.co.*/*',
621 'maps.google.com/*',
622 'docs.google.com/presentation/*',
623 'docs.google.com/document/*',
624 'docs.google.com/spreadsheets/*',
625 'docs.google.com/forms/*',
626 'docs.google.com/drawings/*',
627 ];
628 }
629
630 /**
631 * Setup PDF gallery frontend localization
632 */
633 private static function setup_pdf_gallery_localization()
634 {
635 $script_handle = 'embedpress-pdf-gallery';
636
637 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
638 return;
639 }
640
641 $plugin_url = defined('EMBEDPRESS_URL_ASSETS') ? str_replace('assets/', '', EMBEDPRESS_URL_ASSETS) : '';
642
643 wp_localize_script($script_handle, 'embedpressObj', [
644 'pdfRenderer' => Helper::get_pdf_renderer(),
645 'flipbookRenderer' => Helper::get_flipbook_renderer(),
646 'pluginUrl' => $plugin_url,
647 ]);
648 }
649
650 /**
651 * Setup PDF lightbox frontend localization
652 */
653 private static function setup_pdf_lightbox_localization()
654 {
655 $script_handle = 'embedpress-pdf-lightbox';
656
657 if (!wp_script_is($script_handle, 'enqueued') && !wp_script_is($script_handle, 'registered')) {
658 return;
659 }
660
661 // Only localize if not already done by gallery
662 if (wp_script_is('embedpress-pdf-gallery', 'enqueued')) {
663 return;
664 }
665
666 $plugin_url = defined('EMBEDPRESS_URL_ASSETS') ? str_replace('assets/', '', EMBEDPRESS_URL_ASSETS) : '';
667
668 wp_localize_script($script_handle, 'embedpressObj', [
669 'pdfRenderer' => Helper::get_pdf_renderer(),
670 'flipbookRenderer' => Helper::get_flipbook_renderer(),
671 'pluginUrl' => $plugin_url,
672 ]);
673 }
674
675 /**
676 * Initialize localization manager hooks
677 */
678 /**
679 * Get Twitch settings for Gutenberg localization
680 */
681 private static function get_twitch_settings()
682 {
683 $twitch_settings = get_option(EMBEDPRESS_PLG_NAME . ':twitch', []);
684
685 return [
686 'autoplay' => isset($twitch_settings['embedpress_pro_twitch_autoplay']) ? $twitch_settings['embedpress_pro_twitch_autoplay'] : 'no',
687 'mute' => isset($twitch_settings['embedpress_pro_twitch_mute']) ? $twitch_settings['embedpress_pro_twitch_mute'] : 'yes',
688 'theme' => isset($twitch_settings['embedpress_pro_twitch_theme']) ? $twitch_settings['embedpress_pro_twitch_theme'] : 'dark',
689 'fullscreen' => isset($twitch_settings['embedpress_pro_fs']) ? $twitch_settings['embedpress_pro_fs'] : 'yes',
690 'chat' => isset($twitch_settings['embedpress_pro_twitch_chat']) ? $twitch_settings['embedpress_pro_twitch_chat'] : 'no',
691 'startTime' => isset($twitch_settings['start_time']) ? intval($twitch_settings['start_time']) : 0,
692 ];
693 }
694
695 public static function init()
696 {
697 // Load directly: init() is called from an `init` priority-5 callback in
698 // Core/init.php, so `plugins_loaded` has already fired and registering a
699 // hook on it here is a no-op. Since WP 4.6 `init` is the recommended
700 // hook for load_plugin_textdomain anyway, and WPML's `gettext` filter
701 // is registered well before this point.
702 self::load_text_domain();
703 }
704 }
705