'object', 'properties' => array( 'start' => array( 'type' => 'string' ), 'end' => array( 'type' => 'string' ), ), ); } /** * Gets the default value for a newly created condition of this type. * * @return mixed */ public function default_value() { return array( 'start' => '00:00', 'end' => '23:59', ); } /** * Evaluates the condition against the given context. * * @param Context $context Request context value object. * @param string $operator Operator identifier. * @param mixed $value Configured value. * @return bool */ public function evaluate( Context $context, string $operator, $value ): bool { $start = $this->to_minutes( $value['start'] ?? null ); $end = $this->to_minutes( $value['end'] ?? null ); if ( null === $start || null === $end ) { return true; // Invalid range — fail open. } $now = ( (int) $context->datetime->format( 'H' ) ) * 60 + (int) $context->datetime->format( 'i' ); if ( $start <= $end ) { $in = ( $now >= $start && $now <= $end ); } else { $in = ( $now >= $start || $now <= $end ); // Overnight range. } return 'not_between' === $operator ? ! $in : $in; } /** * Parses an HH:MM string into minutes since midnight. * * @param mixed $value Time string. * @return int|null */ private function to_minutes( $value ): ?int { if ( ! is_string( $value ) || ! preg_match( '/^([01]?\d|2[0-3]):([0-5]\d)$/', $value, $m ) ) { return null; } return (int) $m[1] * 60 + (int) $m[2]; } }