/** * Business Review System * Handles customer reviews, ratings, comments, moderation, * frontend submission/display, and paid-business owner responses. * * Uses the existing "business_review" CPT throughout. */ if ( ! defined( 'ABSPATH' ) ) { exit; } // ============================================================ // REGISTER BUSINESS REVIEW CPT // ============================================================ function bicol_register_review_cpt() { $labels = array( 'name' => 'Business Reviews', 'singular_name' => 'Business Review', 'menu_name' => 'Reviews', 'name_admin_bar' => 'Review', 'add_new' => 'Add New', 'add_new_item' => 'Add New Review', 'new_item' => 'New Review', 'edit_item' => 'Edit Review', 'view_item' => 'View Review', 'all_items' => 'All Reviews', 'search_items' => 'Search Reviews', 'not_found' => 'No reviews found.', 'not_found_in_trash' => 'No reviews found in Trash.', ); $args = array( 'labels' => $labels, 'description' => 'Customer reviews for businesses', 'public' => false, 'publicly_queryable' => false, 'show_ui' => true, 'show_in_menu' => true, 'show_in_nav_menus' => false, 'show_in_rest' => true, 'has_archive' => false, 'rewrite' => false, 'menu_position' => 6, 'menu_icon' => 'dashicons-star-filled', 'supports' => array( 'title', 'editor', 'author' ), 'capability_type' => 'post', ); register_post_type( 'business_review', $args ); } add_action( 'init', 'bicol_register_review_cpt' ); // ============================================================ // REGISTER BUSINESS REVIEW META FIELDS // ============================================================ function bicol_register_review_meta() { $fields = array( '_business_id' => 'integer', '_rating' => 'integer', '_reviewer_email' => 'string', '_reviewer_name' => 'string', '_visit_date' => 'string', '_is_approved' => 'boolean', '_is_featured' => 'boolean', '_is_pinned' => 'boolean', '_reply_from_owner' => 'string', '_response' => 'string', '_response_date' => 'integer', '_verified' => 'boolean', ); foreach ( $fields as $key => $type ) { register_post_meta( 'business_review', $key, array( 'type' => $type, 'single' => true, 'show_in_rest' => true, 'sanitize_callback' => 'bicol_sanitize_review_meta', 'auth_callback' => 'bicol_review_meta_auth_callback', ) ); } } add_action( 'init', 'bicol_register_review_meta', 11 ); function bicol_sanitize_review_meta( $value, $meta_key = '' ) { switch ( $meta_key ) { case '_business_id': case '_rating': case '_response_date': return absint( $value ); case '_reviewer_email': return sanitize_email( $value ); case '_visit_date': return sanitize_text_field( $value ); case '_is_approved': case '_is_featured': case '_is_pinned': case '_verified': return ! empty( $value ) ? 1 : 0; case '_reply_from_owner': case '_response': return sanitize_textarea_field( $value ); default: return sanitize_text_field( $value ); } } function bicol_review_meta_auth_callback( $allowed, $meta_key, $post_id, $user_id ) { if ( current_user_can( 'manage_options' ) ) { return true; } $business_id = absint( get_post_meta( $post_id, '_business_id', true ) ); if ( $business_id ) { $business = get_post( $business_id ); if ( $business && (int) $business->post_author === (int) $user_id ) { return true; } } return false; } // ============================================================ // ADMIN REVIEW META BOX // ============================================================ function bicol_add_review_metabox() { add_meta_box( 'bicol_review_details', 'Review Details', 'bicol_review_metabox_callback', 'business_review', 'normal', 'default' ); } add_action( 'add_meta_boxes', 'bicol_add_review_metabox' ); function bicol_review_metabox_callback( $post ) { wp_nonce_field( 'bicol_save_review_meta', 'bicol_review_nonce' ); $business_id = get_post_meta( $post->ID, '_business_id', true ); $rating = get_post_meta( $post->ID, '_rating', true ); $reviewer_email = get_post_meta( $post->ID, '_reviewer_email', true ); $reviewer_name = get_post_meta( $post->ID, '_reviewer_name', true ); $visit_date = get_post_meta( $post->ID, '_visit_date', true ); $is_approved = get_post_meta( $post->ID, '_is_approved', true ); $is_featured = get_post_meta( $post->ID, '_is_featured', true ); $is_pinned = get_post_meta( $post->ID, '_is_pinned', true ); $owner_reply = get_post_meta( $post->ID, '_reply_from_owner', true ); $response = get_post_meta( $post->ID, '_response', true ); $response_date = get_post_meta( $post->ID, '_response_date', true ); $verified = get_post_meta( $post->ID, '_verified', true ); if ( empty( $response ) && ! empty( $owner_reply ) ) { $response = $owner_reply; } ?>