| @@ -711,10 +711,10 @@ | ||
| 711 | 711 | public static function replaceShortcodeInErrorMsg($msg, $field) |
| 712 | 712 | { |
| 713 | 713 | $shortcodes = [ |
| 714 | 714 | '${field.label}' => isset($field->lbl) ? $field->lbl : '', |
| 715 | - '${field.minimum}' => isset($field->mn) ? $field->mn : '', | |
| 716 | - '${field.maximum}' => isset($field->mx) ? $field->mx : '', | |
| 715 | + '${field.minimum}' => isset($field->mn) ? self::readableRangeValue($field->mn, isset($field->typ) ? $field->typ : '') : '', | |
| 716 | + '${field.maximum}' => isset($field->mx) ? self::readableRangeValue($field->mx, isset($field->typ) ? $field->typ : '') : '', | |
| 717 | 717 | '${field.minimum_file}' => isset($field->config->minFile) ? $field->config->minFile : '', |
| 718 | 718 | '${field.maximum_file}' => isset($field->config->maxFile) ? $field->config->maxFile : '', |
| 719 | 719 | '${field.maximum_size}' => isset($field->config->maxSize) ? $field->config->maxSize : '', |
| 720 | 720 | '${field.minimum_amount}' => isset($field->config->minValue) ? $field->config->minValue : '', |
| @@ -721,8 +721,58 @@ | ||
| 721 | 721 | '${field.maximum_amount}' => isset($field->config->maxValue) ? $field->config->maxValue : '', |
| 722 | 722 | ]; |
| 723 | 723 | $msg = str_replace(array_keys($shortcodes), array_values($shortcodes), $msg); |
| 724 | 724 | return $msg; |
| 725 | + } | |
| 726 | + | |
| 727 | + /** | |
| 728 | + * Date-like min/max are stored in the input's wire format (2026-10-01T09:00, 2026-W40); show | |
| 729 | + * them to visitors in the site's date/time format instead. Anything else is returned as is. | |
| 730 | + * | |
| 731 | + * @param mixed $value field mn/mx | |
| 732 | + * @param string $type field type | |
| 733 | + * | |
| 734 | + * @return mixed | |
| 735 | + */ | |
| 736 | + public static function readableRangeValue($value, $type) | |
| 737 | + { | |
| 738 | + if (!is_string($value) || '' === $value) { | |
| 739 | + return $value; | |
| 740 | + } | |
| 741 | + $dateFormat = (string) get_option('date_format', 'F j, Y'); | |
| 742 | + $timeFormat = (string) get_option('time_format', 'g:i a'); | |
| 743 | + $utc = new \DateTimeZone('UTC'); | |
| 744 | + $formatTimestamp = function ($format, $timestamp) use ($utc) { | |
| 745 | + return function_exists('wp_date') ? wp_date($format, $timestamp, $utc) : gmdate($format, $timestamp); | |
| 746 | + }; | |
| 747 | + | |
| 748 | + switch ($type) { | |
| 749 | + case 'date': | |
| 750 | + $date = \DateTime::createFromFormat('!Y-m-d', $value, $utc); | |
| 751 | + return $date ? $formatTimestamp($dateFormat, $date->getTimestamp()) : $value; | |
| 752 | + | |
| 753 | + case 'datetime-local': | |
| 754 | + $date = \DateTime::createFromFormat('!Y-m-d\TH:i', substr($value, 0, 16), $utc); | |
| 755 | + return $date ? $formatTimestamp($dateFormat . ' ' . $timeFormat, $date->getTimestamp()) : $value; | |
| 756 | + | |
| 757 | + case 'time': | |
| 758 | + $date = \DateTime::createFromFormat('!H:i', substr($value, 0, 5), $utc); | |
| 759 | + return $date ? $formatTimestamp($timeFormat, $date->getTimestamp()) : $value; | |
| 760 | + | |
| 761 | + case 'month': | |
| 762 | + $date = \DateTime::createFromFormat('!Y-m', $value, $utc); | |
| 763 | + return $date ? $formatTimestamp('F Y', $date->getTimestamp()) : $value; | |
| 764 | + | |
| 765 | + case 'week': | |
| 766 | + if (1 === preg_match('/^(\d{4})-W(\d{1,2})$/i', $value, $match)) { | |
| 767 | + // translators: 1: ISO week number, 2: year | |
| 768 | + return sprintf(__('week %1$d of %2$d', 'bit-form'), (int) $match[2], (int) $match[1]); | |
| 769 | + } | |
| 770 | + return $value; | |
| 771 | + | |
| 772 | + default: | |
| 773 | + return $value; | |
| 774 | + } | |
| 725 | 775 | } |
| 726 | 776 | |
| 727 | 777 | public static function getDefaultGlobalMessages() |
| 728 | 778 | { |