Merge branch 'master' into controller-array-fix

This commit is contained in:
Christina Reichel
2025-05-19 12:22:15 +02:00
committed by GitHub
24 changed files with 479 additions and 57 deletions

View File

@ -338,6 +338,12 @@ class BaseYii
* @return object the created object
* @throws InvalidConfigException if the configuration is invalid.
* @see \yii\di\Container
*
* @template T
* @phpstan-param class-string<T>|array{class: class-string<T>, ...}|callable(): T $type
* @psalm-param class-string<T>|array{class: class-string<T>, ...}|callable(): T $type
* @phpstan-return T
* @psalm-return T
*/
public static function createObject($type, array $params = [])
{

View File

@ -9,6 +9,14 @@ Yii Framework 2 Change Log
- Bug #8298: Loading fixtures does not update table sequence for Postgresql database (mtangoo)
- Bug #20347: Fix compatibility with PHP 8.4: remove usage of `session.use_trans_sid` and `session.use_only_cookies` (tehmaestro)
- Bug #20351: Fix behavior for `yii\web\Controller::bindActionParams` around union types (chriscpty)
- Bug #20355: Fix SQL syntax for resetting sequence in `QueryBuilder` for `MSSQL` (terabytesoftw)
- Bug #20371: Fix "Typed property must not be accessed before initialization" when calling `toArray()` on a model with typed properties without default value (uaoleg)
- Enh #20354: Add PHPStan/Psalm annotations for `Container` and `Instance` (max-s-lab)
- Enh #20361: Add PHPStan/Psalm annotations for `ActiveQuery` (max-s-lab)
- Enh #20363: Add PHPStan/Psalm annotations for `ActiveRecord` and `ActiveQuery` (max-s-lab)
- Enh #20372: Add PHPStan/Psalm annotations for `AssetBundle`, `AssetManager` and `View` (max-s-lab)
- Bug #20373: Fixed the type of the first parameter `yii\base\Controller::bindInjectedParams()` (max-s-lab)
- Enh #20374: Add PHPStan/Psalm annotations for `BaseYii`, `BaseObject`, `Component`, `Model`, `Module` and `yii\base\Controller` (max-s-lab)
2.0.52 February 13, 2025

View File

@ -123,7 +123,7 @@ trait ArrayableTrait
{
$data = [];
foreach ($this->resolveFields($fields, $expand) as $field => $definition) {
$attribute = is_string($definition) ? $this->$definition : $definition($this, $field);
$attribute = is_string($definition) ? ($this->$definition ?? null) : $definition($this, $field);
if ($recursive) {
$nestedFields = $this->extractFieldsFor($fields, $field);

View File

@ -100,6 +100,9 @@ class BaseObject implements Configurable
* - call the parent implementation at the end of the constructor.
*
* @param array $config name-value pairs that will be used to initialize the object properties
*
* @phpstan-param array<string, mixed> $config
* @psalm-param array<string, mixed> $config
*/
public function __construct($config = [])
{

View File

@ -461,6 +461,9 @@ class Component extends BaseObject
* Behaviors declared in this method will be attached to the component automatically (on demand).
*
* @return array the behavior configurations.
*
* @phpstan-return array<int|string, class-string|array{class: class-string, ...}>
* @psalm-return array<int|string, class-string|array{class: class-string, ...}>
*/
public function behaviors()
{

View File

@ -87,6 +87,9 @@ class Controller extends Component implements ViewContextInterface
* @param string $id the ID of this controller.
* @param Module $module the module that this controller belongs to.
* @param array $config name-value pairs that will be used to initialize the object properties.
*
* @phpstan-param array<string, mixed> $config
* @psalm-param array<string, mixed> $config
*/
public function __construct($id, $module, $config = [])
{
@ -127,6 +130,9 @@ class Controller extends Component implements ViewContextInterface
* [[\Yii::createObject()]] will be used later to create the requested action
* using the configuration provided here.
* @return array
*
* @phpstan-return array<string, class-string|array{class: class-string, ...}
* @psalm-return array<string, class-string|array{class: class-string, ...}
*/
public function actions()
{
@ -548,7 +554,7 @@ class Controller extends Component implements ViewContextInterface
/**
* Fills parameters based on types and names in action method signature.
* @param \ReflectionType $type The reflected type of the action parameter.
* @param \ReflectionNamedType $type The reflected type of the action parameter.
* @param string $name The name of the parameter.
* @param array &$args The array of arguments for the action, this function may append items to it.
* @param array &$requestedParams The array with requested params, this function may write specific keys to it.
@ -558,7 +564,7 @@ class Controller extends Component implements ViewContextInterface
* (for example an interface type hint) without a proper definition in the container.
* @since 2.0.36
*/
final protected function bindInjectedParams(\ReflectionType $type, $name, &$args, &$requestedParams)
final protected function bindInjectedParams(\ReflectionNamedType $type, $name, &$args, &$requestedParams)
{
// Since it is not a builtin type it must be DI injection.
$typeName = $type->getName();

View File

@ -52,6 +52,15 @@ use yii\validators\Validator;
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*
* @phpstan-property array<string, mixed> $attributes
* @psalm-property array<string, mixed> $attributes
*
* @phpstan-property-read array<string, string[]> $errors
* @psalm-property-read array<string, string[]> $errors
*
* @phpstan-property-read array<string, string> $firstErrors
* @psalm-property-read array<string, string> $firstErrors
*/
class Model extends Component implements StaticInstanceInterface, IteratorAggregate, ArrayAccess, Arrayable
{
@ -151,6 +160,9 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg
*
* @return array validation rules
* @see scenarios()
*
* @phpstan-return array<int|string, mixed>[]
* @psalm-return array<int|string, mixed>[]
*/
public function rules()
{
@ -181,6 +193,9 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg
* are being validated by the validation rules that apply to the scenario.
*
* @return array a list of scenarios and the corresponding active attributes.
*
* @phpstan-return array<string, string[]>
* @psalm-return array<string, string[]>
*/
public function scenarios()
{
@ -293,6 +308,9 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg
*
* @return array attribute labels (name => label)
* @see generateAttributeLabel()
*
* @phpstan-return array<string, string>
* @psalm-return array<string, string>
*/
public function attributeLabels()
{
@ -313,6 +331,9 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg
*
* @return array attribute hints (name => hint)
* @since 2.0.4
*
* @phpstan-return array<string, string>
* @psalm-return array<string, string>
*/
public function attributeHints()
{
@ -580,6 +601,9 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg
*
* @see getFirstErrors()
* @see getFirstError()
*
* @phpstan-return array<string, string[]>
* @psalm-return array<string, string[]>
*/
public function getErrors($attribute = null)
{
@ -596,6 +620,9 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg
* values are the corresponding error messages. An empty array will be returned if there is no error.
* @see getErrors()
* @see getFirstError()
*
* @phpstan-return array<string, string>
* @psalm-return array<string, string>
*/
public function getFirstErrors()
{
@ -633,6 +660,9 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg
* @see getErrors()
* @see getFirstErrors()
* @since 2.0.14
*
* @phpstan-return string[]
* @psalm-return string[]
*/
public function getErrorSummary($showAllErrors)
{
@ -708,6 +738,9 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg
* If it is an array, only the attributes in the array will be returned.
* @param array $except list of attributes whose value should NOT be returned.
* @return array attribute values (name => value).
*
* @phpstan-return array<string, mixed>
* @psalm-return array<string, mixed>
*/
public function getAttributes($names = null, $except = [])
{

View File

@ -153,6 +153,9 @@ class Module extends ServiceLocator
* @param string $id the ID of this module.
* @param Module|null $parent the parent module (if any).
* @param array $config name-value pairs that will be used to initialize the object properties.
*
* @phpstan-param array<string, mixed> $config
* @psalm-param array<string, mixed> $config
*/
public function __construct($id, $parent = null, $config = [])
{

View File

@ -188,6 +188,12 @@ interface CacheInterface extends \ArrayAccess
* the corresponding value in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is `false`.
* @return mixed result of $callable execution
*
* @template TResult of mixed
* @psalm-param callable():TResult|\Closure():TResult $callable
* @phpstan-param callable():TResult|\Closure():TResult $callable
* @psalm-return TResult
* @phpstan-return TResult
*/
public function getOrSet($key, $callable, $duration = null, $dependency = null);
}

View File

@ -71,6 +71,21 @@ use yii\base\InvalidConfigException;
* @since 2.0
*
* @template T of (ActiveRecord|array)
*
* @phpstan-method T|null one($db = null)
* @psalm-method T|null one($db = null)
*
* @phpstan-method T[] all($db = null)
* @psalm-method T[] all($db = null)
*
* @phpstan-method ($value is true ? (T is array ? self<T> : self<array>) : self<T>) asArray($value = true)
* @psalm-method ($value is true ? (T is array ? self<T> : self<array>) : self<T>) asArray($value = true)
*
* @phpstan-method BatchQueryResult<int, T[]> batch($batchSize = 100, $db = null)
* @psalm-method BatchQueryResult<int, T[]> batch($batchSize = 100, $db = null)
*
* @phpstan-method BatchQueryResult<int, T> each($batchSize = 100, $db = null)
* @psalm-method BatchQueryResult<int, T> each($batchSize = 100, $db = null)
*/
class ActiveQuery extends Query implements ActiveQueryInterface
{
@ -316,32 +331,6 @@ class ActiveQuery extends Query implements ActiveQueryInterface
return null;
}
/**
* {@inheritdoc}
*
* @return BatchQueryResult
* @psalm-return T[][]|BatchQueryResult
* @phpstan-return T[][]|BatchQueryResult
* @codeCoverageIgnore
*/
public function batch($batchSize = 100, $db = null)
{
return parent::batch($batchSize, $db);
}
/**
* {@inheritdoc}
*
* @return BatchQueryResult
* @psalm-return T[]|BatchQueryResult
* @phpstan-return T[]|BatchQueryResult
* @codeCoverageIgnore
*/
public function each($batchSize = 100, $db = null)
{
return parent::each($batchSize, $db);
}
/**
* Creates a DB command that can be used to execute this query.
* @param Connection|null $db the DB connection used to create the DB command.

View File

@ -156,6 +156,9 @@ class ActiveRecord extends BaseActiveRecord
* @param string $sql the SQL statement to be executed
* @param array $params parameters to be bound to the SQL statement during execution.
* @return ActiveQuery the newly created [[ActiveQuery]] instance
*
* @phpstan-return ActiveQuery<static>
* @psalm-return ActiveQuery<static>
*/
public static function findBySql($sql, $params = [])
{
@ -408,6 +411,9 @@ class ActiveRecord extends BaseActiveRecord
/**
* {@inheritdoc}
* @return ActiveQuery the newly created [[ActiveQuery]] instance.
*
* @phpstan-return ActiveQuery<static>
* @psalm-return ActiveQuery<static>
*/
public static function find()
{

View File

@ -247,9 +247,11 @@ class QueryBuilder extends \yii\db\QueryBuilder
$table = $this->db->getTableSchema($tableName);
if ($table !== null && $table->sequenceName !== null) {
$tableName = $this->db->quoteTableName($tableName);
if ($value === null) {
$key = $this->db->quoteColumnName(reset($table->primaryKey));
$value = "(SELECT COALESCE(MAX({$key}),0) FROM {$tableName})+1";
$sql = "SELECT COALESCE(MAX({$key}), 0) + 1 FROM {$tableName}";
$value = $this->db->createCommand($sql)->queryScalar();
} else {
$value = (int) $value;
}

View File

@ -158,12 +158,11 @@ class Container extends Component
* @throws InvalidConfigException if the class cannot be recognized or correspond to an invalid definition
* @throws NotInstantiableException If resolved to an abstract class or an interface (since 2.0.9)
*
*
* @template T of class-string
* @psalm-param class-string<T>|array{class: class-string<T>} $class
* @phpstan-param class-string<T>|array{class: class-string<T>} $class
* @psalm-return T
* @phpstan-return T
* @template T of object
* @psalm-param string|class-string<T>|Instance $class
* @phpstan-param string|class-string<T>|Instance $class
* @psalm-return ($class is class-string<T> ? T : object)
* @phpstan-return ($class is class-string<T> ? T : object)
*/
public function get($class, $params = [], $config = [])
{

View File

@ -114,6 +114,12 @@ class Instance
* @param ServiceLocator|Container|null $container the container. This will be passed to [[get()]].
* @return object the object referenced by the Instance, or `$reference` itself if it is an object.
* @throws InvalidConfigException if the reference is invalid
*
* @template T of object
* @psalm-param class-string<T>|null $type
* @phpstan-param class-string<T>|null $type
* @psalm-return ($type is null ? object : T)
* @phpstan-return ($type is null ? object : T)
*/
public static function ensure($reference, $type = null, $container = null)
{

View File

@ -14,9 +14,10 @@ return [
// array, required, list of language codes that the extracted messages
// should be translated to. For example, ['zh-CN', 'de'].
'languages' => [
'af', 'ar', 'az', 'be', 'bg', 'bs', 'ca', 'cs', 'da', 'de', 'el', 'es', 'et', 'fa', 'fi', 'fr', 'he', 'hi',
'pt-BR', 'ro', 'hr', 'hu', 'hy', 'id', 'it', 'ja', 'ka', 'kk', 'ko', 'kz', 'lt', 'lv', 'ms', 'nb-NO', 'nl',
'pl', 'pt', 'ru', 'sk', 'sl', 'sr', 'sr-Latn', 'sv', 'tg', 'th', 'tr', 'uk', 'uz', 'uz-Cy', 'vi', 'zh', 'zh-TW'
'af', 'ar', 'az', 'be', 'bg', 'bs', 'ca', 'cs', 'da', 'de', 'el', 'es', 'et', 'fa', 'fi', 'fr', 'ga', 'he',
'hi', 'pt-BR', 'ro', 'hr', 'hu', 'hy', 'id', 'it', 'ja', 'ka', 'kk', 'ko', 'kz', 'lt', 'lv', 'ms', 'mt',
'nb-NO', 'nl', 'pl', 'pt', 'ru', 'sk', 'sl', 'sr', 'sr-Latn', 'sv', 'tg', 'th', 'tr', 'uk', 'uz', 'uz-Cy', 'vi',
'zh', 'zh-TW'
],
// string, the name of the function for translating messages.
// Defaults to 'Yii::t'. This is used as a mark to find the messages to be

View File

@ -0,0 +1,148 @@
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
/**
* Message translations.
*
* This file is automatically generated by 'yii message/extract' command.
* It contains the localizable messages extracted from source code.
* You may modify this file by translating the extracted messages.
*
* Each array element represents the translation (value) of a message (key).
* If the value is empty, the message is considered as not translated.
* Messages that no longer need translation will have their translations
* enclosed between a pair of '@@' marks.
*
* Message string can be used with plural forms format. Check i18n section
* of the guide for details.
*
* NOTE: this file must be saved in UTF-8 encoding.
*/
return [
' and ' => ' agus ',
'"{attribute}" does not support operator "{operator}".' => '"{attribute}" ní thacaíonn oibreoir "{operator}".',
'(not set)' => '(gan socrú)',
'Action not found.' => 'Gníomh gan aimsiú.',
'Aliases available: {aliases}' => 'Ailiasanna ar fáil: {aliases}',
'An internal server error occurred.' => 'Tharla earráid freastalaí inmheánach.',
'Are you sure you want to delete this item?' => 'An bhfuil tú cinnte gur mhaith leat an mhír seo a scriosadh?',
'Condition for "{attribute}" should be either a value or valid operator specification.' => 'Ba cheart go mbeadh an coinníoll le haghaidh "{attribute}" ina luach nó ina shonraíocht oibritheora bailí.',
'Delete' => 'Scrios',
'Error' => 'Earráid',
'File upload failed.' => 'Theip ar uaslódáil an chomhaid.',
'Home' => 'Baile',
'Invalid data received for parameter "{param}".' => 'Sonraí neamhbhailí faighte don pharaiméadar "{param}".',
'Login Required' => 'Logáil Isteach ag Teastáil',
'Missing required arguments: {params}' => 'Argóintí riachtanacha in easnamh: {params}',
'Missing required parameters: {params}' => 'Paraiméadair riachtanacha in easnamh: {params}',
'No' => 'Níl',
'No results found.' => 'Níor aimsíodh aon torthaí.',
'Only files with these MIME types are allowed: {mimeTypes}.' => 'Ní cheadaítear ach comhaid leis na cineálacha MIME seo: {mimeTypes}',
'Only files with these extensions are allowed: {extensions}.' => 'Ní cheadaítear ach comhaid leis na síntí seo: {extensions}',
'Operator "{operator}" must be used with a search attribute.' => 'Oibreoir "{operator}" Ní mór é a úsáid le tréith cuardaigh.',
'Operator "{operator}" requires multiple operands.' => 'Oibreoir "{operator}" éilíonn oibríochtaí iolracha.',
'Options available: {options}' => 'Roghanna ar fáil: {options}',
'Page not found.' => 'Ní bhfuarthas an leathanach.',
'Please fix the following errors:' => 'Ceartaigh na hearráidí seo a leanas le do thoil:',
'Please upload a file.' => 'Le do thoil uaslódáil comhad.',
'Showing <b>{begin, number}-{end, number}</b> of <b>{totalCount, number}</b> {totalCount, plural, one{item} other{items}}.' => 'Ag taispeáint <b>{begin, number}-{end, number}</b> de <b>{totalCount, number}</b> {totalCount, plural, one{mír} other{míreanna}}.',
'The combination {values} of {attributes} has already been taken.' => 'An meascán {values} de {attributes} Tá glactha cheana féin.',
'The file "{file}" is not an image.' => 'An comhad "{file}" nach íomhá í.',
'The file "{file}" is too big. Its size cannot exceed {formattedLimit}.' => 'An comhad "{file}" ró-mhór. Ní féidir a mhéid a shárú {formattedLimit}.',
'The file "{file}" is too small. Its size cannot be smaller than {formattedLimit}.' => 'An comhad "{file}" ró-bheag. Ní féidir a mhéid a bheith níos lú ná {formattedLimit}.',
'The format of {attribute} is invalid.' => 'Formáid na {attribute} neamhbhailí.',
'The format of {filter} is invalid.' => 'Formáid na {filter} neamhbhailí.',
'The image "{file}" is too large. The height cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'An íomhá "{file}" ró-mhór. Ní féidir leis an airde a bheith níos mó ná {limit, number} {limit, plural, one{pixel} other{pixels}}.',
'The image "{file}" is too large. The width cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'An íomhá "{file}" ró-mhór. Ní féidir leis an leithead a bheith níos mó ná {limit, number} {limit, plural, one{pixel} other{pixels}}.',
'The image "{file}" is too small. The height cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'An íomhá "{file}" ró-bheag. Ní féidir leis an airde a bheith níos lú ná {limit, number} {limit, plural, one{pixel} other{pixels}}.',
'The image "{file}" is too small. The width cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'An íomhá "{file}" ró-bheag. Ní féidir leis an leithead a bheith níos lú ná {limit, number} {limit, plural, one{pixel} other{pixels}}.',
'The requested view "{name}" was not found.' => 'An radharc iarrtha "{name}" níor aimsíodh',
'The verification code is incorrect.' => 'Tá an cód fíoraithe mícheart',
'Total <b>{count, number}</b> {count, plural, one{item} other{items}}.' => 'Iomlán <b>{count, number}</b> {count, plural, one{mír} other{míreanna}}.',
'Unable to verify your data submission.' => 'Ní féidir d\'aighneacht sonraí a fhíorú',
'Unknown alias: -{name}' => 'Ailias anaithnid: -{name}',
'Unknown filter attribute "{attribute}"' => 'Aitreabúid scagaire anaithnid "{attribute}"',
'Unknown option: --{name}' => 'Rogha anaithnid: --{name}',
'Update' => 'Nuashonrú',
'View' => 'Amharc',
'Yes' => 'Tá',
'You are not allowed to perform this action.' => 'Níl cead agat an gníomh seo a dhéanamh.',
'You can upload at most {limit, number} {limit, plural, one{file} other{files}}.' => 'Is féidir leat a uaslódáil ar a mhéad {limit, number} {limit, plural, one{file} other{files}}.',
'You should upload at least {limit, number} {limit, plural, one{file} other{files}}.' => 'Ba chóir duit a uaslódáil ar a laghad {limit, number} {limit, plural, one{file} other{files}}.',
'in {delta, plural, =1{a day} other{# days}}' => 'isteach {delta, plural, =1{lá} other{# laethanta}}',
'in {delta, plural, =1{a minute} other{# minutes}}' => 'isteach {delta, plural, =1{nóiméad} other{# nóiméad}}',
'in {delta, plural, =1{a month} other{# months}}' => 'isteach {delta, plural, =1{mí} other{# mhí}}',
'in {delta, plural, =1{a second} other{# seconds}}' => 'isteach {delta, plural, =1{dara} other{# soicind}}',
'in {delta, plural, =1{a year} other{# years}}' => 'isteach {delta, plural, =1{bliain} other{# blianta}}',
'in {delta, plural, =1{an hour} other{# hours}}' => 'isteach {delta, plural, =1{uair an chloig} other{# uair an chloig}}',
'just now' => 'díreach anois',
'the input value' => 'an luach ionchuir',
'{attribute} "{value}" has already been taken.' => '{attribute} "{value}" Tá glactha cheana féin',
'{attribute} cannot be blank.' => '{attribute} Ní féidir a bheith bán.',
'{attribute} contains wrong subnet mask.' => '{attribute} Tá masc subnet mícheart.',
'{attribute} is invalid.' => '{attribute} neamhbhailí.',
'{attribute} is not a valid URL.' => '{attribute} nach URL bailí é.',
'{attribute} is not a valid email address.' => '{attribute} nach seoladh ríomhphoist bailí é.',
'{attribute} is not in the allowed range.' => '{attribute} nach bhfuil sa raon ceadaithe.',
'{attribute} must be "{requiredValue}".' => '{attribute} caithfidh go bhfuil "{requiredValue}".',
'{attribute} must be a number.' => '{attribute} caithfidh gur uimhir é.',
'{attribute} must be a string.' => '{attribute} Ní mór a bheith ina teaghrán.',
'{attribute} must be a valid IP address.' => '{attribute} caithfidh gur seoladh IP bailí é.',
'{attribute} must be an IP address with specified subnet.' => '{attribute} Ní mór seoladh IP a bheith ann le folíon sonraithe.',
'{attribute} must be an integer.' => '{attribute} Ní mór a bheith ina slánuimhir.',
'{attribute} must be either "{true}" or "{false}".' => '{attribute} Ní mór ceachtar "{true}" nó "{false}".',
'{attribute} must be equal to "{compareValueOrAttribute}".' => '{attribute} Ní mór a bheith comhionann le "{compareValueOrAttribute}".',
'{attribute} must be greater than "{compareValueOrAttribute}".' => '{attribute} ní mór a bheith níos mó ná "{compareValueOrAttribute}".',
'{attribute} must be greater than or equal to "{compareValueOrAttribute}".' => '{attribute} a bheith níos mó ná nó cothrom le "{compareValueOrAttribute}".',
'{attribute} must be less than "{compareValueOrAttribute}".' => '{attribute} Ní mór a bheith níos lú ná "{compareValueOrAttribute}".',
'{attribute} must be less than or equal to "{compareValueOrAttribute}".' => '{attribute} ní mór a bheith níos lú ná nó cothrom le "{compareValueOrAttribute}".',
'{attribute} must be no greater than {max}.' => '{attribute} Ní mór a bheith níos mó ná {max}.',
'{attribute} must be no less than {min}.' => '{attribute} Ní mór a bheith níos lú ná{min}.',
'{attribute} must not be a subnet.' => '{attribute} Ní mór a bheith ina subnet.',
'{attribute} must not be an IPv4 address.' => '{attribute} níor cheart gur seoladh IPv4 é.',
'{attribute} must not be an IPv6 address.' => '{attribute} níor cheart gur seoladh IPv6 é.',
'{attribute} must not be equal to "{compareValueOrAttribute}".' => '{attribute} Ní mór a bheith comhionann le "{compareValueOrAttribute}".',
'{attribute} should contain at least {min, number} {min, plural, one{character} other{characters}}.' => '{attribute} chóir go bhfuil ar a laghad {min, number} {min, plural, one{carachtar} other{carachtair}}.',
'{attribute} should contain at most {max, number} {max, plural, one{character} other{characters}}.' => '{attribute} chóir go bhfuil ar a mhéad {max, number} {max, plural, one{carachtar} other{carachtair}}.',
'{attribute} should contain {length, number} {length, plural, one{character} other{characters}}.' => '{attribute} chóir go bhfuil {length, number} {length, plural, one{carachtar} other{carachtair}}.',
'{compareAttribute} is invalid.' => '{compareAttribute} neamhbhailí.',
'{delta, plural, =1{1 day} other{# days}}' => '{delta, plural, =1{1 lá} eile{# laethanta}}',
'{delta, plural, =1{1 hour} other{# hours}}' => '{delta, plural, =1{1 uair an chloig} eile{# uair an chloig}}',
'{delta, plural, =1{1 minute} other{# minutes}}' => '{delta, plural, =1{1 nóiméad} eile{# nóiméad}}',
'{delta, plural, =1{1 month} other{# months}}' => '{delta, plural, =1{1 mí} eile{# mhí}}',
'{delta, plural, =1{1 second} other{# seconds}}' => '{delta, plural, =1{1 dara} eile{# soicind}}',
'{delta, plural, =1{1 year} other{# years}}' => '{delta, plural, =1{1 bliain} eile{# blianta}}',
'{delta, plural, =1{a day} other{# days}} ago' => '{delta, plural, =1{1 lá} eile{# laethanta}} ó shin',
'{delta, plural, =1{a minute} other{# minutes}} ago' => '{delta, plural, =1{1 nóiméad} eile{# nóiméad}} ó shin',
'{delta, plural, =1{a month} other{# months}} ago' => '{delta, plural, =1{1 mí} eile{# mhí}} ó shin',
'{delta, plural, =1{a second} other{# seconds}} ago' => '{delta, plural, =1{1 dara} eile{# soicind}} ó shin',
'{delta, plural, =1{a year} other{# years}} ago' => '{delta, plural, =1{1 bliain} eile{# blianta}} ó shin',
'{delta, plural, =1{an hour} other{# hours}} ago' => '{delta, plural, =1{1 uair an chloig} eile{# uair an chloig}} ó shin',
'{nFormatted} B' => '{nFormatted} B',
'{nFormatted} GB' => '{nFormatted} GB',
'{nFormatted} GiB' => '{nFormatted} GiB',
'{nFormatted} KiB' => '{nFormatted} KiB',
'{nFormatted} MB' => '{nFormatted} MB',
'{nFormatted} MiB' => '{nFormatted} MiB',
'{nFormatted} PB' => '{nFormatted} PB',
'{nFormatted} PiB' => '{nFormatted} PiB',
'{nFormatted} TB' => '{nFormatted} TB',
'{nFormatted} TiB' => '{nFormatted} TiB',
'{nFormatted} kB' => '{nFormatted} kB',
'{nFormatted} {n, plural, =1{byte} other{bytes}}' => '{nFormatted} {n, plural, =1{beart} eile{bearta}}',
'{nFormatted} {n, plural, =1{gibibyte} other{gibibytes}}' => '{nFormatted} {n, plural, =1{gibibheart} eile{gibítí}}',
'{nFormatted} {n, plural, =1{gigabyte} other{gigabytes}}' => '{nFormatted} {n, plural, =1{gigabyte} eile{ghigibheart}}',
'{nFormatted} {n, plural, =1{kibibyte} other{kibibytes}}' => '{nFormatted} {n, plural, =1{cibeibít} eile{cibítí}}',
'{nFormatted} {n, plural, =1{kilobyte} other{kilobytes}}' => '{nFormatted} {n, plural, =1{cilibheart} eile{cilibheart}}',
'{nFormatted} {n, plural, =1{mebibyte} other{mebibytes}}' => '{nFormatted} {n, plural, =1{meibít} eile{meibítí}}',
'{nFormatted} {n, plural, =1{megabyte} other{megabytes}}' => '{nFormatted} {n, plural, =1{meigibheart} eile{megabytes}}',
'{nFormatted} {n, plural, =1{pebibyte} other{pebibytes}}' => '{nFormatted} {n, plural, =1{peibít} eile{peibít}}',
'{nFormatted} {n, plural, =1{petabyte} other{petabytes}}' => '{nFormatted} {n, plural, =1{peitibít} eile{peiteabóid}}',
'{nFormatted} {n, plural, =1{tebibyte} other{tebibytes}}' => '{nFormatted} {n, plural, =1{teibít} eile{teibítí}}',
'{nFormatted} {n, plural, =1{terabyte} other{terabytes}}' => '{nFormatted} {n, plural, =1{teiribíte} eile{teiribít}}',
];

View File

@ -0,0 +1,141 @@
<?php
/**
* Message translations.
*
* This file is automatically generated by 'yii message/extract' command.
* It contains the localizable messages extracted from source code.
* You may modify this file by translating the extracted messages.
*
* Each array element represents the translation (value) of a message (key).
* If the value is empty, the message is considered as not translated.
* Messages that no longer need translation will have their translations
* enclosed between a pair of '@@' marks.
*
* Message string can be used with plural forms format. Check i18n section
* of the guide for details.
*
* NOTE: this file must be saved in UTF-8 encoding.
*/
return [
' and ' => ' u ',
'"{attribute}" does not support operator "{operator}".' => '"{attribute}" ma jappoġġjax l-operatur "{operator}".',
'(not set)' => '(mhux issettjat)',
'Action not found.' => 'Azzjoni ma nstabitx.',
'Aliases available: {aliases}' => 'Alias disponibbli: {aliases}',
'An internal server error occurred.' => 'Sar żball intern tas-server.',
'Are you sure you want to delete this item?' => 'Int żgur li trid tħassar dan l-oġġett?',
'Condition for "{attribute}" should be either a value or valid operator specification.' => 'Kundizzjoni għal "{attribute}" għandu jkun jew valur jew speċifikazzjoni valida tal-operatur.',
'Delete' => 'Ħassar',
'Error' => 'Żball',
'File upload failed.' => 'It-tlugħ tal-fajl falla.',
'Home' => 'Dar',
'Invalid data received for parameter "{param}".' => 'Data invalida riċevuta għall-parametru "{param}".',
'Login Required' => 'Login Meħtieġa',
'Missing required arguments: {params}' => 'Argumenti meħtieġa nieqsa: {params}',
'Missing required parameters: {params}' => 'Parametri meħtieġa nieqsa: {params}',
'No' => 'Nru',
'No results found.' => 'Ma nstab l-ebda riżultat.',
'Only files with these MIME types are allowed: {mimeTypes}.' => 'Fajls b\'dawn it-tipi MIME biss huma permessi: {mimeTypes}.',
'Only files with these extensions are allowed: {extensions}.' => 'Fajls b\'dawn l-estensjonijiet biss huma permessi: {extensions}.',
'Operator "{operator}" must be used with a search attribute.' => 'Operatur "{operator}" għandu jintuża ma\' attribut ta\' tfittxija.',
'Operator "{operator}" requires multiple operands.' => 'Operatur "{operator}" teħtieġ operandi multipli.',
'Options available: {options}' => 'Għażliet disponibbli: {options}',
'Page not found.' => 'Paġna mhux misjuba.',
'Please fix the following errors:' => 'Jekk jogħġbok waħħal l-iżbalji li ġejjin:',
'Please upload a file.' => 'Jekk jogħġbok ittella\' fajl.',
'Showing <b>{begin, number}-{end, number}</b> of <b>{totalCount, number}</b> {totalCount, plural, one{item} other{items}}.' => 'Wiri <b>{begin, number}-{end, number}</b> ta <b>{totalCount, number}</b> {totalCount, plural, one{oġġett} other{oġġetti}}.',
'The combination {values} of {attributes} has already been taken.' => 'Il-kombinazzjoni {values} ta {attributes} diġà ttieħdet.',
'The file "{file}" is not an image.' => 'Il-fajl "{file}" mhix immaġni',
'The file "{file}" is too big. Its size cannot exceed {formattedLimit}.' => 'Il-fajl "{file}" hija kbira wisq. Id-daqs tiegħu ma jistax jaqbeż {formattedLimit}.',
'The file "{file}" is too small. Its size cannot be smaller than {formattedLimit}.' => 'Il-fajl "{file}" huwa żgħir wisq. Id-daqs tiegħu ma jistax ikun iżgħar minn {formattedLimit}.',
'The format of {attribute} is invalid.' => 'Il-format ta\' {attribute} hija invalida.',
'The format of {filter} is invalid.' => 'Il-format ta\' {filter} hija invalida.',
'The image "{file}" is too large. The height cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'L-immaġni "{file}" hija kbira wisq. L-għoli ma jistax ikun akbar minn {limit, number} {limit, plural, one{pixel} other{pixels}}.',
'The image "{file}" is too large. The width cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'L-immaġni "{file}" hija kbira wisq. Il-wisa \'ma tistax tkun akbar minn {limit, number} {limit, plural, one{pixel} other{pixels}}.',
'The image "{file}" is too small. The height cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'L-immaġni "{file}" huwa żgħir wisq. L-għoli ma jistax ikun iżgħar minn {limit, number} {limit, plural, one{pixel} other{pixels}}.',
'The image "{file}" is too small. The width cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'L-immaġni "{file}" huwa żgħir wisq. Il-wisa \'ma tistax tkun iżgħar minn {limit, number} {limit, plural, one{pixel} other{pixels}}.',
'The requested view "{name}" was not found.' => 'Il-veduta mitluba "{name}" ma nstabx.',
'The verification code is incorrect.' => 'Il-kodiċi ta\' verifika mhux korrett.',
'Total <b>{count, number}</b> {count, plural, one{item} other{items}}.' => 'Total <b>{count, number}</b> {count, plural, one{oġġett} other{oġġetti}}.',
'Unable to verify your data submission.' => 'Ma tistax tivverifika s-sottomissjoni tad-dejta tiegħek.',
'Unknown alias: -{name}' => 'Psewdonimu mhux magħruf: -{name}',
'Unknown filter attribute "{attribute}"' => 'Attribut tal-filtru mhux magħruf "{attribute}"',
'Unknown option: --{name}' => 'Għażla mhux magħrufa: --{name}',
'Update' => 'Aġġornament',
'View' => 'Ara',
'Yes' => 'Iva',
'You are not allowed to perform this action.' => 'M\'intix permess li twettaq din l-azzjoni.',
'You can upload at most {limit, number} {limit, plural, one{file} other{files}}.' => 'Tista \'ttella\' l-aktar {limit, number} {limit, plural, one{file} other{files}}.',
'You should upload at least {limit, number} {limit, plural, one{file} other{files}}.' => 'Għandek ittella mill-inqas {limit, number} {limit, plural, one{file} other{files}}.',
'in {delta, plural, =1{a day} other{# days}}' => 'fi {delta, plural, =1{a jum} other{# jiem}}',
'in {delta, plural, =1{a minute} other{# minutes}}' => 'fi {delta, plural, =1{minuta} other{# minuti}}',
'in {delta, plural, =1{a month} other{# months}}' => 'fi {delta, plural, =1{xahar} other{# xhur}}',
'in {delta, plural, =1{a second} other{# seconds}}' => 'fi {delta, plural, =1{it-tieni} other{# sekondi}}',
'in {delta, plural, =1{a year} other{# years}}' => 'fi {delta, plural, =1{sena} other{# snin}}',
'in {delta, plural, =1{an hour} other{# hours}}' => 'fi {delta, plural, =1{siegħa} other{# sigħat}}',
'just now' => 'biss issa',
'the input value' => 'il-valur tad-dħul',
'{attribute} "{value}" has already been taken.' => '{attribute} "{value}" diġà ttieħdet.',
'{attribute} cannot be blank.' => '{attribute} ma jistax ikun vojt.',
'{attribute} contains wrong subnet mask.' => '{attribute} fih subnet mask ħażina.',
'{attribute} is invalid.' => '{attribute} hija invalida.',
'{attribute} is not a valid URL.' => '{attribute} mhuwiex URL validu.',
'{attribute} is not a valid email address.' => '{attribute} mhuwiex indirizz elettroniku validu.',
'{attribute} is not in the allowed range.' => '{attribute} mhix fil-medda permessa.',
'{attribute} must be "{requiredValue}".' => '{attribute} għandu jkun "{requiredValue}".',
'{attribute} must be a number.' => '{attribute} irid ikun numru.',
'{attribute} must be a string.' => '{attribute} għandu jkun spag.',
'{attribute} must be a valid IP address.' => '{attribute} għandu jkun indirizz IP validu.',
'{attribute} must be an IP address with specified subnet.' => '{attribute} ',
'{attribute} must be an integer.' => '{attribute} għandu jkun numru sħiħ.',
'{attribute} must be either "{true}" or "{false}".' => '{attribute} trid tkun jew "{true}" jew "{false}".',
'{attribute} must be equal to "{compareValueOrAttribute}".' => '{attribute} trid tkun ugwali għal "{compareValueOrAttribute}".',
'{attribute} must be greater than "{compareValueOrAttribute}".' => '{attribute} għandu jkun akbar minn "{compareValueOrAttribute}".',
'{attribute} must be greater than or equal to "{compareValueOrAttribute}".' => '{attribute} għandu jkun akbar minn jew ugwali għal "{compareValueOrAttribute}".',
'{attribute} must be less than "{compareValueOrAttribute}".' => '{attribute} għandu jkun inqas minn "{compareValueOrAttribute}".',
'{attribute} must be less than or equal to "{compareValueOrAttribute}".' => '{attribute} għandu jkun inqas minn jew ugwali għal "{compareValueOrAttribute}".',
'{attribute} must be no greater than {max}.' => '{attribute} m\'għandux ikun akbar minn {max}.',
'{attribute} must be no less than {min}.' => '{attribute} għandu jkun mhux inqas minn {min}.',
'{attribute} must not be a subnet.' => '{attribute} m\'għandux ikun subnet.',
'{attribute} must not be an IPv4 address.' => '{attribute} m\'għandux ikun indirizz IPv4.',
'{attribute} must not be an IPv6 address.' => '{attribute} m\'għandux ikun indirizz IPv6.',
'{attribute} must not be equal to "{compareValueOrAttribute}".' => '{attribute} m\'għandux ikun ugwali għal "{compareValueOrAttribute}".',
'{attribute} should contain at least {min, number} {min, plural, one{character} other{characters}}.' => '{attribute} għandu jkun fih mill-inqas {min, number} {min, plural, one{character} other{characters}}.',
'{attribute} should contain at most {max, number} {max, plural, one{character} other{characters}}.' => '{attribute} għandu jkun fih l-aktar {max, number} {max, plural, one{character} other{characters}}.',
'{attribute} should contain {length, number} {length, plural, one{character} other{characters}}.' => '{attribute} għandu jkun fih {length, number} {length, plural, one{character} other{characters}}.',
'{compareAttribute} is invalid.' => '{compareAttribute} hija invalida',
'{delta, plural, =1{1 day} other{# days}}' => '{delta, plural, =1{1 jum} other{# jiem}}',
'{delta, plural, =1{1 hour} other{# hours}}' => '{delta, plural, =1{1 siegħa} other{# sigħat}}',
'{delta, plural, =1{1 minute} other{# minutes}}' => '{delta, plural, =1{1 minuta} other{# minuti}}',
'{delta, plural, =1{1 month} other{# months}}' => '{delta, plural, =1{1 xahar} other{# xhur}}',
'{delta, plural, =1{1 second} other{# seconds}}' => '{delta, plural, =1{1 it-tieni} other{# sekondi}}',
'{delta, plural, =1{1 year} other{# years}}' => '{delta, plural, =1{1 sena} other{# snin}}',
'{delta, plural, =1{a day} other{# days}} ago' => '{delta, plural, =1{jum} other{# jiem}} ago',
'{delta, plural, =1{a minute} other{# minutes}} ago' => '{delta, plural, =1{minuta} other{# minuti}} ago',
'{delta, plural, =1{a month} other{# months}} ago' => '{delta, plural, =1{xahar} other{# xhur}} ago',
'{delta, plural, =1{a second} other{# seconds}} ago' => '{delta, plural, =1{it-tieni} other{# sekondi}} ago',
'{delta, plural, =1{a year} other{# years}} ago' => '{delta, plural, =1{sena} other{# snin}} ago',
'{delta, plural, =1{an hour} other{# hours}} ago' => '{delta, plural, =1{siegħa} other{# sigħat}} ago',
'{nFormatted} B' => '{nFormatted} B',
'{nFormatted} GB' => '{nFormatted} GB',
'{nFormatted} GiB' => '{nFormatted} GiB',
'{nFormatted} KiB' => '{nFormatted} KiB',
'{nFormatted} MB' => '{nFormatted} MB',
'{nFormatted} MiB' => '{nFormatted} MiB',
'{nFormatted} PB' => '{nFormatted} PB',
'{nFormatted} PiB' => '{nFormatted} PiB',
'{nFormatted} TB' => '{nFormatted} TB',
'{nFormatted} TiB' => '{nFormatted} TiB',
'{nFormatted} kB' => '{nFormatted} kB',
'{nFormatted} {n, plural, =1{byte} other{bytes}}' => '{nFormatted} {n, plural, =1{byte} other{bytes}}',
'{nFormatted} {n, plural, =1{gibibyte} other{gibibytes}}' => '{nFormatted} {n, plural, =1{gibibyte} other{gibibytes}}',
'{nFormatted} {n, plural, =1{gigabyte} other{gigabytes}}' => '{nFormatted} {n, plural, =1{gigabyte} other{gigabytes}}',
'{nFormatted} {n, plural, =1{kibibyte} other{kibibytes}}' => '{nFormatted} {n, plural, =1{kibibyte} other{kibibytes}}',
'{nFormatted} {n, plural, =1{kilobyte} other{kilobytes}}' => '{nFormatted} {n, plural, =1{kilobyte} other{kilobytes}}',
'{nFormatted} {n, plural, =1{mebibyte} other{mebibytes}}' => '{nFormatted} {n, plural, =1{mebibyte} other{mebibytes}}',
'{nFormatted} {n, plural, =1{megabyte} other{megabytes}}' => '{nFormatted} {n, plural, =1{megabyte} other{megabytes}}',
'{nFormatted} {n, plural, =1{pebibyte} other{pebibytes}}' => '{nFormatted} {n, plural, =1{pebibyte} other{pebibytes}}',
'{nFormatted} {n, plural, =1{petabyte} other{petabytes}}' => '{nFormatted} {n, plural, =1{petabyte} other{petabytes}}',
'{nFormatted} {n, plural, =1{tebibyte} other{tebibytes}}' => '{nFormatted} {n, plural, =1{tebibyte} other{tebibytes}}',
'{nFormatted} {n, plural, =1{terabyte} other{terabytes}}' => '{nFormatted} {n, plural, =1{terabyte} other{terabytes}}',
];

View File

@ -26,6 +26,15 @@ use yii\helpers\Url;
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*
* @phpstan-import-type RegisterJsFileOptions from View
* @psalm-import-type RegisterJsFileOptions from View
*
* @phpstan-import-type RegisterCssFileOptions from View
* @psalm-import-type RegisterCssFileOptions from View
*
* @phpstan-import-type PublishOptions from AssetManager
* @psalm-import-type PublishOptions from AssetManager
*/
class AssetBundle extends BaseObject
{
@ -72,6 +81,9 @@ class AssetBundle extends BaseObject
* 'yii\bootstrap\BootstrapAsset',
* ];
* ```
*
* @phpstan-var class-string[]
* @psalm-var class-string[]
*/
public $depends = [];
/**
@ -89,6 +101,9 @@ class AssetBundle extends BaseObject
* This functionality is available since version 2.0.7.
*
* Note that only a forward slash "/" should be used as directory separator.
*
* @phpstan-var (string|array<int|string, mixed>)[]
* @psalm-var (string|array<int|string, mixed>)[]
*/
public $js = [];
/**
@ -96,21 +111,33 @@ class AssetBundle extends BaseObject
* in one of the three formats as explained in [[js]].
*
* Note that only a forward slash "/" should be used as directory separator.
*
* @phpstan-var (string|array<int|string, mixed>)[]
* @psalm-var (string|array<int|string, mixed>)[]
*/
public $css = [];
/**
* @var array the options that will be passed to [[View::registerJsFile()]]
* when registering the JS files in this bundle.
*
* @phpstan-var RegisterJsFileOptions
* @psalm-var RegisterJsFileOptions
*/
public $jsOptions = [];
/**
* @var array the options that will be passed to [[View::registerCssFile()]]
* when registering the CSS files in this bundle.
*
* @phpstan-var RegisterCssFileOptions
* @psalm-var RegisterCssFileOptions
*/
public $cssOptions = [];
/**
* @var array the options to be passed to [[AssetManager::publish()]] when the asset bundle
* is being published. This property is used only when [[sourcePath]] is set.
*
* @phpstan-var PublishOptions
* @psalm-var PublishOptions
*/
public $publishOptions = [];

View File

@ -38,6 +38,24 @@ use yii\helpers\Url;
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*
* @phpstan-type PublishOptions array{
* only?: string[],
* except?: string[],
* caseSensitive?: bool,
* beforeCopy?: callable,
* afterCopy?: callable,
* forceCopy?: bool,
* }
*
* @psalm-type PublishOptions = array{
* only?: string[],
* except?: string[],
* caseSensitive?: bool,
* beforeCopy?: callable,
* afterCopy?: callable,
* forceCopy?: bool,
* }
*/
class AssetManager extends Component
{
@ -463,6 +481,9 @@ class AssetManager extends Component
* @return array the path (directory or file path) and the URL that the asset is published as.
* @throws InvalidArgumentException if the asset to be published does not exist.
* @throws InvalidConfigException if the target directory [[basePath]] is not writeable.
*
* @phpstan-param PublishOptions $options
* @psalm-param PublishOptions $options
*/
public function publish($path, $options = [])
{

View File

@ -41,6 +41,28 @@ use yii\helpers\Url;
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*
* @phpstan-type RegisterJsFileOptions array{
* depends?: class-string[],
* position?: int,
* appendTimestamp?: boolean
* }
*
* @psalm-type RegisterJsFileOptions = array{
* depends?: class-string[],
* position?: int,
* appendTimestamp?: boolean
* }
*
* @phpstan-type RegisterCssFileOptions array{
* depends?: class-string[],
* appendTimestamp?: boolean
* }
*
* @psalm-type RegisterCssFileOptions = array{
* depends?: class-string[],
* appendTimestamp?: boolean
* }
*/
class View extends \yii\base\View
{
@ -445,6 +467,9 @@ class View extends \yii\base\View
* $url as the key. If two CSS files are registered with the same key, the latter
* will overwrite the former.
* @throws InvalidConfigException
*
* @phpstan-param RegisterCssFileOptions $options
* @psalm-param RegisterCssFileOptions $options
*/
public function registerCssFile($url, $options = [], $key = null)
{
@ -569,6 +594,9 @@ class View extends \yii\base\View
* will overwrite the former. Note that position option takes precedence, thus files registered with the same key,
* but different position option will not override each other.
* @throws InvalidConfigException
*
* @phpstan-param RegisterJsFileOptions $options
* @psalm-param RegisterJsFileOptions $options
*/
public function registerJsFile($url, $options = [], $key = null)
{