first commit

This commit is contained in:
2026-01-25 18:18:09 +08:00
commit 509312e604
8136 changed files with 2349298 additions and 0 deletions

View File

@ -0,0 +1,21 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* ArrayHelper provides additional array functionality that you can use in your
* application.
*
* For more details and usage information on ArrayHelper, see the [guide article on array helpers](guide:helper-array).
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class ArrayHelper extends BaseArrayHelper
{
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,558 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
use IntlDateFormatter;
use Yii;
/**
* BaseFormatConverter provides concrete implementation for [[FormatConverter]].
*
* Do not use BaseFormatConverter. Use [[FormatConverter]] instead.
*
* @author Carsten Brandt <mail@cebe.cc>
* @author Enrica Ruedin <e.ruedin@guggach.com>
* @since 2.0
*/
class BaseFormatConverter
{
/**
* @var array the php fallback definition to use for the ICU short patterns `short`, `medium`, `long` and `full`.
* This is used as fallback when the `intl` extension is not installed.
*/
public static $phpFallbackDatePatterns = [
'short' => [
'date' => 'n/j/y',
'time' => 'H:i',
'datetime' => 'n/j/y H:i',
],
'medium' => [
'date' => 'M j, Y',
'time' => 'g:i:s A',
'datetime' => 'M j, Y g:i:s A',
],
'long' => [
'date' => 'F j, Y',
'time' => 'g:i:sA',
'datetime' => 'F j, Y g:i:sA',
],
'full' => [
'date' => 'l, F j, Y',
'time' => 'g:i:sA T',
'datetime' => 'l, F j, Y g:i:sA T',
],
];
/**
* @var array the jQuery UI fallback definition to use for the ICU short patterns `short`, `medium`, `long` and `full`.
* This is used as fallback when the `intl` extension is not installed.
*/
public static $juiFallbackDatePatterns = [
'short' => [
'date' => 'd/m/y',
'time' => '',
'datetime' => 'd/m/y',
],
'medium' => [
'date' => 'M d, yy',
'time' => '',
'datetime' => 'M d, yy',
],
'long' => [
'date' => 'MM d, yy',
'time' => '',
'datetime' => 'MM d, yy',
],
'full' => [
'date' => 'DD, MM d, yy',
'time' => '',
'datetime' => 'DD, MM d, yy',
],
];
private static $_icuShortFormats = [
'short' => 3, // IntlDateFormatter::SHORT,
'medium' => 2, // IntlDateFormatter::MEDIUM,
'long' => 1, // IntlDateFormatter::LONG,
'full' => 0, // IntlDateFormatter::FULL,
];
/**
* Converts a date format pattern from [ICU format](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax)
* to [PHP `date()` function format](https://www.php.net/manual/en/function.date).
*
* The conversion is limited to date patterns that do not use escaped characters.
* Patterns like `d 'of' MMMM yyyy` which will result in a date like `1 of December 2014` may not be converted correctly
* because of the use of escaped characters.
*
* Pattern constructs that are not supported by the PHP format will be removed.
*
* @param string $pattern date format pattern in ICU format.
* @param string $type 'date', 'time', or 'datetime'.
* @param string|null $locale the locale to use for converting ICU short patterns `short`, `medium`, `long` and `full`.
* If not given, `Yii::$app->language` will be used.
* @return string The converted date format pattern.
* @throws \Exception
*/
public static function convertDateIcuToPhp($pattern, $type = 'date', $locale = null)
{
if (isset(self::$_icuShortFormats[$pattern])) {
if (extension_loaded('intl')) {
$pattern = self::createFormatter($locale, $type, $pattern);
} else {
return static::$phpFallbackDatePatterns[$pattern][$type];
}
}
// https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax
// escaped text
$escaped = [];
if (preg_match_all('/(?<!\')\'(.*?[^\'])\'(?!\')/', $pattern, $matches, PREG_SET_ORDER)) {
foreach ($matches as $match) {
$match[1] = str_replace('\'\'', '\'', $match[1]);
$escaped[$match[0]] = '\\' . implode('\\', preg_split('//u', $match[1], -1, PREG_SPLIT_NO_EMPTY));
}
}
return strtr($pattern, array_merge($escaped, [
"''" => "\\'", // two single quotes produce one
'G' => '', // era designator like (Anno Domini)
'Y' => 'o', // 4digit year of "Week of Year"
'y' => 'Y', // 4digit year e.g. 2014
'yyyy' => 'Y', // 4digit year e.g. 2014
'yy' => 'y', // 2digit year number eg. 14
'u' => '', // extended year e.g. 4601
'U' => '', // cyclic year name, as in Chinese lunar calendar
'r' => '', // related Gregorian year e.g. 1996
'Q' => '', // number of quarter
'QQ' => '', // number of quarter '02'
'QQQ' => '', // quarter 'Q2'
'QQQQ' => '', // quarter '2nd quarter'
'QQQQQ' => '', // number of quarter '2'
'q' => '', // number of Stand Alone quarter
'qq' => '', // number of Stand Alone quarter '02'
'qqq' => '', // Stand Alone quarter 'Q2'
'qqqq' => '', // Stand Alone quarter '2nd quarter'
'qqqqq' => '', // number of Stand Alone quarter '2'
'M' => 'n', // Numeric representation of a month, without leading zeros
'MM' => 'm', // Numeric representation of a month, with leading zeros
'MMM' => 'M', // A short textual representation of a month, three letters
'MMMM' => 'F', // A full textual representation of a month, such as January or March
'MMMMM' => '',
'L' => 'n', // Stand alone month in year
'LL' => 'm', // Stand alone month in year
'LLL' => 'M', // Stand alone month in year
'LLLL' => 'F', // Stand alone month in year
'LLLLL' => '', // Stand alone month in year
'w' => 'W', // ISO-8601 week number of year
'ww' => 'W', // ISO-8601 week number of year
'W' => '', // week of the current month
'd' => 'j', // day without leading zeros
'dd' => 'd', // day with leading zeros
'D' => 'z', // day of the year 0 to 365
'F' => '', // Day of Week in Month. eg. 2nd Wednesday in July
'g' => '', // Modified Julian day. This is different from the conventional Julian day number in two regards.
'E' => 'D', // day of week written in short form eg. Sun
'EE' => 'D',
'EEE' => 'D',
'EEEE' => 'l', // day of week fully written eg. Sunday
'EEEEE' => '',
'EEEEEE' => '',
'e' => 'N', // ISO-8601 numeric representation of the day of the week 1=Mon to 7=Sun
'ee' => 'N', // php 'w' 0=Sun to 6=Sat isn't supported by ICU -> 'w' means week number of year
'eee' => 'D',
'eeee' => 'l',
'eeeee' => '',
'eeeeee' => '',
'c' => 'N', // ISO-8601 numeric representation of the day of the week 1=Mon to 7=Sun
'cc' => 'N', // php 'w' 0=Sun to 6=Sat isn't supported by ICU -> 'w' means week number of year
'ccc' => 'D',
'cccc' => 'l',
'ccccc' => '',
'cccccc' => '',
'a' => 'A', // AM/PM marker
'h' => 'g', // 12-hour format of an hour without leading zeros 1 to 12h
'hh' => 'h', // 12-hour format of an hour with leading zeros, 01 to 12 h
'H' => 'G', // 24-hour format of an hour without leading zeros 0 to 23h
'HH' => 'H', // 24-hour format of an hour with leading zeros, 00 to 23 h
'k' => '', // hour in day (1~24)
'kk' => '', // hour in day (1~24)
'K' => '', // hour in am/pm (0~11)
'KK' => '', // hour in am/pm (0~11)
'm' => 'i', // Minutes without leading zeros, not supported by php but we fallback
'mm' => 'i', // Minutes with leading zeros
's' => 's', // Seconds, without leading zeros, not supported by php but we fallback
'ss' => 's', // Seconds, with leading zeros
'S' => '', // fractional second
'SS' => '', // fractional second
'SSS' => '', // fractional second
'SSSS' => '', // fractional second
'A' => '', // milliseconds in day
'z' => 'T', // Timezone abbreviation
'zz' => 'T', // Timezone abbreviation
'zzz' => 'T', // Timezone abbreviation
'zzzz' => 'T', // Timezone full name, not supported by php but we fallback
'Z' => 'O', // Difference to Greenwich time (GMT) in hours
'ZZ' => 'O', // Difference to Greenwich time (GMT) in hours
'ZZZ' => 'O', // Difference to Greenwich time (GMT) in hours
'ZZZZ' => '\G\M\TP', // Time Zone: long localized GMT (=OOOO) e.g. GMT-08:00
'ZZZZZ' => '', // TIme Zone: ISO8601 extended hms? (=XXXXX)
'O' => '', // Time Zone: short localized GMT e.g. GMT-8
'OOOO' => '\G\M\TP', // Time Zone: long localized GMT (=ZZZZ) e.g. GMT-08:00
'v' => '\G\M\TP', // Time Zone: generic non-location (falls back first to VVVV and then to OOOO) using the ICU defined fallback here
'vvvv' => '\G\M\TP', // Time Zone: generic non-location (falls back first to VVVV and then to OOOO) using the ICU defined fallback here
'V' => '', // Time Zone: short time zone ID
'VV' => 'e', // Time Zone: long time zone ID
'VVV' => '', // Time Zone: time zone exemplar city
'VVVV' => '\G\M\TP', // Time Zone: generic location (falls back to OOOO) using the ICU defined fallback here
'X' => '', // Time Zone: ISO8601 basic hm?, with Z for 0, e.g. -08, +0530, Z
'XX' => 'O, \Z', // Time Zone: ISO8601 basic hm, with Z, e.g. -0800, Z
'XXX' => 'P, \Z', // Time Zone: ISO8601 extended hm, with Z, e.g. -08:00, Z
'XXXX' => '', // Time Zone: ISO8601 basic hms?, with Z, e.g. -0800, -075258, Z
'XXXXX' => '', // Time Zone: ISO8601 extended hms?, with Z, e.g. -08:00, -07:52:58, Z
'x' => '', // Time Zone: ISO8601 basic hm?, without Z for 0, e.g. -08, +0530
'xx' => 'O', // Time Zone: ISO8601 basic hm, without Z, e.g. -0800
'xxx' => 'P', // Time Zone: ISO8601 extended hm, without Z, e.g. -08:00
'xxxx' => '', // Time Zone: ISO8601 basic hms?, without Z, e.g. -0800, -075258
'xxxxx' => '', // Time Zone: ISO8601 extended hms?, without Z, e.g. -08:00, -07:52:58
]));
}
/**
* Converts a date format pattern from [PHP `date()` function format](https://www.php.net/manual/en/function.date)
* to [ICU format](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax).
*
* Pattern constructs that are not supported by the ICU format will be removed.
*
* Since 2.0.13 it handles escaped characters correctly.
*
* @param string $pattern date format pattern in PHP `date()` function format.
* @return string The converted date format pattern.
*/
public static function convertDatePhpToIcu($pattern)
{
// https://www.php.net/manual/en/function.date
$result = strtr($pattern, [
"'" => "''''", // single `'` should be encoded as `''`, which internally should be encoded as `''''`
// Day
'\d' => "'d'",
'd' => 'dd', // Day of the month, 2 digits with leading zeros — 01 to 31
'\D' => "'D'",
'D' => 'eee', // A textual representation of a day, three letters — Mon through Sun
'\j' => "'j'",
'j' => 'd', // Day of the month without leading zeros — 1 to 31
'\l' => "'l'",
'l' => 'eeee', // A full textual representation of the day of the week — Sunday through Saturday
'\N' => "'N'",
'N' => 'e', // ISO-8601 numeric representation of the day of the week, 1 (for Monday) through 7 (for Sunday)
'\S' => "'S'",
'S' => '', // English ordinal suffix for the day of the month, 2 characters — st, nd, rd or th. Works well with j
'\w' => "'w'",
'w' => '', // Numeric representation of the day of the week — 0 (for Sunday) through 6 (for Saturday)
'\z' => "'z'",
'z' => 'D', // The day of the year (starting from 0) — 0 through 365
// Week
'\W' => "'W'",
'W' => 'w', // ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) — Example: 42 (the 42nd week in the year)
// Month
'\F' => "'F'",
'F' => 'MMMM', // A full textual representation of a month, January through December
'\m' => "'m'",
'm' => 'MM', // Numeric representation of a month, with leading zeros — 01 through 12
'\M' => "'M'",
'M' => 'MMM', // A short textual representation of a month, three letters — Jan through Dec
'\n' => "'n'",
'n' => 'M', // Numeric representation of a month, without leading zeros — 1 through 12, not supported by ICU but we fallback to "with leading zero"
'\t' => "'t'",
't' => '', // Number of days in the given month — 28 through 31
// Year
'\L' => "'L'",
'L' => '', // Whether it's a leap year, 1 if it is a leap year, 0 otherwise.
'\o' => "'o'",
'o' => 'Y', // ISO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead.
'\Y' => "'Y'",
'Y' => 'yyyy', // A full numeric representation of a year, 4 digits — Examples: 1999 or 2003
'\y' => "'y'",
'y' => 'yy', // A two digit representation of a year — Examples: 99 or 03
// Time
'\a' => "'a'",
'a' => 'a', // Lowercase Ante meridiem and Post meridiem, am or pm
'\A' => "'A'",
'A' => 'a', // Uppercase Ante meridiem and Post meridiem, AM or PM, not supported by ICU but we fallback to lowercase
'\B' => "'B'",
'B' => '', // Swatch Internet time — 000 through 999
'\g' => "'g'",
'g' => 'h', // 12-hour format of an hour without leading zeros — 1 through 12
'\G' => "'G'",
'G' => 'H', // 24-hour format of an hour without leading zeros 0 to 23h
'\h' => "'h'",
'h' => 'hh', // 12-hour format of an hour with leading zeros, 01 to 12 h
'\H' => "'H'",
'H' => 'HH', // 24-hour format of an hour with leading zeros, 00 to 23 h
'\i' => "'i'",
'i' => 'mm', // Minutes with leading zeros — 00 to 59
'\s' => "'s'",
's' => 'ss', // Seconds, with leading zeros — 00 through 59
'\u' => "'u'",
'u' => '', // Microseconds. Example: 654321
// Timezone
'\e' => "'e'",
'e' => 'VV', // Timezone identifier. Examples: UTC, GMT, Atlantic/Azores
'\I' => "'I'",
'I' => '', // Whether or not the date is in daylight saving time, 1 if Daylight Saving Time, 0 otherwise.
'\O' => "'O'",
'O' => 'xx', // Difference to Greenwich time (GMT) in hours, Example: +0200
'\P' => "'P'",
'P' => 'xxx', // Difference to Greenwich time (GMT) with colon between hours and minutes, Example: +02:00
'\T' => "'T'",
'T' => 'zzz', // Timezone abbreviation, Examples: EST, MDT ...
'\Z' => "'Z'",
'Z' => '', // Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. -43200 through 50400
// Full Date/Time
'\c' => "'c'",
'c' => "yyyy-MM-dd'T'HH:mm:ssxxx", // ISO 8601 date, e.g. 2004-02-12T15:19:21+00:00
'\r' => "'r'",
'r' => 'eee, dd MMM yyyy HH:mm:ss xx', // RFC 2822 formatted date, Example: Thu, 21 Dec 2000 16:01:07 +0200
'\U' => "'U'",
'U' => '', // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
'\\\\' => '\\',
]);
// remove `''` - they're result of consecutive escaped chars (`\A\B` will be `'A''B'`, but should be `'AB'`)
// real `'` are encoded as `''''`
return strtr($result, [
"''''" => "''",
"''" => '',
]);
}
/**
* Converts a date format pattern from [ICU format](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax)
* to [jQuery UI date format](https://api.jqueryui.com/datepicker/#utility-formatDate).
*
* Pattern constructs that are not supported by the jQuery UI format will be removed.
*
* @param string $pattern date format pattern in ICU format.
* @param string $type 'date', 'time', or 'datetime'.
* @param string|null $locale the locale to use for converting ICU short patterns `short`, `medium`, `long` and `full`.
* If not given, `Yii::$app->language` will be used.
* @return string The converted date format pattern.
* @throws \Exception
*/
public static function convertDateIcuToJui($pattern, $type = 'date', $locale = null)
{
if (isset(self::$_icuShortFormats[$pattern])) {
if (extension_loaded('intl')) {
$pattern = self::createFormatter($locale, $type, $pattern);
} else {
return static::$juiFallbackDatePatterns[$pattern][$type];
}
}
// https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax
// escaped text
$escaped = [];
if (preg_match_all('/(?<!\')\'.*?[^\']\'(?!\')/', $pattern, $matches)) {
foreach ($matches[0] as $match) {
$escaped[$match] = $match;
}
}
return strtr($pattern, array_merge($escaped, [
'G' => '', // era designator like (Anno Domini)
'Y' => '', // 4digit year of "Week of Year"
'y' => 'yy', // 4digit year e.g. 2014
'yyyy' => 'yy', // 4digit year e.g. 2014
'yy' => 'y', // 2digit year number eg. 14
'u' => '', // extended year e.g. 4601
'U' => '', // cyclic year name, as in Chinese lunar calendar
'r' => '', // related Gregorian year e.g. 1996
'Q' => '', // number of quarter
'QQ' => '', // number of quarter '02'
'QQQ' => '', // quarter 'Q2'
'QQQQ' => '', // quarter '2nd quarter'
'QQQQQ' => '', // number of quarter '2'
'q' => '', // number of Stand Alone quarter
'qq' => '', // number of Stand Alone quarter '02'
'qqq' => '', // Stand Alone quarter 'Q2'
'qqqq' => '', // Stand Alone quarter '2nd quarter'
'qqqqq' => '', // number of Stand Alone quarter '2'
'M' => 'm', // Numeric representation of a month, without leading zeros
'MM' => 'mm', // Numeric representation of a month, with leading zeros
'MMM' => 'M', // A short textual representation of a month, three letters
'MMMM' => 'MM', // A full textual representation of a month, such as January or March
'MMMMM' => '',
'L' => 'm', // Stand alone month in year
'LL' => 'mm', // Stand alone month in year
'LLL' => 'M', // Stand alone month in year
'LLLL' => 'MM', // Stand alone month in year
'LLLLL' => '', // Stand alone month in year
'w' => '', // ISO-8601 week number of year
'ww' => '', // ISO-8601 week number of year
'W' => '', // week of the current month
'd' => 'd', // day without leading zeros
'dd' => 'dd', // day with leading zeros
'D' => 'o', // day of the year 0 to 365
'F' => '', // Day of Week in Month. eg. 2nd Wednesday in July
'g' => '', // Modified Julian day. This is different from the conventional Julian day number in two regards.
'E' => 'D', // day of week written in short form eg. Sun
'EE' => 'D',
'EEE' => 'D',
'EEEE' => 'DD', // day of week fully written eg. Sunday
'EEEEE' => '',
'EEEEEE' => '',
'e' => '', // ISO-8601 numeric representation of the day of the week 1=Mon to 7=Sun
'ee' => '', // php 'w' 0=Sun to 6=Sat isn't supported by ICU -> 'w' means week number of year
'eee' => 'D',
'eeee' => '',
'eeeee' => '',
'eeeeee' => '',
'c' => '', // ISO-8601 numeric representation of the day of the week 1=Mon to 7=Sun
'cc' => '', // php 'w' 0=Sun to 6=Sat isn't supported by ICU -> 'w' means week number of year
'ccc' => 'D',
'cccc' => 'DD',
'ccccc' => '',
'cccccc' => '',
'a' => '', // am/pm marker
'h' => '', // 12-hour format of an hour without leading zeros 1 to 12h
'hh' => '', // 12-hour format of an hour with leading zeros, 01 to 12 h
'H' => '', // 24-hour format of an hour without leading zeros 0 to 23h
'HH' => '', // 24-hour format of an hour with leading zeros, 00 to 23 h
'k' => '', // hour in day (1~24)
'kk' => '', // hour in day (1~24)
'K' => '', // hour in am/pm (0~11)
'KK' => '', // hour in am/pm (0~11)
'm' => '', // Minutes without leading zeros, not supported by php but we fallback
'mm' => '', // Minutes with leading zeros
's' => '', // Seconds, without leading zeros, not supported by php but we fallback
'ss' => '', // Seconds, with leading zeros
'S' => '', // fractional second
'SS' => '', // fractional second
'SSS' => '', // fractional second
'SSSS' => '', // fractional second
'A' => '', // milliseconds in day
'z' => '', // Timezone abbreviation
'zz' => '', // Timezone abbreviation
'zzz' => '', // Timezone abbreviation
'zzzz' => '', // Timezone full name, not supported by php but we fallback
'Z' => '', // Difference to Greenwich time (GMT) in hours
'ZZ' => '', // Difference to Greenwich time (GMT) in hours
'ZZZ' => '', // Difference to Greenwich time (GMT) in hours
'ZZZZ' => '', // Time Zone: long localized GMT (=OOOO) e.g. GMT-08:00
'ZZZZZ' => '', // Time Zone: ISO8601 extended hms? (=XXXXX)
'O' => '', // Time Zone: short localized GMT e.g. GMT-8
'OOOO' => '', // Time Zone: long localized GMT (=ZZZZ) e.g. GMT-08:00
'v' => '', // Time Zone: generic non-location (falls back first to VVVV and then to OOOO) using the ICU defined fallback here
'vvvv' => '', // Time Zone: generic non-location (falls back first to VVVV and then to OOOO) using the ICU defined fallback here
'V' => '', // Time Zone: short time zone ID
'VV' => '', // Time Zone: long time zone ID
'VVV' => '', // Time Zone: time zone exemplar city
'VVVV' => '', // Time Zone: generic location (falls back to OOOO) using the ICU defined fallback here
'X' => '', // Time Zone: ISO8601 basic hm?, with Z for 0, e.g. -08, +0530, Z
'XX' => '', // Time Zone: ISO8601 basic hm, with Z, e.g. -0800, Z
'XXX' => '', // Time Zone: ISO8601 extended hm, with Z, e.g. -08:00, Z
'XXXX' => '', // Time Zone: ISO8601 basic hms?, with Z, e.g. -0800, -075258, Z
'XXXXX' => '', // Time Zone: ISO8601 extended hms?, with Z, e.g. -08:00, -07:52:58, Z
'x' => '', // Time Zone: ISO8601 basic hm?, without Z for 0, e.g. -08, +0530
'xx' => '', // Time Zone: ISO8601 basic hm, without Z, e.g. -0800
'xxx' => '', // Time Zone: ISO8601 extended hm, without Z, e.g. -08:00
'xxxx' => '', // Time Zone: ISO8601 basic hms?, without Z, e.g. -0800, -075258
'xxxxx' => '', // Time Zone: ISO8601 extended hms?, without Z, e.g. -08:00, -07:52:58
]));
}
/**
* Converts a date format pattern from [PHP `date()` function format](https://www.php.net/manual/en/function.date)
* to [jQuery UI date format](https://api.jqueryui.com/datepicker/#utility-formatDate).
*
* The conversion is limited to date patterns that do not use escaped characters.
* Patterns like `jS \o\f F Y` which will result in a date like `1st of December 2014` may not be converted correctly
* because of the use of escaped characters.
*
* Pattern constructs that are not supported by the jQuery UI format will be removed.
*
* @param string $pattern date format pattern in PHP `date()` function format.
* @return string The converted date format pattern.
*/
public static function convertDatePhpToJui($pattern)
{
// https://www.php.net/manual/en/function.date
return strtr($pattern, [
// Day
'd' => 'dd', // Day of the month, 2 digits with leading zeros — 01 to 31
'D' => 'D', // A textual representation of a day, three letters — Mon through Sun
'j' => 'd', // Day of the month without leading zeros — 1 to 31
'l' => 'DD', // A full textual representation of the day of the week — Sunday through Saturday
'N' => '', // ISO-8601 numeric representation of the day of the week, 1 (for Monday) through 7 (for Sunday)
'S' => '', // English ordinal suffix for the day of the month, 2 characters — st, nd, rd or th. Works well with j
'w' => '', // Numeric representation of the day of the week — 0 (for Sunday) through 6 (for Saturday)
'z' => 'o', // The day of the year (starting from 0) — 0 through 365
// Week
'W' => '', // ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) — Example: 42 (the 42nd week in the year)
// Month
'F' => 'MM', // A full textual representation of a month, January through December
'm' => 'mm', // Numeric representation of a month, with leading zeros — 01 through 12
'M' => 'M', // A short textual representation of a month, three letters — Jan through Dec
'n' => 'm', // Numeric representation of a month, without leading zeros — 1 through 12
't' => '', // Number of days in the given month — 28 through 31
// Year
'L' => '', // Whether it's a leap year, 1 if it is a leap year, 0 otherwise.
'o' => '', // ISO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead.
'Y' => 'yy', // A full numeric representation of a year, 4 digits — Examples: 1999 or 2003
'y' => 'y', // A two digit representation of a year — Examples: 99 or 03
// Time
'a' => '', // Lowercase Ante meridiem and Post meridiem, am or pm
'A' => '', // Uppercase Ante meridiem and Post meridiem, AM or PM, not supported by ICU but we fallback to lowercase
'B' => '', // Swatch Internet time — 000 through 999
'g' => '', // 12-hour format of an hour without leading zeros — 1 through 12
'G' => '', // 24-hour format of an hour without leading zeros 0 to 23h
'h' => '', // 12-hour format of an hour with leading zeros, 01 to 12 h
'H' => '', // 24-hour format of an hour with leading zeros, 00 to 23 h
'i' => '', // Minutes with leading zeros — 00 to 59
's' => '', // Seconds, with leading zeros — 00 through 59
'u' => '', // Microseconds. Example: 654321
// Timezone
'e' => '', // Timezone identifier. Examples: UTC, GMT, Atlantic/Azores
'I' => '', // Whether or not the date is in daylight saving time, 1 if Daylight Saving Time, 0 otherwise.
'O' => '', // Difference to Greenwich time (GMT) in hours, Example: +0200
'P' => '', // Difference to Greenwich time (GMT) with colon between hours and minutes, Example: +02:00
'T' => '', // Timezone abbreviation, Examples: EST, MDT ...
'Z' => '', // Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. -43200 through 50400
// Full Date/Time
'c' => 'yyyy-MM-dd', // ISO 8601 date, e.g. 2004-02-12T15:19:21+00:00, skipping the time here because it is not supported
'r' => 'D, d M yy', // RFC 2822 formatted date, Example: Thu, 21 Dec 2000 16:01:07 +0200, skipping the time here because it is not supported
'U' => '@', // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
]);
}
/**
* Creates a date/time formatter based on the given parameters.
*
* @param string|null $locale The locale to be used. If null, the application's current language will be used.
* @param string $type The type of formatter ('date', 'time', etc.)
* @param string $pattern The pattern for the IntlDateFormatter.
*
* @return string The resulting pattern after formatter creation.
*
* @throws \Exception If the 'intl' extension is not loaded.
*/
private static function createFormatter($locale, $type, $pattern)
{
if ($locale === null) {
$locale = Yii::$app->language;
}
if ($type === 'date') {
$formatter = new IntlDateFormatter($locale, self::$_icuShortFormats[$pattern], IntlDateFormatter::NONE);
} elseif ($type === 'time') {
$formatter = new IntlDateFormatter($locale, IntlDateFormatter::NONE, self::$_icuShortFormats[$pattern]);
} else {
$formatter = new IntlDateFormatter($locale, self::$_icuShortFormats[$pattern], self::$_icuShortFormats[$pattern]);
}
return $formatter->getPattern();
}
}

2410
vendor/yiisoft/yii2/helpers/BaseHtml.php vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* BaseHtmlPurifier provides concrete implementation for [[HtmlPurifier]].
*
* Do not use BaseHtmlPurifier. Use [[HtmlPurifier]] instead.
*
* @author Alexander Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class BaseHtmlPurifier
{
/**
* Passes markup through HTMLPurifier making it safe to output to end user.
*
* @param string $content The HTML content to purify
* @param array|\Closure|null $config The config to use for HtmlPurifier.
* If not specified or `null` the default config will be used.
* You can use an array or an anonymous function to provide configuration options:
*
* - An array will be passed to the `HTMLPurifier_Config::create()` method.
* - An anonymous function will be called after the config was created.
* The signature should be: `function($config)` where `$config` will be an
* instance of `HTMLPurifier_Config`.
*
* Here is a usage example of such a function:
*
* ```
* // Allow the HTML5 data attribute `data-type` on `img` elements.
* $content = HtmlPurifier::process($content, function ($config) {
* $config->getHTMLDefinition(true)
* ->addAttribute('img', 'data-type', 'Text');
* });
* ```
*
* @return string the purified HTML content.
*/
public static function process($content, $config = null)
{
$configInstance = \HTMLPurifier_Config::create($config instanceof \Closure ? null : $config);
$configInstance->autoFinalize = false;
$purifier = \HTMLPurifier::instance($configInstance);
$purifier->config->set('Cache.SerializerPath', \Yii::$app->getRuntimePath());
$purifier->config->set('Cache.SerializerPermissions', 0775);
static::configure($configInstance);
if ($config instanceof \Closure) {
call_user_func($config, $configInstance);
}
return $purifier->purify($content);
}
/**
* Allow the extended HtmlPurifier class to set some default config options.
* @param \HTMLPurifier_Config $config
* @since 2.0.3
*/
protected static function configure($config)
{
}
}

View File

@ -0,0 +1,665 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
use Yii;
/**
* BaseInflector provides concrete implementation for [[Inflector]].
*
* Do not use BaseInflector. Use [[Inflector]] instead.
*
* @author Antonio Ramirez <amigo.cobos@gmail.com>
* @author Alexander Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class BaseInflector
{
/**
* @var array the rules for converting a word into its plural form.
* The keys are the regular expressions and the values are the corresponding replacements.
*/
public static $plurals = [
'/([nrlm]ese|deer|fish|sheep|measles|ois|pox|media)$/i' => '\1',
'/^(sea[- ]bass)$/i' => '\1',
'/(m)ove$/i' => '\1oves',
'/(f)oot$/i' => '\1eet',
'/(h)uman$/i' => '\1umans',
'/(s)tatus$/i' => '\1tatuses',
'/(s)taff$/i' => '\1taff',
'/(t)ooth$/i' => '\1eeth',
'/(quiz)$/i' => '\1zes',
'/^(ox)$/i' => '\1\2en',
'/([m|l])ouse$/i' => '\1ice',
'/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
'/(x|ch|ss|sh)$/i' => '\1es',
'/([^aeiouy]|qu)y$/i' => '\1ies',
'/(hive)$/i' => '\1s',
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
'/sis$/i' => 'ses',
'/([ti])um$/i' => '\1a',
'/(p)erson$/i' => '\1eople',
'/(m)an$/i' => '\1en',
'/(c)hild$/i' => '\1hildren',
'/(buffal|tomat|potat|ech|her|vet)o$/i' => '\1oes',
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
'/us$/i' => 'uses',
'/(alias)$/i' => '\1es',
'/(ax|cris|test)is$/i' => '\1es',
'/(currenc)y$/' => '\1ies',
'/s$/' => 's',
'/^$/' => '',
'/$/' => 's',
];
/**
* @var array the rules for converting a word into its singular form.
* The keys are the regular expressions and the values are the corresponding replacements.
*/
public static $singulars = [
'/([nrlm]ese|deer|fish|sheep|measles|ois|pox|media|ss)$/i' => '\1',
'/^(sea[- ]bass)$/i' => '\1',
'/(s)tatuses$/i' => '\1tatus',
'/(f)eet$/i' => '\1oot',
'/(t)eeth$/i' => '\1ooth',
'/^(.*)(menu)s$/i' => '\1\2',
'/(quiz)zes$/i' => '\\1',
'/(matr)ices$/i' => '\1ix',
'/(vert|ind)ices$/i' => '\1ex',
'/^(ox)en/i' => '\1',
'/(alias)(es)*$/i' => '\1',
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
'/([ftw]ax)es/i' => '\1',
'/(cris|ax|test)es$/i' => '\1is',
'/(shoe|slave)s$/i' => '\1',
'/(o)es$/i' => '\1',
'/ouses$/' => 'ouse',
'/([^a])uses$/' => '\1us',
'/([m|l])ice$/i' => '\1ouse',
'/(x|ch|ss|sh)es$/i' => '\1',
'/(m)ovies$/i' => '\1\2ovie',
'/(s)eries$/i' => '\1\2eries',
'/([^aeiouy]|qu)ies$/i' => '\1y',
'/([lr])ves$/i' => '\1f',
'/(tive)s$/i' => '\1',
'/(hive)s$/i' => '\1',
'/(drive)s$/i' => '\1',
'/([^fo])ves$/i' => '\1fe',
'/(^analy)ses$/i' => '\1sis',
'/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
'/([ti])a$/i' => '\1um',
'/(p)eople$/i' => '\1\2erson',
'/(m)en$/i' => '\1an',
'/(c)hildren$/i' => '\1\2hild',
'/(n)ews$/i' => '\1\2ews',
'/(n)etherlands$/i' => '\1\2etherlands',
'/eaus$/' => 'eau',
'/(currenc)ies$/' => '\1y',
'/^(.*us)$/' => '\\1',
'/s$/i' => '',
];
/**
* @var array the special rules for converting a word between its plural form and singular form.
* The keys are the special words in singular form, and the values are the corresponding plural form.
*/
public static $specials = [
'atlas' => 'atlases',
'beef' => 'beefs',
'brother' => 'brothers',
'cafe' => 'cafes',
'child' => 'children',
'cookie' => 'cookies',
'corpus' => 'corpuses',
'cow' => 'cows',
'curve' => 'curves',
'foe' => 'foes',
'ganglion' => 'ganglions',
'genie' => 'genies',
'genus' => 'genera',
'graffito' => 'graffiti',
'hoof' => 'hoofs',
'loaf' => 'loaves',
'man' => 'men',
'money' => 'monies',
'mongoose' => 'mongooses',
'move' => 'moves',
'mythos' => 'mythoi',
'niche' => 'niches',
'numen' => 'numina',
'occiput' => 'occiputs',
'octopus' => 'octopuses',
'opus' => 'opuses',
'ox' => 'oxen',
'pasta' => 'pasta',
'penis' => 'penises',
'sex' => 'sexes',
'soliloquy' => 'soliloquies',
'testis' => 'testes',
'trilby' => 'trilbys',
'turf' => 'turfs',
'wave' => 'waves',
'Amoyese' => 'Amoyese',
'bison' => 'bison',
'Borghese' => 'Borghese',
'bream' => 'bream',
'breeches' => 'breeches',
'britches' => 'britches',
'buffalo' => 'buffalo',
'cantus' => 'cantus',
'carp' => 'carp',
'chassis' => 'chassis',
'clippers' => 'clippers',
'cod' => 'cod',
'coitus' => 'coitus',
'Congoese' => 'Congoese',
'contretemps' => 'contretemps',
'corps' => 'corps',
'debris' => 'debris',
'diabetes' => 'diabetes',
'djinn' => 'djinn',
'eland' => 'eland',
'elk' => 'elk',
'equipment' => 'equipment',
'Faroese' => 'Faroese',
'flounder' => 'flounder',
'Foochowese' => 'Foochowese',
'gallows' => 'gallows',
'Genevese' => 'Genevese',
'Genoese' => 'Genoese',
'Gilbertese' => 'Gilbertese',
'graffiti' => 'graffiti',
'headquarters' => 'headquarters',
'herpes' => 'herpes',
'hijinks' => 'hijinks',
'Hottentotese' => 'Hottentotese',
'information' => 'information',
'innings' => 'innings',
'jackanapes' => 'jackanapes',
'Kiplingese' => 'Kiplingese',
'Kongoese' => 'Kongoese',
'Lucchese' => 'Lucchese',
'mackerel' => 'mackerel',
'Maltese' => 'Maltese',
'mews' => 'mews',
'moose' => 'moose',
'mumps' => 'mumps',
'Nankingese' => 'Nankingese',
'news' => 'news',
'nexus' => 'nexus',
'Niasese' => 'Niasese',
'Pekingese' => 'Pekingese',
'Piedmontese' => 'Piedmontese',
'pincers' => 'pincers',
'Pistoiese' => 'Pistoiese',
'pliers' => 'pliers',
'Portuguese' => 'Portuguese',
'proceedings' => 'proceedings',
'rabies' => 'rabies',
'rice' => 'rice',
'rhinoceros' => 'rhinoceros',
'salmon' => 'salmon',
'Sarawakese' => 'Sarawakese',
'scissors' => 'scissors',
'series' => 'series',
'Shavese' => 'Shavese',
'shears' => 'shears',
'siemens' => 'siemens',
'species' => 'species',
'swine' => 'swine',
'testes' => 'testes',
'trousers' => 'trousers',
'trout' => 'trout',
'tuna' => 'tuna',
'Vermontese' => 'Vermontese',
'Wenchowese' => 'Wenchowese',
'whiting' => 'whiting',
'wildebeest' => 'wildebeest',
'Yengeese' => 'Yengeese',
'software' => 'software',
'hardware' => 'hardware',
];
/**
* @var array fallback map for transliteration used by [[transliterate()]] when intl isn't available.
*/
public static $transliteration = [
'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 'Æ' => 'AE', 'Ç' => 'C',
'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I',
'Ð' => 'D', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ő' => 'O',
'Ø' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ű' => 'U', 'Ý' => 'Y', 'Þ' => 'TH',
'ß' => 'ss',
'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'ae', 'ç' => 'c',
'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i',
'ð' => 'd', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ő' => 'o',
'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'ű' => 'u', 'ý' => 'y', 'þ' => 'th',
'ÿ' => 'y',
];
/**
* Shortcut for `Any-Latin; NFKD` transliteration rule.
*
* The rule is strict, letters will be transliterated with
* the closest sound-representation chars. The result may contain any UTF-8 chars. For example:
* `获取到 どちら Українська: ґ,є, Српска: ђ, њ, џ! ¿Español?` will be transliterated to
* `huò qǔ dào dochira Ukraí̈nsʹka: g̀,ê, Srpska: đ, n̂, d̂! ¿Español?`.
*
* Used in [[transliterate()]].
* For detailed information see [unicode normalization forms](https://unicode.org/reports/tr15/#Normalization_Forms_Table)
* @see https://unicode.org/reports/tr15/#Normalization_Forms_Table
* @see transliterate()
* @since 2.0.7
*/
public const TRANSLITERATE_STRICT = 'Any-Latin; NFKD';
/**
* Shortcut for `Any-Latin; Latin-ASCII` transliteration rule.
*
* The rule is medium, letters will be
* transliterated to characters of Latin-1 (ISO 8859-1) ASCII table. For example:
* `获取到 どちら Українська: ґ,є, Српска: ђ, њ, џ! ¿Español?` will be transliterated to
* `huo qu dao dochira Ukrainsʹka: g,e, Srpska: d, n, d! ¿Espanol?`.
*
* Used in [[transliterate()]].
* For detailed information see [unicode normalization forms](https://unicode.org/reports/tr15/#Normalization_Forms_Table)
* @see https://unicode.org/reports/tr15/#Normalization_Forms_Table
* @see transliterate()
* @since 2.0.7
*/
public const TRANSLITERATE_MEDIUM = 'Any-Latin; Latin-ASCII';
/**
* Shortcut for `Any-Latin; Latin-ASCII; [\u0080-\uffff] remove` transliteration rule.
*
* The rule is loose,
* letters will be transliterated with the characters of Basic Latin Unicode Block.
* For example:
* `获取到 どちら Українська: ґ,є, Српска: ђ, њ, џ! ¿Español?` will be transliterated to
* `huo qu dao dochira Ukrainska: g,e, Srpska: d, n, d! Espanol?`.
*
* Used in [[transliterate()]].
* For detailed information see [unicode normalization forms](https://unicode.org/reports/tr15/#Normalization_Forms_Table)
* @see https://unicode.org/reports/tr15/#Normalization_Forms_Table
* @see transliterate()
* @since 2.0.7
*/
public const TRANSLITERATE_LOOSE = 'Any-Latin; Latin-ASCII; [\u0080-\uffff] remove';
/**
* @var mixed Either a [[\Transliterator]], or a string from which a [[\Transliterator]] can be built
* for transliteration. Used by [[transliterate()]] when intl is available. Defaults to [[TRANSLITERATE_LOOSE]]
* @see https://www.php.net/manual/en/transliterator.transliterate.php
*/
public static $transliterator = self::TRANSLITERATE_LOOSE;
/**
* Converts a word to its plural form.
* Note that this is for English only!
* For example, 'apple' will become 'apples', and 'child' will become 'children'.
* @param string $word the word to be pluralized
* @return string the pluralized word
*/
public static function pluralize($word)
{
if (empty($word)) {
return (string) $word;
}
if (isset(static::$specials[$word])) {
return static::$specials[$word];
}
foreach (static::$plurals as $rule => $replacement) {
if (preg_match($rule, $word)) {
return preg_replace($rule, $replacement, $word);
}
}
return $word;
}
/**
* Returns the singular of the $word.
* @param string $word the english word to singularize
* @return string Singular noun.
*/
public static function singularize($word)
{
if (empty($word)) {
return (string) $word;
}
$result = array_search($word, static::$specials, true);
if ($result !== false) {
return $result;
}
foreach (static::$singulars as $rule => $replacement) {
if (preg_match($rule, $word)) {
return preg_replace($rule, $replacement, $word);
}
}
return $word;
}
/**
* Converts an underscored or CamelCase word into a English
* sentence.
* @param string $words
* @param bool $ucAll whether to set all words to uppercase
* @return string
*/
public static function titleize($words, $ucAll = false)
{
if (empty($words)) {
return (string) $words;
}
$words = static::humanize(static::underscore($words), $ucAll);
return $ucAll ? StringHelper::mb_ucwords($words, self::encoding()) : StringHelper::mb_ucfirst($words, self::encoding());
}
/**
* Returns given word as CamelCased.
*
* Converts a word like "send_email" to "SendEmail". It
* will remove non alphanumeric character from the word, so
* "who's online" will be converted to "WhoSOnline".
* @param string $word the word to CamelCase
* @return string
* @see variablize()
*/
public static function camelize($word)
{
if (empty($word)) {
return (string) $word;
}
return str_replace(' ', '', StringHelper::mb_ucwords(preg_replace('/[^\pL\pN]+/u', ' ', $word), self::encoding()));
}
/**
* Converts a CamelCase name into space-separated words.
* For example, 'PostTag' will be converted to 'Post Tag'.
* @param string $name the string to be converted
* @param bool $ucwords whether to capitalize the first letter in each word
* @return string the resulting words
*/
public static function camel2words($name, $ucwords = true)
{
if (empty($name)) {
return (string) $name;
}
// Add a space before any uppercase letter preceded by a lowercase letter (xY => x Y)
// and any uppercase letter preceded by an uppercase letter and followed by a lowercase letter (XYz => X Yz)
$label = preg_replace('/(?<=\p{Ll})\p{Lu}|(?<=\p{L})\p{Lu}(?=\p{Ll})/u', ' \0', $name);
$label = mb_strtolower(trim(str_replace(['-', '_', '.'], ' ', $label)), self::encoding());
return $ucwords ? StringHelper::mb_ucwords($label, self::encoding()) : $label;
}
/**
* Converts a CamelCase name into an ID in lowercase.
* Words in the ID may be concatenated using the specified character (defaults to '-').
* For example, 'PostTag' will be converted to 'post-tag'.
* @param string $name the string to be converted
* @param string $separator the character used to concatenate the words in the ID
* @param bool|string $strict whether to insert a separator between two consecutive uppercase chars, defaults to false
* @return string the resulting ID
*/
public static function camel2id($name, $separator = '-', $strict = false)
{
if (empty($name)) {
return (string) $name;
}
$regex = $strict ? '/\p{Lu}/u' : '/(?<!\p{Lu})\p{Lu}/u';
if ($separator === '_') {
return mb_strtolower(trim(preg_replace($regex, '_\0', $name), '_'), self::encoding());
}
return mb_strtolower(trim(str_replace('_', $separator, preg_replace($regex, $separator . '\0', $name)), $separator), self::encoding());
}
/**
* Converts an ID into a CamelCase name.
* Words in the ID separated by `$separator` (defaults to '-') will be concatenated into a CamelCase name.
* For example, 'post-tag' is converted to 'PostTag'.
* @param string $id the ID to be converted
* @param string $separator the character used to separate the words in the ID
* @return string the resulting CamelCase name
*/
public static function id2camel($id, $separator = '-')
{
if (empty($id)) {
return (string) $id;
}
return str_replace(' ', '', StringHelper::mb_ucwords(str_replace($separator, ' ', $id), self::encoding()));
}
/**
* Converts any "CamelCased" into an "underscored_word".
* @param string $words the word(s) to underscore
* @return string
*/
public static function underscore($words)
{
if (empty($words)) {
return (string) $words;
}
return mb_strtolower(preg_replace('/(?<=\\pL)(\\p{Lu})/u', '_\\1', $words), self::encoding());
}
/**
* Returns a human-readable string from $word.
* @param string $word the string to humanize
* @param bool $ucAll whether to set all words to uppercase or not
* @return string
*/
public static function humanize($word, $ucAll = false)
{
if (empty($word)) {
return (string) $word;
}
$word = str_replace('_', ' ', preg_replace('/_id$/', '', $word));
$encoding = self::encoding();
return $ucAll ? StringHelper::mb_ucwords($word, $encoding) : StringHelper::mb_ucfirst($word, $encoding);
}
/**
* Same as camelize but first char is in lowercase.
*
* Converts a word like "send_email" to "sendEmail". It
* will remove non alphanumeric character from the word, so
* "who's online" will be converted to "whoSOnline".
* @param string $word to lowerCamelCase
* @return string
*/
public static function variablize($word)
{
if (empty($word)) {
return (string) $word;
}
$word = static::camelize($word);
return mb_strtolower(mb_substr($word, 0, 1, self::encoding())) . mb_substr($word, 1, null, self::encoding());
}
/**
* Converts a class name to its table name (pluralized) naming conventions.
*
* For example, converts "Person" to "people".
* @param string $className the class name for getting related table_name
* @return string
*/
public static function tableize($className)
{
if (empty($className)) {
return (string) $className;
}
return static::pluralize(static::underscore($className));
}
/**
* Returns a string with all spaces converted to given replacement,
* non word characters removed and the rest of characters transliterated.
*
* If intl extension isn't available uses fallback that converts latin characters only
* and removes the rest. You may customize characters map via $transliteration property
* of the helper.
*
* @param string $string An arbitrary string to convert
* @param string $replacement The replacement to use for spaces
* @param bool $lowercase whether to return the string in lowercase or not. Defaults to `true`.
* @return string The converted string.
*/
public static function slug($string, $replacement = '-', $lowercase = true)
{
if (empty($string)) {
return (string) $string;
}
if ((string)$replacement !== '') {
$parts = explode($replacement, static::transliterate($string));
} else {
$parts = [static::transliterate($string)];
}
$replaced = array_map(function ($element) use ($replacement) {
$element = preg_replace('/[^a-zA-Z0-9=\s—-]+/u', '', $element);
return preg_replace('/[=\s—-]+/u', $replacement, $element);
}, $parts);
$string = trim(implode($replacement, $replaced), $replacement);
if ((string)$replacement !== '') {
$string = preg_replace('#' . preg_quote($replacement, '#') . '+#', $replacement, $string);
}
return $lowercase ? strtolower($string) : $string;
}
/**
* Returns transliterated version of a string.
*
* If intl extension isn't available uses fallback that converts latin characters only
* and removes the rest. You may customize characters map via $transliteration property
* of the helper.
*
* @param string $string input string
* @param string|\Transliterator|null $transliterator either a [[\Transliterator]] or a string
* from which a [[\Transliterator]] can be built.
* @return string
* @since 2.0.7 this method is public.
*/
public static function transliterate($string, $transliterator = null)
{
if (empty($string)) {
return (string) $string;
}
if (static::hasIntl()) {
if ($transliterator === null) {
$transliterator = static::$transliterator;
}
return transliterator_transliterate($transliterator, $string);
}
return strtr($string, static::$transliteration);
}
/**
* @return bool if intl extension is loaded
*/
protected static function hasIntl()
{
return extension_loaded('intl');
}
/**
* Converts a table name to its class name.
*
* For example, converts "people" to "Person".
* @param string $tableName
* @return string
*/
public static function classify($tableName)
{
if (empty($tableName)) {
return (string) $tableName;
}
return static::camelize(static::singularize($tableName));
}
/**
* Converts number to its ordinal English form. For example, converts 13 to 13th, 2 to 2nd ...
* @param int $number the number to get its ordinal value
* @return string
*/
public static function ordinalize($number)
{
if (in_array($number % 100, range(11, 13))) {
return $number . 'th';
}
switch ($number % 10) {
case 1:
return $number . 'st';
case 2:
return $number . 'nd';
case 3:
return $number . 'rd';
default:
return $number . 'th';
}
}
/**
* Converts a list of words into a sentence.
*
* Special treatment is done for the last few words. For example,
*
* ```
* $words = ['Spain', 'France'];
* echo Inflector::sentence($words);
* // output: Spain and France
*
* $words = ['Spain', 'France', 'Italy'];
* echo Inflector::sentence($words);
* // output: Spain, France and Italy
*
* $words = ['Spain', 'France', 'Italy'];
* echo Inflector::sentence($words, ' & ');
* // output: Spain, France & Italy
* ```
*
* @param array $words the words to be converted into an string
* @param string|null $twoWordsConnector the string connecting words when there are only two
* @param string|null $lastWordConnector the string connecting the last two words. If this is null, it will
* take the value of `$twoWordsConnector`.
* @param string $connector the string connecting words other than those connected by
* $lastWordConnector and $twoWordsConnector
* @return string the generated sentence
* @since 2.0.1
*/
public static function sentence(array $words, $twoWordsConnector = null, $lastWordConnector = null, $connector = ', ')
{
if ($twoWordsConnector === null) {
$twoWordsConnector = Yii::t('yii', ' and ');
}
if ($lastWordConnector === null) {
$lastWordConnector = $twoWordsConnector;
}
switch (count($words)) {
case 0:
return '';
case 1:
return reset($words);
case 2:
return implode($twoWordsConnector, $words);
default:
return implode($connector, array_slice($words, 0, -1)) . $lastWordConnector . end($words);
}
}
/**
* @return string
*/
private static function encoding()
{
return isset(Yii::$app) ? Yii::$app->charset : 'UTF-8';
}
}

