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