answer( $event_id, $event_name, $status, $date_from, $date_to, $group_by ); } /** * Work out the answer. * * @param int|null $event_id Event ID. * @param string|null $event_name Event title. * @param string|null $status Booking status. * @param string|null $date_from First day, Y-m-d. * @param string|null $date_to Last day, Y-m-d. * @param string|null $group_by Split. * @return array */ private function answer( ?int $event_id, ?string $event_name, ?string $status, ?string $date_from, ?string $date_to, ?string $group_by ): array { $check = $this->guard( 'etn_manage_order' ); if ( $check ) { return $check; } $page = $this->page( __( 'Bookings', 'aisentic' ), '/bookings' ); $status = trim( (string) $status ); $group_by = ( null === $group_by || '' === $group_by ) ? 'none' : $group_by; if ( '' !== $status && ! in_array( $status, self::STATUSES, true ) ) { return $this->unclear( "\"{$status}\" is not a booking status.", $page, self::STATUSES ); } if ( ! in_array( $group_by, self::GROUPS, true ) ) { return $this->unclear( "Cannot split bookings by \"{$group_by}\".", $page, self::GROUPS ); } $from = $this->read_date( $date_from ); $to = $this->read_date( $date_to ); if ( false === $from || false === $to ) { return $this->unclear( 'The date could not be read. Dates must be YYYY-MM-DD.', $page ); } if ( null !== $from && null !== $to && $from > $to ) { return $this->unclear( "The start date {$from} is after the end date {$to}.", $page ); } list( $event_id, $event_title, $stop ) = $this->resolve_event( $event_id, $event_name, $page ); if ( null !== $stop ) { return $stop; } try { $filters = array_filter( [ 'event_id' => $event_id, 'status' => $status, 'date_from' => $from, 'date_to' => $to, ] ); $counts = $this->query->count_records( 'booking', $filters, 'none' === $group_by ? '' : $group_by ); $result = [ 'status' => 'ok', 'total' => $counts['total'], 'filters' => $filters + ( '' !== $event_title ? [ 'event_title' => $event_title ] : [] ), 'page' => $event_id ? $this->event_page( $event_id, $event_title ) : $page, ]; if ( 'none' !== $group_by ) { $result += $this->split( $counts['groups'], $group_by ); } return $result; } catch ( \Throwable $e ) { Log::error( 'Eventin_Count_Bookings_Tool error', [ 'error' => $e->getMessage() ] ); return [ 'error' => 'Could not count bookings: ' . $e->getMessage() ]; } } /** * Shape the split for the model. * * @param array $groups Raw groups. * @param string $group_by Split. * @return array */ private function split( array $groups, string $group_by ): array { if ( 'event' !== $group_by ) { return [ 'by_' . $group_by => $groups ]; } list( $kept, $folded, $others ) = $this->top_groups( $groups ); $result = [ 'by_event' => $this->named_event_groups( $kept ) ]; if ( $folded > 0 ) { $result['other_events'] = [ 'events' => $folded, 'bookings' => $others, 'note' => 'Only the 10 events with the most bookings are listed.', ]; } return $result; } }