View File

@ -0,0 +1,125 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
use yii\base\NotSupportedException;
/**
* Class BaseIpHelper provides concrete implementation for [[IpHelper]]
*
* Do not use BaseIpHelper, use [[IpHelper]] instead.
*
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
* @since 2.0.14
*/
class BaseIpHelper
{
public const IPV4 = 4;
public const IPV6 = 6;
/**
* The length of IPv6 address in bits
*/
public const IPV6_ADDRESS_LENGTH = 128;
/**
* The length of IPv4 address in bits
*/
public const IPV4_ADDRESS_LENGTH = 32;
/**
* Gets the IP version. Does not perform IP address validation.
*
* @param string $ip the valid IPv4 or IPv6 address.
* @return int [[IPV4]] or [[IPV6]]
*/
public static function getIpVersion($ip)
{
return strpos($ip, ':') === false ? self::IPV4 : self::IPV6;
}
/**
* Checks whether IP address or subnet $subnet is contained by $subnet.
*
* For example, the following code checks whether subnet `192.168.1.0/24` is in subnet `192.168.0.0/22`:
*
* ```
* IpHelper::inRange('192.168.1.0/24', '192.168.0.0/22'); // true
* ```
*
* In case you need to check whether a single IP address `192.168.1.21` is in the subnet `192.168.1.0/24`,
* you can use any of theses examples:
*
* ```
* IpHelper::inRange('192.168.1.21', '192.168.1.0/24'); // true
* IpHelper::inRange('192.168.1.21/32', '192.168.1.0/24'); // true
* ```
*
* @param string $subnet the valid IPv4 or IPv6 address or CIDR range, e.g.: `10.0.0.0/8` or `2001:af::/64`
* @param string $range the valid IPv4 or IPv6 CIDR range, e.g. `10.0.0.0/8` or `2001:af::/64`
* @return bool whether $subnet is contained by $range
*
* @throws NotSupportedException
* @see https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
*/
public static function inRange($subnet, $range)
{
list($ip, $mask) = array_pad(explode('/', $subnet), 2, null);
list($net, $netMask) = array_pad(explode('/', $range), 2, null);
$ipVersion = static::getIpVersion($ip);
$netVersion = static::getIpVersion($net);
if ($ipVersion !== $netVersion) {
return false;
}
$maxMask = $ipVersion === self::IPV4 ? self::IPV4_ADDRESS_LENGTH : self::IPV6_ADDRESS_LENGTH;
$mask = isset($mask) ? $mask : $maxMask;
$netMask = isset($netMask) ? $netMask : $maxMask;
$binIp = static::ip2bin($ip);
$binNet = static::ip2bin($net);
return substr($binIp, 0, $netMask) === substr($binNet, 0, $netMask) && $mask >= $netMask;
}
/**
* Expands an IPv6 address to it's full notation.
*
* For example `2001:db8::1` will be expanded to `2001:0db8:0000:0000:0000:0000:0000:0001`
*
* @param string $ip the original valid IPv6 address
* @return string the expanded IPv6 address
*/
public static function expandIPv6($ip)
{
$hex = unpack('H*hex', inet_pton($ip));
return substr(preg_replace('/([a-f0-9]{4})/i', '$1:', $hex['hex']), 0, -1);
}
/**
* Converts IP address to bits representation.
*
* @param string $ip the valid IPv4 or IPv6 address
* @return string bits as a string
* @throws NotSupportedException
*/
public static function ip2bin($ip)
{
$ipBinary = null;
if (static::getIpVersion($ip) === self::IPV4) {
$ipBinary = pack('N', ip2long($ip));
} elseif (@inet_pton('::1') === false) {
throw new NotSupportedException('IPv6 is not supported by inet_pton()!');
} else {
$ipBinary = inet_pton($ip);
}
$result = '';
for ($i = 0, $iMax = strlen($ipBinary); $i < $iMax; $i += 4) {
$result .= str_pad(decbin(unpack('N', substr($ipBinary, $i, 4))[1]), 32, '0', STR_PAD_LEFT);
}
return $result;
}
}

