'sanitize_textarea_field' ) ); } else { register_setting( 'adxbyms_settings', $opt, array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); } } // Header/Footer textareas custom sanitization register_setting( 'adxbyms_settings', 'adxbyms_header_code', array( 'sanitize_callback' => array( $this, 'sanitize_raw_code' ) ) ); register_setting( 'adxbyms_settings', 'adxbyms_footer_code', array( 'sanitize_callback' => array( $this, 'sanitize_raw_code' ) ) ); register_setting( 'adxbyms_settings', 'adxbyms_ads_txt_code', array( 'sanitize_callback' => 'sanitize_textarea_field' ) ); // Register 10 standard display slots for ( $i = 1; $i <= 10; $i++ ) { register_setting( 'adxbyms_settings', "adxbyms_slot_{$i}_enabled", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_slot_{$i}_network_code", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_slot_{$i}_sizes", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_slot_{$i}_pages", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_slot_{$i}_insertion", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_slot_{$i}_alignment", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_slot_{$i}_text", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_slot_{$i}_offset", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_slot_{$i}_devices", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_slot_{$i}_show_label", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); } // Register 10 custom adsense blocks for ( $i = 1; $i <= 10; $i++ ) { register_setting( 'adxbyms_settings', "adxbyms_custom_adsense_block_{$i}_enabled", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_custom_adsense_block_{$i}_code", array( 'sanitize_callback' => array( $this, 'sanitize_raw_code' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_custom_adsense_block_{$i}_insertion", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_custom_adsense_block_{$i}_offset", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_custom_adsense_block_{$i}_alignment", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_custom_adsense_block_{$i}_pages", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_custom_adsense_block_{$i}_devices", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); } // Register 5 responsive ad blocks for ( $i = 1; $i <= 5; $i++ ) { register_setting( 'adxbyms_settings', "adxbyms_responsive_block_{$i}_enabled", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_responsive_block_{$i}_network_code", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_responsive_block_{$i}_insertion", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_responsive_block_{$i}_offset", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_responsive_block_{$i}_alignment", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_responsive_block_{$i}_pages", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_responsive_block_{$i}_devices", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_responsive_block_{$i}_show_label", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); } // Register 5 flying carpet ad blocks for ( $i = 1; $i <= 5; $i++ ) { register_setting( 'adxbyms_settings', "adxbyms_flying_carpet_block_{$i}_enabled", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_flying_carpet_block_{$i}_network_code", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_flying_carpet_block_{$i}_insertion", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_flying_carpet_block_{$i}_offset", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_flying_carpet_block_{$i}_alignment", array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'adxbyms_settings', "adxbyms_flying_carpet_block_{$i}_pages", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); register_setting( 'adxbyms_settings', "adxbyms_flying_carpet_block_{$i}_devices", array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) ); } } /** * Safe default settings values helper. */ public function sanitize_option( $value ) { if ( is_array( $value ) ) { return array_map( 'sanitize_text_field', $value ); } if ( 'true' === $value || 'false' === $value ) { return $value; } return sanitize_text_field( $value ); } /** * Sanitize raw custom HTML/JS ad codes safely. */ public function sanitize_raw_code( $value ) { if ( current_user_can( 'unfiltered_html' ) ) { return $value; // Administrators with unrestricted HTML can paste raw codes directly } // Strict security sandbox: strip unsafe nodes, allow only essential elements $allowed = array( 'div' => array( 'id' => true, 'class' => true, 'style' => true, 'data-*' => true, ), 'span' => array( 'id' => true, 'class' => true, 'style' => true, 'data-*' => true, ), 'ins' => array( 'class' => true, 'style' => true, 'data-*' => true, 'id' => true, ), 'noscript' => array(), ); return wp_kses( $value, $allowed ); } /** * Add Settings Page to WordPress Admin. */ public function add_settings_menu() { add_menu_page( __( 'AdX Ad Inserter', 'adx-ad-inserter' ), __( 'AdX Ad Inserter', 'adx-ad-inserter' ), 'manage_options', 'adx-ad-inserter', array( $this, 'render_settings_page' ), 'dashicons-megaphone', 59 ); } /** * Render the settings template page. */ public function render_settings_page() { // Double check capabilities if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'adx-ad-inserter' ) ); } require_once ADXBYMS_PATH . 'templates/settings-page.php'; } /** * Handle incoming registration callback from Monetiscope. */ public function handle_setup_registration() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( isset( $_GET['page'] ) && 'adx-ad-inserter' === $_GET['page'] && isset( $_GET['registered'] ) && '1' === $_GET['registered'] ) { update_option( 'ms_setup_completed', '1' ); set_transient( 'ms_setup_success_notice', '1', 60 ); wp_safe_redirect( admin_url( 'admin.php?page=adx-ad-inserter' ) ); exit; } } /** * Start output buffer to capture all third-party admin notices on our plugin page. * Runs at priority -100 (before any notice is output). */ public function notices_buffer_start() { if ( ! isset( $_GET['page'] ) || 'adx-ad-inserter' !== $_GET['page'] ) { return; } ob_start(); } /** * Discard the buffered third-party notices on our plugin page. * Runs at priority PHP_INT_MAX (after all notices have been output). */ public function notices_buffer_end() { if ( ! isset( $_GET['page'] ) || 'adx-ad-inserter' !== $_GET['page'] ) { return; } ob_end_clean(); // Discard ALL captured third-party notices. // Now output our own notice directly, outside the buffer scope. $this->display_setup_notices(); } /** * Display success notice after registration. */ public function display_setup_notices() { if ( get_transient( 'ms_setup_success_notice' ) ) { ?>