owner_id < 1 ) { throw new DomainException( 'schedule.owner_id', 'owner_id must be positive.' ); } if ( $this->day_of_week < 0 || $this->day_of_week > 6 ) { throw new DomainException( 'schedule.day_of_week', 'day_of_week must be 0–6.' ); } $this->start_local = self::normalise_time( $this->start_local ); $this->end_local = self::normalise_time( $this->end_local ); if ( $this->end_local === $this->start_local ) { throw new DomainException( 'schedule.range', 'end_local must not equal start_local.' ); } if ( null !== $this->valid_from && null !== $this->valid_until && $this->valid_until < $this->valid_from ) { throw new DomainException( 'schedule.validity', 'valid_until must be on or after valid_from.' ); } } /** * Constructor. * * @param string $time Time string. * @return string HH:MM:SS * * @throws DomainException When invalid. */ private static function normalise_time( string $time ): string { $time = trim( $time ); if ( 1 === preg_match( '/^\d{2}:\d{2}$/', $time ) ) { $time .= ':00'; } if ( 1 !== preg_match( '/^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$/', $time ) ) { throw new DomainException( 'schedule.time_invalid', 'Time must be HH:MM or HH:MM:SS.' ); } return $time; } /** * Database id. * * @since 0.1.0 */ public function id(): ?int { return $this->id; } /** * Owner type. * * @since 0.1.0 */ public function owner_type(): ScheduleOwnerType { return $this->owner_type; } /** * Owner id. * * @since 0.1.0 */ public function owner_id(): int { return $this->owner_id; } /** * Day of week. * * @since 0.1.0 */ public function day_of_week(): int { return $this->day_of_week; } /** * Start local. * * @since 0.1.0 */ public function start_local(): string { return $this->start_local; } /** * End local. * * @since 0.1.0 */ public function end_local(): string { return $this->end_local; } /** * Valid from. * * @since 0.1.0 */ public function valid_from(): ?DateTimeImmutable { return $this->valid_from; } /** * Valid until. * * @since 0.1.0 */ public function valid_until(): ?DateTimeImmutable { return $this->valid_until; } /** * Assign the database id after insert. * * @param int $id New id. * * @throws \Bookline\Domain\Shared\DomainException When id is already set or invalid. * * @since 0.1.0 */ public function assign_id( int $id ): void { if ( null !== $this->id ) { throw new DomainException( 'schedule.id_assigned', 'Schedule id is already assigned.' ); } $this->id = $id; } /** * Whether this weekly row applies on a local calendar date (Y-m-d). * * @param string $date_local Local date Y-m-d. */ public function is_valid_on( string $date_local ): bool { if ( null !== $this->valid_from && $date_local < $this->valid_from->format( 'Y-m-d' ) ) { return false; } if ( null !== $this->valid_until && $date_local > $this->valid_until->format( 'Y-m-d' ) ) { return false; } return true; } }