274
vendor/yiisoft/yii2/helpers/BaseJson.php vendored Normal file
View File

@ -0,0 +1,274 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
use yii\base\Arrayable;
use yii\base\InvalidArgumentException;
use yii\base\Model;
use yii\web\JsExpression;
use yii\web\JsonResponseFormatter;
/**
* BaseJson provides concrete implementation for [[Json]].
*
* Do not use BaseJson. Use [[Json]] instead.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class BaseJson
{
/**
* @var bool|null Enables human readable output a.k.a. Pretty Print.
* This can useful for debugging during development but is not recommended in a production environment!
* In case `prettyPrint` is `null` (default) the `options` passed to `encode` functions will not be changed.
* @since 2.0.43
*/
public static $prettyPrint;
/**
* @var bool Avoids objects with zero-indexed keys to be encoded as array
* `Json::encode((object)['test'])` will be encoded as an object not as an array. This matches the behaviour of `json_encode()`.
* Defaults to false to avoid any backwards compatibility issues.
* Enable for single purpose: `Json::$keepObjectType = true;`
* @see JsonResponseFormatter documentation to enable for all JSON responses
* @since 2.0.44
*/
public static $keepObjectType = false;
/**
* @var array List of JSON Error messages assigned to constant names for better handling of PHP <= 5.5.
* @since 2.0.7
*/
public static $jsonErrorMessages = [
'JSON_ERROR_SYNTAX' => 'Syntax error',
'JSON_ERROR_UNSUPPORTED_TYPE' => 'Type is not supported',
'JSON_ERROR_DEPTH' => 'The maximum stack depth has been exceeded',
'JSON_ERROR_STATE_MISMATCH' => 'Invalid or malformed JSON',
'JSON_ERROR_CTRL_CHAR' => 'Control character error, possibly incorrectly encoded',
'JSON_ERROR_UTF8' => 'Malformed UTF-8 characters, possibly incorrectly encoded',
];
/**
* Encodes the given value into a JSON string.
*
* The method enhances `json_encode()` by supporting JavaScript expressions.
* In particular, the method will not encode a JavaScript expression that is
* represented in terms of a [[JsExpression]] object.
*
* Note that data encoded as JSON must be UTF-8 encoded according to the JSON specification.
* You must ensure strings passed to this method have proper encoding before passing them.
*
* @param mixed $value the data to be encoded.
* @param int $options the encoding options. For more details please refer to
* <https://www.php.net/manual/en/function.json-encode.php>. Default is `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`.
* @return string the encoding result.
* @throws InvalidArgumentException if there is any encoding error.
*/
public static function encode($value, $options = 320)
{
$expressions = [];
$value = static::processData($value, $expressions, uniqid('', true));
set_error_handler(function () {
static::handleJsonError(JSON_ERROR_SYNTAX);
}, E_WARNING);
if (static::$prettyPrint === true) {
$options |= JSON_PRETTY_PRINT;
} elseif (static::$prettyPrint === false) {
$options &= ~JSON_PRETTY_PRINT;
}
$json = json_encode($value, $options);
restore_error_handler();
static::handleJsonError(json_last_error());
return $expressions === [] ? $json : strtr($json, $expressions);
}
/**
* Encodes the given value into a JSON string HTML-escaping entities so it is safe to be embedded in HTML code.
*
* The method enhances `json_encode()` by supporting JavaScript expressions.
* In particular, the method will not encode a JavaScript expression that is
* represented in terms of a [[JsExpression]] object.
*
* Note that data encoded as JSON must be UTF-8 encoded according to the JSON specification.
* You must ensure strings passed to this method have proper encoding before passing them.
*
* @param mixed $value the data to be encoded
* @return string the encoding result
* @since 2.0.4
* @throws InvalidArgumentException if there is any encoding error
*/
public static function htmlEncode($value)
{
return static::encode($value, JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS);
}
/**
* Decodes the given JSON string into a PHP data structure.
* @param string $json the JSON string to be decoded
* @param bool $asArray whether to return objects in terms of associative arrays.
* @return mixed the PHP data
* @throws InvalidArgumentException if there is any decoding error
*/
public static function decode($json, $asArray = true)
{
if (is_array($json)) {
throw new InvalidArgumentException('Invalid JSON data.');
} elseif ($json === null || $json === '') {
return null;
}
$decode = json_decode((string) $json, $asArray);
static::handleJsonError(json_last_error());
return $decode;
}
/**
* Handles [[encode()]] and [[decode()]] errors by throwing exceptions with the respective error message.
*
* @param int $lastError error code from [json_last_error()](https://www.php.net/manual/en/function.json-last-error.php).
* @throws InvalidArgumentException if there is any encoding/decoding error.
* @since 2.0.6
*/
protected static function handleJsonError($lastError)
{
if ($lastError === JSON_ERROR_NONE) {
return;
}
if (PHP_VERSION_ID >= 50500) {
throw new InvalidArgumentException(json_last_error_msg(), $lastError);
}
foreach (static::$jsonErrorMessages as $const => $message) {
if (defined($const) && constant($const) === $lastError) {
throw new InvalidArgumentException($message, $lastError);
}
}
throw new InvalidArgumentException('Unknown JSON encoding/decoding error.');
}
/**
* Pre-processes the data before sending it to `json_encode()`.
* @param mixed $data the data to be processed
* @param array $expressions collection of JavaScript expressions
* @param string $expPrefix a prefix internally used to handle JS expressions
* @return mixed the processed data
*/
protected static function processData($data, &$expressions, $expPrefix)
{
$revertToObject = false;
if (is_object($data)) {
if ($data instanceof JsExpression) {
$token = "!{[$expPrefix=" . count($expressions) . ']}!';
$expressions['"' . $token . '"'] = $data->expression;
return $token;
}
if ($data instanceof \JsonSerializable) {
return static::processData($data->jsonSerialize(), $expressions, $expPrefix);
}
if ($data instanceof \DateTimeInterface) {
return static::processData((array)$data, $expressions, $expPrefix);
}
if ($data instanceof Arrayable) {
$data = $data->toArray();
} elseif ($data instanceof \Generator) {
$_data = [];
foreach ($data as $name => $value) {
$_data[$name] = static::processData($value, $expressions, $expPrefix);
}
$data = $_data;
} elseif ($data instanceof \SimpleXMLElement) {
$data = (array) $data;
// Avoid empty elements to be returned as array.
// Not breaking BC because empty array was always cast to stdClass before.
$revertToObject = true;
} else {
/*
* $data type is changed to array here and its elements will be processed further
* We must cast $data back to object later to keep intended dictionary type in JSON.
* Revert is only done when keepObjectType flag is provided to avoid breaking BC
*/
$revertToObject = static::$keepObjectType;
$result = [];
foreach ($data as $name => $value) {
$result[$name] = $value;
}
$data = $result;
// Avoid empty objects to be returned as array (would break BC without keepObjectType flag)
if ($data === []) {
$revertToObject = true;
}
}
}
if (is_array($data)) {
foreach ($data as $key => $value) {
if (is_array($value) || is_object($value)) {
$data[$key] = static::processData($value, $expressions, $expPrefix);
}
}
}
return $revertToObject ? (object) $data : $data;
}
/**
* Generates a summary of the validation errors.
*
* @param Model|Model[] $models the model(s) whose validation errors are to be displayed.
* @param array $options the tag options in terms of name-value pairs. The following options are specially handled:
*
* - showAllErrors: boolean, if set to true every error message for each attribute will be shown otherwise
* only the first error message for each attribute will be shown. Defaults to `false`.
*
* @return string the generated error summary
* @since 2.0.14
*/
public static function errorSummary($models, $options = [])
{
$showAllErrors = ArrayHelper::remove($options, 'showAllErrors', false);
$lines = self::collectErrors($models, $showAllErrors);
return static::encode($lines);
}
/**
* Return array of the validation errors.
*
* @param Model|Model[] $models the model(s) whose validation errors are to be displayed.
* @param bool $showAllErrors if set to true every error message for each attribute will be shown otherwise
* only the first error message for each attribute will be shown.
* @return array of the validation errors
* @since 2.0.14
*/
private static function collectErrors($models, $showAllErrors)
{
$lines = [];
if (!is_array($models)) {
$models = [$models];
}
foreach ($models as $model) {
$lines[] = $model->getErrorSummary($showAllErrors);
}
return array_unique(call_user_func_array('array_merge', $lines));
}
}

