mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-02 21:41:19 +08:00
Fix #18712: Added $scheme option to yii\i18n\Formatter::asUrl()
This commit is contained in:
@ -12,6 +12,7 @@ Yii Framework 2 Change Log
|
||||
- Enh #18676: Added method `yii\helpers\BaseFileHelper::changeOwnership()` and properties `newFileMode`/`newFileOwnership` in `yii\console\controllers\BaseMigrateController` (rhertogh)
|
||||
- Bug #18678: Fix `yii\caching\DbCache` to use configured cache table name instead of the default one in case of MSSQL varbinary column type detection (aidanbek)
|
||||
- Enh #18695: Added `yii\web\Cookie::SAME_SITE_NONE` constant (rhertogh)
|
||||
- Enh #18712: Added `$scheme` option to `yii\i18n\Formatter::asUrl()` (bizley)
|
||||
- Bug #18648: Fix `yii\web\Request` to properly handle HTTP Basic Auth headers (olegbaturin)
|
||||
- Enh #18726: Added `yii\helpers\Json::$prettyPrint` (rhertogh)
|
||||
|
||||
|
||||
@ -210,7 +210,7 @@ class Formatter extends Component
|
||||
*/
|
||||
public $calendar;
|
||||
/**
|
||||
* @var string the character displayed as the decimal point when formatting a number.
|
||||
* @var string|null the character displayed as the decimal point when formatting a number.
|
||||
* If not set, the decimal separator corresponding to [[locale]] will be used.
|
||||
* If [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available, the default value is '.'.
|
||||
*/
|
||||
@ -223,7 +223,7 @@ class Formatter extends Component
|
||||
*/
|
||||
public $currencyDecimalSeparator;
|
||||
/**
|
||||
* @var string the character displayed as the thousands separator (also called grouping separator) character when formatting a number.
|
||||
* @var string|null the character displayed as the thousands separator (also called grouping separator) character when formatting a number.
|
||||
* If not set, the thousand separator corresponding to [[locale]] will be used.
|
||||
* If [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available, the default value is ','.
|
||||
*/
|
||||
@ -286,7 +286,7 @@ class Formatter extends Component
|
||||
*/
|
||||
public $numberFormatterSymbols = [];
|
||||
/**
|
||||
* @var string the 3-letter ISO 4217 currency code indicating the default currency to use for [[asCurrency]].
|
||||
* @var string|null the 3-letter ISO 4217 currency code indicating the default currency to use for [[asCurrency]].
|
||||
* If not set, the currency code corresponding to [[locale]] will be used.
|
||||
* Note that in this case the [[locale]] has to be specified with a country code, e.g. `en-US` otherwise it
|
||||
* is not possible to determine the default currency.
|
||||
@ -443,8 +443,9 @@ class Formatter extends Component
|
||||
public function format($value, $format)
|
||||
{
|
||||
if ($format instanceof Closure) {
|
||||
return call_user_func($format, $value, $this);
|
||||
} elseif (is_array($format)) {
|
||||
return $format($value, $this);
|
||||
}
|
||||
if (is_array($format)) {
|
||||
if (!isset($format[0])) {
|
||||
throw new InvalidArgumentException('The $format array must contain at least one element.');
|
||||
}
|
||||
@ -463,10 +464,8 @@ class Formatter extends Component
|
||||
throw new InvalidArgumentException("Unknown format type: $format");
|
||||
}
|
||||
|
||||
|
||||
// simple formats
|
||||
|
||||
|
||||
/**
|
||||
* Formats the value as is without any formatting.
|
||||
* This method simply returns back the parameter without any format.
|
||||
@ -578,16 +577,30 @@ class Formatter extends Component
|
||||
* Formats the value as a hyperlink.
|
||||
* @param mixed $value the value to be formatted.
|
||||
* @param array $options the tag options in terms of name-value pairs. See [[Html::a()]].
|
||||
* @param bool|string $scheme the URI scheme to use in the formatted hyperlink (available since 2.0.43):
|
||||
*
|
||||
* - `false (default)`: adding non-secure protocol scheme if there is none added already
|
||||
* - `true`: adding secure protocol scheme if there is none added already
|
||||
* - string: adding the specified scheme (either `http`, `https` or empty string
|
||||
* for protocol-relative URL) if there is none added already
|
||||
*
|
||||
* @return string the formatted result.
|
||||
*/
|
||||
public function asUrl($value, $options = [])
|
||||
public function asUrl($value, $options = [], $scheme = false)
|
||||
{
|
||||
if ($value === null) {
|
||||
return $this->nullDisplay;
|
||||
}
|
||||
$url = $value;
|
||||
|
||||
if (strpos($url, '://') === false) {
|
||||
$url = 'http://' . $url;
|
||||
if ($scheme === false || $scheme === 'http') {
|
||||
$url = 'http://' . $url;
|
||||
} elseif ($scheme === true || $scheme === 'https') {
|
||||
$url = 'https://' . $url;
|
||||
} elseif ($scheme === '') {
|
||||
$url = '//' . $url;
|
||||
}
|
||||
}
|
||||
|
||||
return Html::a(Html::encode($value), $url, $options);
|
||||
@ -608,10 +621,8 @@ class Formatter extends Component
|
||||
return $value ? $this->booleanFormat[1] : $this->booleanFormat[0];
|
||||
}
|
||||
|
||||
|
||||
// date and time formats
|
||||
|
||||
|
||||
/**
|
||||
* Formats the value as a date.
|
||||
* @param int|string|DateTime|DateTimeInterface $value the value to be formatted. The following
|
||||
@ -754,7 +765,7 @@ class Formatter extends Component
|
||||
// avoid time zone conversion for date-only and time-only values
|
||||
if ($type === 'date' || $type === 'time') {
|
||||
list($timestamp, $hasTimeInfo, $hasDateInfo) = $this->normalizeDatetimeValue($value, true);
|
||||
if ($type === 'date' && !$hasTimeInfo || $type === 'time' && !$hasDateInfo) {
|
||||
if (($type === 'date' && !$hasTimeInfo) || ($type === 'time' && !$hasDateInfo)) {
|
||||
$timeZone = $this->defaultTimeZone;
|
||||
}
|
||||
} else {
|
||||
@ -772,18 +783,41 @@ class Formatter extends Component
|
||||
}
|
||||
if (isset($this->_dateFormats[$format])) {
|
||||
if ($type === 'date') {
|
||||
$formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], IntlDateFormatter::NONE, $timeZone, $this->calendar);
|
||||
$formatter = new IntlDateFormatter(
|
||||
$this->locale,
|
||||
$this->_dateFormats[$format],
|
||||
IntlDateFormatter::NONE,
|
||||
$timeZone,
|
||||
$this->calendar
|
||||
);
|
||||
} elseif ($type === 'time') {
|
||||
$formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, $this->_dateFormats[$format], $timeZone, $this->calendar);
|
||||
$formatter = new IntlDateFormatter(
|
||||
$this->locale,
|
||||
IntlDateFormatter::NONE,
|
||||
$this->_dateFormats[$format],
|
||||
$timeZone,
|
||||
$this->calendar
|
||||
);
|
||||
} else {
|
||||
$formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], $this->_dateFormats[$format], $timeZone, $this->calendar);
|
||||
$formatter = new IntlDateFormatter(
|
||||
$this->locale,
|
||||
$this->_dateFormats[$format],
|
||||
$this->_dateFormats[$format],
|
||||
$timeZone,
|
||||
$this->calendar
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $timeZone, $this->calendar, $format);
|
||||
}
|
||||
if ($formatter === null) {
|
||||
throw new InvalidConfigException(intl_get_error_message());
|
||||
$formatter = new IntlDateFormatter(
|
||||
$this->locale,
|
||||
IntlDateFormatter::NONE,
|
||||
IntlDateFormatter::NONE,
|
||||
$timeZone,
|
||||
$this->calendar,
|
||||
$format
|
||||
);
|
||||
}
|
||||
|
||||
// make IntlDateFormatter work with DateTimeImmutable
|
||||
if ($timestamp instanceof \DateTimeImmutable) {
|
||||
$timestamp = new DateTime($timestamp->format(DateTime::ISO8601), $timestamp->getTimezone());
|
||||
@ -824,7 +858,7 @@ class Formatter extends Component
|
||||
* timestamp, the second a boolean indicating whether the timestamp has time information and third a boolean indicating
|
||||
* whether the timestamp has date information.
|
||||
* This parameter is available since version 2.0.1.
|
||||
* @return DateTime|array the normalized datetime value.
|
||||
* @return DateTime|array the normalized datetime value
|
||||
* Since version 2.0.1 this may also return an array if `$checkDateTimeInfo` is true.
|
||||
* The first element of the array is the normalized timestamp and the second is a boolean indicating whether
|
||||
* the timestamp has time information or it is just a date value.
|
||||
@ -846,9 +880,23 @@ class Formatter extends Component
|
||||
if (is_numeric($value)) { // process as unix timestamp, which is always in UTC
|
||||
$timestamp = new DateTime('@' . (int) $value, new DateTimeZone('UTC'));
|
||||
return $checkDateTimeInfo ? [$timestamp, true, true] : $timestamp;
|
||||
} elseif (($timestamp = DateTime::createFromFormat('Y-m-d|', $value, new DateTimeZone($this->defaultTimeZone))) !== false) { // try Y-m-d format (support invalid dates like 2012-13-01)
|
||||
}
|
||||
if (
|
||||
($timestamp = DateTime::createFromFormat(
|
||||
'Y-m-d|',
|
||||
$value,
|
||||
new DateTimeZone($this->defaultTimeZone))
|
||||
) !== false
|
||||
) { // try Y-m-d format (support invalid dates like 2012-13-01)
|
||||
return $checkDateTimeInfo ? [$timestamp, false, true] : $timestamp;
|
||||
} elseif (($timestamp = DateTime::createFromFormat('Y-m-d H:i:s', $value, new DateTimeZone($this->defaultTimeZone))) !== false) { // try Y-m-d H:i:s format (support invalid dates like 2012-13-01 12:63:12)
|
||||
}
|
||||
if (
|
||||
($timestamp = DateTime::createFromFormat(
|
||||
'Y-m-d H:i:s',
|
||||
$value,
|
||||
new DateTimeZone($this->defaultTimeZone))
|
||||
) !== false
|
||||
) { // try Y-m-d H:i:s format (support invalid dates like 2012-13-01 12:63:12)
|
||||
return $checkDateTimeInfo ? [$timestamp, true, true] : $timestamp;
|
||||
}
|
||||
// finally try to create a DateTime object with the value
|
||||
@ -923,30 +971,17 @@ class Formatter extends Component
|
||||
$interval = $value;
|
||||
} else {
|
||||
$timestamp = $this->normalizeDatetimeValue($value);
|
||||
$timeZone = new DateTimeZone($this->timeZone);
|
||||
|
||||
if ($timestamp === false) {
|
||||
// $value is not a valid date/time value, so we try
|
||||
// to create a DateInterval with it
|
||||
try {
|
||||
$interval = new DateInterval($value);
|
||||
} catch (\Exception $e) {
|
||||
// invalid date/time and invalid interval
|
||||
return $this->nullDisplay;
|
||||
}
|
||||
if ($referenceTime === null) {
|
||||
$dateNow = new DateTime('now', $timeZone);
|
||||
} else {
|
||||
$timeZone = new DateTimeZone($this->timeZone);
|
||||
|
||||
if ($referenceTime === null) {
|
||||
$dateNow = new DateTime('now', $timeZone);
|
||||
} else {
|
||||
$dateNow = $this->normalizeDatetimeValue($referenceTime);
|
||||
$dateNow->setTimezone($timeZone);
|
||||
}
|
||||
|
||||
$dateThen = $timestamp->setTimezone($timeZone);
|
||||
|
||||
$interval = $dateThen->diff($dateNow);
|
||||
$dateNow = $this->normalizeDatetimeValue($referenceTime);
|
||||
$dateNow->setTimezone($timeZone);
|
||||
}
|
||||
|
||||
$dateThen = $timestamp->setTimezone($timeZone);
|
||||
$interval = $dateThen->diff($dateNow);
|
||||
}
|
||||
|
||||
if ($interval->invert) {
|
||||
@ -1213,7 +1248,8 @@ class Formatter extends Component
|
||||
* If not given, the number of digits depends in the input value and is determined based on
|
||||
* `NumberFormatter::MIN_FRACTION_DIGITS` and `NumberFormatter::MAX_FRACTION_DIGITS`, which can be configured
|
||||
* using [[$numberFormatterOptions]].
|
||||
* If the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available, the default value depends on your PHP configuration.
|
||||
* If the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available, the default value
|
||||
* depends on your PHP configuration.
|
||||
* If you want consistent behavior between environments where intl is available and not, you should explicitly
|
||||
* specify a value here.
|
||||
* @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]].
|
||||
@ -1497,7 +1533,7 @@ class Formatter extends Component
|
||||
*/
|
||||
public function asLength($value, $decimals = null, $numberOptions = [], $textOptions = [])
|
||||
{
|
||||
return $this->formatUnit(self::UNIT_LENGTH, self::FORMAT_WIDTH_LONG, $value, null, null, $decimals, $numberOptions, $textOptions);
|
||||
return $this->formatUnit(self::UNIT_LENGTH, self::FORMAT_WIDTH_LONG, $value, $decimals, $numberOptions, $textOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1520,7 +1556,7 @@ class Formatter extends Component
|
||||
*/
|
||||
public function asShortLength($value, $decimals = null, $options = [], $textOptions = [])
|
||||
{
|
||||
return $this->formatUnit(self::UNIT_LENGTH, self::FORMAT_WIDTH_SHORT, $value, null, null, $decimals, $options, $textOptions);
|
||||
return $this->formatUnit(self::UNIT_LENGTH, self::FORMAT_WIDTH_SHORT, $value, $decimals, $options, $textOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1540,7 +1576,7 @@ class Formatter extends Component
|
||||
*/
|
||||
public function asWeight($value, $decimals = null, $options = [], $textOptions = [])
|
||||
{
|
||||
return $this->formatUnit(self::UNIT_WEIGHT, self::FORMAT_WIDTH_LONG, $value, null, null, $decimals, $options, $textOptions);
|
||||
return $this->formatUnit(self::UNIT_WEIGHT, self::FORMAT_WIDTH_LONG, $value, $decimals, $options, $textOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1562,38 +1598,29 @@ class Formatter extends Component
|
||||
*/
|
||||
public function asShortWeight($value, $decimals = null, $options = [], $textOptions = [])
|
||||
{
|
||||
return $this->formatUnit(self::UNIT_WEIGHT, self::FORMAT_WIDTH_SHORT, $value, null, null, $decimals, $options, $textOptions);
|
||||
return $this->formatUnit(self::UNIT_WEIGHT, self::FORMAT_WIDTH_SHORT, $value, $decimals, $options, $textOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $unitType one of [[UNIT_WEIGHT]], [[UNIT_LENGTH]]
|
||||
* @param string $unitFormat one of [[FORMAT_WIDTH_SHORT]], [[FORMAT_WIDTH_LONG]]
|
||||
* @param float|int|null $value to be formatted
|
||||
* @param float $baseUnit unit of value as the multiplier of the smallest unit. When `null`, property [[baseUnits]]
|
||||
* will be used to determine base unit using $unitType and $unitSystem.
|
||||
* @param string $unitSystem either [[UNIT_SYSTEM_METRIC]] or [[UNIT_SYSTEM_IMPERIAL]]. When `null`, property [[systemOfUnits]] will be used.
|
||||
* @param int $decimals the number of digits after the decimal point.
|
||||
* @param int|null $decimals the number of digits after the decimal point.
|
||||
* @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]].
|
||||
* @param array $textOptions optional configuration for the number formatter. This parameter will be merged with [[numberFormatterTextOptions]].
|
||||
* @return string
|
||||
* @throws InvalidConfigException when INTL is not installed or does not contain required information
|
||||
*/
|
||||
private function formatUnit($unitType, $unitFormat, $value, $baseUnit, $unitSystem, $decimals, $options, $textOptions)
|
||||
private function formatUnit($unitType, $unitFormat, $value, $decimals, $options, $textOptions)
|
||||
{
|
||||
if ($value === null) {
|
||||
return $this->nullDisplay;
|
||||
}
|
||||
if ($unitSystem === null) {
|
||||
$unitSystem = $this->systemOfUnits;
|
||||
}
|
||||
if ($baseUnit === null) {
|
||||
$baseUnit = $this->baseUnits[$unitType][$unitSystem];
|
||||
}
|
||||
|
||||
$multipliers = array_values($this->measureUnits[$unitType][$unitSystem]);
|
||||
$multipliers = array_values($this->measureUnits[$unitType][$this->systemOfUnits]);
|
||||
|
||||
list($params, $position) = $this->formatNumber(
|
||||
$this->normalizeNumericValue($value) * $baseUnit,
|
||||
$this->normalizeNumericValue($value) * $this->baseUnits[$unitType][$this->systemOfUnits],
|
||||
$decimals,
|
||||
null,
|
||||
$multipliers,
|
||||
@ -1601,7 +1628,7 @@ class Formatter extends Component
|
||||
$textOptions
|
||||
);
|
||||
|
||||
$message = $this->getUnitMessage($unitType, $unitFormat, $unitSystem, $position);
|
||||
$message = $this->getUnitMessage($unitType, $unitFormat, $this->systemOfUnits, $position);
|
||||
|
||||
return (new \MessageFormatter($this->locale, $message))->format([
|
||||
'0' => $params['nFormatted'],
|
||||
@ -1638,7 +1665,10 @@ class Formatter extends Component
|
||||
|
||||
$unitBundle = $this->_resourceBundle[$bundleKey][$unitType][$unitNames[$position]];
|
||||
if ($unitBundle === null) {
|
||||
throw new InvalidConfigException('Current ICU data version does not contain information about unit type "' . $unitType . '" and unit measure "' . $unitNames[$position] . '". Check system requirements.');
|
||||
throw new InvalidConfigException(
|
||||
'Current ICU data version does not contain information about unit type "' . $unitType
|
||||
. '" and unit measure "' . $unitNames[$position] . '". Check system requirements.'
|
||||
);
|
||||
}
|
||||
|
||||
$message = [];
|
||||
@ -1656,7 +1686,7 @@ class Formatter extends Component
|
||||
* Given the value in bytes formats number part of the human readable form.
|
||||
*
|
||||
* @param string|int|float $value value in bytes to be formatted.
|
||||
* @param int $decimals the number of digits after the decimal point
|
||||
* @param int|null $decimals the number of digits after the decimal point
|
||||
* @param int $maxPosition maximum internal position of size unit, ignored if $formatBase is an array
|
||||
* @param array|int $formatBase the base at which each next unit is calculated, either 1000 or 1024, or an array
|
||||
* @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]].
|
||||
@ -1881,7 +1911,7 @@ class Formatter extends Component
|
||||
* to the defined decimal digits.
|
||||
*
|
||||
* @param string|int|float $value the value to be formatted.
|
||||
* @param int $decimals the number of digits after the decimal point. The default value is `2`.
|
||||
* @param int|null $decimals the number of digits after the decimal point. The default value is `2`.
|
||||
* @return string the formatted result.
|
||||
* @see decimalSeparator
|
||||
* @see thousandSeparator
|
||||
|
||||
Reference in New Issue
Block a user