__( 'Affiliate Boxes', 'affistyle' ), 'singular_name' => __( 'Affiliate Box', 'affistyle' ), 'menu_name' => __( 'AffiStyle', 'affistyle' ), 'add_new' => __( 'Add New Box', 'affistyle' ), 'add_new_item' => __( 'Add New Affiliate Box', 'affistyle' ), 'edit_item' => __( 'Edit Affiliate Box', 'affistyle' ), 'new_item' => __( 'New Affiliate Box', 'affistyle' ), 'view_item' => __( 'View Affiliate Box', 'affistyle' ), 'search_items' => __( 'Search Affiliate Boxes', 'affistyle' ), 'not_found' => __( 'No affiliate boxes found', 'affistyle' ), 'not_found_in_trash' => __( 'No affiliate boxes found in Trash', 'affistyle' ), ); $args = array( 'labels' => $labels, 'public' => false, 'show_ui' => true, 'show_in_menu' => true, 'menu_icon' => 'dashicons-index-card', 'capability_type' => 'post', 'hierarchical' => false, 'supports' => array( 'title' ), 'show_in_rest' => true, // Enables Gutenberg and REST API support. ); register_post_type( 'affistyle_box', $args ); } /** * Enqueue media uploader and admin styles only on AffiStyle editing screens. * * @param string $hook Admin page hook. */ public function enqueue_admin_assets( $hook ) { if ( 'post.php' !== $hook && 'post-new.php' !== $hook ) { return; } $screen = get_current_screen(); if ( ! $screen || ! in_array( $screen->post_type, array( 'affistyle_box', 'aff_box' ), true ) ) { return; } wp_enqueue_media(); wp_enqueue_style( 'affistyle-admin-css', AFFISTYLE_URL . 'assets/css/admin-style.css', array(), AFFISTYLE_VERSION ); wp_enqueue_script( 'affistyle-admin-js', AFFISTYLE_URL . 'assets/js/admin-builder.js', array( 'jquery' ), AFFISTYLE_VERSION, array( 'strategy' => 'defer', 'in_footer' => true, ) ); } /** * Add Metaboxes to the CPT screen. */ public function add_affistyle_box_metaboxes() { add_meta_box( 'affistyle_card_details', __( 'Affiliate Card Builder Details', 'affistyle' ), array( $this, 'render_metabox_content' ), array( 'affistyle_box', 'aff_box' ), 'normal', 'high' ); } /** * Render the HTML form inside the metabox. * * @param WP_Post $post Current post object. */ public function render_metabox_content( $post ) { // Unified single security nonce token matching save handler. wp_nonce_field( 'affistyle_save_box_meta', 'affistyle_box_nonce' ); // Retrieve existing values for Product 1 base fields. $template_style = get_post_meta( $post->ID, '_affistyle_template_style', true ); $title_1 = get_post_meta( $post->ID, '_affistyle_title_1', true ); $image_1 = get_post_meta( $post->ID, '_affistyle_image_1', true ); if ( empty( $image_1 ) ) { $image_1 = get_post_meta( $post->ID, '_affistyle_image_url', true ); } $description = get_post_meta( $post->ID, '_affistyle_description', true ); $destination = get_post_meta( $post->ID, '_affistyle_destination', true ); if ( empty( $destination ) ) { $destination = get_post_meta( $post->ID, '_affistyle_url_default', true ); } $button_text = get_post_meta( $post->ID, '_affistyle_button_text', true ); $badge_text = get_post_meta( $post->ID, '_affistyle_badge_text', true ); $bg_color = get_post_meta( $post->ID, '_affistyle_bg_color', true ); $btn_color = get_post_meta( $post->ID, '_affistyle_btn_color', true ); $pros = get_post_meta( $post->ID, '_affistyle_pros', true ); $cons = get_post_meta( $post->ID, '_affistyle_cons', true ); $rating_score = get_post_meta( $post->ID, '_affistyle_rating_score', true ); $review_count = get_post_meta( $post->ID, '_affistyle_review_count', true ); $show_rating_meta = get_post_meta( $post->ID, '_affistyle_show_rating', true ); $show_rating = ( '' === $show_rating_meta ) ? true : ( '1' === (string) $show_rating_meta ); // Fallbacks. if ( empty( $template_style ) ) { $template_style = 'style-1'; } if ( empty( $button_text ) ) { $button_text = __( 'Claim Deal', 'affistyle' ); } if ( empty( $bg_color ) ) { $bg_color = '#ffffff'; } if ( empty( $btn_color ) ) { $btn_color = '#2563eb'; } // Strictly load local metabox-form.php view file. $view_file = AFFISTYLE_PATH . 'admin/views/metabox-form.php'; if ( file_exists( $view_file ) ) { include $view_file; } elseif ( class_exists( 'AffiStyle_Admin_Controller' ) && method_exists( 'AffiStyle_Admin_Controller', 'render_metabox_view' ) ) { AffiStyle_Admin_Controller::render_metabox_view( $post ); } } /** * Save Metabox Data securely for Product 1 Base Fields. * * @param int $post_id Post ID. */ public function save_affistyle_box_meta( $post_id ) { // 1. Verify Nonce. if ( ! isset( $_POST['affistyle_box_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['affistyle_box_nonce'] ) ), 'affistyle_save_box_meta' ) ) { return; } // 2. Prevent autosaves and revisions from overriding meta. if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) { return; } // 3. Verify target post type and user edit permissions. $post_type = get_post_type( $post_id ); if ( 'affistyle_box' !== $post_type && 'aff_box' !== $post_type ) { return; } if ( ! current_user_can( 'edit_post', $post_id ) ) { return; } // 4. Save Template Style. if ( isset( $_POST['affistyle_template_style'] ) ) { $template_style = sanitize_text_field( wp_unslash( $_POST['affistyle_template_style'] ) ); $available_styles = function_exists( 'affistyle_get_available_styles' ) ? affistyle_get_available_styles() : array(); if ( ! isset( $available_styles[ $template_style ] ) ) { $template_style = 'style-1'; } update_post_meta( $post_id, '_affistyle_template_style', $template_style ); } // 5. Sanitize and save general card fields. if ( isset( $_POST['affistyle_description'] ) ) { update_post_meta( $post_id, '_affistyle_description', sanitize_textarea_field( wp_unslash( $_POST['affistyle_description'] ) ) ); } if ( isset( $_POST['affistyle_button_text'] ) ) { update_post_meta( $post_id, '_affistyle_button_text', sanitize_text_field( wp_unslash( $_POST['affistyle_button_text'] ) ) ); } if ( isset( $_POST['affistyle_badge_text'] ) ) { update_post_meta( $post_id, '_affistyle_badge_text', sanitize_text_field( wp_unslash( $_POST['affistyle_badge_text'] ) ) ); } if ( isset( $_POST['affistyle_bg_color'] ) ) { update_post_meta( $post_id, '_affistyle_bg_color', sanitize_hex_color( wp_unslash( $_POST['affistyle_bg_color'] ) ) ); } if ( isset( $_POST['affistyle_btn_color'] ) ) { update_post_meta( $post_id, '_affistyle_btn_color', sanitize_hex_color( wp_unslash( $_POST['affistyle_btn_color'] ) ) ); } if ( isset( $_POST['affistyle_pros'] ) ) { update_post_meta( $post_id, '_affistyle_pros', sanitize_textarea_field( wp_unslash( $_POST['affistyle_pros'] ) ) ); } if ( isset( $_POST['affistyle_cons'] ) ) { update_post_meta( $post_id, '_affistyle_cons', sanitize_textarea_field( wp_unslash( $_POST['affistyle_cons'] ) ) ); } if ( isset( $_POST['affistyle_rating_score'] ) ) { $score = floatval( wp_unslash( $_POST['affistyle_rating_score'] ) ); $score = max( 0.0, min( 5.0, $score ) ); update_post_meta( $post_id, '_affistyle_rating_score', $score ); } if ( isset( $_POST['affistyle_review_count'] ) ) { update_post_meta( $post_id, '_affistyle_review_count', sanitize_text_field( wp_unslash( $_POST['affistyle_review_count'] ) ) ); } $show_rating = isset( $_POST['affistyle_show_rating'] ) ? '1' : '0'; update_post_meta( $post_id, '_affistyle_show_rating', $show_rating ); // 6. Save Product 1 specific fields. if ( isset( $_POST['affistyle_title_1'] ) ) { update_post_meta( $post_id, '_affistyle_title_1', sanitize_text_field( wp_unslash( $_POST['affistyle_title_1'] ) ) ); } if ( isset( $_POST['affistyle_image_1'] ) ) { $img_url_1 = esc_url_raw( wp_unslash( $_POST['affistyle_image_1'] ) ); update_post_meta( $post_id, '_affistyle_image_1', $img_url_1 ); update_post_meta( $post_id, '_affistyle_image_url', $img_url_1 ); } if ( isset( $_POST['affistyle_destination'] ) ) { $sanitized_dest = esc_url_raw( wp_unslash( $_POST['affistyle_destination'] ) ); update_post_meta( $post_id, '_affistyle_destination', $sanitized_dest ); update_post_meta( $post_id, '_affistyle_url_default', $sanitized_dest ); } elseif ( isset( $_POST['affistyle_url_default'] ) ) { $sanitized_dest = esc_url_raw( wp_unslash( $_POST['affistyle_url_default'] ) ); update_post_meta( $post_id, '_affistyle_destination', $sanitized_dest ); update_post_meta( $post_id, '_affistyle_url_default', $sanitized_dest ); } } } new AffiStyle_CPT();