View File

@ -0,0 +1,106 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
use Yii;
use yii\base\InvalidArgumentException;
/**
* BaseMarkdown provides concrete implementation for [[Markdown]].
*
* Do not use BaseMarkdown. Use [[Markdown]] instead.
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class BaseMarkdown
{
/**
* @var array a map of markdown flavor names to corresponding parser class configurations.
*/
public static $flavors = [
'original' => [
'class' => 'cebe\markdown\Markdown',
'html5' => true,
],
'gfm' => [
'class' => 'cebe\markdown\GithubMarkdown',
'html5' => true,
],
'gfm-comment' => [
'class' => 'cebe\markdown\GithubMarkdown',
'html5' => true,
'enableNewlines' => true,
],
'extra' => [
'class' => 'cebe\markdown\MarkdownExtra',
'html5' => true,
],
];
/**
* @var string the markdown flavor to use when none is specified explicitly.
* Defaults to `original`.
* @see flavors
*/
public static $defaultFlavor = 'original';
/**
* Converts markdown into HTML.
*
* @param string $markdown the markdown text to parse
* @param string|null $flavor the markdown flavor to use. See [[$flavors]] for available values.
* Defaults to [[$defaultFlavor]], if not set.
* @return string the parsed HTML output
* @throws InvalidArgumentException when an undefined flavor is given.
*/
public static function process($markdown, $flavor = null)
{
$parser = static::getParser($flavor);
return $parser->parse($markdown);
}
/**
* Converts markdown into HTML but only parses inline elements.
*
* This can be useful for parsing small comments or description lines.
*
* @param string $markdown the markdown text to parse
* @param string|null $flavor the markdown flavor to use. See [[$flavors]] for available values.
* Defaults to [[$defaultFlavor]], if not set.
* @return string the parsed HTML output
* @throws InvalidArgumentException when an undefined flavor is given.
*/
public static function processParagraph($markdown, $flavor = null)
{
$parser = static::getParser($flavor);
return $parser->parseParagraph($markdown);
}
/**
* @param string|null $flavor the markdown flavor to use. See [[$flavors]] for available values.
* Defaults to [[$defaultFlavor]], if not set.
* @return \cebe\markdown\Parser
* @throws InvalidArgumentException when an undefined flavor is given.
*/
protected static function getParser($flavor)
{
if ($flavor === null) {
$flavor = static::$defaultFlavor;
}
if (!isset(static::$flavors[$flavor])) {
throw new InvalidArgumentException("Markdown flavor '$flavor' is not defined.'");
} elseif (!is_object($config = static::$flavors[$flavor])) {
static::$flavors[$flavor] = Yii::createObject($config);
}
return static::$flavors[$flavor];
}
}

