Commit e55bce18 by Anton A

Merge branch 'master' of git://github.com/yiisoft/yii2 into guide-start-hello

parents e64ecc6b e86a7d7a
...@@ -9,18 +9,18 @@ All Rights Reserved. ...@@ -9,18 +9,18 @@ All Rights Reserved.
Введение Введение
------------ --------
* [О Yii](intro-yii.md) * [О Yii](intro-yii.md)
* [Обновление с версии 1.1](intro-upgrade-from-v1.md) * [Обновление с версии 1.1](intro-upgrade-from-v1.md)
Getting Started Первое знакомство
--------------- -----------------
* [Установка Yii](start-installation.md) * [Установка Yii](start-installation.md)
* [Запуск приложения](start-workflow.md) * [Запуск приложения](start-workflow.md)
* [Говорим "привет"](start-hello.md) * [Говорим «привет»](start-hello.md)
* [Работа с формами](start-forms.md) * [Работа с формами](start-forms.md)
* [Работа с базами данных](start-databases.md) * [Работа с базами данных](start-databases.md)
* [Генерация кода при помощи Gii](start-gii.md) * [Генерация кода при помощи Gii](start-gii.md)
......
Что такое Yii?
==============
Yii – это высокопроизводительный компонентный PHP фреймворк, предназначенный для быстрой разработки современных веб
приложений. Слово Yii (произносится как `Йи` `[ji:]`) в китайском языке означает «простой и эволюционирующий». Также Yii
может расшифровываться как акроним **Yes It Is**!
Для каких задач больше всего подходит Yii?
------------------------------------------
Yii – это универсальный фреймворк и может быть задействован во всех типах веб приложений. Благодаря его компонентной
структуре и отличной поддержке кеширования, фреймворк особенно подходит для разработки таких крупных проектов как
порталы, форумы, CMS, магазины или RESTful-приложения.
Сравнение Yii с другими фреймворками
------------------------------------
- Как и многие другие PHP фреймворки, для организации кода Yii использует модель MVC (Model-View-Controller).
- Yii придерживается философии простого и элегантного кода не пытаясь усложнять дизайн только ради следования каким-либо
шаблонам проектирования.
- Yii является full-stack фреймворком и включает в себя проверенные и хорошо зарекомендовавшие себя возможности, такие как
ActiveRecord для реляционных и NoSQL баз данных, поддержку REST API, многоуровневое кеширование и другие.
- Yii отлично расширяем. Вы можете настроить или заменить практически любую часть основного кода. Используя архитектуру
расшрений легко делиться кодом или использовать код сообщества.
- Одна из главных целей Yii – производительность.
Yii — не проект одного человека. Он поддерживается и развивается [сильной командой][] и большим сообществом разработчиков,
которые ей помогают. Разработчики фреймворка следят за тенденциями веб разработки и развитием других проектов. Наиболее
подходящие возможности и лучшие практики регулярно внедряются в фреймворк в виде простых и элегантных интерфейсов.
[сильной командой]: http://www.yiiframework.com/about/
Версии Yii
----------
На данный момент существует две основные ветки Yii: 1.1 и 2.0. Ветка 1.1 является предыдущим поколением и находится
в состоянии поддержки. Версия 2.0 – это полностью переписанный Yii, использующий последние технологии и протоколы, такие
как Composer, PSR, пространства имен, типажи (traits) и многое другое. 2.0 — последнее поколение фреймворка. На этой версии
будут сосредоточены основные усилия несколько следующих лет. Данное руководство именно о версии 2.0.
Требования к ПО и знаниям
-------------------------
Yii 2.0 требует PHP 5.4.0 и выше. Чтобы узнать требования для отдельных возможностей вы можете запустить скрипт проверки
требований, который поставляется с каждым релизом фреймворка.
Для разработки на Yii потребуется общее понимание ООП так как фреймворк полностью следует этой парадигме. Также следует
изучить такие современные возможности PHP как [пространства имён](http://www.php.net/manual/ru/language.namespaces.php)
и [типажи](http://www.php.net/manual/ru/language.oop5.traits.php).
Установка Yii
==============
Вы можете установить Yii двумя способами: используя [Composer](http://getcomposer.org/) или скачав архив.
Первый способ предпочтительнее так как позволяет установить новые [расширения](structure-extensions.md)
или обновить Yii одной командой.
Установка при помощи Composer <a name="installing-via-composer"></a>
-----------------------
Если Composer еще не установлен это можно сделать по инструкции на
[getcomposer.org](https://getcomposer.org/download/), или одним из нижеперечисленных способов:
* на Linux или Mac, используйте следующую команду:
```
curl -s http://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
```
* на Windows, скачайте и запустите [Composer-Setup.exe](https://getcomposer.org/Composer-Setup.exe).
В случае возникновения проблем или если вам необходима дополнительная информация, обращайтесь
к [документации Composer](https://getcomposer.org/doc/) .
После установки Composer устанавливать Yii можно запуститив следующую команду в папке доступной через веб:
```
composer create-project --prefer-dist yiisoft/yii2-app-basic basic
```
Composer установит Yii (шаблонное приложение basic) в папку `basic`.
> **Подсказка**: Если хотите установить последнюю нестабильную версию Yii, вы можете добавить ключ `stability`:
```
composer create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic
```
Стоит отметить, что нестабилную версию Yii нельзя использовать на рабочем сервере.
Установка из архива <a name="installing-from-archive-file"></a>
-------------------------------
Установка Yii из архива состоит из двух шагов:
1. Скачайте архив по адресу [yiiframework.com](http://www.yiiframework.com/download/yii2-basic);
2. Распакуйте скачанный архив в папку, доступную из Web.
Другие опции установки <a name="other-installation-options"></a>
--------------------------
Выше приведены инструкции по установке Yii в виде базового приложения готового к работе.
Это отличный вариант для небольших проектов или для тех, кто только начинает изучать Yii.
Есть два основных варианта такой установки:
* Если вам нужен только сам фреймворк и вы хотели бы создать приложение с нуля, воспользуйтесь инструкцией, описанной в
разделе «[Создание приложения с нуля](tutorial-start-from-scratch.md)».
* Если хотите начать с более продвинутого приложения, хорошо подходящего для работы в команде, используйте
[шаблон приложения advanced](tutorial-advanced-app.md).
Проверка установки <a name="verifying-installation"></a>
----------------------
Если вы установили приложение в директорию `basic` в корневой директории вашего веб сервера и имя сервера `hostname`,
запустить приложение можно открыв следующий URL через браузер:
```
http://hostname/basic/web/index.php
```
![Успешно установленный Yii](images/start-app-installed.png)
Вы должны увидеть страницу приветствия «Congratulations!». Если нет — проверьте требования Yii одним из способов:
* Браузером перейдите по адресу `http://hostname/basic/requirements.php`
* Или выполните команду в консоли:
```
cd basic
php requirements.php
```
Для корректной работы фреймворка вам необходима установка PHP, соответствующая его минимальным требованиям. Основное
требование — PHP версии 5.4 и выше. Если ваше приложение работает с базой данных, необходимо установить
[расширение PHP PDO](http://www.php.net/manual/ru/pdo.installation.php) и соответствующий драйвер
(например, `pdo_mysql` для MySQL).
Настройка веб сервера <a name="configuring-web-servers"></a>
-----------------------
> Информация: можете пропустить этот подраздел если вы только начали знакомиться с фреймворком и пока не разворачиваете
его на рабочем сервере.
Приложение, установленное по инструкциям, приведённым выше, будет работать сразу как с [Apache](http://httpd.apache.org/),
так и с [Nginx](http://nginx.org/) под Windows и Linux.
На рабочем сервере вам наверняка захочется изменить URL приложения с `http://hostname/basic/web/index.php`
на `http://hostname/index.php`. Для этого необходимо изменить корневую директорию в настройках веб сервера так, чтобы та
указывала на `basic/web`. Дополнительно можно спрятать `index.php` следуя описанию в разделе «[Разбор и генерация URL](runtime-url-handling.md)».
Далее будет показано как настроить Apache и Nginx.
> Информация: Устанавливая `basic/web` корневой директорией веб сервера вы защищаете от нежелательного доступа код и данные,
находящиеся на одном уровне с `basic/web`. Это делает приложение более защищенным.
> Информация: Если приложение работает на хостинге где нет доступа к настройкам веб сервера, то можно изменить структуру
приложения как описано в разделе «[Работа на Shared хостинге](tutorial-shared-hosting.md)».
### Рекомендуемые настройки Apache <a name="recommended-apache-configuration"></a>
Добавьте следующее в `httpd.conf` Apache или в конфигурационный файл виртуального хоста. Не забудьте заменить
`path/to/basic/web` на корректный путь к `basic/web`.
```
# Устанавливаем корневой директорией "basic/web"
DocumentRoot "path/to/basic/web"
<Directory "path/to/basic/web">
RewriteEngine on
# Если запрашиваемая в URL директория или файл сущесвуют обращаемся к ним напрямую
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Если нет - перенаправляем запрос на index.php
RewriteRule . index.php
# ...прочие настройки...
</Directory>
```
### Рекомендуемые настройки Nginx <a name="recommended-nginx-configuration"></a>
PHP должен быть установлен как [FPM SAPI](http://php.net/manual/ru/install.fpm.php) для [Nginx](http://wiki.nginx.org/).
Используйте следующие параметры Nginx и не забудьте заменить `path/to/basic/web` на корректный путь к `basic/web`.
```
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## слушаем ipv6
server_name mysite.local;
root /path/to/basic/web;
index index.php;
access_log /path/to/project/log/access.log main;
error_log /path/to/project/log/error.log;
location / {
# Перенаправляем все запросы к несуществующим директориям и файлам на index.php
try_files $uri $uri/ /index.php?$args;
}
# раскомментируйте строки ниже во избежание обработки Yii обращений к несуществующим статическим файлам
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
}
location ~ /\.(ht|svn|git) {
deny all;
}
}
```
Используя данную конфигурацию установите `cgi.fix_pathinfo=0` в `php.ini` чтобы предотвратить лишние системные
вызовы `stat()`.
Учтите, что используя HTTPS необходимо задавать `fastcgi_param HTTPS on;` чтобы Yii мог корректно определять защищенное
соединение.
Validating Input Validating Input
================ ================
> Note: This section is under development. As a rule of thumb, you should never trust the data received from end users and should always validate them
before putting them to good use.
In the [Models](structure-models.md#validation) section, we have described how data validation works Given a [model](structure-models.md) populated with user inputs, you can validate the inputs by calling the
in general. In this section, we will mainly focus on describing core validators, how to define your [[yii\base\Model::validate()]] method. The method will return a boolean value indicating whether the validation
own validators, and different ways of using validators. succeeds or not. If not, you may get the error messages from the [[yii\base\Model::errors]] property. For example,
```php
$model = new \app\models\ContactForm;
## Declaring Validation Rules // populate model attributes with user inputs
$model->attributes = \Yii::$app->request->post('ContactForm');
## Data Validation
### Getting Error Messages
### Empty Values
### Array Values
## Data Filtering
if ($model->validate()) {
// all inputs are valid
} else {
// validation failed: $errors is an array containing error messages
$errors = $model->errors;
}
```
Behind the scene, the `validate()` method does the following steps to perform validation:
## Creating Validators 1. Determine which attributes should be validated by getting the attribute list from [[yii\base\Model::scenarios()]]
using the current [[yii\base\Model::scenario|scenario]]. These attributes are called *active attributes*.
2. Determine which validation rules should be used by getting the rule list from [[yii\base\Model::rules()]]
using the current [[yii\base\Model::scenario|scenario]]. These rules are called *active rules*.
3. Use each active rule to validate each active attribute associated with that rule. If the rule fails,
keep an error message for the attribute in the model.
If none of the built in validators fit your needs, you can create your own validator by creating a method in you model class.
This method will be wrapped by an [[yii\validators\InlineValidator|InlineValidator]] an be called upon validation.
You will do the validation of the attribute and [[yii\base\Model::addError()|add errors]] to the model when validation fails.
The method has the following signature `public function myValidator($attribute, $params)` while you are free to choose the name. ## Declaring Rules <a name="declaring-rules"></a>
Here is an example implementation of a validator validating the age of a user: To make `validate()` really work, you should declare validation rules for the attributes you plan to validate.
This should be done by overriding the [[yii\base\Model::rules()]] method. The following example shows how
the validation rules for the `ContactForm` model are declared:
```php ```php
public function validateAge($attribute, $params)
{
$value = $this->$attribute;
if (strtotime($value) > strtotime('now - ' . $params['min'] . ' years')) {
$this->addError($attribute, 'You must be at least ' . $params['min'] . ' years old to register for this service.');
}
}
public function rules() public function rules()
{ {
return [ return [
// ... // the name, email, subject and body attributes are required
[['birthdate'], 'validateAge', 'params' => ['min' => '12']], [['name', 'email', 'subject', 'body'], 'required'],
// the email attribute should be a valid email address
['email', 'email'],
]; ];
} }
``` ```
You may also set other properties of the [[yii\validators\InlineValidator|InlineValidator]] in the rules definition, The [[yii\base\Model::rules()|rules()]] method should return an array of rules, each of which is an array
for example the [[yii\validators\InlineValidator::$skipOnEmpty|skipOnEmpty]] property: of the following format:
```php ```php
[['birthdate'], 'validateAge', 'params' => ['min' => '12'], 'skipOnEmpty' => false], [
// required, specifies which attributes should be validated by this rule.
// For a single attribute, you can use the attribute name directly
// without having it in an array instead of an array
['attribute1', 'attribute2', ...],
// required, specifies the type of this rule.
// It can be a class name, validator alias, or a validation method name
'validator',
// optional, specifies in which scenario(s) this rule should be applied
// if not given, it means the rule applies to all scenarios
'on' => ['scenario1', 'scenario2', ...],
// optional, specifies additional configurations for the validator object
'property1' => 'value1', 'property2' => 'value2', ...
]
``` ```
For each rule you must specify at least which attributes the rule applies to and what is the type of the rule.
You can specify the rule type in one of the following forms:
### Inline Validators * the alias of a core validator, such as `required`, `in`, `date`, etc. Please refer to
the [Core Validators](tutorial-core-validators.md) for the complete list of core validators.
* the name of a validation method in the model class, or an anonymous function. Please refer to the
[Inline Validators](#inline-validators) subsection for more details.
* the name of a validator class. Please refer to the [Standalone Validators](#standalone-validators)
subsection for more details.
### Standalone Validators A rule can be used to validate one or multiple attributes, and an attribute may be validated by one or multiple rules.
A rule may be applied in certain [scenarios](structure-models.md#scenarios) only by specifying the `on` option.
If you do not specify an `on` option, it means the rule will be applied to all scenarios.
## Client-Side Validation When the `validate()` method is called, it does the following steps to perform validation:
## Conditional Validation 1. Determine which attributes should be validated by checking the current [[yii\base\Model::scenario|scenario]]
against the scenarios declared in [[yii\base\Model::scenarios()]]. These attributes are the active attributes.
2. Determine which rules should be applied by checking the current [[yii\base\Model::scenario|scenario]]
against the rules declared in [[yii\base\Model::rules()]]. These rules are the active rules.
3. Use each active rule to validate each active attribute which is associated with the rule.
According to the above validation steps, an attribute will be validated if and only if it is
an active attribute declared in `scenarios()` and is associated with one or multiple active rules
declared in `rules()`.
To validate attributes only when certain conditions apply, e.g. the validation of
one field depends on the value of another field you can use [[yii\validators\Validator::when|the `when` property]]
to define such conditions:
```php ### Customizing Error Messages <a name="customizing-error-messages"></a>
['state', 'required', 'when' => function($model) { return $model->country == Country::USA; }],
['stateOthers', 'required', 'when' => function($model) { return $model->country != Country::USA; }],
['mother', 'required', 'when' => function($model) { return $model->age < 18 && $model->married != true; }],
```
For better readability the conditions can also be written like this: Most validators have default error messages that will be added to the model being validated when its attributes
fail the validation. For example, the [[yii\validators\RequiredValidator|required]] validator will add
a message "Username cannot be blank." to a model when its `username` attribute fails the rule using this validator.
You can customize the error message of a rule by specifying the `message` property when declaring the rule,
like the following,
```php ```php
public function rules() public function rules()
{ {
$usa = function($model) { return $model->country == Country::USA; };
$notUsa = function($model) { return $model->country != Country::USA; };
$child = function($model) { return $model->age < 18 && $model->married != true; };
return [ return [
['state', 'required', 'when' => $usa], ['username', 'required', 'message' => 'Please choose a username.'],
['stateOthers', 'required', 'when' => $notUsa], // note that it is not possible to write !$usa
['mother', 'required', 'when' => $child],
]; ];
} }
``` ```
When you need conditional validation logic on client-side (`enableClientValidation` is true), don't forget Some validators may support additional error messages to more precisely describe different causes of
to add `whenClient`: validation failures. For example, the [[yii\validators\NumberValidator|number]] validator supports
[[yii\validators\NumberValidator::tooBig|tooBig]] and [[yii\validators\NumberValidator::tooSmall|tooSmall]]
to describe the validation failure when the value being validated is too big and too small, respectively.
You may configure these error messages like configuring other properties of validators in a validation rule.
### Conditional Validation <a name="conditional-validation"></a>
To validate attributes only when certain conditions apply, e.g. the validation of one attribute depends
on the value of another attribute you can use the [[yii\validators\Validator::when|when]] property
to define such conditions. For example,
```php ```php
public function rules() [
{ ['state', 'required', 'when' => function($model) {
$usa = [ return $model->country == 'USA';
'server-side' => function($model) { return $model->country == Country::USA; }, }],
'client-side' => "function (attribute, value) {return $('#country').value == 'USA';}" ]
]; ```
return [ The [[yii\validators\Validator::when|when]] property takes a PHP callable with the following signature:
['state', 'required', 'when' => $usa['server-side'], 'whenClient' => $usa['client-side']],
]; ```php
} /**
* @param Model $model the model being validated
* @param string $attribute the attribute being validated
* @return boolean whether the rule should be applied
*/
function ($model, $attribute)
``` ```
This guide describes all of Yii's validators and their parameters. If you also need to support client-side conditional validation, you should configure
the [[yii\validators\Validator::whenClient|whenClient]] property which takes a string representing a JavaScript
function whose return value determines whether to apply the rule or not. For example,
```php
[
['state', 'required', 'when' => function ($model) {
return $model->country == 'USA';
}, 'whenClient' => "function (attribute, value) {
return $('#country').value == 'USA';
}"],
]
```
### Data Filtering <a name="data-filtering"></a>
## Ad Hoc Validation User inputs often need to be filtered or preprocessed. For example, you may want to trim the spaces around the
`username` input. You may use validation rules to achieve this goal. The following rule declaration shows
how to trim the spaces in the input by using the [trim](tutorial-core-validators.md#trim) core validator:
```php
[
['username', 'trim'],
]
```
You may also use the more general [filter](tutorial-core-validators.md#filter) validator if your data filtering
need is more complex than space trimming.
As you can see, these validation rules do not really validate the inputs. Instead, they will process the values
and save them back to the attributes being validated.
## Ad Hoc Validation <a name="ad-hoc-validation"></a>
Sometimes you need to validate a value that is not bound to any model, such as a standalone email address. The `Validator` class has a Sometimes you need to do *ad hoc validation* for values that are not bound to any model.
`validateValue` method that can help you in these scenarios. Not all validator classes have implemented this method, but the ones that have implemented `validateValue` can be used without a model. For example, to validate an email stored in a string, you can do the following:
If you only need to perform one type of validation (e.g. validating email addresses), you may call
the [[yii\validators\Validator::validate()|validate()]] method of the desired validator, like the following:
```php ```php
$email = 'test@example.com'; $email = 'test@example.com';
$validator = new yii\validators\EmailValidator(); $validator = new yii\validators\EmailValidator();
if ($validator->validate($email, $error)) { if ($validator->validate($email, $error)) {
echo 'Email is valid.'; echo 'Email is valid.';
} else { } else {
...@@ -131,17 +203,20 @@ if ($validator->validate($email, $error)) { ...@@ -131,17 +203,20 @@ if ($validator->validate($email, $error)) {
} }
``` ```
DynamicModel is a model class primarily used to support ad hoc data validation. > Note: Not all validators support such kind of validation. An example is the [unique](tutorial-core-validators.md#unique)
core validator which is designed to work with a model only.
The typical usage of DynamicModel is as follows, If you need to perform multiple validations against several values, you can use [[yii\base\DynamicModel]]
which supports declaring both attributes and rules on the fly. Its usage is like the following:
```php ```php
public function actionSearch($name, $email) public function actionSearch($name, $email)
{ {
$model = DynamicModel::validateData(compact('name', 'email'), [ $model = DynamicModel::validateData(compact('name', 'email'), [
[['name', 'email'], 'string', 'max' => 128]], [['name', 'email'], 'string', 'max' => 128],
['email', 'email'], ['email', 'email'],
]); ]);
if ($model->hasErrors()) { if ($model->hasErrors()) {
// validation fails // validation fails
} else { } else {
...@@ -150,23 +225,123 @@ public function actionSearch($name, $email) ...@@ -150,23 +225,123 @@ public function actionSearch($name, $email)
} }
``` ```
The above example shows how to validate `$name` and `$email` with the help of DynamicModel. The [[yii\base\DynamicModel::validateData()]] method creates an instance of `DynamicModel`, defines the attributes
The [[validateData()]] method creates an instance of DynamicModel, defines the attributes using the given data (`name` and `email` in this example), and then calls [[yii\base\Model::validate()]]
using the given data (`name` and `email` in this example), and then calls [[Model::validate()]]. with the given rules.
Alternatively, you may use the following more "classic" syntax to perform ad hoc data validation:
```php
public function actionSearch($name, $email)
{
$model = new DynamicModel(compact('name', 'email'));
$model->addRule(['name', 'email'], 'string', ['max' => 128])
->addRule('email', 'email')
->validate();
if ($model->hasErrors()) {
// validation fails
} else {
// validation succeeds
}
}
```
You can check the validation result by [[hasErrors()]], like you do with a normal model. After validation, you can check if the validation succeeds or not by calling the
[[yii\base\DynamicModel::hasErrors()|hasErrors()]] method, and then get the validation errors from the
[[yii\base\DynamicModel::errors|errors]] property, like you do with a normal model.
You may also access the dynamic attributes defined through the model instance, e.g., You may also access the dynamic attributes defined through the model instance, e.g.,
`$model->name` and `$model->email`. `$model->name` and `$model->email`.
Alternatively, you may use the following more "classic" syntax to perform ad-hoc data validation:
## Creating Validators <a name="creating-validators"></a>
Besides using the [core validators](tutorial-core-validators.md) included in the Yii releases, you may also
create your own validators. You may create inline validators or standalone validators.
### Inline Validators <a name="inline-validators"></a>
An inline validator is one defined in terms of a model method or an anonymous function. The signature of
the method/function is:
```php ```php
$model = new DynamicModel(compact('name', 'email')); /**
$model->addRule(['name', 'email'], 'string', ['max' => 128]) * @param string $attribute the attribute currently being validated
->addRule('email', 'email') * @param array $params the additional name-value pairs given in the rule
->validate(); */
function ($model, $attribute)
``` ```
DynamicModel implements the above ad-hoc data validation feature by supporting the so-called If an attribute fails the validation, the method/function should call [[yii\base\Model::addError()]] to save
"dynamic attributes". It basically allows an attribute to be defined dynamically through its constructor the error message in the model so that it can be retrieved back later to present to end users.
or [[defineAttribute()]].
Below are some examples:
```php
use yii\base\Model;
class MyForm extends Model
{
public $country;
public $token;
public function rules()
{
return [
// an inline validator defined as the model method validateCountry()
['country', 'validateCountry'],
// an inline validator defined as an anonymous function
['token', function ($attribute, $params) {
if (!ctype_alnum($this->$attribute)) {
$this->addError($attribute, 'The token must contain letters or digits.');
}
}],
];
}
public function validateType($attribute, $params)
{
if (!in_array($this->$attribute, ['USA', 'Web'])) {
$this->addError($attribute, 'The country must be either "USA" or "Web".');
}
}
}
```
### Standalone Validators <a name="standalone-validators"></a>
A standalone validator is a class extending [[yii\validators\Validator]] or its child class. You may implement
its validation logic by overriding the [[yii\validators\Validator::validateAttribute()]] method. If an attribute
fails the validation, call [[yii\base\Model::addError()]] to save the error message in the model, like you do
with [inline validators](#inline-validators). For example,
```php
namespace app\components;
use yii\validators\Validator;
class CountryValidator extends Validator
{
public function validateAttribute($model, $attribute)
{
if (!in_array($model->$attribute, ['USA', 'Web'])) {
$this->addError($attribute, 'The country must be either "USA" or "Web".');
}
}
}
```
If you want your validator to support validating a value without a model, you should also override
[[yii\validators\Validator::validate()]]. You may also override [[yii\validators\Validator::validateValue()]]
instead of `validateAttribute()` and `validate()` because by default the latter two methods are implemented
by calling `validateValue()`.
### Handling Empty and Array Inputs <a name="handling-empty-array-inputs"></a>
### Client-Side Validation <a name="client-side-validation"></a>
...@@ -95,7 +95,7 @@ the [PDO PHP Extension](http://www.php.net/manual/en/pdo.installation.php) and a ...@@ -95,7 +95,7 @@ the [PDO PHP Extension](http://www.php.net/manual/en/pdo.installation.php) and a
Configuring Web Servers <a name="configuring-web-servers"></a> Configuring Web Servers <a name="configuring-web-servers"></a>
----------------------- -----------------------
> Info: You may skip this sub-section for now if you are just testing driving Yii with no intention > Info: You may skip this sub-section for now if you are just test driving Yii with no intention
of deploying it to a production server. of deploying it to a production server.
The application installed according to the above instructions should work out of box with either The application installed according to the above instructions should work out of box with either
......
...@@ -325,8 +325,8 @@ without touching any dependent code. ...@@ -325,8 +325,8 @@ without touching any dependent code.
#### [[yii\base\Application::sourceLanguage|sourceLanguage]] <a name="sourceLanguage"></a> #### [[yii\base\Application::sourceLanguage|sourceLanguage]] <a name="sourceLanguage"></a>
This property specifies the language that the application code is written in. The default value is `'en'`, This property specifies the language that the application code is written in. The default value is `'en-US'`,
meaning English. You should configure this property if the text content in your code is not in English. meaning English (United States). You should configure this property if the text content in your code is not in English.
Like the [language](#language) property, you should configure this property in terms of Like the [language](#language) property, you should configure this property in terms of
an [IETF language tag](http://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands for English, an [IETF language tag](http://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands for English,
......
...@@ -23,30 +23,15 @@ Please refer to the relevant documentation for more details about these advanced ...@@ -23,30 +23,15 @@ Please refer to the relevant documentation for more details about these advanced
## Attributes <a name="attributes"></a> ## Attributes <a name="attributes"></a>
Attributes are the properties that represent business data. By default, attributes are *non-static public* Models represent business data in terms of *attributes*. Each attribute is like a publicly accessible property
member variables if your model class extends directly from [[yii\base\Model]]. of a model. The method [[yii\base\Model::attributes()]] specifies what attributes a model class has.
The following code creates a `ContactForm` model class with four attributes: `name`, `email`, `subject` and `body`. You can access an attribute like accessing a normal object property:
This model represents the input data that is received from an HTML form.
```php
namespace app\models;
use yii\base\Model;
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $body;
}
```
Naturally, you can access an attribute like accessing a normal object property:
```php ```php
$model = new \app\models\ContactForm; $model = new \app\models\ContactForm;
// "name" is an attribute of ContactForm
$model->name = 'example'; $model->name = 'example';
echo $model->name; echo $model->name;
``` ```
...@@ -68,12 +53,33 @@ foreach ($model as $name => $value) { ...@@ -68,12 +53,33 @@ foreach ($model as $name => $value) {
} }
``` ```
### Extending model attributes
The method [[yii\base\Model::attributes()]] defines and returns the names of the attributes in a model. ### Defining Attributes <a name="defining-attributes"></a>
You may override this method to support different ways of defining attributes. For example, [[yii\db\ActiveRecord]]
does so by returning table column names as attribute names. Note that you may also need to override the magic By default, if your model class extends directly from [[yii\base\Model]], all its *non-static public* member
methods such as `__get()`, `__set()` so that the attributes can be accessed like normal object properties. variables are attributes. For example, the `ContactForm` model class below has four attributes: `name`, `email`,
`subject` and `body`. The `ContactForm` model is used to represent the input data received from an HTML form.
```php
namespace app\models;
use yii\base\Model;
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $body;
}
```
You may override [[yii\base\Model::attributes()]] to define attributes in a different way. The method should
return the names of the attributes in a model. For example, [[yii\db\ActiveRecord]] does so by returning
the column names of the associated database table as its attribute names. Note that you may also need to
override the magic methods such as `__get()`, `__set()` so that the attributes can be accessed like
normal object properties.
## Attribute Labels <a name="attribute-labels"></a> ## Attribute Labels <a name="attribute-labels"></a>
...@@ -82,6 +88,15 @@ When displaying values or getting input for attributes, you often need to displa ...@@ -82,6 +88,15 @@ When displaying values or getting input for attributes, you often need to displa
with attributes. For example, given an attribute named `firstName`, you may want to display a label `First Name` with attributes. For example, given an attribute named `firstName`, you may want to display a label `First Name`
which is more user-friendly when displayed to end users in places such as form inputs and error messages. which is more user-friendly when displayed to end users in places such as form inputs and error messages.
You can get the label of an attribute by calling [[yii\base\Model::getAttributeLabel()]]. For example,
```php
$model = new \app\models\ContactForm;
// displays "Label"
echo $model->getAttributeLabel('name');
```
By default, attribute labels are automatically generated from attribute names. The generation is done by By default, attribute labels are automatically generated from attribute names. The generation is done by
the method [[yii\base\Model::generateAttributeLabel()]]. It will turn camel-case variable names into the method [[yii\base\Model::generateAttributeLabel()]]. It will turn camel-case variable names into
multiple words with the first letter in each word in upper case. For example, `username` becomes `Username`, multiple words with the first letter in each word in upper case. For example, `username` becomes `Username`,
...@@ -156,7 +171,8 @@ $model->scenario = 'login'; ...@@ -156,7 +171,8 @@ $model->scenario = 'login';
$model = new User(['scenario' => 'login']); $model = new User(['scenario' => 'login']);
``` ```
To support multiple scenarios by a single model, you may override the [[yii\base\Model::scenarios()]] method, By default, the scenarios supported by a model are determined by the [validation rules](#validation) declared
in the model. However, you can customize this behavior by overriding the [[yii\base\Model::scenarios()]] method,
like the following: like the following:
```php ```php
...@@ -218,10 +234,10 @@ you may want to make sure all attributes are not empty and the `email` attribute ...@@ -218,10 +234,10 @@ you may want to make sure all attributes are not empty and the `email` attribute
If the values for some attributes do not satisfy the corresponding business rules, appropriate error messages If the values for some attributes do not satisfy the corresponding business rules, appropriate error messages
should be displayed to help the user to fix the errors. should be displayed to help the user to fix the errors.
You may call [[yii\base\Model::validate()]] to trigger validation. The method will go through every *active rule* You may call [[yii\base\Model::validate()]] to validate the received data. The method will use
and make sure it is satisfied. If not, an error message will be generated for each failed rule and attribute. the validation rules declared in [[yii\base\Model::rules()]] to validate every relevant attribute. If no error
The method returns a boolean value indicating whether all rules are satisfied. If not, you may retrieve the is found, it will return true. Otherwise, it will keep the errors in the [[yii\base\Model::errors]] property
error messages through the property [[yii\base\Model::errors]] or [[yii\base\Model::firstErrors]]. For example, and return false. For example,
```php ```php
$model = new \app\models\ContactForm; $model = new \app\models\ContactForm;
...@@ -239,7 +255,7 @@ if ($model->validate()) { ...@@ -239,7 +255,7 @@ if ($model->validate()) {
To declare validation rules associated with a model, override the [[yii\base\Model::rules()]] method by returning To declare validation rules associated with a model, override the [[yii\base\Model::rules()]] method by returning
the rules that the model data should satisfy. The following example should the validation rules the rules that the model attributes should satisfy. The following example shows the validation rules declared
for the `ContactForm` model: for the `ContactForm` model:
```php ```php
...@@ -255,50 +271,31 @@ public function rules() ...@@ -255,50 +271,31 @@ public function rules()
} }
``` ```
The `rules()` method returns an array of rules, each of which is an array in the following format: A rule can be used to validate one or multiple attributes, and an attribute may be validated by one or multiple rules.
Please refer to the [Validating Input](input-validation.md) section for more details on how to declare
```php validation rules.
[
// required, specifies which attributes should be validated by this rule.
// For single attribute, you can use the attribute name directly
// without having it in an array instead of an array
['attribute1', 'attribute2', ...],
// required, specifies the type of this rule.
// It can be a class name, validator alias, or a validation method name
'validator',
// optional, specifies in which scenario(s) this rule should be applied
// if not given, it means the rule applies to all scenarios
'on' => ['scenario1', 'scenario2', ...],
// optional, specifies additional configurations for the validator object
'property1' => 'value1', 'property2' => 'value2', ...
]
```
A rule may be applied to one or multiple attributes. A rule may be applicable only in certain [scenarios](#scenarios).
When a rule is applicable in a scenario, it is called an *active rule* in that scenario.
When the `validate()` method is called, it does the following steps to perform validation: Sometimes, you may want a rule to be applied only in certain [scenarios](#scenarios). To do so, you can
specify the `on` property of a rule, like the following:
1. Determine which attributes should be validated by checking the current [[yii\base\Model::scenario|scenario]] ```php
against the scenarios declared in [[yii\base\Model::scenarios()]]. These attributes are the active attributes. public function rules()
2. Determine which rules should be applied by checking the current [[yii\base\Model::scenario|scenario]] {
against the rules declared in [[yii\base\Model::rules()]]. These rules are the active rules. return [
3. Use each active rule to validate each active attribute which is associated with the rule. // username, email and password are all required in "register" scenario
[['username', 'email', 'password'], 'required', 'on' => 'register'],
According to the above validation steps, an attribute will be validated if and only if it is // username and password are required in "login" scenario
an active attribute declared in `scenarios()` and it is associated with one or multiple active rules [['username', 'password'], 'required', 'on' => 'login'],
declared in `rules()`. ];
}
```
Yii provides a set of built-in validators to support commonly needed data validation tasks. You may also If you do not specify the `on` property, the rule would be applied in all scenarios. A rule is called
create your own validators by extending [[yii\validators\Validator]] or writing an inline validation method an *active rule* if it can be applied in the current [[yii\base\Model::scenario|scenario]].
within model classes. For more details about the built-in validators and how to create your own validators,
please refer to the [Input Validation](input-validation.md) section.
> Note: As a rule of thumb, never trust the data coming from end users and always validate them before An attribute will be validated if and only if it is an active attribute declared in `scenarios()` and
putting them to some good use. is associated with one or multiple active rules declared in `rules()`.
## Massive Assignment <a name="massive-assignment"></a> ## Massive Assignment <a name="massive-assignment"></a>
......
...@@ -70,7 +70,7 @@ Yii tries to load appropriate translation from one of the message sources define ...@@ -70,7 +70,7 @@ Yii tries to load appropriate translation from one of the message sources define
'app*' => [ 'app*' => [
'class' => 'yii\i18n\PhpMessageSource', 'class' => 'yii\i18n\PhpMessageSource',
//'basePath' => '@app/messages', //'basePath' => '@app/messages',
//'sourceLanguage' => 'en', //'sourceLanguage' => 'en-US',
'fileMap' => [ 'fileMap' => [
'app' => 'app.php', 'app' => 'app.php',
'app/error' => 'error.php', 'app/error' => 'error.php',
...@@ -323,7 +323,7 @@ class Module extends \yii\base\Module ...@@ -323,7 +323,7 @@ class Module extends \yii\base\Module
{ {
Yii::$app->i18n->translations['modules/users/*'] = [ Yii::$app->i18n->translations['modules/users/*'] = [
'class' => 'yii\i18n\PhpMessageSource', 'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en', 'sourceLanguage' => 'en-US',
'basePath' => '@app/modules/users/messages', 'basePath' => '@app/modules/users/messages',
'fileMap' => [ 'fileMap' => [
'modules/users/validation' => 'validation.php', 'modules/users/validation' => 'validation.php',
...@@ -370,7 +370,7 @@ class Menu extends Widget ...@@ -370,7 +370,7 @@ class Menu extends Widget
$i18n = Yii::$app->i18n; $i18n = Yii::$app->i18n;
$i18n->translations['widgets/menu/*'] = [ $i18n->translations['widgets/menu/*'] = [
'class' => 'yii\i18n\PhpMessageSource', 'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en', 'sourceLanguage' => 'en-US',
'basePath' => '@app/widgets/menu/messages', 'basePath' => '@app/widgets/menu/messages',
'fileMap' => [ 'fileMap' => [
'widgets/menu/messages' => 'messages.php', 'widgets/menu/messages' => 'messages.php',
...@@ -407,7 +407,7 @@ Sometimes you want to correct default framework message translation for your app ...@@ -407,7 +407,7 @@ Sometimes you want to correct default framework message translation for your app
'translations' => [ 'translations' => [
'yii' => [ 'yii' => [
'class' => 'yii\i18n\PhpMessageSource', 'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en', 'sourceLanguage' => 'en-US',
'basePath' => '/path/to/my/message/files' 'basePath' => '/path/to/my/message/files'
], ],
], ],
......
# Upload File with Yii2
### First you need to create a model that will handle the form of download the file.
```php
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
/**
* UploadForm is the model behind the upload form.
*/
class UploadForm extends Model
{
/**
* @var UploadedFile|Null file attribute
*/
public $file;
/**
* @return array the validation rules.
*/
public function rules()
{
return [
[['file'], 'file'],
];
}
}
```
In this code, we created a model ```UploadForm``` with an attribute ```$file``` that will be is ```<input type="file">``` in upload form and pointed out to him validation rule ```file```. This rule is [[yii\validators\FileValidator|FileValidator]]
### Secondly create a view for our model.
```php
<?php
use yii\widgets\ActiveForm;
$form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($model, 'file')->fileInput() ?>
<button>Submit</button>
<?php ActiveForm::end(); ?>
```
It is different attribute ```'enctype' => 'multipart/form-data'``` from the standard form. This value is required when you are using forms that have a file upload control. ```fileInput()``` represents a form input field.
### Thirdly, that create the controller that will connect our form and model.
```php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller
{
public function actionUpload()
{
$model = new UploadForm();
if (Yii::$app->request->isPost) {
$model->file = UploadedFile::getInstance($model, 'file');
if ($model->validate()) {
$model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);
}
}
return $this->render('upload', ['model' => $model]);
}
}
```
The difference here from the standard crud action, so use ```UploadedFile::getInstance(...)``` instead ```model->load(...)```. [[\yii\web\UploadedFile|UploadedFile]] does not run the model validation, it only provides information about the uploaded file. Therefore, you need to run validation manually ```$model->validate()```. This triggers the [[yii\validators\FileValidator|FileValidator]] that expects a file
```php
$file instanceof UploadedFile || $file->error == UPLOAD_ERR_NO_FILE //in code framework
```
If validation done without errors, then save the file
```php
$model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);
```
If you use "basic" application then forlder ```uploads``` should be create inside ```web``` folder.
Everything is ready, now run the page and download the file. Check the folder ```basic/web/uploads``` to make sure that you have downloaded.
## Additional information.
***
### Required rule
If you need to check the mandatory download the file, then use ```skipOnEmpty```.
```php
public function rules()
{
return [
[['file'], 'file', 'skipOnEmpty' => false],
];
}
```
***
### Path upload folder
Folder to download the file can be installed using ```Yii::getAlias('@app/uploads')```. This base path of currently running application and folder ```uploads``
***
### MIME type
FileValidator have property ```$types```
```php
public function rules()
{
return [
[['file'], 'file', 'types' => 'gif, jpg',],
];
}
```
it pulls
```php
in_array(strtolower(pathinfo($file->name, PATHINFO_EXTENSION)), $this->types, true))
```
As you can see, the name of the expansion may be one and the file type - other, actually.
``UploadedFile::getInstance()->type``` also do not take this value for granted.
Instead, use [[\yii\helpers\BaseFileHelper|FileHelper]] and his [[FileHelper::getMimeType()]] to determine the exact MIME type.
If allowed to **load only the images**, using [[\yii\validators\ImageValidator|ImageValidator]] instead [[yii\validators\FileValidator|FileValidator]].
```php
public function rules()
{
return [
[['file'], 'image', 'mimeTypes' => 'image/jpeg, image/png',],
];
}
```
```ImageValidator``` use use ```yii\helpers\FileHelper;``` for check mime types.
[List Mime types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
***
### Multiple files uploader
If you need download multiple files, you will need to alter slightly the controller and view.
At first view:
```php
<?php
use yii\widgets\ActiveForm;
$form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]);
if ($model->hasErrors()) { //it is necessary to see all the errors for all the files.
echo '<pre>';
print_r($model->getErrors());
echo '</pre>';
}
?>
<?= $form->field($model, 'file[]')->fileInput(['multiple' => '']) ?>
<button>Submit</button>
<?php ActiveForm::end(); ?>
```
In fact the only difference is in the one row.
```php
<?= $form->field($model, 'file[]')->fileInput(['multiple' => '']) ?>
```
instead
```php
<?= $form->field($model, 'file')->fileInput() ?>
```
* ```['multiple' => '']``` - HTML <input> multiple Attribute
* ```file[]``` vs ```file`` - need, otherwise UploadedFile sees only one file
We now turn to the controller
```php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller
{
public function actionUpload()
{
$model = new UploadForm();
if (Yii::$app->request->isPost) {
$files = UploadedFile::getInstances($model, 'file');
foreach ($files as $file) {
$_model = new UploadForm();
$_model->file = $file;
if ($_model->validate()) {
$_model->file->saveAs('uploads/' . $_model->file->baseName . '.' . $_model->file->extension);
} else {
foreach ($_model->getErrors('file') as $error) {
$model->addError('file', $error);
}
}
}
if ($model->hasErrors('file')){
$model->addError(
'file',
count($model->getErrors('file')) . ' of ' . count($files) . ' files not uploaded'
);
}
}
return $this->render('upload', ['model' => $model]);
}
}
```
Here the differences in:
* ``` UploadedFile::getInstances($model, 'file');``` instead ``` UploadedFile::getInstance($model, 'file');```. First returns **all** uploaded files for the given model attribute, second - one.
* All other differences follow from the first.
...@@ -33,7 +33,110 @@ Yii переводится на множество языков, в том чи ...@@ -33,7 +33,110 @@ Yii переводится на множество языков, в том чи
build translation ../docs/guide" "../docs/guide-ru" --title="Russian guide translation report" > report-guide-ru.html build translation ../docs/guide" "../docs/guide-ru" --title="Russian guide translation report" > report-guide-ru.html
``` ```
Перед тем, как начать перевод, убедитесь, что никто им ещё не занимается и запишите себя в
[список всех переводимых документов](https://docs.google.com/spreadsheets/d/1uxV0LwmR-8XXqlT8C6VqWllZjuoyIj-UkYpAQPWyUzE/edit?usp=sharing).
Все изменения оформляем в виде [pull request](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md). Все изменения оформляем в виде [pull request](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md).
[Список всех переводимых документов](https://docs.google.com/spreadsheets/d/1uxV0LwmR-8XXqlT8C6VqWllZjuoyIj-UkYpAQPWyUzE/edit?usp=sharing)
доступен для редактирования на Google Docs. ### Общие правила
\ No newline at end of file
- Многие термины не имеют однозначного и широко распространенного перевода на русский язык, поэтому, если в тексте
встречается такой термин, в скобках возле первого упоминания необходимо указать английский вариант; (список используемых
вариантов перевода терминов см. ниже);
- Если кажется, что при переводе какая-то часть текста теряет смысл и вы не уверены в том, как ее правильно перевести,
заключайте эту часть текста в * (внешне шрифт станет наклонным). Это позволит при вычитке/корректуре обратить на эту
часть текста особое внимание;
- При переводе избегайте фактических ошибок!
- В тексте встречаются ссылки на внешние источники, если ссылка ведет на статью, определение термина и т.п., то при
наличии русского варианта на этом же ресурсе или ином авторитетном ресурсе, даем ссылку на русский вариант.
Например `http://en.wikipedia.org/wiki/Captcha``http://ru.wikipedia.org/wiki/Captcha`.
- Комментарии в коде переводятся, если не искажают первоначального смысла; временные комментарии в тексте желательно
использовать только локально! иначе есть вероятность попадания в релиз;
- При переводе названий разделов придерживаемся перевода в `README.md`;
- Добавление собственных комментариев-дополнений возможно, но не приветствуется поскольку во избежание хаоса оригинал
должен быть один. В случае такой необходимости в конце комментария нужно добавить "(прим. пер.)";
- После проведения общей правки документа настоятельно рекомендуется самостоятельно вносить исправления только
грамматических, а также фактических ошибок, имеющих отношение только к данному разделу. В остальных случаях необходимо
вынести предложение по исправлению, улучшению на обсуждение и в случае необходимости централизованно внести коррективы
во все разделы документа.
### Структура документа
При переводе необходимо правильно именовать структурные единицы документы. Следуем структуре, приведенной ниже:
- Глава 1
- Раздел 1
- Раздел 2
- Подраздел 1
- ...
- Раздел N
- Глава 2
- ...
- Глава N
### Перевод специальных сообщений
- Tip → Подсказка
- Note → Примечание
- Info → Информация
### Перевод рисунков
Рисунки к документации содержатся в подпапке `images`. Все они созданы в [yED](http://www.yworks.com/en/products_yed_about.html).
При необходимости перевода исходный файл копируется в директорию `images` перевода, переводится и сохраняется в формате png.
Подписи к рисункам переводятся.
### Грамматика
Обращайте внимание на общую стилистику, орфографию и пунктуацию, перед заливкой конечного варианта перевод можно прогнать
через любую программу с встроенной проверкой, например, Microsoft Word;
### Список терминов
- action — действие.
- active record — без перевода.
- attach handler — «назначить обработчик».
- attribute of the model — атрибут модели.
- camel case — без перевода.
- customization — (тонкая) настройка //Ранее встречался перевод "кастомизация", желательно этот вариант по возможности не использовать.
- column — столбец (если речь про БД).
- content — содержимое.
- controller — контроллер.
- debug (mode) — отладочный (режим) (см. production mode).
- eager loading — метод жадной загрузки/жадная загрузка (см. lazy loading).
- PHP extension — расширение PHP.
- field (of the table) — поле (или атрибут) таблицы.
- framework — фреймворк.
- front-controller — фронт-контроллер.
- getter — геттер.
- (event) handler — обработчик (события).
- hash — хэш.
- helper - помощник.
- id — идентификатор.
- instance — экземпляр.
- lazy loading — отложенная загрузка (загрузим как понадобится и не раньше).
- method — метод (объекта) //Внимание! У объета/класса нет функций, есть только методы.
- model — модель, модель данных.
- model form — модель формы.
- parameter — параметр (у метода или функции, никак не у класса).
- to parse — обрабатывать, если контекст непонятен — парсить.
- placeholder — маркер.
- production (mode) — производственный (режим) (см. debug mode).
- property — свойство (объекта).
- to render — рендерить, формировать.
- related, relation — связанный, связь.
- resolve request — предварительная обработка запроса.
- route — маршрут.
- row (of the table) — строка (таблицы).
- setter — сеттер.
- tabular input — табличный ввод.
- to validate — проверять.
- valid — корректный.
- validator — валидатор.
- validator class — класс валидатора.
- view — представление.
- query builder — конструктор запросов.
\ No newline at end of file
...@@ -206,7 +206,7 @@ class ActiveField extends \yii\widgets\ActiveField ...@@ -206,7 +206,7 @@ class ActiveField extends \yii\widgets\ActiveField
if ($enclosedByLabel) { if ($enclosedByLabel) {
if (!isset($options['template'])) { if (!isset($options['template'])) {
$this->template = $this->form->layout === 'horizontal' ? $this->template = $this->form->layout === 'horizontal' ?
$this->horizontalCheckboxTemplate : $this->checkBoxTemplate; $this->horizontalCheckboxTemplate : $this->checkboxTemplate;
} else { } else {
$this->template = $options['template']; $this->template = $options['template'];
unset($options['template']); unset($options['template']);
......
...@@ -5,6 +5,7 @@ Yii Framework 2 debug extension Change Log ...@@ -5,6 +5,7 @@ Yii Framework 2 debug extension Change Log
-------------------------- --------------------------
- Bug #1263: Fixed the issue that Gii and Debug modules might be affected by incompatible asset manager configuration (qiangxue) - Bug #1263: Fixed the issue that Gii and Debug modules might be affected by incompatible asset manager configuration (qiangxue)
- Enh #2299: Date and time in request list is now never wrapped (samdark)
- Enh #3088: The debug module will manage their own URL rules now (qiangxue) - Enh #3088: The debug module will manage their own URL rules now (qiangxue)
- Enh #3103: debugger panel is now not displayed when printing a page (githubjeka) - Enh #3103: debugger panel is now not displayed when printing a page (githubjeka)
- Enh #3108: Added `yii\debug\Module::enableDebugLogs` to disable logging debug logs by default (qiangxue) - Enh #3108: Added `yii\debug\Module::enableDebugLogs` to disable logging debug logs by default (qiangxue)
......
...@@ -93,3 +93,7 @@ a.desc:after { ...@@ -93,3 +93,7 @@ a.desc:after {
width: 12%; width: 12%;
font-weight: bold; font-weight: bold;
} }
.nowrap {
white-space: nowrap;
}
\ No newline at end of file
...@@ -61,8 +61,9 @@ if (isset($this->context->module->panels['db']) && isset($this->context->module- ...@@ -61,8 +61,9 @@ if (isset($this->context->module->panels['db']) && isset($this->context->module-
[ [
'attribute' => 'time', 'attribute' => 'time',
'value' => function ($data) use ($timeFormatter) { 'value' => function ($data) use ($timeFormatter) {
return $timeFormatter->asDateTime($data['time'], 'short'); return '<span class="nowrap">' . $timeFormatter->asDateTime($data['time'], 'short') . '</span>';
}, },
'format' => 'html',
], ],
'ip', 'ip',
[ [
......
...@@ -68,8 +68,8 @@ class <?= $controllerClass ?> extends <?= StringHelper::basename($generator->bas ...@@ -68,8 +68,8 @@ class <?= $controllerClass ?> extends <?= StringHelper::basename($generator->bas
$dataProvider = $searchModel->search(Yii::$app->request->getQueryParams()); $dataProvider = $searchModel->search(Yii::$app->request->getQueryParams());
return $this->render('index', [ return $this->render('index', [
'dataProvider' => $dataProvider,
'searchModel' => $searchModel, 'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]); ]);
<?php else: ?> <?php else: ?>
$dataProvider = new ActiveDataProvider([ $dataProvider = new ActiveDataProvider([
......
...@@ -19,8 +19,8 @@ use <?= $generator->indexWidgetType === 'grid' ? "yii\\grid\\GridView" : "yii\\w ...@@ -19,8 +19,8 @@ use <?= $generator->indexWidgetType === 'grid' ? "yii\\grid\\GridView" : "yii\\w
/** /**
* @var yii\web\View $this * @var yii\web\View $this
* @var yii\data\ActiveDataProvider $dataProvider
<?= !empty($generator->searchModelClass) ? " * @var " . ltrim($generator->searchModelClass, '\\') . " \$searchModel\n" : '' ?> <?= !empty($generator->searchModelClass) ? " * @var " . ltrim($generator->searchModelClass, '\\') . " \$searchModel\n" : '' ?>
* @var yii\data\ActiveDataProvider $dataProvider
*/ */
$this->title = <?= $generator->generateString(Inflector::pluralize(Inflector::camel2words(StringHelper::basename($generator->modelClass)))) ?>; $this->title = <?= $generator->generateString(Inflector::pluralize(Inflector::camel2words(StringHelper::basename($generator->modelClass)))) ?>;
......
...@@ -79,7 +79,7 @@ class DatePicker extends InputWidget ...@@ -79,7 +79,7 @@ class DatePicker extends InputWidget
echo $this->renderWidget() . "\n"; echo $this->renderWidget() . "\n";
$containerID = $this->inline ? $this->containerOptions['id'] : $this->options['id']; $containerID = $this->inline ? $this->containerOptions['id'] : $this->options['id'];
$language = $this->language ? $this->language : Yii::$app->language; $language = $this->language ? $this->language : Yii::$app->language;
if ($language != 'en') { if ($language != 'en-US') {
$view = $this->getView(); $view = $this->getView();
DatePickerRegionalAsset::register($view); DatePickerRegionalAsset::register($view);
......
...@@ -87,6 +87,7 @@ Yii Framework 2 Change Log ...@@ -87,6 +87,7 @@ Yii Framework 2 Change Log
- Enh: Added support for using path alias with `FileDependency::fileName` (qiangxue) - Enh: Added support for using path alias with `FileDependency::fileName` (qiangxue)
- Enh: Added param `hideOnSinglePage` to `yii\widgets\LinkPager` (arturf) - Enh: Added param `hideOnSinglePage` to `yii\widgets\LinkPager` (arturf)
- Enh: Added support for array attributes in `in` validator (creocoder) - Enh: Added support for array attributes in `in` validator (creocoder)
- Enh: Improved `yii\helpers\Inflector::slug` to support more cases for Russian, Hebrew and special characters (samdark)
- Chg #2898: `yii\console\controllers\AssetController` is now using hashes instead of timestamps (samdark) - Chg #2898: `yii\console\controllers\AssetController` is now using hashes instead of timestamps (samdark)
- Chg #2913: RBAC `DbManager` is now initialized via migration (samdark) - Chg #2913: RBAC `DbManager` is now initialized via migration (samdark)
- Chg #3036: Upgraded Twitter Bootstrap to 3.1.x (qiangxue) - Chg #3036: Upgraded Twitter Bootstrap to 3.1.x (qiangxue)
...@@ -94,6 +95,7 @@ Yii Framework 2 Change Log ...@@ -94,6 +95,7 @@ Yii Framework 2 Change Log
- Chg #3383: Added `$type` parameter to `IdentityInterface::findIdentityByAccessToken()` (qiangxue) - Chg #3383: Added `$type` parameter to `IdentityInterface::findIdentityByAccessToken()` (qiangxue)
- Chg #3531: \yii\grid\GridView now allows any character (except ":") in the attribute part of the shorthand syntax for columns (rawtaz) - Chg #3531: \yii\grid\GridView now allows any character (except ":") in the attribute part of the shorthand syntax for columns (rawtaz)
- Chg #3544: Added `$key` as a parameter to the callable specified via `yii\grid\DataColumn::value` (mdmunir) - Chg #3544: Added `$key` as a parameter to the callable specified via `yii\grid\DataColumn::value` (mdmunir)
- Chg #3687: Default `sourceLanguage` and `language` are now `en-US` in order for i18n formatter to work correctly (samdark)
- Chg: Replaced `clearAll()` and `clearAllAssignments()` in `yii\rbac\ManagerInterface` with `removeAll()`, `removeAllRoles()`, `removeAllPermissions()`, `removeAllRules()` and `removeAllAssignments()` (qiangxue) - Chg: Replaced `clearAll()` and `clearAllAssignments()` in `yii\rbac\ManagerInterface` with `removeAll()`, `removeAllRoles()`, `removeAllPermissions()`, `removeAllRules()` and `removeAllAssignments()` (qiangxue)
- Chg: Added `$user` as the first parameter of `yii\rbac\Rule::execute()` (qiangxue) - Chg: Added `$user` as the first parameter of `yii\rbac\Rule::execute()` (qiangxue)
- Chg: `yii\grid\DataColumn::getDataCellValue()` visibility is now `public` to allow accessing the value from a GridView directly (cebe) - Chg: `yii\grid\DataColumn::getDataCellValue()` visibility is now `public` to allow accessing the value from a GridView directly (cebe)
......
...@@ -21,7 +21,7 @@ use Yii; ...@@ -21,7 +21,7 @@ use Yii;
* @property \yii\db\Connection $db The database connection. This property is read-only. * @property \yii\db\Connection $db The database connection. This property is read-only.
* @property \yii\web\ErrorHandler|\yii\console\ErrorHandler $errorHandler The error handler application * @property \yii\web\ErrorHandler|\yii\console\ErrorHandler $errorHandler The error handler application
* component. This property is read-only. * component. This property is read-only.
* @property \yii\base\Formatter $formatter The formatter application component. This property is read-only. * @property \yii\base\Formatter|\yii\i18n\Formatter $formatter The formatter application component. This property is read-only.
* @property \yii\i18n\I18N $i18n The internationalization component. This property is read-only. * @property \yii\i18n\I18N $i18n The internationalization component. This property is read-only.
* @property \yii\log\Dispatcher $log The log dispatcher component. This property is read-only. * @property \yii\log\Dispatcher $log The log dispatcher component. This property is read-only.
* @property \yii\mail\MailerInterface $mail The mailer interface. This property is read-only. * @property \yii\mail\MailerInterface $mail The mailer interface. This property is read-only.
...@@ -106,13 +106,13 @@ abstract class Application extends Module ...@@ -106,13 +106,13 @@ abstract class Application extends Module
* for English, while `en-US` stands for English (United States). * for English, while `en-US` stands for English (United States).
* @see sourceLanguage * @see sourceLanguage
*/ */
public $language = 'en'; public $language = 'en-US';
/** /**
* @var string the language that the application is written in. This mainly refers to * @var string the language that the application is written in. This mainly refers to
* the language that the messages and view files are written in. * the language that the messages and view files are written in.
* @see language * @see language
*/ */
public $sourceLanguage = 'en'; public $sourceLanguage = 'en-US';
/** /**
* @var Controller the currently active controller instance * @var Controller the currently active controller instance
*/ */
......
...@@ -467,9 +467,9 @@ class BaseInflector ...@@ -467,9 +467,9 @@ class BaseInflector
public static function slug($string, $replacement = '-', $lowercase = true) public static function slug($string, $replacement = '-', $lowercase = true)
{ {
if (extension_loaded('intl') === true) { if (extension_loaded('intl') === true) {
$options = 'Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove;'; $options = 'Any-Latin; NFKD; [:Punctuation:] Remove; [^\u0000-\u007E] Remove';
$string = transliterator_transliterate($options, $string); $string = transliterator_transliterate($options, $string);
$string = preg_replace('/[-\s]+/', $replacement, $string); $string = preg_replace('/[-=\s]+/', $replacement, $string);
} else { } else {
$string = str_replace(array_keys(static::$transliteration), static::$transliteration, $string); $string = str_replace(array_keys(static::$transliteration), static::$transliteration, $string);
$string = preg_replace('/[^\p{L}\p{Nd}]+/u', $replacement, $string); $string = preg_replace('/[^\p{L}\p{Nd}]+/u', $replacement, $string);
......
...@@ -57,7 +57,7 @@ class I18N extends Component ...@@ -57,7 +57,7 @@ class I18N extends Component
if (!isset($this->translations['yii']) && !isset($this->translations['yii*'])) { if (!isset($this->translations['yii']) && !isset($this->translations['yii*'])) {
$this->translations['yii'] = [ $this->translations['yii'] = [
'class' => 'yii\i18n\PhpMessageSource', 'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en', 'sourceLanguage' => 'en-US',
'basePath' => '@yii/messages', 'basePath' => '@yii/messages',
]; ];
} }
......
...@@ -124,9 +124,21 @@ class InflectorTest extends TestCase ...@@ -124,9 +124,21 @@ class InflectorTest extends TestCase
public function testSlug() public function testSlug()
{ {
$this->assertEquals("privet-hello-jii-framework-kak-dela-how-it-goes", Inflector::slug('Привет Hello Йии-- Framework !--- Как дела ? How it goes ?')); $data = [
'Привет. Hello, Йии-- Framework !--- Как дела ? How it goes ?' => 'privet-hello-jii-framework-kak-dela-how-it-goes',
'this is a title' => 'this-is-a-title',
'недвижимость' => 'nedvizimost',
'áàâéèêíìîóòôúùûã' => 'aaaeeeiiiooouuua',
'Ναδάλης ṃỹṛèşưḿĕ' => 'nadales-myresume',
'E=mc²' => 'e-mc2',
'載å¥' => 'e14a',
];
foreach ($data as $source => $expected) {
$this->assertEquals($expected, Inflector::slug($source));
}
$this->assertEquals("this-is-a-title", Inflector::slug('this is a title')); //$this->assertEquals('this-is-my-text-', Inflector::slug('! this is my / text $## '));
} }
public function testClassify() public function testClassify()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment