'object', 'properties' => array( 'type' => array( 'enum' => array( 'subtotal' ) ), 'operator' => array( 'type' => 'string', 'enum' => self::OPERATORS, ), 'min' => array( 'type' => 'string' ), 'max' => array( 'type' => 'string' ), ), ); } /** * {@inheritDoc} */ public function context_dependencies(): array { return array( 'subtotal' ); } /** * {@inheritDoc} * * @param array $condition Raw condition. */ public function sanitize( array $condition ): array { $operator = (string) ( $condition['operator'] ?? 'between' ); return array( 'type' => 'subtotal', 'operator' => in_array( $operator, self::OPERATORS, true ) ? $operator : 'between', 'min' => $this->bound( $condition['min'] ?? '' ), 'max' => $this->bound( $condition['max'] ?? '' ), ); } /** * Optional non-negative decimal bound ('' = no bound). * * @param mixed $value Raw value. */ private function bound( mixed $value ): string { if ( ! is_scalar( $value ) || '' === trim( (string) $value ) ) { return ''; } return (string) wc_format_decimal( max( 0.0, (float) wc_format_decimal( (string) $value ) ), wc_get_price_decimals() ); } /** * {@inheritDoc} * * @param array $condition Condition. * @param Context $context Context. * @param RuleEvaluator $evaluator Evaluator. */ public function matches( array $condition, Context $context, RuleEvaluator $evaluator ): bool { $subtotal = $context->subtotal(); $min = (string) ( $condition['min'] ?? '' ); $max = (string) ( $condition['max'] ?? '' ); $operator = (string) ( $condition['operator'] ?? 'between' ); $above_min = '' === $min || $subtotal >= (float) $min; $below_max = '' === $max || $subtotal <= (float) $max; return match ( $operator ) { 'gte' => $above_min, 'lte' => $below_max, default => $above_min && $below_max, }; } }