View File

@ -0,0 +1,590 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
use Yii;
/**
* BaseStringHelper provides concrete implementation for [[StringHelper]].
*
* Do not use BaseStringHelper. Use [[StringHelper]] instead.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Alex Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class BaseStringHelper
{
/**
* Returns the number of bytes in the given string.
* This method ensures the string is treated as a byte array by using `mb_strlen()`.
*
* @param string $string the string being measured for length
* @return int the number of bytes in the given string.
*/
public static function byteLength($string)
{
return mb_strlen((string)$string, '8bit');
}
/**
* Returns the portion of string specified by the start and length parameters.
* This method ensures the string is treated as a byte array by using `mb_substr()`.
*
* @param string $string the input string. Must be one character or longer.
* @param int $start the starting position
* @param int|null $length the desired portion length. If not specified or `null`, there will be
* no limit on length i.e. the output will be until the end of the string.
* @return string the extracted part of string, or FALSE on failure or an empty string.
* @see https://www.php.net/manual/en/function.substr.php
*/
public static function byteSubstr($string, $start, $length = null)
{
if ($length === null) {
$length = static::byteLength($string);
}
return mb_substr((string)$string, $start, $length, '8bit');
}
/**
* Converts php.ini style size to bytes.
*
* @param string $string php.ini style size. Examples: `512M`, `1024K`, `1G`, `256`.
* @return int the number of bytes equivalent to the specified string.
* @since 2.0.54
*/
public static function convertIniSizeToBytes($string)
{
switch (substr($string, -1)) {
case 'M':
case 'm':
return (int) $string * 1048576;
case 'K':
case 'k':
return (int) $string * 1024;
case 'G':
case 'g':
return (int) $string * 1073741824;
default:
return (int) $string;
}
}
/**
* Returns the trailing name component of a path.
* This method is similar to the php function `basename()` except that it will
* treat both \ and / as directory separators, independent of the operating system.
* This method was mainly created to work on php namespaces. When working with real
* file paths, php's `basename()` should work fine for you.
* Note: this method is not aware of the actual filesystem, or path components such as "..".
*
* @param string $path A path string.
* @param string $suffix If the name component ends in suffix this will also be cut off.
* @return string the trailing name component of the given path.
* @see https://www.php.net/manual/en/function.basename.php
*/
public static function basename($path, $suffix = '')
{
$path = (string)$path;
$len = mb_strlen($suffix);
if ($len > 0 && mb_substr($path, -$len) === $suffix) {
$path = mb_substr($path, 0, -$len);
}
$path = rtrim(str_replace('\\', '/', $path), '/');
$pos = mb_strrpos($path, '/');
if ($pos !== false) {
return mb_substr($path, $pos + 1);
}
return $path;
}
/**
* Returns parent directory's path.
* This method is similar to `dirname()` except that it will treat
* both \ and / as directory separators, independent of the operating system.
*
* @param string $path A path string.
* @return string the parent directory's path.
* @see https://www.php.net/manual/en/function.basename.php
*/
public static function dirname($path)
{
$normalizedPath = rtrim(
str_replace('\\', '/', (string)$path),
'/'
);
$separatorPosition = mb_strrpos($normalizedPath, '/');
if ($separatorPosition !== false) {
return mb_substr($path, 0, $separatorPosition);
}
return '';
}
/**
* Truncates a string to the number of characters specified.
*
* In order to truncate for an exact length, the $suffix char length must be counted towards the $length. For example
* to have a string which is exactly 255 long with $suffix `...` of 3 chars, then `StringHelper::truncate($string, 252, '...')`
* must be used to ensure you have 255 long string afterwards.
*
* @param string $string The string to truncate.
* @param int $length How many characters from original string to include into truncated string.
* @param string $suffix String to append to the end of truncated string.
* @param string|null $encoding The charset to use, defaults to charset currently used by application.
* @param bool $asHtml Whether to treat the string being truncated as HTML and preserve proper HTML tags.
* This parameter is available since version 2.0.1.
* @return string the truncated string.
*/
public static function truncate($string, $length, $suffix = '...', $encoding = null, $asHtml = false)
{
$string = (string)$string;
if ($encoding === null) {
$encoding = Yii::$app ? Yii::$app->charset : 'UTF-8';
}
if ($asHtml) {
return static::truncateHtml($string, $length, $suffix, $encoding);
}
if (mb_strlen($string, $encoding) > $length) {
return rtrim(mb_substr($string, 0, $length, $encoding)) . $suffix;
}
return $string;
}
/**
* Truncates a string to the number of words specified.
*
* @param string $string The string to truncate.
* @param int $count How many words from original string to include into truncated string.
* @param string $suffix String to append to the end of truncated string.
* @param bool $asHtml Whether to treat the string being truncated as HTML and preserve proper HTML tags.
* This parameter is available since version 2.0.1.
* @return string the truncated string.
*/
public static function truncateWords($string, $count, $suffix = '...', $asHtml = false)
{
if ($asHtml) {
return static::truncateHtml($string, $count, $suffix);
}
$words = preg_split('/(\s+)/u', trim($string), 0, PREG_SPLIT_DELIM_CAPTURE);
if (count($words) / 2 > $count) {
return implode('', array_slice($words, 0, ($count * 2) - 1)) . $suffix;
}
return $string;
}
/**
* Truncate a string while preserving the HTML.
*
* @param string $string The string to truncate
* @param int $count The counter
* @param string $suffix String to append to the end of the truncated string.
* @param string|bool $encoding Encoding flag or charset.
* @return string
* @since 2.0.1
*/
protected static function truncateHtml($string, $count, $suffix, $encoding = false)
{
$config = \HTMLPurifier_Config::create(null);
if (Yii::$app !== null) {
$config->set('Cache.SerializerPath', Yii::$app->getRuntimePath());
}
$lexer = \HTMLPurifier_Lexer::create($config);
$tokens = $lexer->tokenizeHTML($string, $config, new \HTMLPurifier_Context());
$openTokens = [];
$totalCount = 0;
$depth = 0;
$truncated = [];
foreach ($tokens as $token) {
if ($token instanceof \HTMLPurifier_Token_Start) { //Tag begins
$openTokens[$depth] = $token->name;
$truncated[] = $token;
++$depth;
} elseif ($token instanceof \HTMLPurifier_Token_Text && $totalCount <= $count) { //Text
if (false === $encoding) {
preg_match('/^(\s*)/um', $token->data, $prefixSpace) ?: $prefixSpace = ['', ''];
$token->data = $prefixSpace[1] . self::truncateWords(ltrim($token->data), $count - $totalCount, '');
$currentCount = self::countWords($token->data);
} else {
$token->data = self::truncate($token->data, $count - $totalCount, '', $encoding);
$currentCount = mb_strlen($token->data, $encoding);
}
$totalCount += $currentCount;
$truncated[] = $token;
} elseif ($token instanceof \HTMLPurifier_Token_End) { //Tag ends
if ($token->name === $openTokens[$depth - 1]) {
--$depth;
unset($openTokens[$depth]);
$truncated[] = $token;
}
} elseif ($token instanceof \HTMLPurifier_Token_Empty) { //Self contained tags, i.e. <img/> etc.
$truncated[] = $token;
}
if ($totalCount >= $count) {
if (0 < count($openTokens)) {
krsort($openTokens);
foreach ($openTokens as $name) {
$truncated[] = new \HTMLPurifier_Token_End($name);
}
}
break;
}
}
$context = new \HTMLPurifier_Context();
$generator = new \HTMLPurifier_Generator($config, $context);
return $generator->generateFromTokens($truncated) . ($totalCount >= $count ? $suffix : '');
}
/**
* Check if given string starts with specified substring. Binary and multibyte safe.
*
* @param string $string Input string
* @param string $with Part to search inside the $string
* @param bool $caseSensitive Case sensitive search. Default is true. When case sensitive is enabled, `$with` must
* exactly match the starting of the string in order to get a true value.
* @return bool Returns true if first input starts with second input, false otherwise
*/
public static function startsWith($string, $with, $caseSensitive = true)
{
$string = (string)$string;
$with = (string)$with;
if (!$bytes = static::byteLength($with)) {
return true;
}
if ($caseSensitive) {
return strncmp($string, $with, $bytes) === 0;
}
$encoding = Yii::$app ? Yii::$app->charset : 'UTF-8';
$string = static::byteSubstr($string, 0, $bytes);
return mb_strtolower($string, $encoding) === mb_strtolower($with, $encoding);
}
/**
* Check if given string ends with specified substring. Binary and multibyte safe.
*
* @param string $string Input string to check
* @param string $with Part to search inside of the `$string`.
* @param bool $caseSensitive Case sensitive search. Default is true. When case sensitive is enabled, `$with` must
* exactly match the ending of the string in order to get a true value.
* @return bool Returns true if first input ends with second input, false otherwise
*/
public static function endsWith($string, $with, $caseSensitive = true)
{
$string = (string)$string;
$with = (string)$with;
if (!$bytes = static::byteLength($with)) {
return true;
}
if ($caseSensitive) {
// Warning check, see https://php.net/substr-compare#refsect1-function.substr-compare-returnvalues
if (static::byteLength($string) < $bytes) {
return false;
}
return substr_compare($string, $with, -$bytes, $bytes) === 0;
}
$encoding = Yii::$app ? Yii::$app->charset : 'UTF-8';
$string = static::byteSubstr($string, -$bytes);
return mb_strtolower($string, $encoding) === mb_strtolower($with, $encoding);
}
/**
* Explodes string into array, optionally trims values and skips empty ones.
*
* @param string $string String to be exploded.
* @param string $delimiter Delimiter. Default is ','.
* @param mixed $trim Whether to trim each element. Can be:
* - boolean - to trim normally;
* - string - custom characters to trim. Will be passed as a second argument to `trim()` function.
* - callable - will be called for each value instead of trim. Takes the only argument - value.
* @param bool $skipEmpty Whether to skip empty strings between delimiters. Default is false.
* @return array
* @since 2.0.4
*/
public static function explode($string, $delimiter = ',', $trim = true, $skipEmpty = false)
{
$result = explode($delimiter, $string);
if ($trim !== false) {
if ($trim === true) {
$trim = 'trim';
} elseif (!is_callable($trim)) {
$trim = function ($v) use ($trim) {
return trim($v, $trim);
};
}
$result = array_map($trim, $result);
}
if ($skipEmpty) {
// Wrapped with array_values to make array keys sequential after empty values removing
$result = array_values(
array_filter(
$result,
function ($value) {
return $value !== '';
}
)
);
}
return $result;
}
/**
* Counts words in a string.
*
* @param string $string the text to calculate
* @return int
* @since 2.0.8
*/
public static function countWords($string)
{
return count(preg_split('/\s+/u', $string, 0, PREG_SPLIT_NO_EMPTY));
}
/**
* Returns string representation of number value with replaced commas to dots, if decimal point
* of current locale is comma.
*
* @param int|float|string $value the value to normalize.
* @return string
* @since 2.0.11
*/
public static function normalizeNumber($value)
{
$value = (string)$value;
$localeInfo = localeconv();
$decimalSeparator = isset($localeInfo['decimal_point']) ? $localeInfo['decimal_point'] : null;
if ($decimalSeparator !== null && $decimalSeparator !== '.') {
$value = str_replace($decimalSeparator, '.', $value);
}
return $value;
}
/**
* Encodes string into "Base 64 Encoding with URL and Filename Safe Alphabet" (RFC 4648).
*
* > Note: Base 64 padding `=` may be at the end of the returned string.
* > `=` is not transparent to URL encoding.
*
* @param string $input the string to encode.
* @return string encoded string.
* @see https://tools.ietf.org/html/rfc4648#page-7
* @since 2.0.12
*/
public static function base64UrlEncode($input)
{
return strtr(base64_encode($input), '+/', '-_');
}
/**
* Decodes "Base 64 Encoding with URL and Filename Safe Alphabet" (RFC 4648).
*
* @param string $input encoded string.
* @return string decoded string.
* @see https://tools.ietf.org/html/rfc4648#page-7
* @since 2.0.12
*/
public static function base64UrlDecode($input)
{
return base64_decode(strtr($input, '-_', '+/'));
}
/**
* Safely casts a float to string independent of the current locale.
* The decimal separator will always be `.`.
*
* @param float|int $number a floating point number or integer.
* @return string the string representation of the number.
* @since 2.0.13
*/
public static function floatToString($number)
{
// . and , are the only decimal separators known in ICU data,
// so its safe to call str_replace here
return str_replace(',', '.', (string)$number);
}
/**
* Checks if the passed string would match the given shell wildcard pattern.
* This function emulates [[fnmatch()]], which may be unavailable at certain environment, using PCRE.
*
* @param string $pattern the shell wildcard pattern.
* @param string $string the tested string.
* @param array $options options for matching. Valid options are:
*
* - caseSensitive: bool, whether pattern should be case sensitive. Defaults to `true`.
* - escape: bool, whether backslash escaping is enabled. Defaults to `true`.
* - filePath: bool, whether slashes in string only matches slashes in the given pattern. Defaults to `false`.
*
* @return bool whether the string matches pattern or not.
* @since 2.0.14
*/
public static function matchWildcard($pattern, $string, $options = [])
{
if ($pattern === '*' && empty($options['filePath'])) {
return true;
}
$replacements = [
'\\\\\\\\' => '\\\\',
'\\\\\\*' => '[*]',
'\\\\\\?' => '[?]',
'\*' => '.*',
'\?' => '.',
'\[\!' => '[^',
'\[' => '[',
'\]' => ']',
'\-' => '-',
];
if (isset($options['escape']) && !$options['escape']) {
unset($replacements['\\\\\\\\']);
unset($replacements['\\\\\\*']);
unset($replacements['\\\\\\?']);
}
if (!empty($options['filePath'])) {
$replacements['\*'] = '[^/\\\\]*';
$replacements['\?'] = '[^/\\\\]';
}
$pattern = strtr(preg_quote($pattern, '#'), $replacements);
$pattern = '#^' . $pattern . '$#us';
if (isset($options['caseSensitive']) && !$options['caseSensitive']) {
$pattern .= 'i';
}
return preg_match($pattern, (string)$string) === 1;
}
/**
* This method provides a unicode-safe implementation of built-in PHP function `ucfirst()`.
*
* @param string $string the string to be proceeded
* @param string $encoding Optional, defaults to "UTF-8"
* @return string
* @see https://www.php.net/manual/en/function.ucfirst.php
* @since 2.0.16
* @phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
*/
public static function mb_ucfirst($string, $encoding = 'UTF-8')
{
$firstChar = mb_substr((string)$string, 0, 1, $encoding);
$rest = mb_substr((string)$string, 1, null, $encoding);
return mb_strtoupper($firstChar, $encoding) . $rest;
}
/**
* This method provides a unicode-safe implementation of built-in PHP function `ucwords()`.
*
* @param string $string the string to be proceeded
* @param string $encoding Optional, defaults to "UTF-8"
* @return string
* @see https://www.php.net/manual/en/function.ucwords
* @since 2.0.16
* @phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
*/
public static function mb_ucwords($string, $encoding = 'UTF-8')
{
$string = (string)$string;
if (empty($string)) {
return $string;
}
$parts = preg_split('/(\s+\W+\s+|^\W+\s+|\s+)/u', $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$ucfirstEven = trim(mb_substr($parts[0], -1, 1, $encoding)) === '';
foreach ($parts as $key => $value) {
$isEven = (bool)($key % 2);
if ($ucfirstEven === $isEven) {
$parts[$key] = static::mb_ucfirst($value, $encoding);
}
}
return implode('', $parts);
}
/**
* Masks a portion of a string with a repeated character.
* This method is multibyte-safe.
*
* @param string $string The input string.
* @param int $start The starting position from where to begin masking.
* This can be a positive or negative integer.
* Positive values count from the beginning,
* negative values count from the end of the string.
* @param int $length The length of the section to be masked.
* The masking will start from the $start position
* and continue for $length characters.
* @param string $mask The character to use for masking. The default is '*'.
* @return string The masked string.
*/
public static function mask($string, $start, $length, $mask = '*')
{
$strLength = mb_strlen($string, 'UTF-8');
// Return original string if start position is out of bounds
if ($start >= $strLength || $start < -$strLength) {
return $string;
}
$masked = mb_substr($string, 0, $start, 'UTF-8');
$masked .= str_repeat($mask, abs($length));
$masked .= mb_substr($string, $start + abs($length), null, 'UTF-8');
return $masked;
}
/**
* Returns the portion of the string that lies between the first occurrence of the start string
* and the last occurrence of the end string after that.
*
* @param string $string The input string.
* @param string $start The string marking the start of the portion to extract.
* @param string $end The string marking the end of the portion to extract.
* @return string|null The portion of the string between the first occurrence of
* start and the last occurrence of end, or null if either start or end cannot be found.
*/
public static function findBetween($string, $start, $end)
{
$startPos = mb_strpos($string, $start);
if ($startPos === false) {
return null;
}
$startPos += mb_strlen($start);
$endPos = mb_strrpos($string, $end, $startPos);
if ($endPos === false) {
return null;
}
return mb_substr($string, $startPos, $endPos - $startPos);
}
}

