forms->find_by_id( $form_id ); if ( null === $form || BookingFormStatus::Active !== $form->status() ) { return null; } return $form; } /** * Ensure a form exists and accepts new sessions. * * @param int $form_id Form id. * * @throws DomainException When missing or inactive. */ public function assert_bookable( int $form_id ): void { if ( $form_id <= 0 ) { return; } $form = $this->forms->find_by_id( $form_id ); if ( null === $form ) { throw new DomainException( 'booking_form.not_found', 'Booking form not found.' ); } if ( BookingFormStatus::Active !== $form->status() ) { throw new DomainException( 'booking_form.inactive', 'This booking form is not accepting bookings.' ); } } /** * Whether a service is offered on this form. * * @param BookingForm|null $form Form (null = unrestricted). * @param Service $service Service. */ public function service_allowed( ?BookingForm $form, Service $service ): bool { if ( null === $form ) { return true; } $service_ids = $form->service_ids(); $category_ids = $form->category_ids(); if ( ( null === $service_ids || [] === $service_ids ) && ( null === $category_ids || [] === $category_ids ) ) { return true; } $id = $service->id(); if ( null !== $id && null !== $service_ids && [] !== $service_ids && in_array( $id, $service_ids, true ) ) { return true; } $category_id = $service->category_id(); if ( null !== $category_id && null !== $category_ids && [] !== $category_ids && in_array( $category_id, $category_ids, true ) ) { return true; } return false; } /** * Whether an agent is offered on this form. * * @param BookingForm|null $form Form. * @param Agent $agent Agent. */ public function agent_allowed( ?BookingForm $form, Agent $agent ): bool { if ( null === $form ) { return true; } $ids = $form->agent_ids(); if ( null === $ids || [] === $ids ) { return true; } $id = $agent->id(); return null !== $id && in_array( $id, $ids, true ); } /** * Whether a location is offered on this form. * * @param BookingForm|null $form Form. * @param Location $location Location. */ public function location_allowed( ?BookingForm $form, Location $location ): bool { if ( null === $form ) { return true; } $ids = $form->location_ids(); if ( null === $ids || [] === $ids ) { return true; } $id = $location->id(); return null !== $id && in_array( $id, $ids, true ); } /** * Count active agents eligible for the form. * * @param BookingForm|null $form Form. */ public function count_eligible_agents( ?BookingForm $form ): int { return $this->count_eligible_agents_for_lists( $form?->agent_ids() ); } /** * Count active locations eligible for the form. * * @param BookingForm|null $form Form. */ public function count_eligible_locations( ?BookingForm $form ): int { return $this->count_eligible_locations_for_lists( $form?->location_ids() ); } /** * Active agents for an id list (null = all active). * * @param list|null $scoped_ids Agent ids. * @return list> */ public function agents_for_lists( ?array $scoped_ids ): array { $out = []; foreach ( $this->agents->find_active( 100, 0 ) as $agent ) { if ( ! $this->id_allowed( $scoped_ids, $agent->id() ) ) { continue; } $out[] = [ 'id' => $agent->id(), 'name' => $agent->display_name(), 'bio' => $agent->bio(), 'avatar_url' => null, ]; } return $out; } /** * Active locations for an id list (null = all active). * * @param list|null $scoped_ids Location ids. * @return list> */ public function locations_for_lists( ?array $scoped_ids ): array { $out = []; foreach ( $this->locations->find_active( 100, 0 ) as $location ) { if ( ! $this->id_allowed( $scoped_ids, $location->id() ) ) { continue; } $out[] = [ 'id' => $location->id(), 'name' => $location->name(), 'address_line1' => $location->address_line1(), 'city' => $location->city(), 'postcode' => $location->postcode(), 'country' => $location->country(), ]; } return $out; } /** * Count active agents eligible for scoped id lists. * * @param list|null $agent_ids Agent ids. */ public function count_eligible_agents_for_lists( ?array $agent_ids ): int { return count( $this->agents_for_lists( $agent_ids ) ); } /** * Count active locations eligible for scoped id lists. * * @param list|null $location_ids Location ids. */ public function count_eligible_locations_for_lists( ?array $location_ids ): int { return count( $this->locations_for_lists( $location_ids ) ); } /** * Whether an entity id is allowed by an optional scope list. * * @param list|null $scoped_ids Scope list. * @param int|null $id Entity id. */ private function id_allowed( ?array $scoped_ids, ?int $id ): bool { if ( null === $scoped_ids || [] === $scoped_ids ) { return true; } return null !== $id && in_array( $id, $scoped_ids, true ); } /** * Active agents for a form's scope, formatted for step descriptors. * * @param BookingForm|null $form Form. * @return list> */ public function agents_for_descriptor( ?BookingForm $form ): array { return $this->agents_for_lists( $form?->agent_ids() ); } /** * Active locations for a form's scope, formatted for step descriptors. * * @param BookingForm|null $form Form. * @return list> */ public function locations_for_descriptor( ?BookingForm $form ): array { return $this->locations_for_lists( $form?->location_ids() ); } }