bulk_tools = new AdFusion_Bulk_Tools(); add_action( 'admin_post_adfusion_save_group_dimensions', array( $this, 'handle_save_group_dimensions' ) ); } /** Term meta keys for Ad Group max dimensions (shared with Premium). */ const META_MAX_WIDTH = '_adf_max_width'; const META_MAX_HEIGHT = '_adf_max_height'; const META_MAX_WIDTH_UNIT = '_adf_max_width_unit'; const META_MAX_HEIGHT_UNIT = '_adf_max_height_unit'; /** * Enqueue media library and admin scripts on the Ad edit screen. * * @param string $hook_suffix The current admin page. Unused but required by the hook. * @return void */ public function enqueue_ad_edit_scripts( $hook_suffix ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found $screen = get_current_screen(); if ( ! $screen || 'adfusion_ad' !== $screen->post_type ) { return; } wp_enqueue_media(); $script_url = defined( 'ADFUSION_PREMIUM_URL' ) ? ADFUSION_PREMIUM_URL . 'assets/js/adf-admin-media.js' : ADFUSION_PLUGIN_URL . 'assets/js/adf-admin-media.js'; wp_enqueue_script( 'adf-admin-media', $script_url, array( 'jquery' ), defined( 'ADFUSION_PREMIUM_VERSION' ) ? ADFUSION_PREMIUM_VERSION : ADFUSION_VERSION, true ); wp_localize_script( 'adf-admin-media', 'adfAdminMedia', array( 'selectImage' => __( 'Select or Upload Image', 'adfusion-ad-manager-and-monetization' ), 'useThisImage' => __( 'Use this image', 'adfusion-ad-manager-and-monetization' ), ) ); } /** * Register the custom meta box for the 'adfusion_ad' post type. * * @return void */ public function add_ad_meta_boxes() { add_meta_box( 'adfusion_ad_details', // Unique ID for the meta box. __( 'Ad Details & Configuration', 'adfusion-ad-manager-and-monetization' ), // Meta box title. array( $this, 'render_ad_meta_box' ), // Callback function to render the HTML. 'adfusion_ad', // Post type to display it on. 'normal', // Placement on the screen (normal, side, advanced). 'high' // Priority. ); } /** * Render the HTML inside the custom meta box. * * @param WP_Post $post The current post object. * @return void */ public function render_ad_meta_box( $post ) { // Add a nonce field for security to verify the request later. wp_nonce_field( 'adfusion_save_ad_data', 'adfusion_ad_meta_nonce' ); // Retrieve existing values from the database if they exist. $ad_type = get_post_meta( $post->ID, '_adf_ad_type', true ); $destination_url = get_post_meta( $post->ID, '_adf_destination_url', true ); if ( empty( $destination_url ) ) { $destination_url = get_post_meta( $post->ID, '_adf_ad_url', true ); } $start_datetime = get_post_meta( $post->ID, '_adf_start_datetime', true ); $end_datetime = get_post_meta( $post->ID, '_adf_end_datetime', true ); if ( empty( $start_datetime ) ) { $start_date = get_post_meta( $post->ID, '_adf_start_date', true ); $start_datetime = ! empty( $start_date ) ? $start_date . ' 00:00:00' : ''; } if ( empty( $end_datetime ) ) { $end_date = get_post_meta( $post->ID, '_adf_end_date', true ); $end_datetime = ! empty( $end_date ) ? $end_date . ' 23:59:59' : ''; } $start_date_val = ! empty( $start_datetime ) ? substr( $start_datetime, 0, 10 ) : ''; $start_time_val = ! empty( $start_datetime ) ? substr( $start_datetime, 11, 5 ) : ''; $end_date_val = ! empty( $end_datetime ) ? substr( $end_datetime, 0, 10 ) : ''; $end_time_val = ! empty( $end_datetime ) ? substr( $end_datetime, 11, 5 ) : ''; $ad_code = get_post_meta( $post->ID, '_adf_ad_code', true ); $google_ad_slot = get_post_meta( $post->ID, '_adf_google_ad_slot', true ); $ad_image = get_post_meta( $post->ID, '_adf_ad_image', true ); $ad_image_mobile = get_post_meta( $post->ID, '_adf_ad_image_mobile', true ); $adf_desktop_only = get_post_meta( $post->ID, '_adf_desktop_only', true ); $adf_mobile_only = get_post_meta( $post->ID, '_adf_mobile_only', true ); // Default to 'image' if no type is set. if ( empty( $ad_type ) ) { $ad_type = 'image'; } // Begin HTML output. ?>

validate_adf_date_ymd( sanitize_text_field( wp_unslash( $_POST['adf_start_date'] ) ) ); } $start_time = ''; if ( isset( $_POST['adf_start_time'] ) ) { $start_time = preg_replace( '/[^0-9:]/', '', sanitize_text_field( wp_unslash( $_POST['adf_start_time'] ) ) ); } if ( preg_match( '/^\d{1,2}:\d{2}$/', $start_time ) ) { $parts = explode( ':', $start_time ); $start_time = sprintf( '%02d:%02d', (int) $parts[0], (int) $parts[1] ); } else { $start_time = ''; } $start_val = ( ! empty( $start_date ) && ! empty( $start_time ) ) ? $start_date . ' ' . $start_time . ':00' : ( ! empty( $start_date ) ? $start_date . ' 00:00:00' : '' ); update_post_meta( $post_id, '_adf_start_datetime', $start_val ); // 13. End Date & Time. $end_date = ''; if ( isset( $_POST['adf_end_date'] ) ) { $end_date = $this->validate_adf_date_ymd( sanitize_text_field( wp_unslash( $_POST['adf_end_date'] ) ) ); } $end_time = ''; if ( isset( $_POST['adf_end_time'] ) ) { $end_time = preg_replace( '/[^0-9:]/', '', sanitize_text_field( wp_unslash( $_POST['adf_end_time'] ) ) ); } if ( preg_match( '/^\d{1,2}:\d{2}$/', $end_time ) ) { $parts = explode( ':', $end_time ); $end_time = sprintf( '%02d:%02d', (int) $parts[0], (int) $parts[1] ); } else { $end_time = ''; } $end_val = ( ! empty( $end_date ) && ! empty( $end_time ) ) ? $end_date . ' ' . $end_time . ':00' : ( ! empty( $end_date ) ? $end_date . ' 23:59:59' : '' ); update_post_meta( $post_id, '_adf_end_datetime', $end_val ); do_action( 'adfusion_after_save_ad_meta', $post_id ); } /** * Validate a sanitized string is Y-m-d or return empty. * * @param string $sanitized Already sanitized text (e.g. from sanitize_text_field). * @return string Empty or Y-m-d. */ private function validate_adf_date_ymd( $sanitized ) { if ( '' === $sanitized || ! is_string( $sanitized ) ) { return ''; } if ( 1 !== preg_match( '/^\d{4}-\d{2}-\d{2}$/', $sanitized ) ) { return ''; } return $sanitized; } /** * Add Settings submenu under AdFusion CPT. * * @return void */ public function add_settings_page() { add_submenu_page( 'edit.php?post_type=adfusion_ad', __( 'Settings', 'adfusion-ad-manager-and-monetization' ), __( 'Settings', 'adfusion-ad-manager-and-monetization' ), 'manage_options', 'adfusion-settings', array( $this, 'render_settings_page' ) ); } /** * Register settings for automatic ad injection. * * @return void */ public function register_settings() { register_setting( 'adfusion_settings_group', 'adfusion_before_content_group', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', ) ); register_setting( 'adfusion_settings_group', 'adfusion_after_content_group', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', ) ); register_setting( 'adfusion_settings_group', 'adfusion_premium_popup_duration_seconds', array( 'type' => 'integer', 'default' => 30, 'sanitize_callback' => function ( $value ) { $val = absint( $value ); return $val >= 0 ? $val : 30; }, ) ); register_setting( 'adfusion_settings_group', 'adfusion_story_header_position', array( 'type' => 'string', 'default' => 'above', 'sanitize_callback' => function ( $value ) { return in_array( $value, array( 'above', 'below' ), true ) ? $value : 'above'; }, ) ); register_setting( 'adfusion_settings_group', 'adf_ads_txt_enabled', array( 'type' => 'string', 'default' => '1', 'sanitize_callback' => function ( $value ) { return ( ! empty( $value ) && '1' === (string) $value ) ? '1' : '0'; }, ) ); if ( ! defined( 'ADFUSION_PREMIUM_VERSION' ) ) { register_setting( 'adfusion_settings_group', 'adf_google_adsense_id', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '', ) ); } } /** * Render the Settings page. * * @return void */ public function render_settings_page() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'adfusion-ad-manager-and-monetization' ) ); } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Tab is display-only; sanitized. $current_tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'settings'; $base_url = add_query_arg( array( 'post_type' => 'adfusion_ad', 'page' => 'adfusion-settings', ), admin_url( 'edit.php' ) ); ?>

render_dimensions_tab(); echo '
'; return; } if ( 'tools' === $current_tab ) { $this->render_import_notices(); $this->bulk_tools->render_tools_tab(); echo ''; return; } $cache_key = ADFUSION_PLUGIN_SLUG . '_ad_groups'; $ad_groups = get_transient( $cache_key ); if ( false === $ad_groups ) { $ad_groups = get_terms( array( 'taxonomy' => 'adfusion_group', 'hide_empty' => false, ) ); if ( ! is_wp_error( $ad_groups ) ) { set_transient( $cache_key, $ad_groups, DAY_IN_SECONDS ); } else { $ad_groups = array(); } } if ( is_wp_error( $ad_groups ) ) { $ad_groups = array(); } ?>

'adfusion_group', 'hide_empty' => false, ) ); if ( is_wp_error( $terms ) || empty( $terms ) ) { echo '

' . esc_html__( 'No Ad Groups found. Create Ad Groups first under Ads → Ad Groups.', 'adfusion-ad-manager-and-monetization' ) . '

'; return; } // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Display-only from our redirect. $saved = isset( $_GET['adfusion_dimensions_saved'] ) && '1' === sanitize_text_field( wp_unslash( $_GET['adfusion_dimensions_saved'] ) ); // phpcs:enable WordPress.Security.NonceVerification.Recommended ?>

term_id, self::META_MAX_WIDTH, true ); $max_height = get_term_meta( $term->term_id, self::META_MAX_HEIGHT, true ); $max_width_unit = get_term_meta( $term->term_id, self::META_MAX_WIDTH_UNIT, true ); $max_height_unit = get_term_meta( $term->term_id, self::META_MAX_HEIGHT_UNIT, true ); $max_width_unit = in_array( $max_width_unit, array( 'px', 'vw' ), true ) ? $max_width_unit : 'px'; $max_height_unit = in_array( $max_height_unit, array( 'px', 'vh' ), true ) ? $max_height_unit : 'px'; $tid = (int) $term->term_id; ?>
name ); ?>

