>, total: int, page: int, per_page: int} * * @since 0.1.0 */ public function handle( int $page, int $per_page, ?string $search = null ): array { $per_page = max( 1, min( 100, $per_page ) ); $page = max( 1, $page ); $offset = ( $page - 1 ) * $per_page; $result = $this->customers->find_all( $per_page, $offset, $search ); $ids = []; foreach ( $result['items'] as $customer ) { $id = $customer->id(); if ( null !== $id ) { $ids[] = $id; } } $summaries = $this->bookings->summarise_for_customers( $ids ); $items = []; foreach ( $result['items'] as $customer ) { $items[] = $this->to_admin_array( $customer, $summaries ); } return [ 'items' => $items, 'total' => $result['total'], 'page' => $page, 'per_page' => $per_page, ]; } /** * Map a customer entity to the admin API shape. * * @param Customer $customer Customer entity. * @param array $summaries Booking summaries. * @return array */ private function to_admin_array( Customer $customer, array $summaries ): array { $display = trim( $customer->first_name() . ' ' . ( $customer->last_name() ?? '' ) ); $id = $customer->id(); $summary = null !== $id && isset( $summaries[ $id ] ) ? $summaries[ $id ] : null; return [ 'id' => $id, 'uuid' => $customer->uuid()->to_string(), 'display_name' => '' !== $display ? $display : $customer->first_name(), 'email' => $customer->email()->to_string(), 'phone' => $customer->phone()?->to_string(), 'status' => $customer->status()->value, 'created_at' => $customer->created_at()->format( 'c' ), 'bookings_count' => null !== $summary ? $summary['count'] : 0, 'first_booking_at' => null !== $summary ? $summary['first_start']->format( 'c' ) : null, ]; } }