'accelvia_sanitize_options', ) ); } add_action('admin_init', 'accelvia_register_settings'); /** * Sanitize and validate all plugin options. * * @param array $input Raw input from the settings form. * @return array Sanitized options. */ function accelvia_sanitize_options($input) { error_log('accelvia_sanitize_input: ' . print_r($input, true)); $sanitized = array(); // Checkboxes – cast to '1' or '0'. $checkboxes = array( 'enable_protection', 'disable_right_click', 'disable_shortcuts', 'disable_text_selection', 'disable_image_drag', 'disable_copy', 'disable_devtools', 'disable_screenshot', 'encrypt_content', 'skip_admins', 'watermark_enabled', ); foreach ($checkboxes as $key) { $sanitized[$key] = !empty($input[$key]) ? '1' : '0'; } // Notification type – whitelist. $allowed_types = array('alert', 'toast'); $sanitized['notification_type'] = (isset($input['notification_type']) && in_array($input['notification_type'], $allowed_types, true)) ? $input['notification_type'] : 'toast'; // Notification message – sanitize text. $sanitized['notification_message'] = isset($input['notification_message']) ? sanitize_text_field($input['notification_message']) : __('This content is protected by Accelvia.', 'accelvia-content-protection'); // Protected post types – array of sanitized slugs. $pt_input = isset($input['protected_post_types']) ? (array) $input['protected_post_types'] : array(); $pt_input = array_filter($pt_input); // Removes the empty string from our hidden field. $sanitized['protected_post_types'] = array_map('sanitize_key', $pt_input); // Excluded page IDs – comma-separated integers. $sanitized['excluded_page_ids'] = ''; if (!empty($input['excluded_page_ids'])) { $raw_ids = preg_split('/[\s,]+/', trim($input['excluded_page_ids'])); $clean_ids = array_filter(array_map('absint', $raw_ids)); $sanitized['excluded_page_ids'] = implode(',', $clean_ids); } // ── Watermark Settings ────────────────────────────────────── // Watermark type – whitelist. $allowed_wm_types = array('image', 'text'); $sanitized['watermark_type'] = (isset($input['watermark_type']) && in_array($input['watermark_type'], $allowed_wm_types, true)) ? $input['watermark_type'] : 'text'; // Watermark image. $sanitized['watermark_image_url'] = isset($input['watermark_image_url']) ? esc_url_raw($input['watermark_image_url']) : ''; $sanitized['watermark_image_id'] = isset($input['watermark_image_id']) ? absint($input['watermark_image_id']) : 0; // Watermark text. $sanitized['watermark_text'] = isset($input['watermark_text']) ? sanitize_text_field($input['watermark_text']) : __('© Protected by Accelvia', 'accelvia-content-protection'); // Font size (12–72). $sanitized['watermark_font_size'] = isset($input['watermark_font_size']) ? max(12, min(72, absint($input['watermark_font_size']))) : 16; // Font color. $sanitized['watermark_font_color'] = isset($input['watermark_font_color']) ? sanitize_hex_color($input['watermark_font_color']) : '#ffffff'; if (empty($sanitized['watermark_font_color'])) { $sanitized['watermark_font_color'] = '#ffffff'; } // Position – whitelist. $allowed_positions = array( 'top-left', 'top-center', 'top-right', 'middle-left', 'center', 'middle-right', 'bottom-left', 'bottom-center', 'bottom-right', 'tiled', ); $sanitized['watermark_position'] = (isset($input['watermark_position']) && in_array($input['watermark_position'], $allowed_positions, true)) ? $input['watermark_position'] : 'bottom-right'; // Opacity (0–100). $sanitized['watermark_opacity'] = isset($input['watermark_opacity']) ? max(0, min(100, absint($input['watermark_opacity']))) : 50; // Size (5–100). $sanitized['watermark_size'] = isset($input['watermark_size']) ? max(5, min(100, absint($input['watermark_size']))) : 30; // Tile spacing (0–300). $sanitized['watermark_tile_spacing'] = isset($input['watermark_tile_spacing']) ? max(0, min(300, absint($input['watermark_tile_spacing']))) : 80; // Scope – whitelist. $allowed_scopes = array('all', 'selector'); $sanitized['watermark_scope'] = (isset($input['watermark_scope']) && in_array($input['watermark_scope'], $allowed_scopes, true)) ? $input['watermark_scope'] : 'all'; // Selector strings (must preserve '>' and quotes, so wp_unslash and strip tags). $sanitized['watermark_selector'] = isset($input['watermark_selector']) ? wp_strip_all_tags(wp_unslash($input['watermark_selector'])) : ''; $sanitized['watermark_exclude_selector'] = isset($input['watermark_exclude_selector']) ? wp_strip_all_tags(wp_unslash($input['watermark_exclude_selector'])) : ''; $sanitized['watermark_excluded_page_ids'] = isset($input['watermark_excluded_page_ids']) ? sanitize_text_field($input['watermark_excluded_page_ids']) : ''; // Device – whitelist. $allowed_devices = array('both', 'desktop', 'mobile'); $sanitized['watermark_device'] = (isset($input['watermark_device']) && in_array($input['watermark_device'], $allowed_devices, true)) ? $input['watermark_device'] : 'both'; return $sanitized; } /** * Enqueue admin assets only on the plugin's settings page. * * @param string $hook Current admin page hook suffix. */ function accelvia_enqueue_admin_assets($hook) { if ('settings_page_accelvia-protection' !== $hook) { return; } wp_enqueue_style( 'accelvia-admin-css', ACCELVIA_PLUGIN_URL . 'assets/css/admin.css', array(), ACCELVIA_VERSION ); // WordPress color picker for watermark font color. wp_enqueue_style('wp-color-picker'); // WordPress media uploader for watermark image upload. wp_enqueue_media(); wp_enqueue_script( 'accelvia-admin-js', ACCELVIA_PLUGIN_URL . 'assets/js/admin.js', array('wp-color-picker'), ACCELVIA_VERSION, true ); } add_action('admin_enqueue_scripts', 'accelvia_enqueue_admin_assets'); /** * Render the full settings page HTML. */ function accelvia_render_settings_page() { if (!current_user_can('manage_options')) { wp_die(esc_html__('You do not have permission to access this page.', 'accelvia-content-protection')); } $options = get_option(ACCELVIA_OPTION_KEY, array()); // Merge with defaults to ensure all keys exist. $defaults = array( 'enable_protection' => '0', 'disable_right_click' => '1', 'disable_shortcuts' => '1', 'disable_text_selection' => '0', 'disable_image_drag' => '1', 'disable_copy' => '0', 'disable_devtools' => '1', 'disable_screenshot' => '1', 'encrypt_content' => '1', 'notification_type' => 'toast', 'notification_message' => __('This content is protected by Accelvia.', 'accelvia-content-protection'), 'skip_admins' => '1', 'protected_post_types' => array('post', 'page'), 'excluded_page_ids' => '', // Watermark defaults. 'watermark_enabled' => '0', 'watermark_type' => 'text', 'watermark_image_url' => '', 'watermark_image_id' => 0, 'watermark_text' => __('© Protected by Accelvia', 'accelvia-content-protection'), 'watermark_font_size' => 16, 'watermark_font_color' => '#ffffff', 'watermark_position' => 'bottom-right', 'watermark_opacity' => 50, 'watermark_size' => 30, 'watermark_tile_spacing' => 80, 'watermark_scope' => 'all', 'watermark_selector' => '', 'watermark_exclude_selector' => '', 'watermark_excluded_page_ids' => '', 'watermark_device' => 'both', ); $options = wp_parse_args($options, $defaults); // Get all public post types. $post_types = get_post_types(array('public' => true), 'objects'); ?>
v