'adfusion_group', 'hide_empty' => false, 'fields' => 'ids', ) ); if ( ! is_wp_error( $terms ) ) { foreach ( $terms as $tid ) { $tid = (int) $tid; $w = isset( $raw_w[ $tid ] ) ? absint( $raw_w[ $tid ] ) : 0; $h = isset( $raw_h[ $tid ] ) ? absint( $raw_h[ $tid ] ) : 0; $wu = isset( $raw_wu[ $tid ] ) && in_array( $raw_wu[ $tid ], array( 'px', 'vw' ), true ) ? $raw_wu[ $tid ] : 'px'; $hu = isset( $raw_hu[ $tid ] ) && in_array( $raw_hu[ $tid ], array( 'px', 'vh' ), true ) ? $raw_hu[ $tid ] : 'px'; update_term_meta( $tid, self::META_MAX_WIDTH, $w > 0 ? $w : '' ); update_term_meta( $tid, self::META_MAX_HEIGHT, $h > 0 ? $h : '' ); update_term_meta( $tid, self::META_MAX_WIDTH_UNIT, $w > 0 ? $wu : '' ); update_term_meta( $tid, self::META_MAX_HEIGHT_UNIT, $h > 0 ? $hu : '' ); } } wp_safe_redirect( add_query_arg( array( 'post_type' => 'adfusion_ad', 'page' => 'adfusion-settings', 'tab' => 'dimensions', 'adfusion_dimensions_saved' => 1, ), admin_url( 'edit.php' ) ) ); exit; } /** * Render admin notices for CSV import results. * * @return void */ private function render_import_notices() { // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Import/sync result params from our own redirect; sanitized. if ( isset( $_GET['adfusion_sync_urls'] ) && 'success' === sanitize_key( wp_unslash( $_GET['adfusion_sync_urls'] ) ) ) { $count = isset( $_GET['adfusion_sync_count'] ) ? absint( $_GET['adfusion_sync_count'] ) : 0; echo '

'; echo esc_html( sprintf( /* translators: %d: number of ads updated */ __( 'Destination URLs synced. %d ad(s) updated.', 'adfusion-ad-manager-and-monetization' ), $count ) ); echo '

'; return; } if ( ! isset( $_GET['adfusion_import'] ) ) { return; } $status = isset( $_GET['adfusion_import'] ) ? sanitize_key( wp_unslash( $_GET['adfusion_import'] ) ) : ''; if ( 'success' === $status ) { $created = isset( $_GET['adfusion_created'] ) ? absint( $_GET['adfusion_created'] ) : 0; $updated = isset( $_GET['adfusion_updated'] ) ? absint( $_GET['adfusion_updated'] ) : 0; echo '

'; echo esc_html( sprintf( /* translators: 1: number of ads created, 2: number of ads updated */ __( 'Import complete. %1$d ad(s) created, %2$d ad(s) updated.', 'adfusion-ad-manager-and-monetization' ), $created, $updated ) ); echo '

'; } elseif ( 'error' === $status ) { $msg = isset( $_GET['adfusion_import_msg'] ) ? sanitize_key( wp_unslash( $_GET['adfusion_import_msg'] ) ) : ''; $messages = array( 'no_file' => __( 'No file was uploaded.', 'adfusion-ad-manager-and-monetization' ), 'read_failed' => __( 'Could not read the uploaded file.', 'adfusion-ad-manager-and-monetization' ), 'empty_file' => __( 'The CSV file is empty or invalid.', 'adfusion-ad-manager-and-monetization' ), ); $text = isset( $messages[ $msg ] ) ? $messages[ $msg ] : __( 'An error occurred during import.', 'adfusion-ad-manager-and-monetization' ); echo '

' . esc_html( $text ) . '

'; } // phpcs:enable WordPress.Security.NonceVerification.Recommended } } // Instantiate the class. if ( is_admin() ) { new AdFusion_Admin(); }