444
vendor/yiisoft/yii2/helpers/BaseUrl.php vendored Normal file
View File

@ -0,0 +1,444 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
use Yii;
use yii\base\InvalidArgumentException;
/**
* BaseUrl provides concrete implementation for [[Url]].
*
* Do not use BaseUrl. Use [[Url]] instead.
*
* @author Alexander Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class BaseUrl
{
/**
* @var \yii\web\UrlManager URL manager to use for creating URLs
* @since 2.0.8
*/
public static $urlManager;
/**
* Creates a URL for the given route.
*
* This method will use [[\yii\web\UrlManager]] to create a URL.
*
* You may specify the route as a string, e.g., `site/index`. You may also use an array
* if you want to specify additional query parameters for the URL being created. The
* array format must be:
*
* ```
* // generates: /index.php?r=site/index&param1=value1&param2=value2
* ['site/index', 'param1' => 'value1', 'param2' => 'value2']
* ```
*
* If you want to create a URL with an anchor, you can use the array format with a `#` parameter.
* For example,
*
* ```
* // generates: /index.php?r=site/index&param1=value1#name
* ['site/index', 'param1' => 'value1', '#' => 'name']
* ```
*
* A route may be either absolute or relative. An absolute route has a leading slash (e.g. `/site/index`),
* while a relative route has none (e.g. `site/index` or `index`). A relative route will be converted
* into an absolute one by the following rules:
*
* - If the route is an empty string, the current [[\yii\web\Controller::route|route]] will be used;
* - If the route contains no slashes at all (e.g. `index`), it is considered to be an action ID
* of the current controller and will be prepended with [[\yii\web\Controller::uniqueId]];
* - If the route has no leading slash (e.g. `site/index`), it is considered to be a route relative
* to the current module and will be prepended with the module's [[\yii\base\Module::uniqueId|uniqueId]].
*
* Starting from version 2.0.2, a route can also be specified as an alias. In this case, the alias
* will be converted into the actual route first before conducting the above transformation steps.
*
* Below are some examples of using this method:
*
* ```
* // /index.php?r=site%2Findex
* echo Url::toRoute('site/index');
*
* // /index.php?r=site%2Findex&src=ref1#name
* echo Url::toRoute(['site/index', 'src' => 'ref1', '#' => 'name']);
*
* // https://www.example.com/index.php?r=site%2Findex
* echo Url::toRoute('site/index', true);
*
* // https://www.example.com/index.php?r=site%2Findex
* echo Url::toRoute('site/index', 'https');
*
* // /index.php?r=post%2Findex assume the alias "@posts" is defined as "post/index"
* echo Url::toRoute('@posts');
* ```
*
* @param string|array $route use a string to represent a route (e.g. `index`, `site/index`),
* or an array to represent a route with query parameters (e.g. `['site/index', 'param1' => 'value1']`).
* @param bool|string $scheme the URI scheme to use in the generated URL:
*
* - `false` (default): generating a relative URL.
* - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]].
* - string: generating an absolute URL with the specified scheme (either `http`, `https` or empty string
* for protocol-relative URL).
*
* @return string the generated URL
* @throws InvalidArgumentException a relative route is given while there is no active controller
*/
public static function toRoute($route, $scheme = false)
{
$route = (array) $route;
$route[0] = static::normalizeRoute($route[0]);
if ($scheme !== false) {
return static::getUrlManager()->createAbsoluteUrl($route, is_string($scheme) ? $scheme : null);
}
return static::getUrlManager()->createUrl($route);
}
/**
* Normalizes route and makes it suitable for UrlManager. Absolute routes are staying as is
* while relative routes are converted to absolute ones.
*
* A relative route is a route without a leading slash, such as "view", "post/view".
*
* - If the route is an empty string, the current [[\yii\web\Controller::route|route]] will be used;
* - If the route contains no slashes at all, it is considered to be an action ID
* of the current controller and will be prepended with [[\yii\web\Controller::uniqueId]];
* - If the route has no leading slash, it is considered to be a route relative
* to the current module and will be prepended with the module's uniqueId.
*
* Starting from version 2.0.2, a route can also be specified as an alias. In this case, the alias
* will be converted into the actual route first before conducting the above transformation steps.
*
* @param string $route the route. This can be either an absolute route or a relative route.
* @return string normalized route suitable for UrlManager
* @throws InvalidArgumentException a relative route is given while there is no active controller
*/
protected static function normalizeRoute($route)
{
$route = Yii::getAlias((string) $route);
if (strncmp($route, '/', 1) === 0) {
// absolute route
return ltrim($route, '/');
}
// relative route
if (Yii::$app->controller === null) {
throw new InvalidArgumentException("Unable to resolve the relative route: $route. No active controller is available.");
}
if (strpos($route, '/') === false) {
// empty or an action ID
return $route === '' ? Yii::$app->controller->getRoute() : Yii::$app->controller->getUniqueId() . '/' . $route;
}
// relative to module
return ltrim(Yii::$app->controller->module->getUniqueId() . '/' . $route, '/');
}
/**
* Creates a URL based on the given parameters.
*
* This method is very similar to [[toRoute()]]. The only difference is that this method
* requires a route to be specified as an array only. If a string is given, it will be treated as a URL.
* In particular, if `$url` is
*
* - an array: [[toRoute()]] will be called to generate the URL. For example:
* `['site/index']`, `['post/index', 'page' => 2]`. Please refer to [[toRoute()]] for more details
* on how to specify a route.
* - a string with a leading `@`: it is treated as an alias, and the corresponding aliased string
* will be returned.
* - an empty string: the currently requested URL will be returned;
* - a normal string: it will be returned as is.
*
* When `$scheme` is specified (either a string or `true`), an absolute URL with host info (obtained from
* [[\yii\web\UrlManager::$hostInfo]]) will be returned. If `$url` is already an absolute URL, its scheme
* will be replaced with the specified one.
*
* Below are some examples of using this method:
*
* ```
* // /index.php?r=site%2Findex
* echo Url::to(['site/index']);
*
* // /index.php?r=site%2Findex&src=ref1#name
* echo Url::to(['site/index', 'src' => 'ref1', '#' => 'name']);
*
* // /index.php?r=post%2Findex assume the alias "@posts" is defined as "/post/index"
* echo Url::to(['@posts']);
*
* // the currently requested URL
* echo Url::to();
*
* // /images/logo.gif
* echo Url::to('@web/images/logo.gif');
*
* // images/logo.gif
* echo Url::to('images/logo.gif');
*
* // https://www.example.com/images/logo.gif
* echo Url::to('@web/images/logo.gif', true);
*
* // https://www.example.com/images/logo.gif
* echo Url::to('@web/images/logo.gif', 'https');
*
* // //www.example.com/images/logo.gif
* echo Url::to('@web/images/logo.gif', '');
* ```
*
*
* @param array|string $url the parameter to be used to generate a valid URL
* @param bool|string $scheme the URI scheme to use in the generated URL:
*
* - `false` (default): generating a relative URL.
* - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]].
* - string: generating an absolute URL with the specified scheme (either `http`, `https` or empty string
* for protocol-relative URL).
*
* @return string the generated URL
* @throws InvalidArgumentException a relative route is given while there is no active controller
*/
public static function to($url = '', $scheme = false)
{
if (is_array($url)) {
return static::toRoute($url, $scheme);
}
$url = Yii::getAlias($url);
if ($url === '') {
$url = Yii::$app->getRequest()->getUrl();
}
if ($scheme === false) {
return $url;
}
if (static::isRelative($url)) {
// turn relative URL into absolute
$url = static::getUrlManager()->getHostInfo() . '/' . ltrim($url, '/');
}
return static::ensureScheme($url, $scheme);
}
/**
* Normalize the URL by ensuring it uses specified scheme.
*
* If the URL is relative or the scheme is not a string, normalization is skipped.
*
* @param string $url the URL to process
* @param string $scheme the URI scheme used in the URL (e.g. `http` or `https`). Use an empty string to
* create protocol-relative URL (e.g. `//example.com/path`)
* @return string the processed URL
* @since 2.0.11
*/
public static function ensureScheme($url, $scheme)
{
if (static::isRelative($url) || !is_string($scheme)) {
return $url;
}
if (strncmp($url, '//', 2) === 0) {
// e.g. //example.com/path/to/resource
return $scheme === '' ? $url : "$scheme:$url";
}
if (($pos = strpos($url, '://')) !== false) {
if ($scheme === '') {
$url = substr($url, $pos + 1);
} else {
$url = $scheme . substr($url, $pos);
}
}
return $url;
}
/**
* Returns the base URL of the current request.
* @param bool|string $scheme the URI scheme to use in the returned base URL:
*
* - `false` (default): returning the base URL without host info.
* - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]].
* - string: returning an absolute base URL with the specified scheme (either `http`, `https` or empty string
* for protocol-relative URL).
* @return string
*/
public static function base($scheme = false)
{
$url = static::getUrlManager()->getBaseUrl();
if ($scheme !== false) {
$url = static::getUrlManager()->getHostInfo() . $url;
$url = static::ensureScheme($url, $scheme);
}
return $url;
}
/**
* Remembers the specified URL so that it can be later fetched back by [[previous()]].
*
* @param string|array $url the URL to remember. Please refer to [[to()]] for acceptable formats.
* If this parameter is not specified, the currently requested URL will be used.
* @param string|null $name the name associated with the URL to be remembered. This can be used
* later by [[previous()]]. If not set, [[\yii\web\User::setReturnUrl()]] will be used with passed URL.
* @see previous()
* @see \yii\web\User::setReturnUrl()
*/
public static function remember($url = '', $name = null)
{
$url = static::to($url);
if ($name === null) {
Yii::$app->getUser()->setReturnUrl($url);
} else {
Yii::$app->getSession()->set($name, $url);
}
}
/**
* Returns the URL previously [[remember()|remembered]].
*
* @param string|null $name the named associated with the URL that was remembered previously.
* If not set, [[\yii\web\User::getReturnUrl()]] will be used to obtain remembered URL.
* @return string|null the URL previously remembered. Null is returned if no URL was remembered with the given name
* and `$name` is not specified.
* @see remember()
* @see \yii\web\User::getReturnUrl()
*/
public static function previous($name = null)
{
if ($name === null) {
return Yii::$app->getUser()->getReturnUrl();
}
return Yii::$app->getSession()->get($name);
}
/**
* Returns the canonical URL of the currently requested page.
*
* The canonical URL is constructed using the current controller's [[\yii\web\Controller::route]] and
* [[\yii\web\Controller::actionParams]]. You may use the following code in the layout view to add a link tag
* about canonical URL:
*
* ```
* $this->registerLinkTag(['rel' => 'canonical', 'href' => Url::canonical()]);
* ```
*
* @return string the canonical URL of the currently requested page
*/
public static function canonical()
{
$params = Yii::$app->controller->actionParams;
$params[0] = Yii::$app->controller->getRoute();
return static::getUrlManager()->createAbsoluteUrl($params);
}
/**
* Returns the home URL.
*
* @param bool|string $scheme the URI scheme to use for the returned URL:
*
* - `false` (default): returning a relative URL.
* - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]].
* - string: returning an absolute URL with the specified scheme (either `http`, `https` or empty string
* for protocol-relative URL).
*
* @return string home URL
*/
public static function home($scheme = false)
{
$url = Yii::$app->getHomeUrl();
if ($scheme !== false) {
$url = static::getUrlManager()->getHostInfo() . $url;
$url = static::ensureScheme($url, $scheme);
}
return $url;
}
/**
* Returns a value indicating whether a URL is relative.
* A relative URL does not have host info part.
* @param string $url the URL to be checked
* @return bool whether the URL is relative
*/
public static function isRelative($url)
{
return preg_match('~^[[:alpha:]][[:alnum:]+-.]*://|^//~', $url) === 0;
}
/**
* Creates a URL by using the current route and the GET parameters.
*
* You may modify or remove some of the GET parameters, or add additional query parameters through
* the `$params` parameter. In particular, if you specify a parameter to be null, then this parameter
* will be removed from the existing GET parameters; all other parameters specified in `$params` will
* be merged with the existing GET parameters. For example,
*
* ```
* // assume $_GET = ['id' => 123, 'src' => 'google'], current route is "post/view"
*
* // /index.php?r=post%2Fview&id=123&src=google
* echo Url::current();
*
* // /index.php?r=post%2Fview&id=123
* echo Url::current(['src' => null]);
*
* // /index.php?r=post%2Fview&id=100&src=google
* echo Url::current(['id' => 100]);
* ```
*
* Note that if you're replacing array parameters with `[]` at the end you should specify `$params` as nested arrays.
* For a `PostSearchForm` model where parameter names are `PostSearchForm[id]` and `PostSearchForm[src]` the syntax
* would be the following:
*
* ```
* // index.php?r=post%2Findex&PostSearchForm%5Bid%5D=100&PostSearchForm%5Bsrc%5D=google
* echo Url::current([
* $postSearch->formName() => ['id' => 100, 'src' => 'google'],
* ]);
* ```
*
* @param array $params an associative array of parameters that will be merged with the current GET parameters.
* If a parameter value is null, the corresponding GET parameter will be removed.
* @param bool|string $scheme the URI scheme to use in the generated URL:
*
* - `false` (default): generating a relative URL.
* - `true`: returning an absolute base URL whose scheme is the same as that in [[\yii\web\UrlManager::$hostInfo]].
* - string: generating an absolute URL with the specified scheme (either `http`, `https` or empty string
* for protocol-relative URL).
*
* @return string the generated URL
* @since 2.0.3
*/
public static function current(array $params = [], $scheme = false)
{
$currentParams = Yii::$app->getRequest()->getQueryParams();
$currentParams[0] = '/' . Yii::$app->controller->getRoute();
$route = array_replace_recursive($currentParams, $params);
return static::toRoute($route, $scheme);
}
/**
* @return \yii\web\UrlManager URL manager used to create URLs
* @since 2.0.8
*/
protected static function getUrlManager()
{
return static::$urlManager ?: Yii::$app->getUrlManager();
}
}

