'booking', 'plural' => 'bookings', 'ajax' => false, ) ); $this->status_filter = $status_filter; } public function get_columns() { return array( 'cb' => '', 'full_name' => esc_html__( 'Name', 'ab-veh-take' ), 'contact' => esc_html__( 'Contact', 'ab-veh-take' ), 'journey_type' => esc_html__( 'Journey Type', 'ab-veh-take' ), 'route' => esc_html__( 'Route', 'ab-veh-take' ), 'num_passengers' => esc_html__( 'People', 'ab-veh-take' ), 'vehicle_type' => esc_html__( 'Vehicle', 'ab-veh-take' ), 'schedule' => esc_html__( 'Date & Time', 'ab-veh-take' ), 'status' => esc_html__( 'Status', 'ab-veh-take' ), 'created_at' => esc_html__( 'Submitted', 'ab-veh-take' ), ); } public function get_sortable_columns() { return array( 'full_name' => array( 'full_name', false ), 'created_at' => array( 'created_at', true ), 'schedule' => array( 'booking_date', false ), 'status' => array( 'status', false ), ); } protected function column_cb( $item ) { return sprintf( '', $item->id ); } protected function column_full_name( $item ) { $actions = array(); if ( 'pending' === $item->status ) { $actions['approve'] = sprintf( '%s', esc_url( $this->row_action_url( 'approve', $item->id ) ), esc_html__( 'Approve', 'ab-veh-take' ) ); } else { $actions['pending'] = sprintf( '%s', esc_url( $this->row_action_url( 'pending', $item->id ) ), esc_html__( 'Mark Pending', 'ab-veh-take' ) ); } $actions['delete'] = sprintf( '%s', esc_url( $this->row_action_url( 'delete', $item->id ) ), esc_js( __( 'Delete this booking permanently?', 'ab-veh-take' ) ), esc_html__( 'Delete', 'ab-veh-take' ) ); return sprintf( '%1$s%2$s', esc_html( $item->full_name ), $this->row_actions( $actions ) ); } protected function column_contact( $item ) { $out = esc_html( $item->email ); if ( ! empty( $item->phone ) ) { $out .= '
' . esc_html( $item->phone ) . ''; } return $out; } protected function column_journey_type( $item ) { return 'multistop' === $item->journey_type ? '' . esc_html__( 'Multi-Stop', 'ab-veh-take' ) . '' : '' . esc_html__( 'One-Way', 'ab-veh-take' ) . ''; } protected function column_route( $item ) { if ( 'multistop' === $item->journey_type ) { $stops = json_decode( $item->stops, true ); if ( is_array( $stops ) && ! empty( $stops ) ) { $lines = array(); foreach ( $stops as $i => $stop ) { $lines[] = ( $i + 1 ) . '. ' . esc_html( $stop['address'] ?? '' ); } return implode( '
', $lines ); } return esc_html__( '—', 'ab-veh-take' ); } return esc_html( $item->pickup_address ) . '
→ ' . esc_html( $item->destination_address ); } protected function column_schedule( $item ) { $date = $item->booking_date ? date_i18n( 'M j, Y', strtotime( $item->booking_date ) ) : esc_html__( '—', 'ab-veh-take' ); $time = $item->booking_time ? date_i18n( 'g:i A', strtotime( $item->booking_time ) ) : ''; return esc_html( trim( $date . ' ' . $time ) ); } protected function column_status( $item ) { $class = 'pending' === $item->status ? 'actb-status-pending' : 'actb-status-approved'; return '' . esc_html( ucfirst( $item->status ) ) . ''; } protected function column_created_at( $item ) { return esc_html( date_i18n( 'M j, Y g:i A', strtotime( $item->created_at ) ) ); } protected function column_num_passengers( $item ) { return $item->num_passengers ? esc_html( $item->num_passengers ) : esc_html__( '—', 'ab-veh-take' ); } protected function column_vehicle_type( $item ) { return $item->vehicle_type ? esc_html( $item->vehicle_type ) : esc_html__( '—', 'ab-veh-take' ); } protected function column_default( $item, $column_name ) { return isset( $item->$column_name ) ? esc_html( $item->$column_name ) : ''; } public function get_bulk_actions() { return array( 'bulk_approve' => esc_html__( 'Approve', 'ab-veh-take' ), 'bulk_pending' => esc_html__( 'Mark Pending', 'ab-veh-take' ), 'bulk_delete' => esc_html__( 'Delete', 'ab-veh-take' ), ); } private function row_action_url( $action, $id ) { return add_query_arg( array( 'page' => 'ab-veh-take-bookings', 'abvt_action' => $action, 'booking_id' => $id, '_wpnonce' => wp_create_nonce( 'abvt_row_action_' . $id ), ), admin_url( 'admin.php' ) ); } public function prepare_items() { $per_page = 20; $paged = isset( $_REQUEST['paged'] ) ? max( 1, absint( wp_unslash( $_REQUEST['paged'] ) ) ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $search = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $orderby = isset( $_REQUEST['orderby'] ) ? sanitize_key( wp_unslash( $_REQUEST['orderby'] ) ) : 'created_at'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $order = isset( $_REQUEST['order'] ) ? sanitize_key( wp_unslash( $_REQUEST['order'] ) ) : 'desc'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( 'schedule' === $orderby ) { $orderby = 'booking_date'; } $args = array( 'status' => $this->status_filter, 'per_page' => $per_page, 'paged' => $paged, 'search' => $search, 'orderby' => $orderby, 'order' => $order, ); $this->items = AB_Veh_Take_DB::get_bookings( $args ); $total_items = AB_Veh_Take_DB::count_bookings( array( 'status' => $this->status_filter, 'search' => $search ) ); $this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() ); $this->set_pagination_args( array( 'total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil( $total_items / $per_page ), ) ); } }