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