View File

@ -0,0 +1,272 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
use yii\base\Arrayable;
use yii\base\InvalidValueException;
/**
* BaseVarDumper provides concrete implementation for [[VarDumper]].
*
* Do not use BaseVarDumper. Use [[VarDumper]] instead.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class BaseVarDumper
{
private static $_objects;
private static $_output;
private static $_depth;
/**
* Displays a variable.
* This method achieves the similar functionality as var_dump and print_r
* but is more robust when handling complex objects such as Yii controllers.
* @param mixed $var variable to be dumped
* @param int $depth maximum depth that the dumper should go into the variable. Defaults to 10.
* @param bool $highlight whether the result should be syntax-highlighted
*/
public static function dump($var, $depth = 10, $highlight = false)
{
echo static::dumpAsString($var, $depth, $highlight);
}
/**
* Dumps a variable in terms of a string.
* This method achieves the similar functionality as var_dump and print_r
* but is more robust when handling complex objects such as Yii controllers.
* @param mixed $var variable to be dumped
* @param int $depth maximum depth that the dumper should go into the variable. Defaults to 10.
* @param bool $highlight whether the result should be syntax-highlighted
* @return string the string representation of the variable
*/
public static function dumpAsString($var, $depth = 10, $highlight = false)
{
self::$_output = '';
self::$_objects = [];
self::$_depth = $depth;
self::dumpInternal($var, 0);
if ($highlight) {
$result = highlight_string("<?php\n" . self::$_output, true);
self::$_output = preg_replace('/&lt;\\?php<br \\/>/', '', $result, 1);
}
return self::$_output;
}
/**
* @param mixed $var variable to be dumped
* @param int $level depth level
*/
private static function dumpInternal($var, $level)
{
switch (gettype($var)) {
case 'boolean':
self::$_output .= $var ? 'true' : 'false';
break;
case 'integer':
self::$_output .= (string)$var;
break;
case 'double':
self::$_output .= (string)$var;
break;
case 'string':
self::$_output .= "'" . addslashes($var) . "'";
break;
case 'resource':
self::$_output .= '{resource}';
break;
case 'NULL':
self::$_output .= 'null';
break;
case 'unknown type':
self::$_output .= '{unknown}';
break;
case 'array':
if (self::$_depth <= $level) {
self::$_output .= '[...]';
} elseif (empty($var)) {
self::$_output .= '[]';
} else {
$keys = array_keys($var);
$spaces = str_repeat(' ', $level * 4);
self::$_output .= '[';
foreach ($keys as $key) {
self::$_output .= "\n" . $spaces . ' ';
self::dumpInternal($key, 0);
self::$_output .= ' => ';
self::dumpInternal($var[$key], $level + 1);
}
self::$_output .= "\n" . $spaces . ']';
}
break;
case 'object':
if (($id = array_search($var, self::$_objects, true)) !== false) {
self::$_output .= get_class($var) . '#' . ($id + 1) . '(...)';
} elseif (self::$_depth <= $level) {
self::$_output .= get_class($var) . '(...)';
} else {
$id = array_push(self::$_objects, $var);
$className = get_class($var);
$spaces = str_repeat(' ', $level * 4);
self::$_output .= "$className#$id\n" . $spaces . '(';
if ('__PHP_Incomplete_Class' !== get_class($var) && method_exists($var, '__debugInfo')) {
$dumpValues = $var->__debugInfo();
if (!is_array($dumpValues)) {
throw new InvalidValueException('__debuginfo() must return an array');
}
} else {
$dumpValues = (array) $var;
}
foreach ($dumpValues as $key => $value) {
$keyDisplay = strtr(trim($key), "\0", ':');
self::$_output .= "\n" . $spaces . " [$keyDisplay] => ";
self::dumpInternal($value, $level + 1);
}
self::$_output .= "\n" . $spaces . ')';
}
break;
}
}
/**
* Exports a variable as a string representation.
*
* The string is a valid PHP expression that can be evaluated by PHP parser
* and the evaluation result will give back the variable value.
*
* This method is similar to `var_export()`. The main difference is that
* it generates more compact string representation using short array syntax.
*
* It also handles objects by using the PHP functions serialize() and unserialize().
*
* PHP 5.4 or above is required to parse the exported value.
*
* @param mixed $var the variable to be exported.
* @return string a string representation of the variable
*/
public static function export($var)
{
self::$_output = '';
self::exportInternal($var, 0);
return self::$_output;
}
/**
* @param mixed $var variable to be exported
* @param int $level depth level
*/
private static function exportInternal($var, $level)
{
switch (gettype($var)) {
case 'NULL':
self::$_output .= 'null';
break;
case 'array':
if (empty($var)) {
self::$_output .= '[]';
} else {
$keys = array_keys($var);
$outputKeys = ($keys !== range(0, count($var) - 1));
$spaces = str_repeat(' ', $level * 4);
self::$_output .= '[';
foreach ($keys as $key) {
self::$_output .= "\n" . $spaces . ' ';
if ($outputKeys) {
self::exportInternal($key, 0);
self::$_output .= ' => ';
}
self::exportInternal($var[$key], $level + 1);
self::$_output .= ',';
}
self::$_output .= "\n" . $spaces . ']';
}
break;
case 'object':
if ($var instanceof \Closure) {
self::$_output .= self::exportClosure($var);
} else {
try {
$output = 'unserialize(' . var_export(serialize($var), true) . ')';
} catch (\Exception $e) {
// serialize may fail, for example: if object contains a `\Closure` instance
// so we use a fallback
if ($var instanceof Arrayable) {
self::exportInternal($var->toArray(), $level);
return;
} elseif ($var instanceof \IteratorAggregate) {
$varAsArray = [];
foreach ($var as $key => $value) {
$varAsArray[$key] = $value;
}
self::exportInternal($varAsArray, $level);
return;
} elseif ('__PHP_Incomplete_Class' !== get_class($var) && method_exists($var, '__toString')) {
$output = var_export($var->__toString(), true);
} else {
$outputBackup = self::$_output;
$output = var_export(self::dumpAsString($var), true);
self::$_output = $outputBackup;
}
}
self::$_output .= $output;
}
break;
default:
self::$_output .= var_export($var, true);
}
}
/**
* Exports a [[Closure]] instance.
* @param \Closure $closure closure instance.
* @return string
*/
private static function exportClosure(\Closure $closure)
{
$reflection = new \ReflectionFunction($closure);
$fileName = $reflection->getFileName();
$start = $reflection->getStartLine();
$end = $reflection->getEndLine();
if ($fileName === false || $start === false || $end === false) {
return 'function() {/* Error: unable to determine Closure source */}';
}
--$start;
$source = implode("\n", array_slice(file($fileName), $start, $end - $start));
$tokens = token_get_all('<?php ' . $source);
array_shift($tokens);
$closureTokens = [];
$pendingParenthesisCount = 0;
foreach ($tokens as $token) {
if (isset($token[0]) && $token[0] === T_FUNCTION) {
$closureTokens[] = $token[1];
continue;
}
if ($closureTokens !== []) {
$closureTokens[] = isset($token[1]) ? $token[1] : $token;
if ($token === '}') {
$pendingParenthesisCount--;
if ($pendingParenthesisCount === 0) {
break;
}
} elseif ($token === '{') {
$pendingParenthesisCount++;
}
}
}
return implode('', $closureTokens);
}
}

