admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'ab_veh_take_availability_nonce' ), 'labels' => array( 'wide' => AB_Veh_Take_Settings::get( 'label_wide' ), 'limited' => AB_Veh_Take_Settings::get( 'label_limited' ), 'scarce' => AB_Veh_Take_Settings::get( 'label_scarce' ), 'unavailable' => AB_Veh_Take_Settings::get( 'label_unavailable' ), ), ); wp_localize_script( 'abvt-availability-admin', 'ABVT_AVAIL_DATA', $avail_data ); } } /* --------------------------------------------------------------- * Manage Availability page * ------------------------------------------------------------- */ public function render_availability_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } ?>

maybe_handle_row_action(); $this->maybe_handle_bulk_action(); $status_filter = isset( $_GET['status'] ) ? sanitize_key( wp_unslash( $_GET['status'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['view'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $this->render_single_booking( absint( $_GET['view'] ) ); return; } $table = new AB_Veh_Take_List_Table( $status_filter ); $table->prepare_items(); $count_all = AB_Veh_Take_DB::count_bookings(); $count_pending = AB_Veh_Take_DB::count_by_status( 'pending' ); $count_approved = AB_Veh_Take_DB::count_by_status( 'approved' ); ?>


search_box( __( 'Search bookings', 'ab-veh-take' ), 'actb-search' ); ?> display(); ?>

' . esc_html__( 'Booking not found.', 'ab-veh-take' ) . '

'; return; } ?>

full_name ) ); ?>

←

journey_type ) : $stops = json_decode( $booking->stops, true ); ?>
status ) ); ?>
journey_type ) ); ?>
pickup_address ); ?>
destination_address ); ?>
booking_date ); ?>
booking_time ); ?>
num_passengers ? esc_html( $booking->num_passengers ) : esc_html__( '—', 'ab-veh-take' ); ?>
vehicle_type ? esc_html( $booking->vehicle_type ) : esc_html__( '—', 'ab-veh-take' ); ?>
full_name ); ?>
email ); ?>
phone ); ?>
created_at ) ) ); ?>

status ) : ?>

$redirect_notice ), remove_query_arg( array( 'abvt_action', 'booking_id', '_wpnonce', 'view' ) ) ) ); exit; } } private function maybe_handle_bulk_action() { // Capability check must come first, before reading any request data. if ( ! current_user_can( 'manage_options' ) ) { return; } // Checks both $_POST and $_GET so bulk actions succeed with
$booking_ids = isset( $_REQUEST['booking_ids'] ) ? wp_unslash( $_REQUEST['booking_ids'] ) : array(); if ( empty( $booking_ids ) || ! is_array( $booking_ids ) ) { return; } check_admin_referer( 'bulk-bookings' ); $action = ''; $primary_action = isset( $_REQUEST['action'] ) && is_scalar( $_REQUEST['action'] ) ? sanitize_key( wp_unslash( $_REQUEST['action'] ) ) : ''; $secondary_action = isset( $_REQUEST['action2'] ) && is_scalar( $_REQUEST['action2'] ) ? sanitize_key( wp_unslash( $_REQUEST['action2'] ) ) : ''; if ( $primary_action && '-1' !== $primary_action ) { $action = $primary_action; } elseif ( $secondary_action && '-1' !== $secondary_action ) { $action = $secondary_action; } if ( ! $action ) { return; } $ids = array_map( 'absint', $booking_ids ); $redirect_notice = ''; foreach ( $ids as $id ) { if ( 'bulk_approve' === $action ) { AB_Veh_Take_DB::update_status( $id, 'approved' ); $redirect_notice = 'bulk_approved'; } elseif ( 'bulk_pending' === $action ) { AB_Veh_Take_DB::update_status( $id, 'pending' ); $redirect_notice = 'bulk_marked_pending'; } elseif ( 'bulk_delete' === $action ) { AB_Veh_Take_DB::delete_booking( $id ); $redirect_notice = 'bulk_deleted'; } } $redirect_url = wp_get_referer(); $target_url = $redirect_url ? remove_query_arg( array( 'abvt_notice' ), $redirect_url ) : admin_url( 'admin.php?page=ab-veh-take-bookings' ); if ( $redirect_notice ) { $target_url = add_query_arg( array( 'abvt_notice' => $redirect_notice ), $target_url ); } wp_safe_redirect( $target_url ); exit; } public function admin_notices() { $notice = isset( $_GET['abvt_notice'] ) ? sanitize_key( wp_unslash( $_GET['abvt_notice'] ) ) : ''; if ( empty( $notice ) ) { return; } $messages = array( 'approved' => __( 'Booking approved.', 'ab-veh-take' ), 'marked_pending' => __( 'Booking marked as pending.', 'ab-veh-take' ), 'deleted' => __( 'Booking deleted.', 'ab-veh-take' ), 'bulk_approved' => __( 'Selected bookings approved.', 'ab-veh-take' ), 'bulk_marked_pending' => __( 'Selected bookings marked as pending.', 'ab-veh-take' ), 'bulk_deleted' => __( 'Selected bookings deleted.', 'ab-veh-take' ), 'saved' => __( 'Settings saved.', 'ab-veh-take' ), 'reset' => __( 'Colors reset to default.', 'ab-veh-take' ), 'layout_reset' => __( 'Layout and typography reset to default.', 'ab-veh-take' ), 'test_email_sent' => __( 'Test email sent successfully. Check the inbox for the Admin Notification Email address.', 'ab-veh-take' ), 'test_email_failed' => __( 'The test email could not be sent. Your server\'s mail (wp_mail) configuration is likely blocking delivery — check your hosting/SMTP setup.', 'ab-veh-take' ), ); if ( isset( $messages[ $notice ] ) ) { $css_class = 'test_email_failed' === $notice ? 'notice-error' : 'notice-success'; echo '

' . esc_html( $messages[ $notice ] ) . '

'; } } /* --------------------------------------------------------------- * Settings page * ------------------------------------------------------------- */ public function render_settings_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } $settings = AB_Veh_Take_Settings::get_all(); ?>


$field ) : ?>


$field ) : ?>

