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