19
vendor/yiisoft/yii2/helpers/Console.php vendored Normal file
View File

@ -0,0 +1,19 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* Console helper provides useful methods for command line related tasks such as getting input or formatting and coloring
* output.
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class Console extends BaseConsole
{
}

View File

@ -0,0 +1,19 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* File system helper.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Alex Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class FileHelper extends BaseFileHelper
{
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* FormatConverter provides functionality to convert between different formatting pattern formats.
*
* It provides functions to convert date format patterns between different conventions.
*
* @author Carsten Brandt <mail@cebe.cc>
* @author Enrica Ruedin <e.ruedin@guggach.com>
* @since 2.0
*/
class FormatConverter extends BaseFormatConverter
{
}

24
vendor/yiisoft/yii2/helpers/Html.php vendored Normal file
View File

@ -0,0 +1,24 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* Html provides a set of static methods for generating commonly used HTML tags.
*
* Nearly all of the methods in this class allow setting additional html attributes for the html
* tags they generate. You can specify, for example, `class`, `style` or `id` for an html element
* using the `$options` parameter. See the documentation of the [[tag()]] method for more details.
*
* For more details and usage information on Html, see the [guide article on html helpers](guide:helper-html).
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Html extends BaseHtml
{
}

View File

@ -0,0 +1,34 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* HtmlPurifier provides an ability to clean up HTML from any harmful code.
*
* Basic usage is the following:
*
* ```
* echo HtmlPurifier::process($html);
* ```
*
* If you want to configure it:
*
* ```
* echo HtmlPurifier::process($html, [
* 'Attr.EnableID' => true,
* ]);
* ```
*
* For more details please refer to [HTMLPurifier documentation](http://htmlpurifier.org/).
*
* @author Alexander Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class HtmlPurifier extends BaseHtmlPurifier
{
}

View File

@ -0,0 +1,18 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* Inflector pluralizes and singularizes English nouns. It also contains some other useful methods.
*
* @author Antonio Ramirez <amigo.cobos@gmail.com>
* @since 2.0
*/
class Inflector extends BaseInflector
{
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* Class IpHelper provides a set of IP-related static methods.
*
* Methods expect correct IP addresses.
* To validate IP addresses use [[\yii\validators\IpValidator|IpValidator]].
*
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
* @since 2.0.14
*/
class IpHelper extends BaseIpHelper
{
}

19
vendor/yiisoft/yii2/helpers/Json.php vendored Normal file
View File

@ -0,0 +1,19 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* Json is a helper class providing JSON data encoding and decoding.
* It enhances the PHP built-in functions `json_encode()` and `json_decode()`
* by supporting encoding JavaScript expressions and throwing exceptions when decoding fails.
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Json extends BaseJson
{
}

View File

@ -0,0 +1,33 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* Markdown provides an ability to transform markdown into HTML.
*
* Basic usage is the following:
*
* ```
* $myHtml = Markdown::process($myText); // use original markdown flavor
* $myHtml = Markdown::process($myText, 'gfm'); // use github flavored markdown
* $myHtml = Markdown::process($myText, 'extra'); // use markdown extra
* ```
*
* You can configure multiple flavors using the [[$flavors]] property.
*
* For more details please refer to the [Markdown library documentation](https://github.com/cebe/markdown#readme).
*
* > Note: The Markdown library works with PHPDoc annotations so if you use it together with
* > PHP `opcache` make sure [it does not strip comments](https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.save-comments).
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class Markdown extends BaseMarkdown
{
}

View File

@ -0,0 +1,93 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
use yii\base\InvalidConfigException;
/**
* Object that represents the replacement of array value while performing [[ArrayHelper::merge()]].
*
* Usage example:
*
* ```
* $array1 = [
* 'ids' => [
* 1,
* ],
* 'validDomains' => [
* 'example.com',
* 'www.example.com',
* ],
* ];
*
* $array2 = [
* 'ids' => [
* 2,
* ],
* 'validDomains' => new \yii\helpers\ReplaceArrayValue([
* 'yiiframework.com',
* 'www.yiiframework.com',
* ]),
* ];
*
* $result = \yii\helpers\ArrayHelper::merge($array1, $array2);
* ```
*
* The result will be
*
* ```
* [
* 'ids' => [
* 1,
* 2,
* ],
* 'validDomains' => [
* 'yiiframework.com',
* 'www.yiiframework.com',
* ],
* ]
* ```
*
* @author Robert Korulczyk <robert@korulczyk.pl>
* @since 2.0.10
*/
class ReplaceArrayValue
{
/**
* @var mixed value used as replacement.
*/
public $value;
/**
* Constructor.
* @param mixed $value value used as replacement.
*/
public function __construct($value)
{
$this->value = $value;
}
/**
* Restores class state after using `var_export()`.
*
* @param array $state
* @return ReplaceArrayValue
* @throws InvalidConfigException when $state property does not contain `value` parameter
* @see https://www.php.net/manual/en/function.var-export.php
* @since 2.0.16
*/
public static function __set_state($state)
{
if (!isset($state['value'])) {
throw new InvalidConfigException('Failed to instantiate class "ReplaceArrayValue". Required parameter "value" is missing');
}
return new self($state['value']);
}
}

View File

@ -0,0 +1,19 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* StringHelper.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Alex Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class StringHelper extends BaseStringHelper
{
}

View File

@ -0,0 +1,64 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* Object that represents the removal of array value while performing [[ArrayHelper::merge()]].
*
* Usage example:
*
* ```
* $array1 = [
* 'ids' => [
* 1,
* ],
* 'validDomains' => [
* 'example.com',
* 'www.example.com',
* ],
* ];
*
* $array2 = [
* 'ids' => [
* 2,
* ],
* 'validDomains' => new \yii\helpers\UnsetArrayValue(),
* ];
*
* $result = \yii\helpers\ArrayHelper::merge($array1, $array2);
* ```
*
* The result will be
*
* ```
* [
* 'ids' => [
* 1,
* 2,
* ],
* ]
* ```
*
* @author Robert Korulczyk <robert@korulczyk.pl>
* @since 2.0.10
*/
class UnsetArrayValue
{
/**
* Restores class state after using `var_export()`.
*
* @param array $state
* @return UnsetArrayValue
* @see https://www.php.net/manual/en/function.var-export.php
* @since 2.0.16
*/
public static function __set_state($state)
{
return new self();
}
}

20
vendor/yiisoft/yii2/helpers/Url.php vendored Normal file
View File

@ -0,0 +1,20 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* Url provides a set of static methods for managing URLs.
*
* For more details and usage information on Url, see the [guide article on url helpers](guide:helper-url).
*
* @author Alexander Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class Url extends BaseUrl
{
}

View File

@ -0,0 +1,27 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\helpers;
/**
* VarDumper is intended to replace the buggy PHP function var_dump and print_r.
* It can correctly identify the recursively referenced objects in a complex
* object structure. It also has a recursive depth control to avoid indefinite
* recursive display of some peculiar variables.
*
* VarDumper can be used as follows,
*
* ```
* VarDumper::dump($var);
* ```
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class VarDumper extends BaseVarDumper
{
}

View File

@ -0,0 +1,24 @@
<?php
/**
* MIME aliases.
*
* This file contains aliases for MIME types.
*
* All extra changes made to this file must be committed to /build/controllers/MimeTypeController.php
* otherwise they will be lost on next build.
*/
return [
'text/rtf' => 'application/rtf',
'text/xml' => 'application/xml',
'image/svg' => 'image/svg+xml',
'image/x-bmp' => 'image/bmp',
'image/x-bitmap' => 'image/bmp',
'image/x-xbitmap' => 'image/bmp',
'image/x-win-bitmap' => 'image/bmp',
'image/x-windows-bmp' => 'image/bmp',
'image/ms-bmp' => 'image/bmp',
'image/x-ms-bmp' => 'image/bmp',
'application/bmp' => 'image/bmp',
'application/x-bmp' => 'image/bmp',
'application/x-win-bitmap' => 'image/bmp',
];

File diff suppressed because it is too large Load Diff

1024
vendor/yiisoft/yii2/helpers/mimeTypes.php vendored Normal file

File diff suppressed because it is too large Load Diff