isset( $_POST['notification_email'] ) && is_scalar( $_POST['notification_email'] ) ? sanitize_email( wp_unslash( $_POST['notification_email'] ) ) : '', ); if ( empty( $data['notification_email'] ) || ! is_email( $data['notification_email'] ) ) { $data['notification_email'] = get_option( 'admin_email' ); } if ( isset( $_POST['vehicle_types'] ) && is_array( $_POST['vehicle_types'] ) ) { $vehicle_types = array_map( 'sanitize_text_field', array_filter( wp_unslash( $_POST['vehicle_types'] ), 'is_scalar' ) ); $vehicle_types = array_values( array_unique( array_filter( array_map( 'trim', $vehicle_types ) ) ) ); $data['vehicle_types'] = ! empty( $vehicle_types ) ? $vehicle_types : AB_Veh_Take_Settings::default_vehicle_types(); } else { // When all vehicle rows are removed by admin, reset to defaults $data['vehicle_types'] = AB_Veh_Take_Settings::default_vehicle_types(); } foreach ( AB_Veh_Take_Settings::layout_fields() as $key => $field ) { if ( isset( $_POST[ $key ] ) && is_scalar( $_POST[ $key ] ) ) { $value = intval( $_POST[ $key ] ); $value = max( $field['min'], min( $field['max'], $value ) ); $data[ $key ] = $value; } } foreach ( AB_Veh_Take_Settings::text_fields() as $key => $field ) { if ( isset( $_POST[ $key ] ) && is_scalar( $_POST[ $key ] ) ) { $text = sanitize_text_field( wp_unslash( $_POST[ $key ] ) ); $data[ $key ] = '' !== $text ? $text : $field['default']; } } foreach ( AB_Veh_Take_Settings::content_fields() as $key => $field ) { if ( isset( $_POST[ $key ] ) && is_scalar( $_POST[ $key ] ) ) { $text = sanitize_text_field( wp_unslash( $_POST[ $key ] ) ); $data[ $key ] = '' !== $text ? $text : $field['default']; } } foreach ( AB_Veh_Take_Settings::typography_fields() as $key => $field ) { if ( isset( $_POST[ $key ] ) && is_scalar( $_POST[ $key ] ) ) { $value = sanitize_text_field( wp_unslash( $_POST[ $key ] ) ); if ( 'font_family' === $key ) { $data[ $key ] = preg_replace( '/[^a-zA-Z0-9 ,_-]/', '', $value ); } elseif ( false !== strpos( $key, 'weight' ) ) { $data[ $key ] = in_array( $value, array( '300', '400', '500', '600', '700', '800', '900' ), true ) ? $value : $field['default']; } else { $number = (float) $value; $data[ $key ] = max( $field['min'], min( $field['max'], $number ) ); } } } foreach ( AB_Veh_Take_Settings::color_fields() as $key => $field ) { if ( isset( $_POST[ $key ] ) && is_scalar( $_POST[ $key ] ) ) { $color = sanitize_hex_color( wp_unslash( $_POST[ $key ] ) ); $data[ $key ] = $color ? $color : $field['default']; } } AB_Veh_Take_Settings::update( $data ); wp_safe_redirect( add_query_arg( array( 'page' => 'ab-veh-take-settings', 'abvt_notice' => 'saved' ), admin_url( 'admin.php' ) ) ); exit; } public function reset_colors() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Not allowed.', 'ab-veh-take' ) ); } $nonce = isset( $_POST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'abvt_reset_colors_nonce' ) ) { wp_die( esc_html__( 'Security check failed.', 'ab-veh-take' ) ); } AB_Veh_Take_Settings::reset_colors(); wp_safe_redirect( add_query_arg( array( 'page' => 'ab-veh-take-settings', 'abvt_notice' => 'reset' ), admin_url( 'admin.php' ) ) ); exit; } public function reset_layout() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Not allowed.', 'ab-veh-take' ) ); } $nonce = isset( $_POST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'abvt_reset_layout_nonce' ) ) { wp_die( esc_html__( 'Security check failed.', 'ab-veh-take' ) ); } AB_Veh_Take_Settings::reset_layout(); wp_safe_redirect( add_query_arg( array( 'page' => 'ab-veh-take-settings', 'abvt_notice' => 'layout_reset' ), admin_url( 'admin.php' ) ) ); exit; } public function send_test_email() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Not allowed.', 'ab-veh-take' ) ); } $nonce = isset( $_POST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'abvt_send_test_email_nonce' ) ) { wp_die( esc_html__( 'Security check failed.', 'ab-veh-take' ) ); } $result = AB_Veh_Take_Emails::send_test_email(); $notice = $result['sent'] ? 'test_email_sent' : 'test_email_failed'; wp_safe_redirect( add_query_arg( array( 'page' => 'ab-veh-take-settings', 'abvt_notice' => $notice ), admin_url( 'admin.php' ) ) ); exit; } }