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