PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.4.11
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.4.11
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 / EmbedPress / Ends / Back / Settings / EmbedpressSettings.php
embedpress / EmbedPress / Ends / Back / Settings Last commit date
templates 3 months ago EmbedpressSettings.php 3 months ago
EmbedpressSettings.php
752 lines
1 <?php
2 namespace EmbedPress\Ends\Back\Settings;
3
4 use EmbedPress\Includes\Classes\Helper;
5
6 class EmbedpressSettings {
7 var $page_slug = '';
8 /**
9 * @var int|string
10 */
11 protected $file_version;
12
13 public function __construct($page_slug = 'embedpress') {
14 $this->page_slug = $page_slug;
15 $this->file_version = defined( 'WP_DEBUG') && WP_DEBUG ? time() : EMBEDPRESS_VERSION;
16 add_action('admin_enqueue_scripts', [$this, 'handle_scripts_and_styles']);
17 add_action('admin_menu', [$this, 'register_menu']);
18 add_action( 'init', [$this, 'save_settings']);
19
20 // Add activation redirect hook
21 add_action( 'admin_init', [$this, 'embedpress_maybe_redirect_to_settings']);
22
23 // ajax
24 add_action( 'wp_ajax_embedpress_elements_action', [$this, 'update_elements_list']);
25 add_action( 'wp_ajax_embedpress_settings_action', [$this, 'save_settings']);
26 add_action( 'wp_ajax_save_global_brand_image', [$this, 'save_global_brand_image']);
27 add_action( 'wp_ajax_embedpress_dismiss_element', [$this, 'dismiss_element']);
28 add_action( 'wp_ajax_embedpress_dismiss_feature_notice', [$this, 'dismiss_feature_notice']);
29
30 $g_settings = get_option( EMBEDPRESS_PLG_NAME, [] );
31
32 if(!isset($g_settings['turn_off_rating_help'])){
33 $g_settings['turn_off_rating_help'] = true;
34 update_option(EMBEDPRESS_PLG_NAME, $g_settings);
35 }
36 if(!isset($g_settings['turn_off_milestone'])){
37 $g_settings['turn_off_milestone'] = true;
38 update_option(EMBEDPRESS_PLG_NAME, $g_settings);
39 }
40
41 // Set default value for embedpress_document_powered_by to 'yes' on fresh installations
42 if(!isset($g_settings['embedpress_document_powered_by'])){
43 $g_settings['embedpress_document_powered_by'] = 'yes';
44 update_option(EMBEDPRESS_PLG_NAME, $g_settings);
45 }
46
47
48 // Migration
49 $option = 'embedpress_elements_updated'; // to update initially for backward compatibility
50 if ( !get_option( $option, false) ) {
51 $elements_initial_states = [
52 'gutenberg' => [
53 'google-docs-block' => 'google-docs-block',
54 'document' => 'document',
55 'embedpress' => 'embedpress',
56 'embedpress-pdf' => 'embedpress-pdf',
57 'google-sheets-block' => 'google-sheets-block',
58 'google-slides-block' => 'google-slides-block',
59 'youtube-block' => 'youtube-block',
60 'google-forms-block' => 'google-forms-block',
61 'google-drawings-block' => 'google-drawings-block',
62 'google-maps-block' => 'google-maps-block',
63 'twitch-block' => 'twitch-block',
64 'wistia-block' => 'wistia-block',
65 'vimeo-block' => 'vimeo-block',
66 ],
67 'elementor' => [
68 'embedpress-document' => 'embedpress-document',
69 'embedpress' => 'embedpress',
70 'embedpress-pdf' => 'embedpress-pdf',
71 ]
72 ];
73
74
75 $settings = get_option( EMBEDPRESS_PLG_NAME, [] );
76 $yt = get_option( EMBEDPRESS_PLG_NAME.':youtube' );
77 if ( empty( $settings) && empty( $yt) ) {
78 $settings['need_first_time_redirect'] = true;
79 }
80 if ( !isset( $settings['enablePluginInAdmin']) ) {
81 $settings['enablePluginInAdmin'] = 1;
82 }
83 if ( !isset( $settings['enablePluginInFront']) ) {
84 $settings['enablePluginInFront'] = 1;
85 }
86
87 update_option( EMBEDPRESS_PLG_NAME.":elements", $elements_initial_states);
88 update_option( EMBEDPRESS_PLG_NAME, $settings);
89 update_option( $option, true);
90 }
91 $migration_v_320 = 'embedpress_v_320_migration';
92 if ( !get_option( $migration_v_320, false) ) {
93 $elements = (array) get_option( EMBEDPRESS_PLG_NAME.":elements", []);
94 $elements['gutenberg']['embedpress-pdf'] = 'embedpress-pdf';
95 $elements['elementor']['embedpress-pdf'] = 'embedpress-pdf';
96 update_option( EMBEDPRESS_PLG_NAME.":elements", $elements);
97 update_option( $migration_v_320, true);
98 }
99
100 $migration_v_330 = 'embedpress_v_330_migration';
101 if ( !get_option( $migration_v_330, false) ) {
102 $elements = (array) get_option( EMBEDPRESS_PLG_NAME.":elements", []);
103 $elements['gutenberg']['embedpress-calendar'] = 'embedpress-calendar';
104 $elements['elementor']['embedpress-calendar'] = 'embedpress-calendar';
105 update_option( EMBEDPRESS_PLG_NAME.":elements", $elements);
106 update_option( $migration_v_330, true);
107 }
108
109 add_action( 'admin_init', [$this, 'embedpress_maybe_redirect_to_settings'] );
110
111
112
113
114 }
115 function embedpress_maybe_redirect_to_settings() {
116 $settings = get_option( EMBEDPRESS_PLG_NAME, [] );
117 if ( isset( $settings['need_first_time_redirect']) && $settings['need_first_time_redirect'] ) {
118 // Skip redirect if already done, doing AJAX, or in certain admin contexts
119 if ( get_option( 'embedpress_activation_redirect_done' ) || wp_doing_ajax() || wp_doing_cron() ) {
120 return;
121 }
122
123 // Skip redirect for bulk activations, network admin, or CLI
124 if ( is_network_admin() || isset( $_GET['activate-multi'] ) || defined( 'WP_CLI' ) ) {
125 return;
126 }
127
128 // Skip redirect if not in admin area or if user doesn't have proper capabilities
129 if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) {
130 return;
131 }
132
133 // Skip redirect if we're already on the EmbedPress settings page
134 if ( isset( $_GET['page'] ) && $_GET['page'] === $this->page_slug ) {
135 return;
136 }
137
138 // Set redirect done flag and clear the redirect trigger
139 update_option( 'embedpress_activation_redirect_done', true );
140 $settings['need_first_time_redirect'] = false;
141 update_option( EMBEDPRESS_PLG_NAME, $settings);
142
143 // Perform the redirect
144 wp_safe_redirect( admin_url('admin.php?page='.$this->page_slug) );
145 exit;
146 }
147 }
148 public function update_elements_list() {
149
150 if (!current_user_can('manage_options')) {
151 wp_send_json_error(array('message' => 'You do not have sufficient permissions to access this functionality.'));
152 return;
153 }
154
155 if ( !empty($_POST['_wpnonce'] && wp_verify_nonce( $_POST['_wpnonce'], 'embedpress_elements_action')) ) {
156 $option = EMBEDPRESS_PLG_NAME.":elements";
157 $elements = (array) get_option( $option, []);
158 $settings = (array) get_option( EMBEDPRESS_PLG_NAME, []);
159
160 $type = !empty( $_POST['element_type']) ? sanitize_text_field( $_POST['element_type']) : '';
161 $name = !empty( $_POST['element_name']) ? sanitize_text_field( $_POST['element_name']) : '';
162 $checked = !empty( $_POST['checked']) ? $_POST['checked'] : false;
163 if ( 'false' != $checked ) {
164 $elements[$type][$name] = $name;
165 if ( $type === 'classic' ) {
166 $settings[$name] = 1;
167 }
168 }else{
169 if( isset( $elements[$type]) && isset( $elements[$type][$name])){
170 unset( $elements[$type][$name]);
171 }
172 if ( $type === 'classic' ) {
173 $settings[$name] = 0;
174 }
175 }
176 update_option( EMBEDPRESS_PLG_NAME, $settings);
177 update_option( $option, $elements);
178 wp_send_json_success();
179 }
180 wp_send_json_error();
181 }
182
183 public function register_menu() {
184 add_menu_page( __('EmbedPress Settings', 'embedpress'), 'EmbedPress', 'manage_options', $this->page_slug,
185 [ $this, 'render_settings_page' ], EMBEDPRESS_URL_ASSETS.'images/menu-icon.svg', 64 );
186
187 // Add Dashboard submenu (replaces the default first submenu item)
188 add_submenu_page( $this->page_slug, __('EmbedPress Dashboard', 'embedpress'), __('Dashboard', 'embedpress'), 'manage_options', $this->page_slug,
189 [ $this, 'render_settings_page' ] );
190
191 // Add Branding submenu
192 add_submenu_page( $this->page_slug, __('EmbedPress Branding', 'embedpress'), __('Branding', 'embedpress'), 'manage_options', $this->page_slug . '&page_type=custom-logo',
193 [ $this, 'render_settings_page' ] );
194
195 // Add Custom Ads submenu
196 add_submenu_page( $this->page_slug, __('EmbedPress Custom Ads', 'embedpress'), __('Custom Ads', 'embedpress'), 'manage_options', $this->page_slug . '&page_type=ads',
197 [ $this, 'render_settings_page' ] );
198
199
200 // Add Shortcode submenu
201 add_submenu_page( $this->page_slug, __('EmbedPress Shortcode', 'embedpress'), __('Shortcode', 'embedpress'), 'manage_options', $this->page_slug . '&page_type=shortcode',
202 [ $this, 'render_settings_page' ] );
203
204 // Add Settings submenu
205 add_submenu_page( $this->page_slug, __('EmbedPress Settings', 'embedpress'), __('Settings', 'embedpress'), 'manage_options', $this->page_slug . '&page_type=settings',
206 [ $this, 'render_settings_page' ] );
207
208
209 // Add License submenu (only if pro is active)
210 if ( apply_filters('embedpress/is_allow_rander', false) ) {
211 add_submenu_page( $this->page_slug, __('EmbedPress License', 'embedpress'), __('License', 'embedpress'), 'manage_options', $this->page_slug . '&page_type=license',
212 [ $this, 'render_settings_page' ] );
213 }
214
215 // Add admin footer script to handle menu highlighting
216 add_action('admin_footer', [$this, 'admin_menu_highlight_script']);
217
218 // Add filter to reorder menu items - License should be last
219 add_filter('admin_menu', [$this, 'reorder_submenu_items'], 999);
220 }
221
222 public function handle_scripts_and_styles() {
223 if ( !empty( $_REQUEST['page']) && $this->page_slug === $_REQUEST['page'] ) {
224 $this->enqueue_styles();
225 $this->enqueue_scripts();
226 }
227 }
228
229 public function admin_menu_highlight_script() {
230 // Only load on EmbedPress admin pages
231 $current_page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : '';
232 if ($current_page !== $this->page_slug) {
233 return;
234 }
235
236 $page_type = isset($_GET['page_type']) ? sanitize_text_field($_GET['page_type']) : '';
237 // Fixed: Evaluate PHP filter on server-side before passing to JavaScript
238 $is_pro_active = apply_filters('embedpress/is_allow_rander', false);
239
240 ?>
241 <script type="text/javascript">
242 /* EmbedPress Admin Menu Highlight Script - Fixed apply_filters issue */
243 jQuery(document).ready(function($) {
244 // Remove current highlighting
245 $('#adminmenu .wp-submenu li').removeClass('current');
246 $('#adminmenu .wp-submenu a').removeClass('current');
247
248 var pageType = '<?php echo esc_js($page_type); ?>';
249 var isProActive = <?php echo $is_pro_active ? 'true' : 'false'; ?>;
250 var menuSelector = '';
251
252 // Map page types to menu selectors
253 switch(pageType) {
254 case 'settings':
255 menuSelector = 'a[href*="page_type=settings"]';
256 break;
257 case 'shortcode':
258 menuSelector = 'a[href*="page_type=shortcode"]';
259 break;
260 case 'sources':
261 menuSelector = 'a[href*="page_type=sources"]';
262 break;
263 case 'elements':
264 menuSelector = 'a[href*="page_type=elements"]';
265 break;
266 case 'custom-logo':
267 menuSelector = 'a[href*="page_type=custom-logo"]';
268 break;
269 case 'ads':
270 menuSelector = 'a[href*="page_type=ads"]';
271 break;
272 case 'license':
273 menuSelector = 'a[href*="page_type=license"]';
274 break;
275 default:
276 // Default to Dashboard (no page_type or hub)
277 menuSelector = 'a[href="admin.php?page=<?php echo esc_js($this->page_slug); ?>"]';
278 break;
279 }
280
281 // Highlight the correct menu item
282 if (menuSelector) {
283 var $menuItem = $('#adminmenu .wp-submenu ' + menuSelector);
284 if ($menuItem.length) {
285 $menuItem.addClass('current').parent().addClass('current');
286 }
287 }
288 });
289 </script>
290 <?php
291 }
292
293 public function enqueue_scripts() {
294 if ( !did_action( 'wp_enqueue_media') ) {
295 wp_enqueue_media();
296 }
297 // Settings assets and localization are now handled by AssetManager and LocalizationManager
298 // This method is kept for backward compatibility but functionality has been moved
299 }
300
301 public function enqueue_styles() {
302 // Settings styles are now handled by AssetManager
303 // Keep only WordPress core styles that are needed
304 wp_enqueue_style( 'wp-color-picker' );
305 }
306
307 public function render_settings_page( ) {
308 global $template, $page_slug, $nonce_field, $ep_page, $gen_menu_template_names, $brand_menu_template_names, $pro_active, $coming_soon, $success_message, $error_message, $platform_menu_template_names;
309
310 $page_slug = $this->page_slug; // make this available for included template
311 $template = !empty( $_GET['page_type'] ) ? sanitize_file_name( $_GET['page_type']) : 'hub';
312
313 $nonce_field = wp_nonce_field('ep_settings_nonce', 'ep_settings_nonce', true, false);
314 $ep_page = admin_url('admin.php?page='.$this->page_slug);
315 $gen_menu_template_names = apply_filters('ep_general_menu_tmpl_names', ['settings', 'shortcode',]);
316 $platform_menu_template_names = apply_filters('ep_platform_menu_tmpl_names', [ 'youtube', 'vimeo', 'wistia', 'twitch','dailymotion', 'soundcloud' ,'spotify','google-calendar','opensea']);
317 $brand_menu_template_names = apply_filters('ep_brand_menu_templates', ['custom-logo', 'branding',]);
318 $pro_active = apply_filters('embedpress/is_allow_rander', false);
319 $coming_soon = "<span class='ep-coming-soon'>". esc_html__( '(Coming soon)', 'embedpress'). "</span>";
320 $success_message = esc_html__( "Settings Updated", "embedpress" );
321 $error_message = esc_html__( "Ops! Something went wrong.", "embedpress" );
322 include_once EMBEDPRESS_SETTINGS_PATH . 'templates/main-template.php';
323 }
324
325 public function save_settings() {
326 // needs to check for ajax and return response accordingly.
327 if ( !empty( $_POST['ep_settings_nonce']) && wp_verify_nonce( $_POST['ep_settings_nonce'], 'ep_settings_nonce') ) {
328 $submit_type = !empty( $_POST['submit'] ) ? $_POST['submit'] : '';
329 $save_handler_method = "save_{$submit_type}_settings";
330 do_action( "before_{$save_handler_method}");
331 do_action( "before_embedpress_settings_save");
332 if ( method_exists( $this, $save_handler_method ) ) {
333 $this->$save_handler_method();
334 }
335 do_action( "after_embedpress_settings_save");
336 $return_url = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : admin_url();
337 $return_url = add_query_arg( 'success', 1, $return_url );
338 if ( wp_doing_ajax() ) {
339 wp_send_json_success();
340 }
341 wp_safe_redirect( $return_url);
342 exit();
343 }
344 }
345
346 public function save_settings_settings() {
347 $settings = (array) get_option( EMBEDPRESS_PLG_NAME, []);
348 $settings ['enableEmbedResizeWidth'] = isset( $_POST['enableEmbedResizeWidth']) ? intval( $_POST['enableEmbedResizeWidth']) : 600;
349 $settings ['enableEmbedResizeHeight'] = isset( $_POST['enableEmbedResizeHeight']) ? intval( $_POST['enableEmbedResizeHeight']) : 550;
350 $settings ['pdf_custom_color_settings'] = isset( $_POST['pdf_custom_color_settings']) ? intval( $_POST['pdf_custom_color_settings']) : 0;
351 $settings ['turn_off_rating_help'] = isset( $_POST['turn_off_rating_help']) ? intval( $_POST['turn_off_rating_help']) : 0;
352 $settings ['turn_off_milestone'] = isset( $_POST['turn_off_milestone']) ? intval( $_POST['turn_off_milestone']) : 0;
353
354 $settings ['custom_color'] = isset( $_POST['custom_color']) ? $_POST['custom_color'] : '#333333';
355
356 // Pro will handle g_loading_animation settings and other
357 // Keep backward compatibility with old filter names
358 $settings = apply_filters( 'ep_general_settings_before_save', $settings, $_POST);
359 $settings = apply_filters( 'ep_settings_settings_before_save', $settings, $_POST);
360
361 update_option( EMBEDPRESS_PLG_NAME, $settings);
362
363 // Keep backward compatibility with old action names
364 do_action( 'ep_general_settings_after_save', $settings, $_POST);
365 do_action( 'ep_settings_settings_after_save', $settings, $_POST);
366 }
367
368 // Keep backward compatibility method
369 public function save_general_settings() {
370 return $this->save_settings_settings();
371 }
372
373 public function save_youtube_settings() {
374 $option_name = EMBEDPRESS_PLG_NAME.':youtube';
375 $settings = get_option( $option_name, []);
376 $settings['api_key'] = isset( $_POST['api_key']) ? sanitize_text_field( $_POST['api_key']) : 0;
377 $settings['pagesize'] = isset( $_POST['pagesize']) ? sanitize_text_field( $_POST['pagesize']) : 0;
378 $settings['start_time'] = isset( $_POST['start_time']) ? sanitize_text_field( $_POST['start_time']) : 0;
379 $settings['end_time'] = isset( $_POST['end_time']) ? sanitize_text_field( $_POST['end_time']) : 0;
380 $settings['autoplay'] = isset( $_POST['autoplay']) ? sanitize_text_field( $_POST['autoplay']) : '';
381 $settings['controls'] = isset( $_POST['controls']) ? sanitize_text_field( $_POST['controls']) : '';
382 $settings['fs'] = isset( $_POST['fs']) ? sanitize_text_field( $_POST['fs']) : '';
383 $settings['iv_load_policy'] = isset( $_POST['iv_load_policy']) ? sanitize_text_field( $_POST['iv_load_policy']) : 1;
384 $settings['color'] = isset( $_POST['color']) ? sanitize_text_field( $_POST['color']) : 'red';
385 $settings['rel'] = isset( $_POST['rel']) ? sanitize_text_field( $_POST['rel']) : 1;
386 $settings['license_key'] = 1; // backward compatibility
387
388 // Pro will handle g_loading_animation settings and other
389 $settings = apply_filters( 'ep_youtube_settings_before_save', $settings);
390 update_option( $option_name, $settings);
391 do_action( 'ep_youtube_settings_after_save', $settings);
392
393 }
394
395 public function save_wistia_settings() {
396 $option_name = EMBEDPRESS_PLG_NAME.':wistia';
397 $settings = get_option( $option_name, []);
398 $settings['start_time'] = isset( $_POST['start_time']) ? sanitize_text_field( $_POST['start_time']) : 0;
399 $settings['autoplay'] = isset( $_POST['autoplay']) ? sanitize_text_field( $_POST['autoplay']) : '';
400 $settings['display_fullscreen_button'] = isset( $_POST['display_fullscreen_button']) ? sanitize_text_field( $_POST['display_fullscreen_button']) : '';
401 $settings['small_play_button'] = isset( $_POST['small_play_button']) ? sanitize_text_field( $_POST['small_play_button']) : '';
402 $settings['player_color'] = isset( $_POST['player_color']) ? sanitize_text_field( $_POST['player_color']) : '';
403 $settings['plugin_resumable'] = isset( $_POST['plugin_resumable']) ? sanitize_text_field( $_POST['plugin_resumable']) : '';
404 $settings['plugin_focus'] = isset( $_POST['plugin_focus']) ? sanitize_text_field( $_POST['plugin_focus']) : '';
405 $settings['plugin_rewind'] = isset( $_POST['plugin_rewind']) ? sanitize_text_field( $_POST['plugin_rewind']) : '';
406 $settings['display_playbar'] = isset( $_POST['display_playbar']) ? sanitize_text_field( $_POST['display_playbar']) : 1;
407 $settings['plugin_rewind_time'] = isset( $_POST['plugin_rewind_time']) ? sanitize_text_field( $_POST['plugin_rewind_time']) : 10;
408 $settings['always_show_controls'] = isset( $_POST['always_show_controls']) ? sanitize_text_field( $_POST['always_show_controls']) : '';
409 $settings['license_key'] = 1; // backward compatibility
410 // Pro will handle g_loading_animation settings and other
411 $settings = apply_filters( 'ep_wistia_settings_before_save', $settings);
412 update_option( $option_name, $settings);
413 do_action( 'ep_wistia_settings_after_save', $settings);
414 }
415
416 public function save_vimeo_settings() {
417 $option_name = EMBEDPRESS_PLG_NAME.':vimeo';
418 $settings = get_option( $option_name, []);
419 $settings['start_time'] = isset( $_POST['start_time']) ? sanitize_text_field( $_POST['start_time']) : 0;
420 $settings['autoplay'] = isset( $_POST['autoplay']) ? sanitize_text_field( $_POST['autoplay']) : '';
421 $settings['color'] = isset( $_POST['color']) ? sanitize_text_field( $_POST['color']) : '#00adef';
422 $settings['display_title'] = isset( $_POST['display_title']) ? sanitize_text_field( $_POST['display_title']) : 1;
423 $settings['display_author'] = isset( $_POST['display_author']) ? sanitize_text_field( $_POST['display_author']) : 1;
424 $settings['display_avatar'] = isset( $_POST['display_avatar']) ? sanitize_text_field( $_POST['display_avatar']) : 1;
425 $settings['license_key'] = 1; // backward compatibility
426 // Pro will handle g_loading_animation settings and other
427 $settings = apply_filters( 'ep_vimeo_settings_before_save', $settings);
428 update_option( $option_name, $settings);
429 do_action( 'ep_vimeo_settings_after_save', $settings);
430 }
431
432 public function save_twitch_settings() {
433 $option_name = EMBEDPRESS_PLG_NAME.':twitch';
434 $settings = get_option( $option_name, []);
435 $settings['embedpress_pro_twitch_autoplay'] = isset( $_POST['autoplay']) ? sanitize_text_field( $_POST['autoplay']) : 'no';
436 $settings['embedpress_pro_fs'] = isset( $_POST['fs']) ? sanitize_text_field( $_POST['fs']) : 'yes';
437 $settings['start_time'] = isset( $_POST['start_time']) ? sanitize_text_field( $_POST['start_time']) : 0;
438 $settings['embedpress_pro_twitch_theme'] = isset( $_POST['theme']) ? sanitize_text_field( $_POST['theme']) : 'dark';
439 $settings['embedpress_pro_twitch_mute'] = isset( $_POST['mute']) ? sanitize_text_field( $_POST['mute']) : 'yes';
440 $settings['license_key'] = 1; // backward compatibility
441 // Pro will handle g_loading_animation settings and other
442 $settings = apply_filters( 'ep_twitch_settings_before_save', $settings);
443 update_option( $option_name, $settings);
444 do_action( 'ep_twitch_settings_after_save', $settings);
445 }
446
447 public function save_spotify_settings() {
448 $option_name = EMBEDPRESS_PLG_NAME.':spotify';
449 $settings = get_option( $option_name, []);
450 $settings['theme'] = isset( $_POST['spotify_theme']) ? sanitize_text_field( $_POST['spotify_theme']) : '1';
451 $settings['license_key'] = 1; // backward compatibility
452
453 $settings = apply_filters( 'ep_spotify_settings_before_save', $settings);
454 update_option( $option_name, $settings);
455 do_action( 'ep_spotify_settings_after_save', $settings);
456 return $settings;
457 }
458
459 public function save_custom_logo_settings() {
460 do_action( 'before_embedpress_branding_save');
461 $settings = (array) get_option( EMBEDPRESS_PLG_NAME, []);
462
463 // If checkbox is checked, it will be in POST data with value 'yes'
464 // If unchecked, it won't be in POST data, so we set it to 'no'
465 $settings['embedpress_document_powered_by'] = isset( $_POST['embedpress_document_powered_by'] ) ? sanitize_text_field( $_POST['embedpress_document_powered_by'] ) : 'no';
466
467 update_option( EMBEDPRESS_PLG_NAME, $settings);
468 do_action( 'after_embedpress_branding_save');
469
470 }
471
472 public function save_dailymotion_settings() {
473 $option_name = EMBEDPRESS_PLG_NAME.':dailymotion';
474 $settings = get_option( $option_name, []);
475 $settings['start_time'] = isset( $_POST['start_time']) ? sanitize_text_field( $_POST['start_time']) : 0;
476 $settings['visual'] = isset( $_POST['visual']) ? sanitize_text_field( $_POST['visual']) : '';
477 $settings['autoplay'] = isset( $_POST['autoplay']) ? sanitize_text_field( $_POST['autoplay']) : '';
478 $settings['play_on_mobile'] = isset( $_POST['play_on_mobile']) ? sanitize_text_field( $_POST['play_on_mobile']) : '';
479 $settings['color'] = isset( $_POST['color']) ? sanitize_text_field( $_POST['color']) : '#dd3333';
480 $settings['controls'] = isset( $_POST['controls']) ? sanitize_text_field( $_POST['controls']) : '';
481 $settings['video_info'] = isset( $_POST['video_info']) ? sanitize_text_field( $_POST['video_info']) : '';
482 $settings['mute'] = isset( $_POST['mute']) ? sanitize_text_field( $_POST['mute']) : '';
483 // Pro will handle g_loading_animation settings and other
484 $settings = apply_filters( 'ep_dailymotion_settings_before_save', $settings);
485 update_option( $option_name, $settings);
486 do_action( 'ep_dailymotion_settings_after_save', $settings);
487 }
488
489 public function save_soundcloud_settings() {
490 $option_name = EMBEDPRESS_PLG_NAME.':soundcloud';
491 $settings = get_option( $option_name, []);
492 $settings['visual'] = isset( $_POST['visual']) ? sanitize_text_field( $_POST['visual']) : '';
493 $settings['autoplay'] = isset( $_POST['autoplay']) ? sanitize_text_field( $_POST['autoplay']) : '';
494 $settings['play_on_mobile'] = isset( $_POST['play_on_mobile']) ? sanitize_text_field( $_POST['play_on_mobile']) : '';
495 $settings['share_button'] = isset( $_POST['share_button']) ? sanitize_text_field( $_POST['share_button']) : '';
496 $settings['comments'] = isset( $_POST['comments']) ? sanitize_text_field( $_POST['comments']) : '';
497 $settings['color'] = isset( $_POST['color']) ? sanitize_text_field( $_POST['color']) : '';
498 $settings['artwork'] = isset( $_POST['artwork']) ? sanitize_text_field( $_POST['artwork']) : '';
499 $settings['play_count'] = isset( $_POST['play_count']) ? sanitize_text_field( $_POST['play_count']) : '';
500 $settings['username'] = isset( $_POST['username']) ? sanitize_text_field( $_POST['username']) : '';
501
502 $settings['license_key'] = 1; // backward compatibility
503 // Pro will handle g_loading_animation settings and other
504 $settings = apply_filters( 'ep_soundcloud_settings_before_save', $settings);
505 update_option( $option_name, $settings);
506 do_action( 'ep_soundcloud_settings_after_save', $settings);
507 }
508
509 public function save_gcalendar_settings() {
510 $client_secret = !empty( $_POST['epgc_client_secret']) ? json_decode( wp_unslash( trim( $_POST['epgc_client_secret'])), true) : [];
511 $epgc_cache_time = !empty( $_POST['epgc_cache_time'] ) ? absint( $_POST['epgc_cache_time']) : 0;
512 $epgc_selected_calendar_ids = !empty( $_POST['epgc_selected_calendar_ids'] ) ? array_map( 'sanitize_text_field', $_POST['epgc_selected_calendar_ids']) : [];
513
514
515 $pretty_client_secret = '';
516 if ( !empty( $client_secret) ) {
517 $pretty_client_secret = $this->get_pretty_json_string( $client_secret);
518 }
519
520 update_option( 'epgc_client_secret', $pretty_client_secret);
521 update_option( 'epgc_cache_time', $epgc_cache_time);
522 update_option( 'epgc_selected_calendar_ids', $epgc_selected_calendar_ids);
523
524 }
525
526 public function save_opensea_settings() {
527 $option_name = EMBEDPRESS_PLG_NAME.':opensea';
528 $settings = get_option( $option_name, []);
529 $settings['api_key'] = isset( $_POST['api_key']) ? sanitize_text_field( $_POST['api_key']) : 0;
530 $settings['limit'] = isset( $_POST['limit']) ? sanitize_text_field( $_POST['limit']) : 0;
531 $settings['orderby'] = isset( $_POST['orderby']) ? sanitize_text_field( $_POST['orderby']) : 0;
532
533 $settings['license_key'] = 1; // backward compatibility
534
535 // Pro will handle g_loading_animation settings and other
536 $settings = apply_filters( 'ep_opensea_settings_before_save', $settings);
537 update_option( $option_name, $settings);
538 do_action( 'ep_opensea_settings_after_save', $settings);
539 }
540
541
542 function get_pretty_json_string($array) {
543 return str_replace(" ", " ", json_encode($array, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
544 }
545
546 /**
547 * AJAX handler for saving global brand image
548 */
549 public function save_global_brand_image() {
550 // Verify nonce for security
551 if (!wp_verify_nonce($_POST['nonce'], 'embedpress_ajax_nonce')) {
552 wp_die('Security check failed');
553 }
554
555 // Check user capabilities
556 if (!current_user_can('manage_options')) {
557 wp_die('Insufficient permissions');
558 }
559
560 $logo_url = isset($_POST['logo_url']) ? esc_url_raw($_POST['logo_url']) : '';
561 $logo_id = isset($_POST['logo_id']) ? intval($_POST['logo_id']) : '';
562
563 // Save global brand settings
564 $global_brand_settings = [
565 'logo_url' => $logo_url,
566 'logo_id' => $logo_id,
567 ];
568
569 $updated = update_option(EMBEDPRESS_PLG_NAME . ':global_brand', $global_brand_settings);
570
571 // If global brand image is being set, auto-enable branding for providers without custom logos
572 if (!empty($logo_url)) {
573 $this->auto_enable_global_branding($logo_url, $logo_id);
574 }
575
576 if ($updated !== false) {
577 wp_send_json_success([
578 'message' => 'Global brand image saved successfully',
579 'logo_url' => $logo_url,
580 'logo_id' => $logo_id
581 ]);
582 } else {
583 wp_send_json_error('Failed to save global brand image');
584 }
585 }
586
587 /**
588 * AJAX handler for dismissing UI elements (banners, popups, etc.)
589 */
590 public function dismiss_element() {
591 // Verify nonce for security
592 if (!wp_verify_nonce($_POST['nonce'], 'embedpress_ajax_nonce')) {
593 wp_die('Security check failed');
594 }
595
596 // Check user capabilities
597 if (!current_user_can('manage_options')) {
598 wp_die('Insufficient permissions');
599 }
600
601 $element_type = isset($_POST['element_type']) ? sanitize_text_field($_POST['element_type']) : '';
602
603 // Define valid dismiss types and their corresponding option names
604 $valid_dismiss_types = [
605 'main_banner' => 'embedpress_main_banner_dismissed',
606 'hub_popup' => 'embedpress_hub_popup_dismissed',
607 'popup_banner' => 'embedpress_popup_dismissed', // Legacy support
608 ];
609
610 if (array_key_exists($element_type, $valid_dismiss_types)) {
611 $option_name = $valid_dismiss_types[$element_type];
612 update_option($option_name, true);
613
614 // Store current plugin version when hub_popup is dismissed
615 // This ensures popup shows again on next version update
616 if ($element_type === 'hub_popup') {
617 update_option('embedpress_last_popup_version', EMBEDPRESS_VERSION);
618 }
619
620 wp_send_json_success([
621 'message' => ucfirst(str_replace('_', ' ', $element_type)) . ' dismissed successfully',
622 'element_type' => $element_type,
623 'option_name' => $option_name
624 ]);
625 }
626
627 wp_send_json_error([
628 'message' => 'Invalid element type: ' . $element_type,
629 'valid_types' => array_keys($valid_dismiss_types)
630 ]);
631 }
632
633 /**
634 * AJAX handler for dismissing feature notices
635 */
636 public function dismiss_feature_notice() {
637 // Verify nonce for security
638 if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'embedpress_feature_notice_nonce')) {
639 wp_send_json_error(['message' => 'Security check failed']);
640 }
641
642 // Check user capabilities
643 if (!current_user_can('manage_options')) {
644 wp_send_json_error(['message' => 'Insufficient permissions']);
645 }
646
647 $notice_id = isset($_POST['notice_id']) ? sanitize_text_field($_POST['notice_id']) : '';
648
649 if (empty($notice_id)) {
650 wp_send_json_error(['message' => 'Notice ID is required']);
651 }
652
653 // Define valid notice types and their corresponding option names
654 $valid_notices = [
655 'analytics' => 'embedpress_feature_notice_analytics_dismissed',
656 ];
657
658 if (array_key_exists($notice_id, $valid_notices)) {
659 $option_name = $valid_notices[$notice_id];
660 update_option($option_name, true);
661
662 wp_send_json_success([
663 'message' => 'Feature notice dismissed successfully',
664 'notice_id' => $notice_id,
665 'option_name' => $option_name
666 ]);
667 }
668
669 wp_send_json_error([
670 'message' => 'Invalid notice ID: ' . $notice_id,
671 'valid_notices' => array_keys($valid_notices)
672 ]);
673 }
674
675 /**
676 * Auto-enable branding for all providers that don't have custom logos
677 */
678 private function auto_enable_global_branding($logo_url, $logo_id) {
679 $providers = ['youtube', 'vimeo', 'wistia', 'twitch', 'dailymotion', 'document'];
680
681 foreach ($providers as $provider) {
682 $option_name = EMBEDPRESS_PLG_NAME . ':' . $provider;
683 $settings = get_option($option_name, []);
684
685 // Only auto-enable if provider doesn't have a custom logo set
686 $has_custom_logo = isset($settings['logo_url']) && !empty($settings['logo_url']);
687
688 if (!$has_custom_logo) {
689 // Enable branding but don't set logo_url/logo_id - let the template logic handle global fallback
690 $settings['branding'] = 'yes';
691 update_option($option_name, $settings);
692 }
693 }
694 }
695
696 /**
697 * Reorder submenu items to put Analytics 2nd and License last
698 */
699 public function reorder_submenu_items() {
700 global $submenu;
701
702 // Check if our menu exists
703 if (!isset($submenu[$this->page_slug])) {
704 return;
705 }
706
707 $license_item = null;
708 $analytics_item = null;
709 $reordered_menu = [];
710
711 // Find and extract License and Analytics items
712 foreach ($submenu[$this->page_slug] as $item) {
713 if (isset($item[0])) {
714 if ($item[0] === __('License', 'embedpress')) {
715 $license_item = $item;
716 continue; // Skip adding to reordered menu
717 } elseif ($item[0] === __('Analytics', 'embedpress')) {
718 $analytics_item = $item;
719 continue; // Skip adding to reordered menu
720 }
721 }
722 $reordered_menu[] = $item;
723 }
724
725 // Rebuild the menu with proper order
726 $final_menu = [];
727
728 // Add first item (Dashboard)
729 if (!empty($reordered_menu[0])) {
730 $final_menu[] = $reordered_menu[0];
731 }
732
733 // Add Analytics as 2nd item if it exists
734 if ($analytics_item !== null) {
735 $final_menu[] = $analytics_item;
736 }
737
738 // Add remaining items (except first which we already added)
739 for ($i = 1; $i < count($reordered_menu); $i++) {
740 $final_menu[] = $reordered_menu[$i];
741 }
742
743 // Add License at the end if it exists
744 if ($license_item !== null) {
745 $final_menu[] = $license_item;
746 }
747
748 // Replace the submenu with reordered items
749 $submenu[$this->page_slug] = $final_menu;
750 }
751 }
752