Browse Source

Merge branch 'master' into 2.1

tags/3.0.0-alpha1
SilverFire - Dmitry Naumenko 6 years ago
parent
commit
fa71f808c1
No known key found for this signature in database
GPG Key ID: 39DD917A92B270A
  1. 1
      .appveyor.yml
  2. 16
      docs/guide-ja/README.md
  3. 2
      docs/guide-ja/db-query-builder.md
  4. 55
      docs/guide-ja/helper-array.md
  5. 52
      docs/guide-ja/helper-html.md
  6. 23
      docs/guide-ja/helper-overview.md
  7. 33
      docs/guide-ja/helper-url.md
  8. 2
      docs/guide-ja/input-forms.md
  9. 35
      docs/guide-ja/rest-authentication.md
  10. 28
      docs/guide-ja/rest-controllers.md
  11. 22
      docs/guide-ja/rest-error-handling.md
  12. 19
      docs/guide-ja/rest-quick-start.md
  13. 15
      docs/guide-ja/rest-rate-limiting.md
  14. 52
      docs/guide-ja/rest-resources.md
  15. 19
      docs/guide-ja/rest-routing.md
  16. 33
      docs/guide-ja/rest-versioning.md
  17. 3
      docs/guide-ja/test-acceptance.md
  18. 10
      docs/guide-ja/test-environment-setup.md
  19. 56
      docs/guide-ja/test-fixtures.md
  20. 3
      docs/guide-ja/test-functional.md
  21. 15
      docs/guide-ja/test-overview.md
  22. 9
      docs/guide-ja/test-unit.md
  23. 58
      docs/guide-ja/tutorial-console.md
  24. 189
      docs/guide-ja/tutorial-core-validators.md
  25. 7
      docs/guide-ja/tutorial-docker.md
  26. 132
      docs/guide-ja/tutorial-i18n.md
  27. 9
      docs/guide-ja/tutorial-mailing.md
  28. 56
      docs/guide-ja/tutorial-performance-tuning.md
  29. 13
      docs/guide-ja/tutorial-shared-hosting.md
  30. 11
      docs/guide-ja/tutorial-start-from-scratch.md
  31. 11
      docs/guide-ja/tutorial-template-engines.md
  32. 26
      docs/guide-ja/tutorial-yii-as-micro-framework.md
  33. 66
      docs/guide-ja/tutorial-yii-integration.md
  34. 2
      docs/guide-ru/concept-components.md
  35. 18
      docs/guide-ru/concept-configurations.md
  36. 10
      docs/guide-ru/concept-di-container.md
  37. 8
      docs/guide-ru/concept-service-locator.md
  38. 36
      docs/guide-ru/helper-array.md
  39. 18
      docs/guide-ru/helper-overview.md
  40. 8
      docs/guide-ru/helper-url.md
  41. 22
      docs/guide-ru/runtime-logging.md
  42. 38
      docs/guide-ru/runtime-routing.md
  43. 6
      docs/guide-ru/start-looking-ahead.md
  44. 24
      docs/guide-ru/test-fixtures.md
  45. 8
      docs/guide-ru/tutorial-template-engines.md
  46. 4
      docs/guide-ru/tutorial-yii-as-micro-framework.md
  47. 119
      docs/guide-vi/structure-application-components.md
  48. 607
      docs/guide-vi/structure-applications.md
  49. 444
      docs/guide-vi/structure-controllers.md
  50. 116
      docs/guide-vi/structure-entry-scripts.md
  51. 529
      docs/guide-vi/structure-models.md
  52. 16
      docs/guide/README.md
  53. 18
      docs/guide/db-active-record.md
  54. 2
      docs/guide/db-query-builder.md
  55. 4
      docs/guide/tutorial-template-engines.md
  56. 5
      docs/internals-ja/README.md
  57. 3
      docs/internals-ja/automation.md
  58. 85
      docs/internals-ja/core-code-style.md
  59. 7
      docs/internals-ja/design-decisions.md
  60. 56
      docs/internals-ja/git-workflow.md
  61. 15
      docs/internals-ja/project-organization.md
  62. 3
      docs/internals-ja/pull-request-qa.md
  63. 16
      docs/internals-ja/release.md
  64. 3
      docs/internals-ja/report-an-issue.md
  65. 9
      docs/internals-ja/translation-workflow.md
  66. 13
      docs/internals-ja/versions.md
  67. 5
      docs/internals-ja/view-code-style.md
  68. 10
      framework/CHANGELOG.md
  69. 20
      framework/base/View.php
  70. 6
      framework/base/Widget.php
  71. 160
      framework/behaviors/OptimisticLockBehavior.php
  72. 10
      framework/console/controllers/HelpController.php
  73. 6
      framework/db/BaseActiveRecord.php
  74. 2
      framework/db/Schema.php
  75. 15
      framework/filters/Cors.php
  76. 32
      framework/helpers/BaseInflector.php
  77. 38
      framework/helpers/BaseStringHelper.php
  78. 2
      framework/http/CookieCollection.php
  79. 20
      tests/data/ar/Cat.php
  80. 30
      tests/framework/base/ViewTest.php
  81. 22
      tests/framework/base/WidgetTest.php
  82. 283
      tests/framework/behaviors/OptimisticLockBehaviorTest.php
  83. 16
      tests/framework/db/ActiveRecordTest.php
  84. 22
      tests/framework/filters/CorsTest.php
  85. 14
      tests/framework/helpers/InflectorTest.php
  86. 46
      tests/framework/helpers/StringHelperTest.php

1
.appveyor.yml

@ -30,6 +30,7 @@ install:
- echo extension=php_intl.dll >> php.ini
- echo extension=php_mbstring.dll >> php.ini
- echo extension=php_openssl.dll >> php.ini
- echo extension=php_pdo_sqlite.dll >> php.ini
- IF NOT EXIST C:\tools\composer.phar (cd C:\tools && appveyor DownloadFile https://getcomposer.org/download/1.4.1/composer.phar)
before_test:

16
docs/guide-ja/README.md

@ -182,14 +182,14 @@ RESTful ウェブ・サービス
ウィジェット
------------
* [[yii\grid\GridView|GridView]]
* [[yii\widgets\ListView|ListView]]
* [[yii\widgets\DetailView|DetailView]]
* [[yii\widgets\ActiveForm|ActiveForm]]
* [[yii\widgets\Pjax|Pjax]]
* [[yii\widgets\Menu|Menu]]
* [[yii\widgets\LinkPager|LinkPager]]
* [[yii\widgets\LinkSorter|LinkSorter]]
* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc/guide/2.0/ja/input-forms#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Bootstrap ウィジェット](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [jQuery UI ウィジェット](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)

2
docs/guide-ja/db-query-builder.md

@ -237,7 +237,7 @@ $query->where(['id' => $userQuery]);
```php
// 脆弱なコード:
$column = $request->get('column');
$value = $request->get('value);
$value = $request->get('value');
$query->where([$column => $value]);
// $value は安全です。しかし、$column の名前はエンコードされません。
```

55
docs/guide-ja/helper-array.md

@ -1,13 +1,15 @@
配列ヘルパ
==========
[PHP の充実した配列関数](http://php.net/manual/ja/book.array.php) への追加として、Yii の配列ヘルパは、配列をさらに効率的に扱うことを可能にするスタティックなメソッドを提供しています。
[PHP の充実した配列関数](http://php.net/manual/ja/book.array.php) への追加として、
Yii の配列ヘルパは、配列をさらに効率的に扱うことを可能にするスタティックなメソッドを提供しています。
## 値を取得する <span id="getting-values"></span>
配列、オブジェクト、またはその両方から成る複雑な構造から標準的な PHP を使って値を取得することは、非常に面倒くさい仕事です。
最初に `isset` でキーの存在をチェックしなければならず、次に、キーが存在していれば値を取得し、存在していなければ、デフォルト値を提供しなければなりません。
最初に `isset` でキーの存在をチェックしなければならず、次に、キーが存在していれば値を取得し、存在していなければ、
デフォルト値を提供しなければなりません。
```php
class User
@ -45,13 +47,13 @@ $fullName = ArrayHelper::getValue($user, function ($user, $defaultValue) {
});
```
三番目のオプションの引数はデフォルト値であり、指定されない場合は `null` となります。
以下のようにして使用します。
三番目のオプションの引数はデフォルト値であり、指定されない場合は `null` となります。以下のようにして使用します。
```php
$username = ArrayHelper::getValue($comment, 'user.username', 'Unknown');
```
## 値を設定する <span id="setting-values"></span>
```php
@ -115,8 +117,8 @@ $type = ArrayHelper::remove($array, 'type');
## キーの存在をチェックする <span id="checking-existence-of-keys"></span>
`ArrayHelper::keyExists` は、大文字と小文字を区別しないキーの比較をサポートすることを除いて、[array_key_exists](http://php.net/manual/ja/function.array-key-exists.php) と同じ動作をします。
例えば、
`ArrayHelper::keyExists` は、大文字と小文字を区別しないキーの比較をサポートすることを除いて、
[array_key_exists](http://php.net/manual/ja/function.array-key-exists.php) と同じ動作をします。例えば、
```php
$data1 = [
@ -134,8 +136,7 @@ if (!ArrayHelper::keyExists('username', $data1, false) || !ArrayHelper::keyExist
## カラムを取得する <span id="retrieving-columns"></span>
データ行またはオブジェクトの配列から、あるカラムの値を取得する必要があることがよくあります。
良くある例は、ID のリストの取得です。
データ行またはオブジェクトの配列から、あるカラムの値を取得する必要があることがよくあります。良くある例は、ID のリストの取得です。
```php
$array = [
@ -147,7 +148,8 @@ $ids = ArrayHelper::getColumn($array, 'id');
結果は `['123', '345']` となります。
追加の変形が要求されたり、値の取得方法が複雑であったりする場合は、無名関数を二番目の引数として指定することが出来ます。
追加の変形が要求されたり、値の取得方法が複雑であったりする場合は、
無名関数を二番目の引数として指定することが出来ます。
```php
$result = ArrayHelper::getColumn($array, function ($element) {
@ -162,10 +164,12 @@ $result = ArrayHelper::getColumn($array, function ($element) {
入力値は、多次元配列であるか、オブジェクトの配列でなければなりません。
`$key` は、サブ配列のキーの名前、オブジェクトのプロパティの名前、または、キーとして使用される値を返す無名関数とすることが出来ます。
`$groups` 属性はキーの配列であり、入力値の配列を一つまたは複数のサブ配列にグループ化するために使用されます。
`$groups` 属性はキーの配列であす。これは、入力値の配列を一つまたは複数のサブ配列にグループ化するために
キーとして使用されます。
特定の要素の `$key` 属性またはその値が `null` であるとき、`$groups` が定義されていない場合は、その要素は破棄されて、結果には入りません。
そうではなく、`$groups` が指定されている場合は、配列の要素はキー無しで結果の配列に追加されます。
そうではなく、`$groups` が指定されている場合は、
配列の要素はキー無しで結果の配列に追加されます。
例えば、
@ -224,7 +228,8 @@ $result = ArrayHelper::index($array, 'data', [function ($element) {
}, 'device']);
```
結果は、最初のレベルが `id` でグループ化され、第2のレベルが `device` でグループ化され、第3のレベルが `data` でインデックスされた連想配列になります。
結果は、最初のレベルが `id` でグループ化され、第2のレベルが `device` でグループ化され、
第3のレベルが `data` でインデックスされた連想配列になります。
```php
[
@ -244,13 +249,11 @@ $result = ArrayHelper::index($array, 'data', [function ($element) {
]
```
## マップを作成する <span id="building-maps"></span>
多次元配列またはオブジェクトの配列からマップ (キー・値 のペア) を作成するためには `map` メソッドを使うことが出来ます。
`$from``$to` のパラメータで、マップを構成するキー名またはプロパティ名を指定します。
オプションで、グループ化のためのフィールド `$group` に従って、マップをグループ化することも出来ます。
例えば、
オプションで、グループ化のためのフィールド `$group` に従って、マップをグループ化することも出来ます。例えば、
```php
$array = [
@ -283,8 +286,7 @@ $result = ArrayHelper::map($array, 'id', 'name', 'class');
## 多次元配列の並べ替え <span id="multidimensional-sorting"></span>
`multisort` メソッドは、オブジェクトの配列または入れ子にされた配列を、一つまたは複数のキーによって並べ替えることを手助けします。
例えば、
`multisort` メソッドは、オブジェクトの配列または入れ子にされた配列を、一つまたは複数のキーによって並べ替えることを手助けします。例えば、
```php
$data = [
@ -318,7 +320,8 @@ ArrayHelper::multisort($data, function($item) {
一つのキーによる並べ替えの場合は、`SORT_ASC` か `SORT_DESC` のいずれかです。
複数の値による並べ替えの場合は、並べ替えの順序の配列を渡して、値ごとに違う順序で並べ替えることが出来ます。
最後の引数は並べ替えのフラグで、PHP の [sort()](http://php.net/manual/ja/function.sort.php) 関数に渡されるのと同じ値を取ることが出来ます。
最後の引数は並べ替えのフラグで、
PHP の [sort()](http://php.net/manual/ja/function.sort.php) 関数に渡されるのと同じ値を取ることが出来ます。
## 配列の型を検出する <span id="detecting-array-types"></span>
@ -345,15 +348,15 @@ $encoded = ArrayHelper::htmlEncode($data);
$decoded = ArrayHelper::htmlDecode($data);
```
デフォルトでは、値だけがエンコードされます。
二番目の引数を `false` として渡すことによって、配列のキーもエンコードすることが出来ます。
デフォルトでは、値だけがエンコードされます。二番目の引数を `false` として渡すことによって、配列のキーもエンコードすることが出来ます。
エンコードにはアプリケーションの文字セットが使用されますが、三番目の引数によってそれを変更することも出来ます。
## 配列をマージする <span id="merging-arrays"></span>
[[yii\helpers\ArrayHelper::merge()|ArrayHelper::merge()]] を使って、二つまたはそれ以上の配列を再帰的に一つの配列にマージすることが出来ます。
各配列に同じ文字列のキー値を持つ要素がある場合は、([array_merge_recursive()](http://php.net/manual/ja/function.array-merge-recursive.php) とは違って)後のものが前のものを上書きします。
各配列に同じ文字列のキー値を持つ要素がある場合は、
([array_merge_recursive()](http://php.net/manual/ja/function.array-merge-recursive.php) とは違って)後のものが前のものを上書きします。
両方の配列が、同じキーを持つ配列型の要素を持っている場合は、再帰的なマージが実行されます。
添字型の要素については、後の配列の要素が前の配列の要素の後に追加されます。
[[yii\helpers\UnsetArrayValue]] オブジェクトを使って前の配列にある値を非設定に指定したり、
@ -419,8 +422,7 @@ $result = ArrayHelper::merge($array1, $array2);
## オブジェクトを配列に変換する <span id="converting-objects-to-arrays"></span>
オブジェクトまたはオブジェクトの配列を配列に変換する必要があることがよくあります。
最もよくあるのは、REST API によってデータ配列を提供するなどの目的で、アクティブ・レコード・モデルを変換する場合です。
そうするために、次のコードを使うことが出来ます。
最もよくあるのは、REST API によってデータ配列を提供するなどの目的で、アクティブ・レコード・モデルを変換する場合です。そうするために、次のコードを使うことが出来ます。
```php
$posts = Post::find()->limit(10)->all();
@ -440,8 +442,7 @@ $data = ArrayHelper::toArray($posts, [
最初の引数が変換したいデータです。この例では、`Post` AR モデルを変換しようとしています。
二番目の引数は、クラスごとの変換マップです。
ここでは、`Post` モデルの変換マップを設定しています。
二番目の引数は、クラスごとの変換マップです。ここでは、`Post` モデルの変換マップを設定しています。
変換マップの配列が、一連のマップを含んでいます。各マップは以下のいずれかの形式を取ります。
- フィールド名 - そのままインクルードされる。
@ -460,7 +461,8 @@ $data = ArrayHelper::toArray($posts, [
]
```
特定のクラスについて、配列に変換するデフォルトの方法を提供するためには、そのクラスの [[yii\base\Arrayable|Arrayable]] インタフェイスを実装することが出来ます。
特定のクラスについて、配列に変換するデフォルトの方法を提供するためには、
そのクラスの [[yii\base\Arrayable|Arrayable]] インタフェイスを実装することが出来ます。
## 配列の中にあるかどうか調べる <span id="testing-arrays"></span>
@ -479,5 +481,4 @@ ArrayHelper::isIn('a', new ArrayObject(['a']));
// true
ArrayHelper::isSubset(new ArrayObject(['a', 'c']), new ArrayObject(['a', 'b', 'c']));
```

52
docs/guide-ja/helper-html.md

@ -24,12 +24,10 @@ Yii はそのような手助けを Html ヘルパの形式で提供します。
<?= Html::tag('p', Html::encode($user->name), ['class' => 'username']) ?>
```
最初の引数はタグの名前です。
二番目の引数は、開始タグと終了タグの間に囲まれることになるコンテントです。
最初の引数はタグの名前です。二番目の引数は、開始タグと終了タグの間に囲まれることになるコンテントです。
`Html::encode` を使っていることに注目してください。
これは、必要な場合には HTML を使うことが出来るように、コンテントが自動的にはエンコードされないからです。
三番目の引数は HTML のオプション、言い換えると、タグの属性です。
この配列で、キーは `class`、`href`、`target` などの属性の名前であり、値は属性の値です。
三番目の引数は HTML のオプション、言い換えると、タグの属性です。この配列で、キーは `class`、`href`、`target` などの属性の名前であり、値は属性の値です。
上記のコードは次の HTML を生成します。
@ -43,13 +41,16 @@ Yii はそのような手助けを Html ヘルパの形式で提供します。
その全ての場合において、いくつか追加の処理がなされることを知っておいてください。
- 値が `null` である場合は、対応する属性はレンダリングされません。
- 値が真偽値である属性は、[真偽値属性 (boolean attributes)](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes) として扱われます。
- 値が真偽値である属性は、[真偽値属性 (boolean attributes)](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes)
として扱われます。
- 属性の値は [[yii\helpers\Html::encode()|Html::encode()]] を使って HTML エンコードされます。
- 属性の値が配列である場合は、次のように処理されます。
* 属性が [[yii\helpers\Html::$dataAttributes]] にリストされているデータ属性である場合、例えば `data``ng` である場合は、値の配列にある要素の一つ一つについて、属性のリストがレンダリングされます。
* 属性が [[yii\helpers\Html::$dataAttributes]] にリストされているデータ属性である場合、例えば `data``ng` である場合は、
値の配列にある要素の一つ一つについて、属性のリストがレンダリングされます。
例えば、`'data' => ['id' => 1, 'name' => 'yii']` は `data-id="1" data-name="yii"` を生成します。
また、`'data' => ['params' => ['id' => 1, 'name' => 'yii'], 'status' => 'ok']` は `data-params='{"id":1,"name":"yii"}' data-status="ok"` を生成します。
また、`'data' => ['params' => ['id' => 1, 'name' => 'yii'], 'status' => 'ok']` は
`data-params='{"id":1,"name":"yii"}' data-status="ok"` を生成します。
後者の例において、下位の配列に対して JSON 形式が使用されていることに注意してください。
* 属性がデータ属性でない場合は、値は JSON エンコードされます。
例えば、`['params' => ['id' => 1, 'name' => 'yii']` は `params='{"id":1,"name":"yii"}'` を生成します。
@ -136,7 +137,8 @@ Html::addCssStyle($options, 'height: 200px; position: absolute;');
Html::removeCssStyle($options, ['width', 'height']);
```
[[yii\helpers\Html::addCssStyle()|addCssStyle()]] を使うときには、CSS プロパティの名前と値に対応する「キー-値」ペアの配列か、または、`width: 100px; height: 200px;` のような文字列を指定することが出来ます。
[[yii\helpers\Html::addCssStyle()|addCssStyle()]] を使うときには、CSS プロパティの名前と値に対応する「キー-値」ペアの配列か、
または、`width: 100px; height: 200px;` のような文字列を指定することが出来ます。
この二つの形式は、[[yii\helpers\Html::cssStyleFromArray()|cssStyleFromArray()]] と [[yii\helpers\Html::cssStyleToArray()|cssStyleToArray()]] を使って、双方向に変換することが出来ます。
[[yii\helpers\Html::removeCssStyle()|removeCssStyle()]] メソッドは、削除すべきプロパティの配列を受け取ります。
プロパティが一つだけである場合は、文字列で指定することも出来ます。
@ -145,9 +147,11 @@ Html::removeCssStyle($options, ['width', 'height']);
### コンテントをエンコードおよびデコードする <span id="encoding-and-decoding-content"></span>
コンテントが適切かつ安全に HTML として表示されるためには、コンテント内の特殊文字がエンコードされなければなりません。
特殊文字のエンコードとデコードは、PHP では [htmlspecialchars](http://www.php.net/manual/ja/function.htmlspecialchars.php) と [htmlspecialchars_decode](http://www.php.net/manual/ja/function.htmlspecialchars-decode.php) によって行われます。
特殊文字のエンコードとデコードは、PHP では [htmlspecialchars](http://www.php.net/manual/ja/function.htmlspecialchars.php) と
[htmlspecialchars_decode](http://www.php.net/manual/ja/function.htmlspecialchars-decode.php) によって行われます。
これらのメソッドを直接使用する場合の問題は、文字エンコーディングと追加のフラグを毎回指定しなければならないことです。
フラグは毎回同じものであり、文字エンコーディングはセキュリティ問題を防止するためにアプリケーションのそれと一致すべきものですから、Yii は二つのコンパクトかつ使いやすいメソッドを用意しました。
フラグは毎回同じものであり、文字エンコーディングはセキュリティ問題を防止するためにアプリケーションのそれと一致すべきものですから、
Yii は二つのコンパクトかつ使いやすいメソッドを用意しました。
```php
$userName = Html::encode($user->name);
@ -173,10 +177,8 @@ $decodedUserName = Html::decode($userName);
<?= Html::beginForm(['order/update', 'id' => $id], 'post', ['enctype' => 'multipart/form-data']) ?>
```
最初の引数は、フォームが送信されることになる URL です。
これは [[yii\helpers\Url::to()|Url::to()]] によって受け入れられる Yii のルートおよびパラメータの形式で指定することが出来ます。
第二の引数は使われるメソッドです。`post` がデフォルトです。
第三の引数はフォームタグのオプションの配列です。
最初の引数は、フォームが送信されることになる URL です。これは [[yii\helpers\Url::to()|Url::to()]] によって受け入れられる Yii のルートおよびパラメータの形式で指定することが出来ます。
第二の引数は使われるメソッドです。`post` がデフォルトです。第三の引数はフォームタグのオプションの配列です。
上記の場合では、POST リクエストにおけるフォーム・データのエンコーディング方法を `multipart/form-data` に変更しています。
これはファイルをアップロードするために必要とされます。
@ -248,8 +250,7 @@ $decodedUserName = Html::decode($userName);
<?= Html::activeListBox($users, 'id', ArrayHelper::map($userModels, 'id', 'name')) ?>
```
最初の引数はインプットの名前、第二の引数は現在選択されている値です。
そして第三の引数は「キー-値」のペアであり、配列のキーはリストの値、配列の値はリストのラベルです。
最初の引数はインプットの名前、第二の引数は現在選択されている値です。そして第三の引数は「キー-値」のペアであり、配列のキーはリストの値、配列の値はリストのラベルです。
複数の選択肢を選択できるようにしたい場合は、チェックボックス・リストが最適です。
@ -268,8 +269,7 @@ $decodedUserName = Html::decode($userName);
### ラベルとエラー <span id="labels-and-errors"></span>
インプットと同じように、ラベルを生成するメソッドが二つあります。
モデルからデータを取るアクティブなラベルと、データを直接受け入れるアクティブでないラベルです。
インプットと同じように、ラベルを生成するメソッドが二つあります。モデルからデータを取るアクティブなラベルと、データを直接受け入れるアクティブでないラベルです。
```php
<?= Html::label('ユーザ名', 'username', ['class' => 'label username']) ?>
@ -308,9 +308,7 @@ echo Html::getAttributeValue($post, 'title');
echo Html::getAttributeValue($post, '[0]authors[0]');
```
上記において、最初の引数はモデルであり、第二の引数は属性を示す式です。
これは最も単純な形式においては属性名ですが、配列の添字を前 および/または 後に付けた属性名とすることも出来ます。
配列の添字は主として表形式データ入力のために使用されます。
上記において、最初の引数はモデルであり、第二の引数は属性を示す式です。これは最も単純な形式においては属性名ですが、配列の添字を前 および/または 後に付けた属性名とすることも出来ます。配列の添字は主として表形式データ入力のために使用されます。
- `[0]content` は、表形式データ入力で使われます。表形式入力の最初のモデルの "content" 属性を表します。
- `dates[0]` は、"dates" 属性の最初の配列要素を表します。
@ -355,8 +353,7 @@ CSS ファイルの外部スタイルをリンクしたい場合は、次のよ
<![endif]-->
```
最初の引数は URL であり、第二の引数はオプションの配列です。
通常のオプションに加えて、次のものを指定することが出来ます。
最初の引数は URL であり、第二の引数はオプションの配列です。通常のオプションに加えて、次のものを指定することが出来ます。
- `condition` - 指定された条件を使って `<link` を条件付きコメントで囲みます。
条件付きコメントなんて、使う必要が無くなっちゃえば良いのにね ;)
@ -369,8 +366,7 @@ JavaScript ファイルをリンクするためには、次のようにします
<?= Html::jsFile('@web/js/main.js') ?>
```
CSS と同じように、最初の引数はインクルードされるファイルへのリンクを指定するものです。
オプションを第二の引数として渡すことが出来ます。
CSS と同じように、最初の引数はインクルードされるファイルへのリンクを指定するものです。オプションを第二の引数として渡すことが出来ます。
オプションに置いて、`cssFile` のオプションと同じように、`condition` を指定することが出来ます。
@ -382,8 +378,7 @@ CSS と同じように、最初の引数はインクルードされるファイ
<?= Html::a('プロファイル', ['user/view', 'id' => $id], ['class' => 'profile-link']) ?>
```
最初の引数はタイトルです。
これはエンコードされませんので、エンド・ユーザから取得したデータを使う場合は、`Html::encode()` でエンコードする必要があります。
最初の引数はタイトルです。これはエンコードされませんので、エンド・ユーザから取得したデータを使う場合は、`Html::encode()` でエンコードする必要があります。
第二の引数が、`<a` タグの `href` に入ることになるものです
どのような値が受け入れられるかについて、詳細は [Url::to()](helper-url.md) を参照してください。
第三の引数は、タグのプロパティの配列です。
@ -407,8 +402,7 @@ CSS と同じように、最初の引数はインクルードされるファイ
<img src="http://example.com/images/logo.png" alt="私のロゴ" />
```
最初の引数は、[エイリアス](concept-aliases.md) 以外にも、ルートとパラメータ、または URL を受け入れることが出来ます。
[Url::to()](helper-url.md) と同様です。
最初の引数は、[エイリアス](concept-aliases.md) 以外にも、ルートとパラメータ、または URL を受け入れることが出来ます。[Url::to()](helper-url.md) と同様です。
## リスト <span id="lists"></span>

23
docs/guide-ja/helper-overview.md

@ -4,10 +4,10 @@
> Note: このセクションはまだ執筆中です。
Yii は、一般的なコーディングのタスク、例えば、文字列や配列の操作、HTML コードの生成などを手助けする多くのクラスを提供しています。
これらのヘルパ・クラスは `yii\helpers` 名前空間の下に編成されており、すべてスタティックなクラス (すなわち、スタティックなプロパティとメソッドのみを含み、インスタンス化すべきでないクラス) です。
これらのヘルパ・クラスは `yii\helpers` 名前空間の下に編成されており、すべてスタティックなクラス
(すなわち、スタティックなプロパティとメソッドのみを含み、インスタンス化すべきでないクラス) です。
ヘルパ・クラスは、そのスタティックなメソッドの一つを直接に呼び出すことによって使用します。
例えば、
ヘルパ・クラスは、そのスタティックなメソッドの一つを直接に呼び出すことによって使用します。例えば、
```php
use yii\helpers\Html;
@ -43,10 +43,13 @@ echo Html::encode('Test > test');
ヘルパ・クラスをカスタマイズする <span id="customizing-helper-classes"></span>
------------------------------
コア・ヘルパ・クラス (例えば [[yii\helpers\ArrayHelper]]) をカスタマイズするためには、そのヘルパに対応する基底クラス (例えば [[yii\helpers\BaseArrayHelper]]) を拡張するクラスを作成して、名前空間も含めて、対応する具象クラス (例えば [[yii\helpers\ArrayHelper]]) と同じ名前を付けます。
コア・ヘルパ・クラス (例えば [[yii\helpers\ArrayHelper]]) をカスタマイズするためには、
そのヘルパに対応する基底クラス (例えば [[yii\helpers\BaseArrayHelper]]) を拡張するクラスを作成して、名前空間も含めて、
対応する具象クラス (例えば [[yii\helpers\ArrayHelper]]) と同じ名前を付けます。
このクラスが、フレームワークのオリジナルの実装を置き換えるものとしてセットアップされます。
次の例は、[[yii\helpers\ArrayHelper]] クラスの [[yii\helpers\ArrayHelper::merge()|merge()]] メソッドをカスタマイズする方法を示すものです。
次の例は、[[yii\helpers\ArrayHelper]] クラスの [[yii\helpers\ArrayHelper::merge()|merge()]]
メソッドをカスタマイズする方法を示すものです。
```php
<?php
@ -62,14 +65,16 @@ class ArrayHelper extends BaseArrayHelper
}
```
あなたのクラスを `ArrayHelper.php` という名前のファイルに保存します。
このファイルはどこに置いても構いません。例えば、`@app/components` に置くことにしましょう。
あなたのクラスを `ArrayHelper.php` という名前のファイルに保存します。このファイルはどこに置いても構いません。例えば、`@app/components` に置くことにしましょう。
次に、アプリケーションの [エントリ・スクリプト](structure-entry-scripts.md) で、次のコード行を `yii.php` ファイルをインクルードする行の後に追加して、[Yii クラス・オートローダ](concept-autoloading.md) に、フレームワークから本来のヘルパ・クラスをロードする代りに、あなたのカスタム・クラスをロードすべきことを教えます。
次に、アプリケーションの [エントリ・スクリプト](structure-entry-scripts.md) で、
次のコード行を `yii.php` ファイルをインクルードする行の後に追加して、[Yii クラス・オートローダ](concept-autoloading.md) に、
フレームワークから本来のヘルパ・クラスをロードする代りに、あなたのカスタム・クラスをロードすべきことを教えます。
```php
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';
```
ヘルパ・クラスのカスタマイズは、ヘルパの既存の関数の振る舞いを変更したい場合にだけ役立つものであることに注意してください。
アプリケーションの中で使用する関数を追加したい場合は、そのための独立したヘルパを作成する方が良いでしょう。
アプリケーションの中で使用する関数を追加したい場合は、
そのための独立したヘルパを作成する方が良いでしょう。

33
docs/guide-ja/helper-url.md

@ -6,8 +6,7 @@ Url ヘルパは URL を管理するための一連のスタティック・メ
## よく使う URL を取得する <span id="getting-common-urls"></span>
よく使う URL を取得するために使うことが出来るメソッドが二つあります。
すなわち、ホーム URL と、現在のリクエストのベース URL を取得するメソッドです。
よく使う URL を取得するために使うことが出来るメソッドが二つあります。すなわち、ホーム URL と、現在のリクエストのベース URL を取得するメソッドです。
ホーム URL を取得するためには、次のようにします。
```php
@ -17,8 +16,7 @@ $httpsAbsoluteHomeUrl = Url::home('https');
```
パラメータが渡されない場合は、生成される URL は相対 URL になります。
パラメータとして `true` を渡せば、現在のスキーマの絶対 URL を取得することが出来ます。
または、スキーマ (`http`, `https`) を明示的に指定しても構いません。
パラメータとして `true` を渡せば、現在のスキーマの絶対 URL を取得することが出来ます。または、スキーマ (`http`, `https`) を明示的に指定しても構いません。
現在のリクエストのベース URL を取得するためには、次のようにします。
@ -41,8 +39,7 @@ $url = Url::toRoute(['product/view', 'id' => 42]);
```
ルートは、文字列として指定することが出来ます (例えば、`site/index`)。
または、生成される URL に追加のクエリ・パラメータを指定したい場合は、配列を使うことも出来ます。
配列の形式は、以下のようにしなければなりません。
または、生成される URL に追加のクエリ・パラメータを指定したい場合は、配列を使うことも出来ます。配列の形式は、以下のようにしなければなりません。
```php
// /index.php?r=site%2Findex&param1=value1&param2=value2 を生成
@ -56,16 +53,18 @@ $url = Url::toRoute(['product/view', 'id' => 42]);
['site/index', 'param1' => 'value1', '#' => 'name']
```
ルートは、絶対ルートか相対ルートかのどちらかです。
絶対ルートは先頭にスラッシュを持ち (例えば `/site/index`)、相対ルートは持ちません (例えば `site/index` または `index`)。
ルートは、絶対ルートか相対ルートかのどちらかです。絶対ルートは先頭にスラッシュを持ち (例えば `/site/index`)、相対ルートは持ちません (例えば `site/index` または `index`)。
相対ルートは次の規則に従って絶対ルートに変換されます。
- ルートが空文字列である場合は、現在の [[yii\web\Controller::route|ルート]] が使用されます。
- ルートがスラッシュを全く含まない場合は (例えば `index`)、カレント・コントローラのアクション ID であると見なされて、カレント・コントローラの [[\yii\web\Controller::uniqueId|uniqueId]] が前置されます。
- ルートが先頭にスラッシュを含まない場合は (例えば `site/index`)、カレント・モジュールに対する相対ルートと見なされて、カレント・モジュールの [[\yii\base\Module::uniqueId|uniqueId]] が前置されます。
- ルートがスラッシュを全く含まない場合は (例えば `index`)、カレント・コントローラのアクション ID であると見なされて、
カレント・コントローラの [[\yii\web\Controller::uniqueId|uniqueId]] が前置されます。
- ルートが先頭にスラッシュを含まない場合は (例えば `site/index`)、カレント・モジュールに対する相対ルートと見なされて、
カレント・モジュールの [[\yii\base\Module::uniqueId|uniqueId]] が前置されます。
バージョン 2.0.2 以降では、[エイリアス](concept-aliases.md) の形式でルートを指定することが出来ます。
その場合は、エイリアスが最初に実際のルートに変換され、そのルートが上記の規則に従って絶対ルートに変換されます。
その場合は、エイリアスが最初に実際のルートに変換され、
そのルートが上記の規則に従って絶対ルートに変換されます。
以下に、このメソッドの使用例をいくつか挙げます。
@ -87,18 +86,20 @@ echo Url::toRoute('site/index', 'https');
```
もうひとつ、[[toRoute()]] と非常によく似た `Url::to()` というメソッドがあります。
唯一の違いは、このメソッドはルートを配列として指定することを要求する、という点です。
文字列が与えられた場合は、URL として扱われます。
唯一の違いは、このメソッドはルートを配列として指定することを要求する、という点です。文字列が与えられた場合は、URL として扱われます。
最初の引数は、次のいずれかを取り得ます。
- 配列: URL を生成するために [[toRoute()]] が呼び出されます。例えば、`['site/index']`、`['post/index', 'page' => 2]`。
- 配列: URL を生成するために [[toRoute()]] が呼び出されます。
例えば、`['site/index']`、`['post/index', 'page' => 2]`。
ルートの指定方法の詳細については [[toRoute()]] を参照してください。
- `@` で始まる文字列: これはエイリアスとして扱われ、エイリアスに対応する文字列が返されます。
- `@` で始まる文字列: これはエイリアスとして扱われ、
エイリアスに対応する文字列が返されます。
- 空文字列: 現在リクエストされている URL が返されます。
- 通常の文字列: その通りのものとして扱われます。
`$scheme` (文字列または `true`) が指定された場合は、ホスト情報 ([[\yii\web\UrlManager::hostInfo]] から取得されます) を伴う絶対 URL が返されます。
`$scheme` (文字列または `true`) が指定された場合は、ホスト情報 ([[\yii\web\UrlManager::hostInfo]] から取得されます)
を伴う絶対 URL が返されます。
`$url` が既に絶対 URL であった場合には、スキームが指定されたものに置き換えられます。
下記にいくつかの用例を挙げます。

2
docs/guide-ja/input-forms.md

@ -1,7 +1,7 @@
フォームを作成する
==================
アクティブ・レコードに基づくフォーム : ActiveForm
アクティブ・レコードに基づくフォーム : ActiveForm <span id="activerecord-based-forms-activeform"></span>
-----------------------------------------------
Yii においてフォームを使用するときは、主として [[yii\widgets\ActiveForm]] による方法を使います。
フォームがモデルに基づくものである場合はこの方法を選ぶべきです。

35
docs/guide-ja/rest-authentication.md

@ -5,15 +5,21 @@
これは、セッションやクッキーは使用すべきでないことを意味します。
従って、ユーザの認証ステータスをセッションやクッキーで保持することが出来ないため、全てのリクエストに何らかの認証情報を付加する必要があります。
通常使われるのは、ユーザを認証するための秘密のアクセス・トークンを全てのリクエストとともに送信する方法です。
アクセス・トークンはユーザを一意に特定して認証することが出来るものですので、**API リクエストは、中間者攻撃 (man-in-the-middle attack) を防止するために、常に HTTPS 経由で送信されなければなりません**。
アクセス・トークンはユーザを一意に特定して認証することが出来るものですので、
**API リクエストは、中間者攻撃 (man-in-the-middle attack) を防止するために、常に HTTPS 経由で送信されなければなりません**。
アクセス・トークンを送信するには、いくつかの異なる方法があります。
* [HTTP Basic 認証](http://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC): アクセス・トークンはユーザ名として送信されます。
この方法は、アクセス・トークンを API コンシューマ側で安全に保存することが出来る場合、例えば API コンシューマがサーバ上で走るプログラムである場合などにのみ使用されるべきです。
* クエリ・パラメータ: アクセス・トークンは API の URL、例えば、`https://example.com/users?access-token=xxxxxxxx` でクエリ・パラメータとして送信されます。
ほとんどのウェブ・サーバはクエリ・パラメータをサーバのログに記録するため、この手法は、アクセス・トークンを HTTP ヘッダを使って送信することができない `JSONP` リクエストに応答するために主として使用されるべきです。
* [OAuth 2](http://oauth.net/2/): OAuth2 プロトコルに従って、アクセス・トークンはコンシューマによって権限付与サーバから取得され、[HTTP Bearer Tokens](http://tools.ietf.org/html/rfc6750) 経由で API サーバに送信されます。
この方法は、アクセス・トークンを API コンシューマ側で安全に保存することが出来る場合、
例えば API コンシューマがサーバ上で走るプログラムである場合などにのみ使用されるべきです。
* クエリ・パラメータ: アクセス・トークンは API の URL、例えば、`https://example.com/users?access-token=xxxxxxxx`
でクエリ・パラメータとして送信されます。
ほとんどのウェブ・サーバはクエリ・パラメータをサーバのログに記録するため、この手法は、
アクセス・トークンを HTTP ヘッダを使って送信することができない `JSONP` リクエストに応答するために主として使用されるべきです。
* [OAuth 2](http://oauth.net/2/): OAuth2 プロトコルに従って、
アクセス・トークンはコンシューマによって権限付与サーバから取得され、[HTTP Bearer Tokens](http://tools.ietf.org/html/rfc6750) 経由で
API サーバに送信されます。
Yii は上記の全ての認証方法をサポートしています。新しい認証方法を作成することも簡単に出来ます。
@ -22,15 +28,18 @@ Yii は上記の全ての認証方法をサポートしています。新しい
1. `user` [アプリケーション・コンポーネント](structure-application-components.md) を構成します。
- [[yii\web\User::enableSession|enableSession]] プロパティを `false` に設定します。
- [[yii\web\User::loginUrl|loginUrl]] プロパティを `null` に設定し、ログインページにリダイレクトする代りに HTTP 403 エラーを表示します。
2. REST コントローラ・クラスにおいて、`authenticator` ビヘイビアを構成することによって、どの認証方法を使用するかを指定します。
2. REST コントローラ・クラスにおいて、`authenticator` ビヘイビアを構成することによって、
どの認証方法を使用するかを指定します。
3. [[yii\web\User::identityClass|ユーザ・アイデンティティ・クラス]] において [[yii\web\IdentityInterface::findIdentityByAccessToken()]] を実装します。
ステップ 1 は必須ではありませんが、ステート・レスであるべき RESTful API のために推奨されます。
[[yii\web\User::enableSession|enableSession]] が `false` である場合、ユーザの認証ステータスがセッションを使ってリクエストをまたいで存続することはありません。
その代りに、すべてのリクエストに対して認証が実行されます。このことは、ステップ 2 と 3 によって達成されます。
> Tip: RESTful API をアプリケーションの形式で開発する場合は、アプリケーションの構成情報で `user` アプリケーション・コンポーネント(structure-application-components.md) の [[yii\web\User::enableSession|enableSession]] プロパティを構成することが出来ます。
> Tip: RESTful API をアプリケーションの形式で開発する場合は、アプリケーションの構成情報で `user` アプリケーション・コンポーネント(structure-application-components.md)
> [[yii\web\User::enableSession|enableSession]] プロパティを構成することが出来ます。
> RESTful API をモジュールとして開発する場合は、次のように、モジュールの `init()` メソッドに一行を追加することが出来ます。
>
> ```php
> public function init()
> {
@ -97,18 +106,22 @@ class User extends ActiveRecord implements IdentityInterface
}
```
上記のように認証が有効化された後は、全ての API リクエストに対して、リクエストされたコントローラが `beforeAction()` の段階でユーザを認証することを試みます。
上記のように認証が有効化された後は、全ての API リクエストに対して、リクエストされたコントローラ
`beforeAction()` の段階でユーザを認証することを試みます。
認証が成功すると、コントローラはその他のチェック (レート制限、権限付与など) をしてから、アクションを実行します。
認証されたユーザのアイデンティティは `Yii::$app->user->identity` によって取得することが出来ます。
認証が失敗したときは、HTTP ステータス 401 およびその他の適切なヘッダ (HTTP Basic 認証に対する `WWW-Authenticate` ヘッダなど) を持つレスポンスが送り返されます。
認証が失敗したときは、HTTP ステータス 401 およびその他の適切なヘッダ (HTTP Basic 認証に対する `WWW-Authenticate` ヘッダなど)
を持つレスポンスが送り返されます。
## 権限付与 <span id="authorization"></span>
ユーザが認証された後、おそらくは、リクエストされたリソースに対してリクエストされたアクションを実行する許可を彼または彼女が持っているかどうかをチェックしたいでしょう。
ユーザが認証された後、おそらくは、リクエストされたリソースに対してリクエストされたアクションを実行する許可を
彼または彼女が持っているかどうかをチェックしたいでしょう。
*権限付与* と呼ばれるこのプロセスについては、[権限付与](security-authorization.md) のセクションで詳細に説明されています。
あなたのコントローラが [[yii\rest\ActiveController]] から拡張したものである場合は、[[yii\rest\ActiveController::checkAccess()|checkAccess()]] メソッドをオーバーライドして権限付与のチェックを実行することが出来ます。
あなたのコントローラが [[yii\rest\ActiveController]] から拡張したものである場合は、
[[yii\rest\ActiveController::checkAccess()|checkAccess()]] メソッドをオーバーライドして権限付与のチェックを実行することが出来ます。
このメソッドが [[yii\rest\ActiveController]] によって提供されている内蔵のアクションから呼び出されます。

28
docs/guide-ja/rest-controllers.md

@ -1,12 +1,14 @@
コントローラ
============
リソース・クラスを作成して、リソース・データをどのようにフォーマットすべきかを指定したら、次は、RESTful API を通じてエンド・ユーザにリソースを公開するコントローラ・アクションを作成します。
リソース・クラスを作成して、リソース・データをどのようにフォーマットすべきかを指定したら、
次は、RESTful API を通じてエンド・ユーザにリソースを公開するコントローラ・アクションを作成します。
Yii は、RESTful アクションを作成する仕事を簡単にするための二つの基底コントローラ・クラスを提供しています。
すなわち、[[yii\rest\Controller]] と [[yii\rest\ActiveController]] です。
二つのコントローラの違いは、後者は [アクティブ・レコード](db-active-record.md) として表現されるリソースの扱いに特化した一連のアクションをデフォルトで提供する、という点にあります。
従って、あなたが [アクティブ・レコード](db-active-record.md) を使っていて、提供される組み込みのアクションに満足できるのであれば、コントローラ・クラスを [[yii\rest\ActiveController]] から拡張することを検討すると良いでしょう。
従って、あなたが [アクティブ・レコード](db-active-record.md) を使っていて、提供される組み込みのアクションに満足できるのであれば、
コントローラ・クラスを [[yii\rest\ActiveController]] から拡張することを検討すると良いでしょう。
そうすれば、最小限のコードで強力な RESTful API を作成することが出来ます。
[[yii\rest\Controller]] と [[yii\rest\ActiveController]] は、ともに、下記の機能を提供します。
@ -25,12 +27,14 @@ Yii は、RESTful アクションを作成する仕事を簡単にするため
## コントローラ・クラスを作成する <span id="creating-controller"></span>
新しいコントローラ・クラスを作成する場合、コントローラ・クラスの命名規約は、リソースの型の名前を単数形で使う、というものです。
新しいコントローラ・クラスを作成する場合、コントローラ・クラスの命名規約は、
リソースの型の名前を単数形で使う、というものです。
例えば、ユーザの情報を提供するコントローラは `UserController` と名付けることが出来ます。
新しいアクションを作成する仕方はウェブ・アプリケーションの場合とほぼ同じです。
唯一の違いは、`render()` メソッドを呼んでビューを使って結果を表示する代りに、RESTful アクションの場合はデータを直接に返す、という点です。
[[yii\rest\Controller::serializer|シリアライザ]] と [[yii\web\Response|レスポンス・オブジェクト]] が、元のデータからリクエストされた形式への変換を処理します。
[[yii\rest\Controller::serializer|シリアライザ]] と [[yii\web\Response|レスポンス・オブジェクト]] が、
元のデータからリクエストされた形式への変換を処理します。
例えば、
```php
@ -71,14 +75,15 @@ public function behaviors()
}
```
### CORS <span id="cors"></span>
コントローラに [CORS (クロス・オリジン・リソース共有)](structure-filters.md#cors) フィルタを追加するのは、上記の他のフィルタを追加するのより、若干複雑になります。
と言うのは、CORS フィルタは認証メソッドより前に適用されなければならないため、他のフィルタとは少し異なるアプローチが必要だからです。
また、ブラウザが認証クレデンシャルを送信する必要なく、リクエストが出来るかどうかを前もって安全に判断できるように、
[CORS プリフライト・リクエスト](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests) の認証を無効にする必要もあります。
下記のコードは、[[yii\rest\ActiveController]] を拡張した既存のコントローラに [[yii\filters\Cors]] フィルタを追加するのに必要なコードを示しています。
[CORS プリフライト・リクエスト](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests)
の認証を無効にする必要もあります。
下記のコードは、[[yii\rest\ActiveController]] を拡張した既存のコントローラに
[[yii\filters\Cors]] フィルタを追加するのに必要なコードを示しています。
```php
use yii\filters\auth\HttpBasicAuth;
@ -108,7 +113,8 @@ public function behaviors()
## `ActiveController` を拡張する <span id="extending-active-controller"></span>
コントローラを [[yii\rest\ActiveController]] から拡張する場合は、このコントローラを通じて提供しようとしているリソース・クラスの名前を [[yii\rest\ActiveController::modelClass|modelClass]] プロパティにセットしなければなりません。
コントローラを [[yii\rest\ActiveController]] から拡張する場合は、このコントローラを通じて提供しようとしているリソース・クラスの名前を
[[yii\rest\ActiveController::modelClass|modelClass]] プロパティにセットしなければなりません。
リソース・クラスは [[yii\db\ActiveRecord]] から拡張しなければなりません。
@ -124,8 +130,7 @@ public function behaviors()
* [[yii\rest\OptionsAction|options]]: サポートされている HTTP メソッドを返す。
これらのアクションは全て [[yii\rest\ActiveController::actions()|actions()]] メソッドによって宣言されます。
`actions()` メソッドをオーバーライドすることによって、これらのアクションを構成したり、そのいくつかを無効化したりすることが出来ます。
例えば、
`actions()` メソッドをオーバーライドすることによって、これらのアクションを構成したり、そのいくつかを無効化したりすることが出来ます。例えば、
```php
public function actions()
@ -152,7 +157,8 @@ public function prepareDataProvider()
### アクセス・チェックを実行する <span id="performing-access-check"></span>
RESTful API によってリソースを公開するときには、たいてい、現在のユーザがリクエストしているリソースにアクセスしたり操作したりする許可を持っているか否かをチェックする必要があります。
RESTful API によってリソースを公開するときには、たいてい、
現在のユーザがリクエストしているリソースにアクセスしたり操作したりする許可を持っているか否かをチェックする必要があります。
これは、[[yii\rest\ActiveController]] を使う場合は、[[yii\rest\ActiveController::checkAccess()|checkAccess()]] メソッドを次のようにオーバーライドすることによって出来ます。
```php

22
docs/guide-ja/rest-error-handling.md

@ -1,11 +1,13 @@
エラー処理
==========
RESTful API リクエストを処理していて、ユーザのリクエストにエラーがあったり、何か予期しないことがサーバ上で起ったりしたときには、単に例外を投げて、ユーザに何かがうまく行かなかったことを知らせることも出来ます。
しかし、エラーの原因 (例えば、リクエストされたリソースが存在しない、など) を特定することが出来るなら、適切な HTTP ステータス・コード (例えば、404 ステータス・コードを表わす [[yii\web\NotFoundHttpException]]) と一緒に例外を投げることを検討すべきです。
RESTful API リクエストを処理していて、ユーザのリクエストにエラーがあったり、何か予期しないことがサーバ上で起ったりしたときには、
単に例外を投げて、ユーザに何かがうまく行かなかったことを知らせることも出来ます。
しかし、エラーの原因 (例えば、リクエストされたリソースが存在しない、など) を特定することが出来るなら、
適切な HTTP ステータス・コード (例えば、404 ステータス・コードを表わす [[yii\web\NotFoundHttpException]])
と一緒に例外を投げることを検討すべきです。
そうすれば、Yii は対応する HTTP ステータスのコードとテキストをレスポンスとともに送信します。
Yii はまた、レスポンス・ボディにも、シリアライズされた表現形式の例外を含めます。
例えば、
Yii はまた、レスポンス・ボディにも、シリアライズされた表現形式の例外を含めます。例えば、
```
HTTP/1.1 404 Not Found
@ -29,14 +31,14 @@ Content-Type: application/json; charset=UTF-8
`Location` ヘッダが、新しく作成されたリソースを指し示す URL を含んでいます。
* `204`: リクエストは成功裡に処理されましたが、レスポンスはボディ・コンテントを含んでいません (`DELTE` リクエストなどの場合)。
* `304`: リソースは修正されていません。キャッシュしたバージョンを使うことが可能です。
* `400`: 無効なリクエストです。これはユーザのさまざまな行為によって引き起こされます。例えば、リクエストのボディに無効な JSON データを入れたり、無効なアクションパラメータを指定したり、など。
* `400`: 無効なリクエストです。これはユーザのさまざまな行為によって引き起こされます。
例えば、リクエストのボディに無効な JSON データを入れたり、無効なアクションパラメータを指定したり、など。
* `401`: 認証が失敗しました。
* `403`: 認証されたユーザは指定された API エンド・ボイントにアクセスすることを許可されていません。
* `404`: リクエストされたリソースは存在しません。
* `405`: メソッドが許可されていません。どの HTTP メソッドが許可されているか、`Allow` ヘッダをチェックしてください。
* `415`: サポートされていないメディア・タイプです。リクエストされたコンテント・タイプまたはバージョン番号が無効です。
* `422`: データの検証が失敗しました (例えば `POST` リクエストに対するレスポンスで)。
レスポンス・ボディで詳細なエラー・メッセージをチェックしてください。
* `422`: データの検証が失敗しました (例えば `POST` リクエストに対するレスポンスで)。レスポンス・ボディで詳細なエラー・メッセージをチェックしてください。
* `429`: リクエストの数が多すぎます。レート制限のためにリクエストが拒絶されました。
* `500`: 内部的サーバエラー。これは内部的なプログラムエラーによって生じ得ます。
@ -44,7 +46,8 @@ Content-Type: application/json; charset=UTF-8
## エラー・レスポンスをカスタマイズする <span id="customizing-error-response"></span>
場合によっては、デフォルトのエラー・レスポンス形式をカスタマイズしたいことがあるでしょう。
例えば、さまざまな HTTP ステータスを使ってさまざまなエラーを示すという方法によるのではなく、次に示すように、HTTP ステータスとしては常に 200 を使い、実際の HTTP ステータス・コードはレスポンスの JSON 構造の一部として包み込む、という方式です。
例えば、さまざまな HTTP ステータスを使ってさまざまなエラーを示すという方法によるのではなく、次に示すように、
HTTP ステータスとしては常に 200 を使い、実際の HTTP ステータス・コードはレスポンスの JSON 構造の一部として包み込む、という方式です。
```
HTTP/1.1 200 OK
@ -87,4 +90,5 @@ return [
];
```
上記のコードは、`suppress_response_code` が `GET` のパラメータとして渡された場合に、レスポンスを (成功したものも、失敗したものも) 上記で説明したように再フォーマットします。
上記のコードは、`suppress_response_code` が `GET` のパラメータとして渡された場合に、
レスポンスを (成功したものも、失敗したものも) 上記で説明したように再フォーマットします。

19
docs/guide-ja/rest-quick-start.md

@ -39,10 +39,8 @@ class UserController extends ActiveController
```
このコントローラ・クラスは、よく使用される一揃いの RESTful アクションを実装した [[yii\rest\ActiveController]] を拡張するものです。
[[yii\rest\ActiveController::modelClass|modelClass]] を `app\models\User` と指定することによって、データの取得と操作にどのモデルが使用できるかをコントローラに教えてやります。
The controller class extends from [[yii\rest\ActiveController]], which implements a common set of RESTful actions.
By specifying [[yii\rest\ActiveController::modelClass|modelClass]]
as `app\models\User`, the controller knows which model can be used for fetching and manipulating data.
[[yii\rest\ActiveController::modelClass|modelClass]] として `app\models\User` が指定されているため、
コントローラがどのモデルを使用してデータの取得と操作が出来るかがわかります。
## URL 規則を構成する <span id="configuring-url-rules"></span>
@ -60,8 +58,8 @@ as `app\models\User`, the controller knows which model can be used for fetching
]
```
上記の構成情報は、主として、`user` コントローラの URL 規則を追加して、ユーザのデータが綺麗な URL と意味のある HTTP 動詞によってアクセスおよび操作できるようにするものです。
上記の構成情報は、主として、`user` コントローラの URL 規則を追加して、ユーザのデータが綺麗な URL と意味のある
HTTP 動詞によってアクセスおよび操作できるようにするものです。
> Info: Yii はコントローラの名前を自動的に複数形にしてエンド・ボイントとして使用します (下の「試してみる」(#trying-it-out) を参照してください)。
> この振る舞いは [[yii\rest\UrlRule::$pluralize]] プロパティを使って構成することが可能です。
@ -69,7 +67,8 @@ as `app\models\User`, the controller knows which model can be used for fetching
## JSON の入力を可能にする <span id="enabling-json-input"></span>
API が JSON 形式で入力データを受け取ることが出来るように、`request` [アプリケーション・コンポーネント](structure-application-components.md) の [[yii\web\Request::$parsers|parsers]] プロパティを構成して、JSON 入力のために [[yii\web\JsonParser]] を使うようにします。
API が JSON 形式で入力データを受け取ることが出来るように、`request` [アプリケーション・コンポーネント](structure-application-components.md) の
[[yii\web\Request::$parsers|parsers]] プロパティを構成して、JSON 入力のために [[yii\web\JsonParser]] を使うようにします。
```php
'request' => [
@ -201,8 +200,10 @@ Yii の RESTful API フレームワークを使う場合は、API エンド・
そして、コントローラを使って、単一タイプのリソースに対するエンド・ボイントを実装するアクションを編成します。
リソースは [[yii\base\Model]] クラスを拡張するデータ・モデルとして表現されます。
データベース (リレーショナルまたは NoSQL) を扱っている場合は、[[yii\db\ActiveRecord|ActiveRecord]] を使ってリソースを表現することが推奨されます。
データベース (リレーショナルまたは NoSQL) を扱っている場合は、[[yii\db\ActiveRecord|ActiveRecord]]
を使ってリソースを表現することが推奨されます。
[[yii\rest\UrlRule]] を使って API エンド・ボイントへのルーティングを簡単にすることが出来ます。
これは要求されてはいませんが、RESTful API は、保守を容易にするために、ウェブのフロントエンドやバックエンドとは別の独立したアプリケーションとして開発することが推奨されます。
これは要求されてはいませんが、RESTful API は、保守を容易にするために、
ウェブのフロントエンドやバックエンドとは別の独立したアプリケーションとして開発することが推奨されます。

15
docs/guide-ja/rest-rate-limiting.md

@ -14,7 +14,8 @@
* `saveAllowance()`: 許可されているリクエストの残り数と現在の UNIX タイムスタンプの両方を保存します。
ユーザ・テーブルに二つのカラムを追加して、許容されているリクエスト数とタイムスタンプの情報を記録するのが良いでしょう。
それらを定義すれば、`loadAllowance()` と `saveAllowance()` は、認証された現在のユーザに対応する二つのカラムの値を読み書きするものとして実装することが出来ます。
それらを定義すれば、`loadAllowance()` と `saveAllowance()` は、
認証された現在のユーザに対応する二つのカラムの値を読み書きするものとして実装することが出来ます。
パフォーマンスを向上させるために、これらの情報をキャッシュや NoSQL ストレージに保存することを検討しても構いません。
`User` モデルにおける実装は次のようなものになります。
@ -38,10 +39,12 @@ public function saveAllowance($request, $action, $allowance, $timestamp)
}
```
アイデンティティのクラスに必要なインタフェイスを実装すると、Yii は [[yii\rest\Controller]] のアクション・フィルタとして構成された [[yii\filters\RateLimiter]] を使って、自動的にレート制限のチェックを行うようになります。
アイデンティティのクラスに必要なインタフェイスを実装すると、Yii は [[yii\rest\Controller]] のアクション・フィルタとして構成された
[[yii\filters\RateLimiter]] を使って、自動的にレート制限のチェックを行うようになります。
レート制限を超えると、レート・リミッタが [[yii\web\TooManyRequestsHttpException]] を投げます。
レート・リミッタは、REST コントローラ・クラスの中で、次のようにして構成することが出来ます。
レート・リミッタは、REST コントローラ・クラスの中で、
次のようにして構成することが出来ます。
```php
public function behaviors()
@ -52,10 +55,12 @@ public function behaviors()
}
```
レート制限が有効にされると、デフォルトでは、送信される全てのレスポンスに、現在のレート制限の情報を含む次の HTTP ヘッダが付加されます。
レート制限が有効にされると、デフォルトでは、送信される全てのレスポンスに、
現在のレート制限の情報を含む次の HTTP ヘッダが付加されます。
* `X-Rate-Limit-Limit` - 一定期間内に許可されるリクエストの最大数
* `X-Rate-Limit-Remaining` - 現在の期間において残っている許可されているリクエスト数
* `X-Rate-Limit-Reset` - 許可されているリクエストの最大数にリセットされるまで待たなければならない秒数
これらのヘッダは、上記のコード例で示されているように、[[yii\filters\RateLimiter::enableRateLimitHeaders]] を `false` に設定することで無効にすることが出来ます。
これらのヘッダは、上記のコード例で示されているように、[[yii\filters\RateLimiter::enableRateLimitHeaders]] を
`false` に設定することで無効にすることが出来ます。

52
docs/guide-ja/rest-resources.md

@ -4,7 +4,9 @@
RESTful API は、つまるところ、*リソース* にアクセスし、それを操作するものです。
MVC の枠組の中では、リソースは [モデル](structure-models.md) として見ることが出来ます。
リソースをどのように表現すべきかについて制約がある訳ではありませんが、Yii においては、通常は、次のような理由によって、リソースを [[yii\base\Model]] またはその子クラス (例えば [[yii\db\ActiveRecord]]) のオブジェクトとして表現することになります。
リソースをどのように表現すべきかについて制約がある訳ではありませんが、
Yii においては、通常は、次のような理由によって、リソースを [[yii\base\Model]] またはその子クラス (例えば [[yii\db\ActiveRecord]])
のオブジェクトとして表現することになります。
* [[yii\base\Model]] は [[yii\base\Arrayable]] インタフェイスを実装しています。
これによって、リソースのデータを RESTful API を通じて公開する仕方をカスタマイズすることが出来ます。
@ -13,7 +15,8 @@ MVC の枠組の中では、リソースは [モデル](structure-models.md) と
* [[yii\db\ActiveRecord]] は DB データのアクセスと操作に対する強力なサポートを提供しています。
リソース・データがデータベースに保存されているときは、アクティブ・レコードが最適の選択です。
このセクションでは、主として、[[yii\base\Model]] クラス (またはその子クラス) から拡張したリソース・クラスにおいて、RESTful API を通じて返すことが出来るデータを指定する方法を説明します。
このセクションでは、主として、[[yii\base\Model]] クラス (またはその子クラス) から拡張したリソース・クラスにおいて、
RESTful API を通じて返すことが出来るデータを指定する方法を説明します。
リソース・クラスが [[yii\base\Model]] から拡張したものでない場合は、全てのパブリックなメンバ変数が返されます。
@ -25,41 +28,41 @@ Yii はこのプロセスを二つのステップに分けます。
次に、その配列が [[yii\web\ResponseFormatterInterface|レスポンス・フォーマッタ]] によって、リクエストされた形式 (例えば JSON や XML) の文字列にシリアライズされます。
リソース・クラスを開発するときに主として力を注ぐべきなのは、最初のステップです。
[[yii\base\Model::fields()|fields()]] および/または [[yii\base\Model::extraFields()|extraFields()]] をオーバーライドすることによって、リソースのどういうデータ (*フィールド* と呼ばれます) を配列表現に入れることが出来るかを指定することが出来ます。
この二つのメソッドの違いは、前者が配列表現に含まれるべきフィールドのデフォルトのセットを指定するのに対して、後者はエンド・ユーザが `expand` クエリ・パラメータで要求したときに配列に含めることが出来る追加のフィールドを指定する、という点にあります。
例えば、
[[yii\base\Model::fields()|fields()]] および/または [[yii\base\Model::extraFields()|extraFields()]] をオーバーライドすることによって、
リソースのどういうデータ (*フィールド* と呼ばれます) を配列表現に入れることが出来るかを指定することが出来ます。
この二つのメソッドの違いは、前者が配列表現に含まれるべきフィールドのデフォルトのセットを指定するのに対して、
後者はエンド・ユーザが `expand` クエリ・パラメータで要求したときに配列に含めることが出来る追加のフィールドを指定する、
という点にあります。例えば、
```
// fields() 宣言されている全てのフィールドを返す。
// fields() 宣言されている全てのフィールドを返す。
http://localhost/users
// "id" と "email" のフィールドだけを返す (ただし、fields() で宣言されているなら) 。
// "id" と "email" のフィールドだけを返す (ただし、fields() で宣言されていれば) 。
http://localhost/users?fields=id,email
// fields() の全てのフィールドと "profile" のフィールドを返す (ただし、"profile" が extraFields() で宣言されているなら)。
// fields() の全てのフィールドと "profile" のフィールドを返す (ただし、"profile" が extraFields() で宣言されていれば)。
http://localhost/users?expand=profile
// fields() の全てのフィールドと post の "author" フィールドを返す
// (ただし、"author" が post モデルの extraFields() にあれば)。
http://localhost/comments?expand=post.author
// "id"、"email"、"profile" のフィールドだけを返す
// (ただし、"id" と "email" が fields() で宣言されており、
// "profile" が extraFields() で宣言されているなら)。
// "id" と"email" (ただし、fileds() で宣言されていれば) と
// "profile" (ただし、extraFields() で宣言されていれば) を返す。
http://localhost/users?fields=id,email&expand=profile
```
### fields()` をオーバーライドする <span id="overriding-fields"></span>
デフォルトでは、[[yii\base\Model::fields()]] は、モデルの全ての属性をフィールドとして返し、[[yii\db\ActiveRecord::fields()]] は、DB から投入された属性だけを返します。
デフォルトでは、[[yii\base\Model::fields()]] は、モデルの全ての属性をフィールドとして返し、
[[yii\db\ActiveRecord::fields()]] は、DB から投入された属性だけを返します。
`fields()` をオーバーライドして、フィールドを追加、削除、名前変更、または再定義することが出来ます。
`fields()` の返り値は配列でなければなりません。
配列のキーはフィールド名であり、配列の値は対応するフィールドの定義です。
フィールドの定義は、プロパティ/属性の名前か、あるいは、対応するフィールドの値を返す無名関数とすることが出来ます。
フィールド名がそれを定義する属性名と同一であるという特殊な場合においては、配列のキーを省略することが出来ます。
例えば、
フィールド名がそれを定義する属性名と同一であるという特殊な場合においては、配列のキーを省略することが出来ます。例えば、
```php
// 明示的に全てのフィールドをリストする方法。(API の後方互換性を保つために) DB テーブルやモデル属性の
@ -99,7 +102,8 @@ public function fields()
### `extraFields()` をオーバーライドする<span id="overriding-extra-fields"></span>
デフォルトでは、[[yii\base\Model::extraFields()]] は空の配列を返し、[[yii\db\ActiveRecord::extraFields()]] は DB から取得されたリレーションの名前を返します。
デフォルトでは、[[yii\base\Model::extraFields()]] は空の配列を返し、[[yii\db\ActiveRecord::extraFields()]]
は DB から取得されたリレーションの名前を返します。
`extraFields()` によって返されるデータの形式は `fields()` のそれと同じです。
通常、`extraFields()` は、主として、値がオブジェクトであるフィールドを指定するのに使用されます。
@ -138,12 +142,12 @@ public function extraFields()
[HATEOAS](http://en.wikipedia.org/wiki/HATEOAS) は、Hypermedia as the Engine of Application State (アプリケーション状態のエンジンとしてのハイパーメディア) の略称です。
HATEOAS は、RESTful API は自分が返すリソースについて、どのようなアクションがサポートされているかをクライアントが発見できるような情報を返すべきである、という概念です。
HATEOAS のキーポイントは、リソース・データが API によって提供されるときには、関連する情報を一群のハイパーリンクによって返すべきである、ということです。
HATEOAS のキーポイントは、リソース・データが API によって提供されるときには、
関連する情報を一群のハイパーリンクによって返すべきである、ということです。
あなたのリソース・クラスは、[[yii\web\Linkable]] インタフェイスを実装することによって、HATEOAS をサポートすることが出来ます。
このインタフェイスは、[[yii\web\Link|リンク]] のリストを返すべき [[yii\web\Linkable::getLinks()|getLinks()]] メソッド一つだけを含みます。
典型的には、少なくとも、リソース・オブジェクトそのものへの URL を表現する `self` リンクを返さなければなりません。
例えば、
典型的には、少なくとも、リソース・オブジェクトそのものへの URL を表現する `self` リンクを返さなければなりません。例えば、
```php
use yii\base\Model;
@ -234,7 +238,8 @@ class PostController extends Controller
}
```
データ・プロバイダが RESTful API のレスポンスで送信される場合は、[[yii\rest\Serializer]] が現在のページのリソースを取り出して、リソース・オブジェクトの配列としてシリアライズします。
データ・プロバイダが RESTful API のレスポンスで送信される場合は、[[yii\rest\Serializer]]
が現在のページのリソースを取り出して、リソース・オブジェクトの配列としてシリアライズします。
それだけでなく、[[yii\rest\Serializer]] は次の HTTP ヘッダを使ってページネーション情報もレスポンスに含めます。
* `X-Pagination-Total-Count`: リソースの総数
@ -247,7 +252,10 @@ REST API におけるコレクションはデータ・プロバイダである
その一例を [クイック・スタート](rest-quick-start.md#trying-it-out) のセクションで見ることが出来ます。
バージョン 2.0.13 以降、Yii はコレクションをフィルターする便利な機能を提供しています。
### コレクションをフィルタリングする <span id="filtering-collections"></span>
バージョン 2.0.13 以降、Yii はコレクションをフィルタリングする便利な機能を提供しています。
その一例を [クイック・スタート](rest-quick-start.md#trying-it-out) のガイドに見ることが出来ます。
エンド・ボイントをあなた自身が実装しようとしている場合、フィルタリングは
データ・プロバイダのガイドの [データフィルタを使ってデータ・プロバイダをフィルタリングする](output-data-providers.md#filtering-data-providers-using-data-filters) のセクションで述べられている方法で行うことが出来ます。
データ・プロバイダのガイドの [データ・フィルタを使ってデータ・プロバイダをフィルタリングする](output-data-providers.md#filtering-data-providers-using-data-filters
のセクションで述べられている方法で行うことが出来ます。

19
docs/guide-ja/rest-routing.md

@ -1,11 +1,13 @@
ルーティング
============
リソースとコントローラのクラスが準備できたら、通常のウェブ・アプリケーションと同じように、`http://localhost/index.php?r=user/create` というような URL を使ってリソースにアクセスすることが出来ます。
リソースとコントローラのクラスが準備できたら、通常のウェブ・アプリケーションと同じように、
`http://localhost/index.php?r=user/create` というような URL を使ってリソースにアクセスすることが出来ます。
実際には、綺麗な URL を有効にして HTTP 動詞を利用したいというのが普通でしょう。
例えば、`POST /users` というリクエストが `user/create` アクションへのアクセスを意味するようにする訳です。
これは、アプリケーションの構成情報で `urlManager` [アプリケーション・コンポーネント](structure-application-components.md) を次のように構成することによって容易に達成することが出来ます。
これは、アプリケーションの構成情報で `urlManager` [アプリケーション・コンポーネント](structure-application-components.md)
を次のように構成することによって容易に達成することが出来ます。
```php
'urlManager' => [
@ -18,7 +20,8 @@
]
```
ウェブ・アプリケーションの URL 管理と比べたときに、上記で目に付く新しいことは、RESTful API リクエストのルーティングに [[yii\rest\UrlRule]] を使用していることです。
ウェブ・アプリケーションの URL 管理と比べたときに、上記で目に付く新しいことは、
RESTful API リクエストのルーティングに [[yii\rest\UrlRule]] を使用していることです。
この特殊な URL 規則クラスが、一揃いの子 URL 規則を作成して、指定されたコントローラのルーティングと URL 生成をサポートします。
例えば、上記のコードは、おおむね下記の規則と等価です。
@ -46,8 +49,8 @@
* `OPTIONS /users`: エンド・ボイント `/users` に関してサポートされる動詞を示す。
* `OPTIONS /users/123`: エンド・ボイント `/users/123` に関してサポートされる動詞を示す。
`only` および `except` オプションを構成すると、それぞれ、どのアクションをサポートするか、また、どのアクションを無効にするかを明示的に指定することが出来ます。
例えば、
`only` および `except` オプションを構成すると、それぞれ、どのアクションをサポートするか、
また、どのアクションを無効にするかを明示的に指定することが出来ます。例えば、
```php
[
@ -75,10 +78,10 @@
この振舞いは [[yii\rest\UrlRule::pluralize]] を `false` に設定することで無効にすることが出来ます。
> Info: コントローラ ID の複数形化は [[yii\helpers\Inflector::pluralize()]] によって行われます。
このメソッドは特殊な複数形の規則を考慮します。
例えば、`box` という単語の複数形は `boxs` ではなく `boxes` になります。
このメソッドは特殊な複数形の規則を考慮します。例えば、`box` という単語の複数形は `boxs` ではなく `boxes` になります。
自動的な複数形化があなたの要求を満たさない場合は、[[yii\rest\UrlRule::controller]] プロパティを構成して、エンド・ボイント URL で使用される名前とコントローラ ID の対応を明示的に指定することも可能です。
自動的な複数形化があなたの要求を満たさない場合は、[[yii\rest\UrlRule::controller]] プロパティを構成して、
エンド・ボイント URL で使用される名前とコントローラ ID の対応を明示的に指定することも可能です。
例えば、次のコードはエンド・ボイント名 `u` をコントローラ ID `user` に割り当てます。
```php

33
docs/guide-ja/rest-versioning.md

@ -1,14 +1,12 @@
バージョン管理
==============
良い API は*バージョン管理* されています。
すなわち、一つのバージョンを絶え間なく変更するのではなく、変更と新機能は API の新しいバージョンにおいて実装されます。
クライアント・サイドとサーバ・サイドの両方のコードを完全に制御できるウェブ・アプリケーションとは違って、API はあなたの制御が及ばないクライアントによって使用されることを想定したものです。
このため、API の後方互換性 (BC) は、可能な限り保たれなければなりません。
BC を損なうかも知れない変更が必要な場合は、それを API の新しいバージョンにおいて導入し、バージョン番号を上げるべきです。
そうすれば、既存のクライアントは、API の古いけれども動作するバージョンを使い続けることが出来ますし、新しいまたはアップグレードされたクライアントは、新しい API バージョンで新しい機能を使うことが出来ます。
良い API は*バージョン管理* されています。すなわち、一つのバージョンを絶え間なく変更するのではなく、変更と新機能は API の新しいバージョンにおいて実装されます。
クライアント・サイドとサーバ・サイドの両方のコードを完全に制御できるウェブ・アプリケーションとは違って、API はあなたの制御が及ばないクライアントによって使用されることを想定したものです。このため、API の後方互換性 (BC) は、可能な限り保たれなければなりません。
BC を損なうかも知れない変更が必要な場合は、それを API の新しいバージョンにおいて導入し、バージョン番号を上げるべきです。そうすれば、既存のクライアントは、API の古いけれども動作するバージョンを使い続けることが出来ますし、新しいまたはアップグレードされたクライアントは、新しい API バージョンで新しい機能を使うことが出来ます。
> Tip: API のバージョン番号の設計に関する詳細情報は [Semantic Versioning](http://semver.org/) を参照してください。
> Tip: API のバージョン番号の設計に関する詳細情報は
[Semantic Versioning](http://semver.org/) を参照してください。
API のバージョン管理を実装する方法としてよく使われるのは、バージョン番号を API の URL に埋め込む方法です。
例えば、`http://example.com/v1/users` が API バージョン 1 の `/users` エンド・ボイントを指す、というものです。
@ -28,10 +26,12 @@ Accept: application/vnd.company.myapp-v1+json
* API 実装の各メジャー・バージョンを独立したモジュールに置き、モジュールの ID はメジャー・バージョン番号 (例えば `v1``v2`) とします。
当然ながら、API の URL はメジャー・バージョン番号を含むことになります。
* 各メジャー・バージョンの中では (従って対応するモジュールの中では) `Accept` HTTP リクエスト・ヘッダを使ってマイナー・バージョン番号を決定し、マイナー・バージョンに応じたレスポンスのための条件分岐コードを書きます。
* 各メジャー・バージョンの中では (従って対応するモジュールの中では) `Accept` HTTP リクエスト・ヘッダを使ってマイナー・バージョン番号を決定し、
マイナー・バージョンに応じたレスポンスのための条件分岐コードを書きます。
メジャー・バージョンを提供する各モジュールは、それぞれ、指定されたバージョンのためのリソースとコントローラのクラスを含んでいなければなりません。
コードの責任範囲をより良く分離するために、共通の基底のリソースとコントローラのクラスを保持して、それをバージョンごとの個別のモジュールでサブ・クラス化することが出来ます。
コードの責任範囲をより良く分離するために、共通の基底のリソースとコントローラのクラスを保持して、
それをバージョンごとの個別のモジュールでサブ・クラス化することが出来ます。
サブ・クラスの中で、`Model::fields()` のような具体的なコードを実装します。
あなたのコードを次のように編成することが出来ます。
@ -90,17 +90,22 @@ return [
];
```
上記のコードの結果として、`http://example.com/v1/users` はバージョン 1 のユーザ一覧を返し、`http://example.com/v2/users` はバージョン 2 のユーザ一覧を返すことになります。
上記のコードの結果として、`http://example.com/v1/users` はバージョン 1 のユーザ一覧を返し、
`http://example.com/v2/users` はバージョン 2 のユーザ一覧を返すことになります。
モジュール化のおかげで、異なるメジャー・バージョンのためのコードを綺麗に分離することが出来ます。
しかし、モジュール化しても、共通の基底クラスやその他の共有リソースを通じて、モジュール間でコードを再利用することは引き続いて可能です。
マイナー・バージョン番号を扱うためには、[[yii\filters\ContentNegotiator|contentNegotiator]] ビヘイビアによって提供されるコンテント・ネゴシエーションの機能を利用することが出来ます。
`contentNegotiator` ビヘイビアは、どのコンテント・タイプをサポートするかを決定するときに、[[yii\web\Response::acceptParams]] プロパティをセットします。
マイナー・バージョン番号を扱うためには、[[yii\filters\ContentNegotiator|contentNegotiator]]
ビヘイビアによって提供されるコンテント・ネゴシエーションの機能を利用することが出来ます。
`contentNegotiator` ビヘイビアは、どのコンテント・タイプをサポートするかを決定するときに、
[[yii\web\Response::acceptParams]] プロパティをセットします。
例えば、リクエストが HTTP ヘッダ `Accept: application/json; version=v1` を伴って送信された場合、コンテント・ネゴシエーションの後では、[[yii\web\Response::acceptParams]] に `['version' => 'v1']` という値が含まれています。
例えば、リクエストが HTTP ヘッダ `Accept: application/json; version=v1` を伴って送信された場合、
コンテント・ネゴシエーションの後では、[[yii\web\Response::acceptParams]] に `['version' => 'v1']` という値が含まれています。
`acceptParams` のバージョン情報に基づいて、アクション、リソース・クラス、シリアライザなどの個所で条件付きのコードを書いて、適切な機能を提供することが出来ます。
`acceptParams` のバージョン情報に基づいて、アクション、リソース・クラス、シリアライザなどの個所で条件付きのコードを書いて、
適切な機能を提供することが出来ます。
マイナー・バージョンは、定義上、後方互換性を保つことを要求するものですので、コードの中でバージョンチェックをする個所はそれほど多くないものと期待されます。
そうでない場合は、たいていは、新しいメジャー・バージョンを作成する必要がある、ということです。

3
docs/guide-ja/test-acceptance.md

@ -1,8 +1,7 @@
受入テスト
==========
受入テストはユーザの視点からシナリオを検証するものです。
テストされるアプリケーションは PhpBrowser または実際のブラウザによってアクセスされます。
受入テストはユーザの視点からシナリオを検証するものです。テストされるアプリケーションは PhpBrowser または実際のブラウザによってアクセスされます。
どちらの場合でも、ブラウザは HTTP によって通信しますので、アプリケーションはウェブ・サーバによってホストされる必要があります。
受入テストは Codeception フレームワークの助けを借りて実装されています。Codeception フレームワークには優れたドキュメントがありますので、参照して下さい。

10
docs/guide-ja/test-environment-setup.md

@ -1,16 +1,20 @@
テスト環境の構築
================
Yii 2 は [`Codeception`](https://github.com/Codeception/Codeception) テスト・フレームワークとの統合を公式にサポートしており、次のタイプのテストを作成することを可能にしています。
Yii 2 は [`Codeception`](https://github.com/Codeception/Codeception) テスト・フレームワークとの統合を公式にサポートしており、
次のタイプのテストを作成することを可能にしています。
- [単体テスト](test-unit.md) - 一かたまりのコードが期待通りに動くことを検証する。
- [機能テスト](test-functional.md) - ブラウザのエミュレーションによって、ユーザの視点からシナリオを検証する。
- [受入テスト](test-acceptance.md) - ブラウザの中で、ユーザの視点からシナリオを検証する。
これら三つのタイプのテスト全てについて、Yii は、[`yii2-basic`](https://github.com/yiisoft/yii2-app-basic) と [`yii2-advanced`](https://github.com/yiisoft/yii2-app-advanced) の両方のプロジェクト・テンプレートで、そのまま使えるテストセットを提供しています。
これら三つのタイプのテスト全てについて、Yii は、[`yii2-basic`](https://github.com/yiisoft/yii2-app-basic) と
[`yii2-advanced`](https://github.com/yiisoft/yii2-app-advanced) の両方のプロジェクト・テンプレートで、
そのまま使えるテストセットを提供しています。
ベーシック・テンプレート、アドバンスト・テンプレートの両方とも、Codeception がプリ・インストールされて付いて来ます。
これらのテンプレートの一つを使っていない場合は、下記のコンソールコマンドを発行することで Codeception をインストールすることが出来ます。
これらのテンプレートの一つを使っていない場合は、下記のコンソールコマンドを発行することで
Codeception をインストールすることが出来ます。
```
composer require codeception/codeception

56
docs/guide-ja/test-fixtures.md

@ -101,7 +101,8 @@ class UserProfileFixture extends ActiveFixture
また、同じ理由によって、`UserFixture` は常に `UserProfileFixture` がアンロードされた後でアンロードされます。
上記では、DB テーブルに関してフィクスチャを定義する方法を示しました。
DB と関係しないフィクスチャ (例えば、何らかのファイルやディレクトリに関するフィクスチャ) を定義するためには、より汎用的な基底クラス [[yii\test\Fixture]] から拡張して、[[yii\test\Fixture::load()|load()]] と [[yii\test\Fixture::unload()|unload()]] のメソッドをオーバーライドすることが出来ます。
DB と関係しないフィクスチャ (例えば、何らかのファイルやディレクトリに関するフィクスチャ) を定義するためには、より汎用的な基底クラス [[yii\test\Fixture]] から拡張して、
[[yii\test\Fixture::load()|load()]] と [[yii\test\Fixture::unload()|unload()]] のメソッドをオーバーライドすることが出来ます。
## フィクスチャを使用する
@ -109,13 +110,13 @@ DB と関係しないフィクスチャ (例えば、何らかのファイルや
[Codeception](http://codeception.com/) を使ってコードをテストしている場合は、フィクスチャのローディングとアクセスについては、
内蔵されているサポートを使用することが出来ます。
その他のテスト・フレームワークを使っている場合は、テスト・ケースで [[yii\test\FixtureTrait]] を使って同じ目的を達することが出来ます。
その他のテスト・フレームワークを使っている場合は、テスト・ケースで [[yii\test\FixtureTrait]]
を使って同じ目的を達することが出来ます。
次に、Codeception を使って `UserProfile` 単体テストクラスを書く方法を説明します。
`\Codeception\Test\Unit` を拡張するあなたの単体テスト・クラスにおいて、 `_fixtures()` メソッドの中で使いたいフィクスチャを宣言するか、
または、アクターの `haveFixtures()` メソッドを直接に使用します。
例えば、
または、アクターの `haveFixtures()` メソッドを直接に使用します。例えば、
```php
namespace app\tests\unit\models;
@ -149,17 +150,17 @@ class UserProfileTest extends \Codeception\Test\Unit
クラス名あるいはフィクスチャを指す構成情報配列を使うことが出来ます。
構成情報配列を使うと、フィクスチャがロードされるときのフィクスチャのプロパティをカスタマイズすることが出来ます。
また、フィクスチャにエイリアスを割り当てることも出来ます。
上記の例では、`UserProfileFixture` に `profiles` というエイリアスが与えられています。
そうすると、テスト・メソッドの中でエイリアスを使ってフィクスチャ・オブジェクトにアクセスすることが出来るようになります。
例えば、
また、フィクスチャにエイリアスを割り当てることも出来ます。上記の例では、`UserProfileFixture` に `profiles` というエイリアスが与えられています。
そうすると、テスト・メソッドの中でエイリアスを使ってフィクスチャ・オブジェクトにアクセスすることが出来るようになります。例えば、
```php
$profile = $I->grabFixture('profiles', 'user1');
```
`UserProfileFixture` オブジェクトを返します。
さらには、`UserProfileFixture` は `ActiveFixture` を拡張するものですので、フィクスチャによって提供されたデータに対して、次の構文を使ってアクセスすることも出来ます。
さらには、`UserProfileFixture` は `ActiveFixture` を拡張するものですので、フィクスチャによって提供されたデータに対して、
次の構文を使ってアクセスすることも出来ます。
```php
// 'user1' というエイリアスのデータ行に対応する UserProfileModel を返す
@ -195,7 +196,6 @@ data\
このようにして、テスト間でフィクスチャのデータ・ファイルが衝突するのを回避し、必要に応じてデータ・ファイルを使い分けます。
> Note: 上の例では、フィクスチャ・ファイルには例示目的だけの名前が付けられています。
> 実際の仕事では、フィクスチャ・クラスがどのフィクスチャ・クラスを拡張したものであるかに従って名前を付けるべきです。
> 例えば、DB フィクスチャを [[yii\test\ActiveFixture]] から拡張している場合は、DB テーブルの名前をフィクスチャのデータ・ファイル名として使うべきです。
@ -217,8 +217,7 @@ Yii は `yii fixture` コマンドライン・ツールでフィクスチャを
次のようなフィクスチャ・データをロードするとしましょう。
```
# users.php ファイル
# フィクスチャ・データ・パス (デフォルトでは @tests\unit\fixtures\data) に保存されている
# users.php ファイル - フィクスチャ・データ・パス (デフォルトでは @tests\unit\fixtures\data) に保存
return [
[
@ -237,33 +236,26 @@ return [
],
];
```
データベースにデータをロードするフィクチャを使う場合は、これらの行が `users` テーブルに対して適用されます。
NoSQL フィクスチャ、例えば `mongodb` フィクチャを使う場合は、このデータは `users` コレクションに対して適用されます。
データベースにデータをロードするフィクチャを使う場合は、これらの行が `users` テーブルに対して適用されます。NoSQL フィクスチャ、例えば `mongodb` フィクチャを使う場合は、このデータは `users` コレクションに対して適用されます。
さまざまなロード戦略を実装する方法などについて公式 [ドキュメント](https://github.com/yiisoft/yii2/blob/master/docs/guide/test-fixtures.md)を参照して下さい。
上記のフィクスチャのサンプルは `yii2-faker` エクステンションによって生成されました。これについての詳細は、[自動生成のセクション](#auto-generating-fixtures) を参照して下さい。
フィクスチャ・クラスの名前は複数形であってはいけません。
### フィクスチャをロードする
フィクスチャ・クラスは `Fixture` という接尾辞を持たなければいけません。
デフォルトでは、フィクスチャは `tests\unit\fixtures` 名前空間の下で探されます。
この挙動は構成またはコマンド・オプションによって変更することが出来ます。
`-User` のように名前の前に `-` を指定することで、ロードまたはアンロードから除外するフィクスチャを指定することが出来ます。
フィクスチャ・クラスは `Fixture` という接尾辞を持たなければいけません。デフォルトでは、フィクスチャは `tests\unit\fixtures` 名前空間の下で探されます。
この挙動は構成またはコマンド・オプションによって変更することが出来ます。`-User` のように名前の前に `-` を指定することで、ロードまたはアンロードから除外するフィクスチャを指定することが出来ます。
フィクスチャをロードするためには、次のコマンドを実行します。
> Note: データをロードする前に、アンロードのシーケンスが実行されます。これによって、通常は、前に実行されたフィクスチャによって挿入された
既存のデータが全てクリーンアップされることになります。
> Note: データをロードする前に、アンロードのシーケンスが実行されます。これによって、通常は、前に実行されたフィクスチャによって挿入された 既存のデータが全てクリーンアップされることになります。
```
yii fixture/load <fixture_name>
```
要求される `fixture_name` パラメータが、データがロードされるフィクスチャの名前を指定するものです。
いくつかのフィクスチャを一度にロードすることが出来ます。
下記はこのコマンドの正しい形式です。
いくつかのフィクスチャを一度にロードすることが出来ます。下記はこのコマンドの正しい形式です。
```
// `User` フィクスチャをロードする
@ -284,14 +276,11 @@ yii fixture "*"
// 一つを除いて全てのフィクスチャをロードする
yii fixture "*, -DoNotLoadThisOne"
// 異なる名前空間からフィクスチャをロードする
// デフォルトの名前空間は tests\unit\fixtures
// 異なる名前空間からフィクスチャをロードする (デフォルトの名前空間は tests\unit\fixtures)
yii fixture User --namespace='alias\my\custom\namespace'
// 他のフィクスチャをロードする前に、グローバルフィクスチャ
// `some\name\space\CustomFixture` をロードする。
// デフォルトでは、このオプションが `InitDbFixture` について適用され、
// 整合性チェックが無効化/有効化されます。
// 他のフィクスチャをロードする前に、グローバルフィクスチャ `some\name\space\CustomFixture` をロードする。
// デフォルトでは、このオプションが `InitDbFixture` について適用され、整合性チェックが無効化/有効化されます。
// カンマで区切って複数のグローバル・フィクスチャを指定することが出来ます。
yii fixture User --globalFixtures='some\name\space\Custom'
```
@ -301,9 +290,7 @@ yii fixture User --globalFixtures='some\name\space\Custom'
フィクスチャをアンロードするためには、次のコマンドを実行します。
```
// Users フィクスチャをアンロードする。
// デフォルトではフィクスチャのストレージをクリアします。
// 例えば、"users" テーブル、または、mongodb フィクスチャなら "users" コレクションがクリアされます。
// Users フィクスチャをアンロードする。デフォルトではフィクスチャのストレージをクリアします。(例えば、"users" テーブル、または、mongodb フィクスチャなら "users" コレクションがクリアされます。)
yii fixture/unload User
// いくつかのフィクスチャをアンロードする
@ -340,8 +327,7 @@ yii fixture/unload "*, -DoNotUnloadThisOne"
### フィクスチャを自動生成する
Yii は、あなたの代りに、何らかのテンプレートに従ってフィクスチャを自動生成することが出来ます。
さまざまなデータで、また、いろいろな言語と形式で、フィクスチャを生成することが出来ます。
Yii は、あなたの代りに、何らかのテンプレートに従ってフィクスチャを自動生成することが出来ます。さまざまなデータで、また、いろいろな言語と形式で、フィクスチャを生成することが出来ます。
この機能は、[Faker](https://github.com/fzaninotto/Faker) ライブラリと `yii2-faker` エクステンションによって実現されています。
詳細については、エクステンションの [ガイド](https://github.com/yiisoft/yii2-faker/tree/master/docs/guide-ja) を参照して下さい。.

3
docs/guide-ja/test-functional.md

@ -6,7 +6,8 @@
POST や GET のパラメータなどの環境変数を設定しておいてから、アプリケーションのインスタンスをコードから直接に実行します。
機能テストは一般的に受入テストより高速であり、失敗した場合に詳細なスタックトレースを提供してくれます。
経験則から言うと、特別なウェブ・サーバ設定や JavaScript による複雑な UI を持たない場合は、機能テストの方を選ぶべきです。
経験則から言うと、特別なウェブ・サーバ設定や JavaScript による複雑な UI を持たない場合は、
機能テストの方を選ぶべきです。
機能テストは Codeception フレームワークの助けを借りて実装されています。これにつては、優れたドキュメントがあります。

15
docs/guide-ja/test-overview.md

@ -6,21 +6,23 @@
例えば、PHP でクラスを書くとき、私たちはステップごとにデバッグしたり、または単純に `echo` 文や `die` 文を使ったりして、実装が最初の計画通りに動作することを検証します。
ウェブ・アプリケーションの場合は、何らかのテスト・データをフォームに入力して、ページが期待通りにユーザと相互作用をすることを確認します。
テストを実行するプロセスを自動化して、何かを検証する必要があるときは、いつでも、それを代行してくれるコードを呼び出すだけでよいようにすることが出来ます。
テストを実行するプロセスを自動化して、何かを検証する必要があるときは、いつでも、
それを代行してくれるコードを呼び出すだけでよいようにすることが出来ます。
結果が計画したものと合致することを検証するコードが *テスト* と呼ばれ、それを作成して更に実行するプロセスが *テスト自動化* として知られています。
このテストの章の主題は、このテストの自動化です。
## テストとともに開発する
テスト駆動開発 (TDD) とビヘイビア駆動開発 (BDD) のソフトウェア開発手法においては、実際のコードを書く前に、コードの断片または全体の機能の振る舞いを一連のシナリオまたはテストとして記述します。
そして、その後で初めて、テストに合格するように実装を作成して、意図された振る舞いが達成されていることを検証します。
テスト駆動開発 (TDD) とビヘイビア駆動開発 (BDD) のソフトウェア開発手法においては、実際のコードを書く前に、
コードの断片または全体の機能の振る舞いを一連のシナリオまたはテストとして記述します。
そして、その後で初めて、テストに合格するように実装を作成して、
意図された振る舞いが達成されていることを検証します。
一つの機能を開発するプロセスは以下のようになります。
- 実装されるべき機能を記述するテストを作成する。
- 新しいテストを走らせて、失敗することを確認する。
まだ実装がないので、これは予期された結果です。
- 新しいテストを走らせて、失敗することを確認する。まだ実装がないので、これは予期された結果です。
- 新しいテストに合格するための単純なコードを書く。
- 全てのテストを走らせて、全てが合格することを確認する。
- コードを改良して、それでも全てのテストが OK であることを確認する。
@ -31,7 +33,8 @@
> Tip: 多数の小さくて単純なイテレーションを繰り返すために時間を取られていると感じる場合は、テスト・シナリオのカバー範囲を広くして、テストを再度実行するまでの作業量を増やしてみてください。
> デバッグばかりやっている場合は、逆に範囲を狭めてみてください。
全ての実装作業の前にテストを作成する理由は、そうすれば、その後で、達成したい事柄に集中して「どのようにするか」に没頭することが出来るからです。
全ての実装作業の前にテストを作成する理由は、そうすれば、その後で、
達成したい事柄に集中して「どのようにするか」に没頭することが出来るからです。
通常、そのようにすることは、良い抽象化、機能修正時の容易なテスト保守、また、結合度の低いコンポーネントにつながります。
ですから、このような手法の長所を要約すると次のようになります。

9
docs/guide-ja/test-unit.md

@ -5,8 +5,7 @@
すなわち、さまざまな入力パラメータを与えて、クラスのメソッドが期待通りの結果を返すかどうかを検証します。
単体テストは、通常は、テストされるクラスを書く人によって開発されます。
Yii における単体テストは、PHPUnit と Codeception (こちらはオプションです) の上に構築されます。
従って、それらのドキュメントを通読することが推奨されます。
Yii における単体テストは、PHPUnit と Codeception (こちらはオプションです) の上に構築されます。従って、それらのドキュメントを通読することが推奨されます。
- [Codeception for Yii framework](http://codeception.com/for/yii)
- [Codeception Unit Tests](http://codeception.com/docs/05-UnitTests)
@ -17,9 +16,9 @@ Yii における単体テストは、PHPUnit と Codeception (こちらはオプ
アドバンスト・テンプレートでプロジェクトを開始した場合、テストの実行については、
["テスト" のガイド](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide-ja/start-testing.md) を参照して下さい。
ベーシック・テンプレートでプロジェクトを開始した場合は、
check its [README の "testing" のセクション](https://github.com/yiisoft/yii2-app-basic/blob/master/README.md#testing) を参照して下さい。
ベーシック・テンプレートでプロジェクトを開始した場合は、[README の "testing" のセクション](https://github.com/yiisoft/yii2-app-basic/blob/master/README.md#testing) を参照して下さい。
## フレームワークの単体テスト
Yii フレームワーク自体に対する単体テストを走らせたい場合は、"[Yii 2 の開発を始めよう](https://github.com/yiisoft/yii2/blob/master/docs/internals-ja/getting-started.md)" の説明に従ってください。
Yii フレームワーク自体に対する単体テストを走らせたい場合は、"[Yii 2 の開発を始めよう](https://github.com/yiisoft/yii2/blob/master/docs/internals-ja/getting-started.md)"
の説明に従ってください。

58
docs/guide-ja/tutorial-console.md

@ -5,8 +5,7 @@
コンソール・アプリケーションは、主として、ウェブ・サイトのために実行する必要のあるバックグラウンドのタスクやメンテナンスのタスクを作成するために使われるものです。
コンソール・アプリケーションの構造は Yii のウェブ・アプリケーションのそれと非常に良く似ています。
コンソール・アプリケーションは一つまたは複数の [[yii\console\Controller]] クラスから構成されます。
コントローラはコンソール環境ではしばしば「コマンド」と呼ばれます。
コンソール・アプリケーションは一つまたは複数の [[yii\console\Controller]] クラスから構成されます。コントローラはコンソール環境ではしばしば「コマンド」と呼ばれます。
また、各コントローラは、ウェブのコントローラと全く同じように、一つまたは複数のアクションを持つことが出来ます。
プロジェクト・テンプレートは、両方とも、既にコンソール・アプリケーションを持っています。
@ -43,7 +42,9 @@ yii <route> [--option1=value1 --option2=value2 ... argument1 argument2 ...]
上記において、`<route>` はコントローラ・アクションへのルートを示すものです。
オプション (options) はクラスのプロパティに代入され、引数 (arguments) はアクション・メソッドのパラメータとなります。
例えば、[[yii\console\controllers\MigrateController::$migrationTable|MigrateController::$migrationTable]] として `migrations` を指定し、マイグレーションの上限を 5 と指定して [[yii\console\controllers\MigrateController::actionUp()|MigrateController::actionUp()]] を呼び出すためには、次のようにします。
例えば、[[yii\console\controllers\MigrateController::$migrationTable|MigrateController::$migrationTable]] として `migrations` を指定し、
マイグレーションの上限を 5 と指定して [[yii\console\controllers\MigrateController::actionUp()|MigrateController::actionUp()]]
を呼び出すためには、次のようにします。
```
yii migrate/up 5 --migrationTable=migrations
@ -68,6 +69,7 @@ yii migrate/up 5 --migrationTable=migrations
*/
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/vendor/yiisoft/yii2/Yii.php';
@ -79,8 +81,7 @@ $exitCode = $application->run();
exit($exitCode);
```
このスクリプトはアプリケーションの一部として生成されるものです。
あなたの必要を満たすように、自由に編集して構いません。
このスクリプトはアプリケーションの一部として生成されるものです。あなたの必要を満たすように、自由に編集して構いません。
エラー発生時にスタック・トレースを見たくない、または、全体のパフォーマンスを上げたい、という場合は、`YII_DEBUG` 定数を `false` に設定することが出来ます。
ベーシック・プロジェクト・テンプレートでも、アドバンスト・プロジェクト・テンプレートでも、コンソール・アプリケーションのエントリ・スクリプトは、開発者に優しい環境を提供するために、デフォルトでデバッグを有効にしています。
@ -91,17 +92,21 @@ exit($exitCode);
上記のコードで見るように、コンソール・アプリケーションは、`console.php` という名前のそれ自身の構成情報ファイルを使用します。
このファイルの中で、さまざまな [アプリケーション・コンポーネント](structure-application-components.md)、取り分け、コンソール・アプリケーションのためのプロパティを構成しなければなりません。
ウェブ・アプリケーションとコンソール・アプリケーションが構成情報のパラメータと値を数多く共有する場合は、共通の部分を独立したファイルに移動して、そのファイルを両方のアプリケーション (ウェブとコンソール) の構成情報にインクルードすることを検討しても良いでしょう。
ウェブ・アプリケーションとコンソール・アプリケーションが構成情報のパラメータと値を数多く共有する場合は、共通の部分を独立したファイルに移動して、
そのファイルを両方のアプリケーション (ウェブとコンソール) の構成情報にインクルードすることを検討しても良いでしょう。
その例をアドバンスト・プロジェクト・テンプレートの中で見ることが出来ます。
> Tip: 場合によっては、エントリ・スクリプトで指定されているのとは異なるアプリケーション構成情報を使ってコンソール・コマンドを実行したいことがあります。
> 例えば、`yii migrate` コマンドを使ってテストのデータベースをアップグレードするとき、データベースが個々のテストスイートの中で構成されているような場合です。
> Tip: 場合によっては、エントリ・スクリプトで指定されているのとは異なるアプリケーション構成情報を使って
> コンソール・コマンドを実行したいことがあります。
> 例えば、`yii migrate` コマンドを使ってテストのデータベースをアップグレードするとき、
> データベースが個々のテストスイートの中で構成されているような場合です。
> 構成情報を動的に変更するためには、コマンドを実行するときに `appconfig` オプションを使ってカスタムの構成情報ファイルを指定するだけで大丈夫です。
>
> ```
> yii <route> --appconfig=path/to/config.php ...
> ```
コンソール・コマンドの補完 <span id="console-command-completion"></span>
--------------------------
@ -110,8 +115,7 @@ exit($exitCode);
### Bash の補完
bash completion がインストールされていることを確認して下さい。
ほとんどの bash のインストレーションでは、デフォルトで利用可能になっています。
bash completion がインストールされていることを確認して下さい。ほとんどの bash のインストレーションでは、デフォルトで利用可能になっています。
補完スクリプトを `/etc/bash_completion.d/` に置いて下さい。
@ -150,34 +154,35 @@ autoload -Uz compinit && compinit -i
exec $SHELL -l
```
あなた自身のコンソール・コマンドを作成する <span id="create-command"></span>
------------------------------------------
### コンソールのコントローラとアクション
コンソール・コマンドは、[[yii\console\Controller]] を拡張するコントローラ・クラスとして定義することが出来ます。
コントローラ・クラスの中で、コントローラのサブ・コマンドに対応する一つまたは複数のアクションを定義します。
各アクションの中で、その特定のサブ・コマンドのための適切なタスクを実装するコードを書きます。
コントローラ・クラスの中で、コントローラのサブ・コマンドに対応する一つまたは複数のアクションを定義します。各アクションの中で、その特定のサブ・コマンドのための適切なタスクを実装するコードを書きます。
コマンドを実行するときは、コントローラのアクションに対するルートを指定する必要があります。
例えば、ルート `migrate/create` は、[[yii\console\controllers\MigrateController::actionCreate()|MigrateController::actionCreate()]] アクション・メソッドに対応するサブコマンドを呼び出します。
例えば、ルート `migrate/create` は、[[yii\console\controllers\MigrateController::actionCreate()|MigrateController::actionCreate()]]
アクション・メソッドに対応するサブコマンドを呼び出します。
実行時に提供されたルートにアクション ID が含まれない場合は、(ウェブのコントローラの場合と同じように) デフォルトのアクションが実行されます。
### オプション
[[yii\console\Controller::options()]] メソッドをオーバーライドすることによって、コンソール・コマンド (controller/actionID) で利用できるオプションを指定することが出来ます。
このメソッドはコントローラ・クラスのパブリックなプロパティのリストを返さなければなりません。
コマンドを実行するときは、`--OptionName=OptionValue` という構文を使ってオプションの値を指定することが出来ます。これはコントローラ・クラスの `OptionName` プロパティに `OptionValue` を割り当てるものです。
コマンドを実行するときは、`--OptionName=OptionValue` という構文を使ってオプションの値を指定することが出来ます。
これはコントローラ・クラスの `OptionName` プロパティに `OptionValue` を割り当てるものです。
オプションのデフォルト値が配列型である場合、実行時にこのオプションをセットすると、オプションの値は、入力文字列をカンマで分離することによって、配列に変換されます。
オプションのデフォルト値が配列型である場合、実行時にこのオプションをセットすると、
オプションの値は、入力文字列をカンマで分離することによって、配列に変換されます。
### オプションのエイリアス
バージョン 2.0.8 以降、コンソールコマンドは、オプションにエイリアスを追加するための [[yii\console\Controller::optionAliases()]] メソッドを提供しています。
バージョン 2.0.8 以降、コンソールコマンドは、オプションにエイリアスを追加するための
[[yii\console\Controller::optionAliases()]] メソッドを提供しています。
エイリアスを定義するためには、コントローラで [[yii\console\Controller::optionAliases()]] をオーバーライドします。
例えば、
エイリアスを定義するためには、コントローラで [[yii\console\Controller::optionAliases()]] をオーバーライドします。例えば、
```php
namespace app\commands;
@ -213,8 +218,7 @@ class HelloController extends Controller
### 引数
オプションに加えてに、コマンドは引数を取ることも出来ます。
引数は、リクエストされたサブ・コマンドに対応するアクション・メソッドへのパラメータとして渡されます。
オプションに加えてに、コマンドは引数を取ることも出来ます。引数は、リクエストされたサブ・コマンドに対応するアクション・メソッドへのパラメータとして渡されます。
最初の引数は最初のパラメータに対応し、二番目の引数は二番目のパラメータに対応し、以下同様です。
コマンドが呼び出されたときに十分な数の引数が提供されなかったときは、対応するパラメータは、定義されていれば、宣言されているデフォルト値をとります。
デフォルト値が設定されておらず、実行時に値が提供されなかった場合は、コマンドはエラーで終了します。
@ -244,12 +248,12 @@ class ExampleController extends \yii\console\Controller
### 終了コード
終了コードを使うことはコンソール・アプリケーション開発のベスト・プラクティスです。
コマンドは何も問題が無かったことを示すために `0` を返すのが慣例です。
コマンドが 1 以上の値を返したときは、何かエラーを示唆するものとみなされます。
コマンドは何も問題が無かったことを示すために `0` を返すのが慣例です。コマンドが 1 以上の値を返したときは、何かエラーを示唆するものとみなされます。
返される数値がエラーコードであり、それによってエラーに関する詳細を見出すことが出来る場合もあります。
例えば、`1` は一般的な未知のエラーを示すものとし、`2` 以上の全てのコードは特定のエラー、例えば、入力エラー、ファイルが見つからない、等々を示すものとすることが出来ます。
コンソール・コマンドに終了コードを返させるためには、単にコントローラのアクション・メソッドで整数を返すようにします。
コンソール・コマンドに終了コードを返させるためには、
単にコントローラのアクション・メソッドで整数を返すようにします。
```php
public function actionIndex()
@ -284,8 +288,7 @@ public function actionIndex()
Yii のコンソール・コマンドは出力の書式設定をサポートしています。
これは、コマンドを走らせている端末がサポートしていない場合は、自動的に書式設定の無い出力にグレードダウンされます。
書式設定された文字列を出力することは簡単です。
ボールドのテキストを出力するには、次のようにします。
書式設定された文字列を出力することは簡単です。ボールドのテキストを出力するには、次のようにします。
```php
$this->stdout("Hello?\n", Console::BOLD);
@ -300,8 +303,7 @@ echo "Hello, my name is $name.";
### 表形式
バージョン 2.0.13 以降、表形式のデータをコンソールに表示するウィジェットが追加されています。
次のようにして使うことが出来ます。
バージョン 2.0.13 以降、表形式のデータをコンソールに表示するウィジェットが追加されています。次のようにして使うことが出来ます。
```php
echo Table::widget([

189
docs/guide-ja/tutorial-core-validators.md

@ -1,8 +1,7 @@
コア・バリデータ
================
Yii は、一般的に使われる一連のコア・バリデータを提供しています。
コア・バリデータは、主として、`yii\validators` 名前空間の下にあります。
Yii は、一般的に使われる一連のコア・バリデータを提供しています。コア・バリデータは、主として、`yii\validators` 名前空間の下にあります。
長ったらしいバリデータ・クラス名を使う代りに、*エイリアス* を使って使用するコア・バリデータを指定することが出来ます。
例えば、[[yii\validators\RequiredValidator]] クラスを参照するのに `required` というエイリアスを使うことが出来ます。
@ -39,7 +38,8 @@ public function rules()
- `strict`: 入力値の型が `trueValue``falseValue` の型と一致しなければならないかどうか。デフォルト値は `false`
> Note: HTML フォームで送信されたデータ入力値は全て文字列であるため、通常は、[[yii\validators\BooleanValidator::strict|strict]] プロパティは `false` のままにすべきです。
> Note: HTML フォームで送信されたデータ入力値は全て文字列であるため、通常は、
[[yii\validators\BooleanValidator::strict|strict]] プロパティは `false` のままにすべきです。
## [[yii\captcha\CaptchaValidator|captcha]] <span id="captcha"></span>
@ -50,11 +50,14 @@ public function rules()
]
```
このバリデータは、通常、[[yii\captcha\CaptchaAction]] および [[yii\captcha\Captcha]] と一緒に使われ、入力値が [[yii\captcha\Captcha|CAPTCHA]] ウィジェットによって表示された検証コードと同じであることを確認します。
このバリデータは、通常、[[yii\captcha\CaptchaAction]] および [[yii\captcha\Captcha]] と一緒に使われ、
入力値が [[yii\captcha\Captcha|CAPTCHA]] ウィジェットによって表示された検証コードと同じであることを確認します。
- `caseSensitive`: 検証コードの比較で大文字と小文字を区別するかどうか。デフォルト値は `false`
- `captchaAction`: CAPTCHA 画像を表示する [[yii\captcha\CaptchaAction|CAPTCHA アクション]] に対応する [ルート](structure-controllers.md#routes)。デフォルト値は `'site/captcha'`
- `skipOnEmpty`: 入力値が空のときに検証をスキップできるかどうか。デフォルト値は `false` で、入力が必須であることを意味します。
- `captchaAction`: CAPTCHA 画像を表示する [[yii\captcha\CaptchaAction|CAPTCHA アクション]] に対応する
[ルート](structure-controllers.md#routes)。デフォルト値は `'site/captcha'`
- `skipOnEmpty`: 入力値が空のときに検証をスキップできるかどうか。デフォルト値は `false` で、
入力が必須であることを意味します。
## [[yii\validators\CompareValidator|compare]] <span id="compare"></span>
@ -72,10 +75,12 @@ public function rules()
]
```
このバリデータは指定された入力値を他の値と比較し、両者の関係が `operator` プロパティで指定されたものであることを確認します。
このバリデータは指定された入力値を他の値と比較し、両者の関係が
`operator` プロパティで指定されたものであることを確認します。
- `compareAttribute`: その値が比較対象となる属性の名前。
このバリデータが属性を検証するのに使用されるとき、このプロパティのデフォルト値はその属性の名前に接尾辞 `_repeat` を付けた名前になります。
このバリデータが属性を検証するのに使用されるとき、このプロパティのデフォルト値はその属性の名前に接尾辞
`_repeat` を付けた名前になります。
例えば、検証される属性が `password` であれば、このプロパティのデフォルト値は `password_repeat` となります。
- `compareValue`: 入力値が比較される定数値。
このプロパティと `compareAttribute` の両方が指定された場合は、このプロパティが優先されます。
@ -90,14 +95,15 @@ public function rules()
* `<`: 検証される値が比較される値よりも小さいことを検証する。
* `<=`: 検証される値が比較される値よりも小さいか等しいことを検証する。
- `type`: デフォルトの比較タイプは '[[yii\validators\CompareValidator::TYPE_STRING|string]]' (文字列) であり、その場合、値は 1 バイトごとに比較されます。
数値を比較する場合は、必ず [[yii\validators\CompareValidator::$type|$type]] を '[[yii\validators\CompareValidator::TYPE_NUMBER|number]]' に設定して、数値としての比較を有効にして下さい。
数値を比較する場合は、必ず [[yii\validators\CompareValidator::$type|$type]] を '[[yii\validators\CompareValidator::TYPE_NUMBER|number]]' に設定して、
数値としての比較を有効にして下さい。
### 日付の値を比較する
compare バリデータは、文字列や数値を比較するためにしか使えません。
日付のような値を比較する必要がある場合は、二つの選択肢があります。
日付をある固定値と比較するときは、単に [[yii\validators\DateValidator|date]] バリデータを使って、その [[yii\validators\DateValidator::$min|$min]] や [[yii\validators\DateValidator::$max|$max]] のプロパティを指定すれば良いでしょう。
日付をある固定値と比較するときは、単に [[yii\validators\DateValidator|date]] バリデータを使って、
その [[yii\validators\DateValidator::$min|$min]] や [[yii\validators\DateValidator::$max|$max]] のプロパティを指定すれば良いでしょう。
フォームに入力された二つの日付、例えば、`fromDate` と `toDate` のフィールドを比較する必要がある場合は、
次のように、compare バリデータと date バリデータを組み合わせて使うことが出来ます。
@ -111,13 +117,14 @@ compare バリデータは、文字列や数値を比較するためにしか使
そして、有効な日付であった場合は、機械が読める形式に変換されます。
その後に、これらの二つの値が compare バリデータによって比較されます。
現在、date バリデータはクライアント・サイドのバリデーションを提供していませんので、これはサーバ・サイドでのみ動作します。
そのため、compare バリデータについても、[[yii\validators\CompareValidator::$enableClientValidation|$enableClientValidation]] は `false` に設定されています。
そのため、compare バリデータについても、[[yii\validators\CompareValidator::$enableClientValidation|$enableClientValidation]] は
`false` に設定されています。
## [[yii\validators\DateValidator|date]] <span id="date"></span>
[[yii\validators\DateValidator|date]] バリデータには 3 つの異なるショートカットがあります。
[[yii\validators\DateValidator|date]] バリデータには三つの異なる
ショートカットがあります。
```php
[
@ -128,10 +135,12 @@ compare バリデータは、文字列や数値を比較するためにしか使
```
このバリデータは、入力値が正しい書式の date、time、または datetime であるかどうかをチェックします。
オプションとして、入力値を UNIX タイムスタンプ (または、その他、機械による読み取りが可能な形式) に変換して、[[yii\validators\DateValidator::timestampAttribute|timestampAttribute]] によって指定された属性に保存することも出来ます。
オプションとして、入力値を UNIX タイムスタンプ (または、その他、機械による読み取りが可能な形式) に変換して、
[[yii\validators\DateValidator::timestampAttribute|timestampAttribute]] によって指定された属性に保存することも出来ます。
- `format`: 検証される値が従っているべき日付/時刻の書式。
これには [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax) で記述されている日付/時刻のパターンを使うことが出来ます。
これには [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax)
で記述されている日付/時刻のパターンを使うことが出来ます。
あるいは、PHP の `Datetime` クラスによって認識される書式に接頭辞 `php:` を付けた文字列でも構いません。
サポートされている書式については、<http://php.net/manual/ja/datetime.createfromformat.php> を参照してください。
このプロパティが設定されていないときは、`Yii::$app->formatter->dateFormat` の値を取ります。
@ -141,19 +150,25 @@ compare バリデータは、文字列や数値を比較するためにしか使
その場合は、元の値は検証実行後にタイムスタンプで上書きされます。
[DatePicker で日付の入力を扱う](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide-ja/topics-date-picker.md) に使用例がありますので、参照してください。
バージョン 2.0.4 以降では、[[yii\validators\DateValidator::$timestampAttributeFormat|$timestampAttributeFormat]] と [[yii\validators\DateValidator::$timestampAttributeTimeZone|$timestampAttributeTimeZone]] を使って、この属性に対するフォーマットとタイム・ゾーンを指定することが出来ます。
バージョン 2.0.4 以降では、[[yii\validators\DateValidator::$timestampAttributeFormat|$timestampAttributeFormat]] と
[[yii\validators\DateValidator::$timestampAttributeTimeZone|$timestampAttributeTimeZone]] を使って、
この属性に対するフォーマットとタイム・ゾーンを指定することが出来ます。
`timestampAttribute` を使う場合、入力値が UNIX タイムスタンプに変換されること、そして、UNIX タイムスタンプは定義により UTC であることに注意して下さい。
すなわち、[[yii\validators\DateValidator::timeZone|入力のタイム・ゾーン]] から UTC への変換が実行されます。
- バージョン 2.0.4 以降では、タイムスタンプの [[yii\validators\DateValidator::$min|最小値]] または [[yii\validators\DateValidator::$max|最大値]] を指定することも出来ます。
- バージョン 2.0.4 以降では、タイムスタンプの [[yii\validators\DateValidator::$min|最小値]] または
[[yii\validators\DateValidator::$max|最大値]] を指定することも出来ます。
入力が必須でない場合には、date バリデータに加えて、default バリデータ (デフォルト値フィルタ) を追加すれば、空の入力値が `null` として保存されることを保証することが出来ます。
そうしないと、データベースに `0000-00-00` という日付が保存されたり、デート・ピッカーの入力フィールドが `1970-01-01` になったりしてしまいます。
入力が必須でない場合には、date バリデータに加えて、default バリデータ (デフォルト値フィルタ) を追加すれば、
空の入力値が `null` として保存されることを保証することが出来ます。そうしないと、データベースに `0000-00-00` という日付が保存されたり、
デート・ピッカーの入力フィールドが `1970-01-01` になったりしてしまいます。
```php
[
[['from_date', 'to_date'], 'default', 'value' => null],
[['from_date', 'to_date'], 'date'],
]
```
## [[yii\validators\DefaultValueValidator|default]] <span id="default"></span>
@ -177,8 +192,7 @@ compare バリデータは、文字列や数値を比較するためにしか使
その代りに、検証される属性が空のときに、その属性にデフォルト値を割り当てます。
- `value`: デフォルト値、または、デフォルト値を返す PHP コーラブル。
検証される属性が空のときにこのデフォルト値が割り当てられます。
PHP コーラブルのシグニチャは、次のものでなければなりません。
検証される属性が空のときにこのデフォルト値が割り当てられます。PHP コーラブルのシグニチャは、次のものでなければなりません。
```php
function foo($model, $attribute) {
@ -191,6 +205,7 @@ function foo($model, $attribute) {
データベース・スキーマによるデフォルト値は、モデルの [loadDefaultValues()](db-active-record.md#default-attribute-values)
によってロードすることが出来ます。
## [[yii\validators\NumberValidator|double]] <span id="double"></span>
```php
@ -200,13 +215,10 @@ function foo($model, $attribute) {
]
```
このバリデータは、入力値が実数値であるかどうかをチェックします。
[number](#number) バリデータと等価です。
このバリデータは、入力値が実数値であるかどうかをチェックします。[number](#number) バリデータと等価です。
- `max`: 上限値 (その値を含む)。
設定されていない場合は、バリデータが上限値をチェックしないことを意味します。
- `min`: 下限値 (その値を含む)。
設定されていない場合は、バリデータが下限値をチェックしないことを意味します。
- `max`: 上限値 (その値を含む)。設定されていない場合は、バリデータが上限値をチェックしないことを意味します。
- `min`: 下限値 (その値を含む)。設定されていない場合は、バリデータが下限値をチェックしないことを意味します。
## [[yii\validators\EachValidator|each]] <span id="each"></span>
@ -224,13 +236,13 @@ function foo($model, $attribute) {
これは、配列の *全ての* 要素が指定された検証規則による検証に成功するかどうかを調べるものです。
上の例では、`categoryIDs` 属性は配列を値として取らなければならず、配列の各要素は `integer` の検証規則によって検証されることになります。
- `rule`: 検証規則を指定する配列。
配列の最初の要素がバリデータのクラス名かエイリアスを指定します。
- `rule`: 検証規則を指定する配列。配列の最初の要素がバリデータのクラス名かエイリアスを指定します。
配列の残りの「名前・値」のペアが、バリデータ・オブジェクトを構成するのに使われます。
- `allowMessageFromRule`: 埋め込まれた検証規則によって返されるエラー・メッセージを使うかどうか。
デフォルト値は `true` です。これが `false` の場合は、`message` をエラー・メッセージとして使います。
> Note: 属性が配列でない場合は、検証が失敗したと見なされ、`message` がエラー・メッセージとして返されます。
> Note: 属性が配列でない場合は、検証が失敗したと見なされ、
`message` がエラー・メッセージとして返されます。
## [[yii\validators\EmailValidator|email]] <span id="email"></span>
@ -257,33 +269,36 @@ function foo($model, $attribute) {
```php
[
// a1 の値が属性 "a1" で表されるカラムに存在する必要がある
// a1 の入力値が a1 のカラムに存在する必要がある
['a1', 'exist'],
// a1 の値が属性 "a2" で表されるカラムに存在する必要がある
// a1 の入力値が a2 のカラムに存在する必要がある
['a1', 'exist', 'targetAttribute' => 'a2'],
// a1 の値が "a1" のカラム、a2 の値が "a2" のカラムに存在する必要がある
// 両者はともにエラー・メッセージを受け取る
// a1 と a2 の両方が存在する必要がある。両者はともにエラー・メッセージを受け取る
[['a1', 'a2'], 'exist', 'targetAttribute' => ['a1', 'a2']],
// a1 の値が "a1" のカラム、a2 の値が "a2" のカラムに存在する必要がある
// a1 のみがエラー・メッセージを受け取る
// a1 と a2 の両方が存在する必要がある。a1 のみがエラー・メッセージを受け取る
['a1', 'exist', 'targetAttribute' => ['a1', 'a2']],
// a2 の値が "a2" のカラム、a1 の値が "a3" のカラムに存在する必要がある
// a1 がエラー・メッセージを受け取る
// a2 の値が a2 のカラム、a1 の値が a3 のカラムに存在する必要がある。a1 がエラー・メッセージを受け取る
['a1', 'exist', 'targetAttribute' => ['a2', 'a1' => 'a3']],
// a1 の値が "a1" のカラムに存在する必要がある
// a1 が配列である場合は、その全ての要素が "a1" のカラムに存在する必要がある
// a1 が存在する必要がある。a1 が配列である場合は、その全ての要素が存在する必要がある
['a1', 'exist', 'allowArray' => true],
// type_id が ProductType クラスで定義されているテーブルの id カラムに存在する必要がある
['type_id', 'exist', 'targetClass' => ProductType::class, 'targetAttribute' => ['type_id' => 'id']],
// 同上。定義済みの "type" リレーションを使用。
['type_id', 'exist', 'targetRelation' => 'type'],
]
```
このバリデータは、入力値が [アクティブ・レコード](db-active-record.md) の属性によって表されるテーブルのカラムに存在するかどうかをチェックします。
`targetAttribute` を使って [アクティブ・レコード](db-active-record.md) の属性を指定し、`targetClass` によって対応するクラスを指定することが出来ます。
これらを指定しない場合は、検証されるモデルの属性とクラスの値が使用されます。
`targetAttribute` を使って [アクティブ・レコード](db-active-record.md) の属性を指定し、
`targetClass` によって対応するクラスを指定することが出来ます。
これらを指定しない場合は、検証されるモデルの属性とクラスが使用されます。
このバリデータは、一つまたは複数のカラムに対する検証に使用することが出来ます
(複数のカラムに対する検証の場合は、それらの属性の組み合せが存在しなければならないことを意味します)。
@ -293,15 +308,14 @@ function foo($model, $attribute) {
- `targetAttribute`: `targetClass` において、入力値の存在を検証するために使用される属性の名前。
設定されていない場合は、現在検証されている属性の名前が使用されます。
複数のカラムの存在を同時に検証するために配列を使うことが出来ます。
配列の値は存在を検証するのに使用される属性であり、配列のキーはその値が検証される属性です。
配列の値は存在を検証するのに使用される属性であり、配列のキーは入力値が検証される属性です。
キーと値が同じ場合は、値だけを指定することが出来ます。
- `filter`: 入力値の存在をチェックするのに使用される DB クエリに適用される追加のフィルタ。
これには、文字列、または、追加のクエリ条件を表現する配列を使うことが出来ます
(クエリ条件の書式については、[[yii\db\Query::where()]] を参照してください)。
または、`function ($query)` というシグニチャを持つ無名関数でも構いません。
`$query` は関数の中で修正できる [[yii\db\Query|Query]] オブジェクトです。
- `allowArray`: 入力値が配列であることを許容するか否か。
デフォルト値は `false`
- `allowArray`: 入力値が配列であることを許容するか否か。デフォルト値は `false`
このプロパティが `true` で入力値が配列であった場合は、配列の全ての要素がターゲットのカラムに存在しなければなりません。
`targetAttribute` を配列で指定して複数のカラムに対して検証しようとしている場合は、このプロパティを `true` に設定することが出来ないことに注意してください。
@ -326,13 +340,10 @@ function foo($model, $attribute) {
リストは、配列、または、空白かカンマで区切られたファイルの MIME タイプからなる文字列 (例えば、"image/jpeg, image/png") で指定することが出来ます。
特殊文字 `*` によるワイルドカードのマスクを使って、一群の MIME タイプに一致させることも出来ます。
例えば `image/*` は、`image/` で始まる全ての MIME タイプ (`image/jpeg`, `image/png` など) を通します。
MIME タイプ名は大文字と小文字を区別しません。
デフォルト値は `null` であり、すべての MIME タイプが許可されることを意味します。
MIME タイプ名は大文字と小文字を区別しません。デフォルト値は `null` であり、すべての MIME タイプが許可されることを意味します。
MIME タイプの詳細については、[一般的なメディア・タイプ](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types) を参照してください。
- `minSize`: アップロードされるファイルに要求される最小限のバイト数。
デフォルト値は `null` であり、下限値が無いことを意味します。
- `maxSize`: アップロードされるファイルに許可される最大限のバイト数。
デフォルト値は `null` であり、上限値が無いことを意味します。
- `minSize`: アップロードされるファイルに要求される最小限のバイト数。デフォルト値は `null` であり、下限値が無いことを意味します。
- `maxSize`: アップロードされるファイルに許可される最大限のバイト数。デフォルト値は `null` であり、上限値が無いことを意味します。
- `maxFiles`: 指定された属性が保持しうる最大限のファイル数。
デフォルト値は 1 であり、入力値がアップロードされた一つだけのファイルでなければならないことを意味します。
この値が 2 以上である場合は、入力値は最大で `maxFiles` 数のアップロードされたファイルからなる配列でなければなりません。
@ -362,19 +373,18 @@ function foo($model, $attribute) {
このバリデータはデータを検証しません。
代りに、入力値にフィルタを適用して、それを検証される属性に書き戻します。
- `filter`: フィルタを定義する PHP コールバック。
これには、グローバル関数の名前、無名関数などを指定することが出来ます。
関数のシグニチャは ``function ($value) { return $newValue; }` でなければなりません。
このプロパティは必須項目です。
- `skipOnArray`: 入力値が配列である場合にフィルタをスキップするか否か。
デフォルト値は `false`
- `filter`: フィルタを定義する PHP コールバック。これには、グローバル関数の名前、無名関数などを指定することが出来ます。
関数のシグニチャは ``function ($value) { return $newValue; }` でなければなりません。このプロパティは必須項目です。
- `skipOnArray`: 入力値が配列である場合にフィルタをスキップするか否か。デフォルト値は `false`
フィルタが配列の入力を処理できない場合は、このプロパティを `true` に設定しなければなりません。
そうしないと、何らかの PHP エラーが生じ得ます。
> Tip: 入力値をトリムしたい場合は、[trim](#trim) バリデータを直接使うことが出来ます。
> Tip: `filter` のコールバックに期待されるシグニチャを持つ PHP 関数が多数存在します。
> 例えば、([intval](http://php.net/manual/ja/function.intval.php) や [boolval](http://php.net/manual/ja/function.boolval.php) などを使って) 型キャストを適用し、属性が特定の型になるように保証したい場合は、それらの関数をクロージャで包む必要はなく、単にフィルタの関数名を指定するだけで十分です。
> 例えば、([intval](http://php.net/manual/ja/function.intval.php) や [boolval](http://php.net/manual/ja/function.boolval.php)
> などを使って) 型キャストを適用し、属性が特定の型になるように保証したい場合は、
> それらの関数をクロージャで包む必要はなく、単にフィルタの関数名を指定するだけで十分です。
>
> ```php
> ['property', 'filter', 'filter' => 'boolval'],
@ -403,7 +413,6 @@ function foo($model, $attribute) {
- `minHeight`: 画像の高さの最小値。デフォルト値は `null` であり、下限値がないことを意味します。
- `maxHeight`: 画像の高さの最大値。デフォルト値は `null` であり、上限値がないことを意味します。
## [[yii\validators\IpValidator|ip]] <span id="ip"></span>
```php
[
@ -434,17 +443,14 @@ function foo($model, $attribute) {
デフォルト値は `false`
- `normalize`: CIDR を持たないアドレスに、最も短い (IPv4 では 32、IPv6 では 128) CIDR プレフィクスを追加するか否か。
`subnet``false` 以外の場合にのみ動作します。
例えば、
`subnet``false` 以外の場合にのみ動作します。例えば、
* `10.0.1.5``10.0.1.5/32` に正規化され、
* `2008:db0::1``2008:db0::1/128` に正規化されます
デフォルト値は `false`
- `negation`: 検証の対象となるアドレスが先頭に否定文字 `!` を持つことが出来るか否か。
デフォルト値は `false`
- `negation`: 検証の対象となるアドレスが先頭に否定文字 `!` を持つことが出来るか否か。デフォルト値は `false`
- `expandIPv6`: IPv6 アドレスを完全な記法に展開するか否か。
例えば、`2008:db0::1` は `2008:0db0:0000:0000:0000:0000:0000:0001` に展開されます。
デフォルト値は `false`
例えば、`2008:db0::1` は `2008:0db0:0000:0000:0000:0000:0000:0001` に展開されます。デフォルト値は `false`
- `ranges`: 許容または禁止される IPv4 または IPv6 の範囲の配列。
配列が空の場合、またはこのオプションが設定されていない場合は、全ての IP アドレスが許容されます。
@ -463,11 +469,10 @@ function foo($model, $attribute) {
```
この例では、`192.168.10.0/24` のサブネットを除いて、全ての IPv4 および IPv6 アドレスが許容されます。
IPv4 アドレス `192.168.10.128` も、制約の前にリストされているため、同様に許容されます。
- `networks`: `ranges` で使用する事が出来るネットワークのエイリアスの配列。
配列の形式は、
- `networks`: `ranges` で使用する事が出来るネットワークのエイリアスの配列。配列の形式は、
* キー - エイリアス名
* 値 - 文字列の配列。文字列は、範囲、IP アドレス、または、他のエイリアスとすることが出来ます。
また、文字列は (`negation` オプションとは独立に) `!` によって否定することが出来ます。
また、文字列は (`negation` オプションとは独立に) `!` によって否定することが出来ます。
デフォルトで、次のエイリアスが定義されています。
@ -482,7 +487,6 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている
> Info: このバリデータは、バージョン 2.0.7 以降で利用することが出来ます。
## [[yii\validators\RangeValidator|in]] <span id="in"></span>
```php
@ -529,7 +533,8 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている
このバリデータは、入力値が指定された正規表現に一致するかどうかをチェックします。
- `pattern`: 入力値が一致すべき正規表現。このプロパティを設定することは必須です。そうしないと、例外が投げられます。
- `pattern`: 入力値が一致すべき正規表現。このプロパティを設定することは必須です。
そうしないと、例外が投げられます。
- `not`: 検証結果を反転すべきかどうか。
デフォルト値は false で、入力値がパターンに一致したときにだけ検証が成功することを意味します。
このプロパティが true に設定されているときは、入力値がパターンに一致しない場合にだけ検証が成功したと見なされます。
@ -561,14 +566,15 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている
このバリデータは、入力値が提供されており、空ではないことをチェックします。
- `requiredValue`: 入力値として要求される値。
このプロパティが設定されていない場合は、入力値が空ではいけないことを意味します。
- `requiredValue`: 入力値として要求される値。このプロパティが設定されていない場合は、入力値が空ではいけないことを意味します。
- `strict`: 値を検証するときに、データ型をチェックするかどうか。デフォルト値は `false`
`requiredValue` が設定されていない場合、このプロパティが `true` であるときは、バリデータは入力値が厳密な意味で `null` であるかどうかをチェックします。
一方、このプロパティが `false` であるときは、値が空か否かの判断に緩い規則を使います。
`requiredValue` が設定されている場合、このプロパティが `true` であるときは、入力値と `requiredValue` を比較するときに型のチェックを行います。
`requiredValue` が設定されている場合、このプロパティが `true` であるときは、
入力値と `requiredValue` を比較するときに型のチェックを行います。
> Info: 値が空であるか否かを決定する方法については、独立したトピックとして、[空の入力値を扱う](input-validation.md#handling-empty-inputs) のセクションでカバーされています。
> Info: 値が空であるか否かを決定する方法については、独立したトピックとして、
> [空の入力値を扱う](input-validation.md#handling-empty-inputs) のセクションでカバーされています。
## [[yii\validators\SafeValidator|safe]] <span id="safe"></span>
@ -599,10 +605,12 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている
これは、次のいずれかの形式で指定することが出来ます。
* 一つの整数: 文字列がちょうどその長さでなければならない、その長さ。
* 一つの要素を持つ配列: 入力文字列の長さの最小値 (例えば、`[8]`)。これは `min` を上書きします。
* 二つの要素を持つ配列: 入力文字列の長さの最小値と最大値 (例えば、`[8, 128]`)。これは `min``max` の両方を上書きします。
* 二つの要素を持つ配列: 入力文字列の長さの最小値と最大値 (例えば、`[8, 128]`)。
これは `min``max` の両方を上書きします。
- `min`: 入力文字列の長さの最小値。設定されていない時は、長さの下限値がないことを意味します。
- `max`: 入力文字列の長さの最大値。設定されていない時は、長さの上限値がないことを意味します。
- `encoding`: 検証される入力文字列の文字エンコーディング。設定されていない時は、アプリケーションの [[yii\base\Application::charset|charset]] の値が使われ、デフォルトでは `UTF-8` となります。
- `encoding`: 検証される入力文字列の文字エンコーディング。設定されていない時は、
アプリケーションの [[yii\base\Application::charset|charset]] の値が使われ、デフォルトでは `UTF-8` となります。
## [[yii\validators\FilterValidator|trim]] <span id="trim"></span>
@ -614,8 +622,7 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている
]
```
このバリデータはデータの検証を実行しません。
その代りに、入力値の前後にあるホワイト・スペースをトリムします。
このバリデータはデータの検証を実行しません。その代りに、入力値の前後にあるホワイト・スペースをトリムします。
入力値が配列であるときは、このバリデータによって無視されることに注意してください。
@ -623,22 +630,19 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている
```php
[
// a1 の値が属性 "a1" で表されるカラムにおいてユニークである必要がある
// a1 の入力値が a1 のカラムにおいてユニークである必要がある
['a1', 'unique'],
// a1 の値が属性 "a2" で表されるカラムにおいてユニークである必要がある
// a1 の入力値が a2 のカラムにおいてユニークである必要がある
['a1', 'unique', 'targetAttribute' => 'a2'],
// a1 の値が "a1" のカラム、a2 の値が "a2" のカラムにおいてユニークである必要がある
// 両者はともにエラー・メッセージを受け取る
// a1 と a2 の両方がユニークである必要がある。両者がともにエラー・メッセージを受け取る
[['a1', 'a2'], 'unique', 'targetAttribute' => ['a1', 'a2']],
// a1 の値が "a1" のカラム、a2 の値が "a2" のカラムにおいてユニークである必要がある
// a1 のみがエラー・メッセージを受け取る
// a1 と a2 の両方がユニークである必要がある。a1 のみがエラー・メッセージを受け取る
['a1', 'unique', 'targetAttribute' => ['a1', 'a2']],
// a2 の値が "a2" のカラム、a1 の値が "a3" のカラムにおいてユニークである必要がある
// a1 がエラー・メッセージを受け取る
// a2 の値が a2 のカラム、a1 の値が a3 のカラムにおいてユニークである必要がある。a1 がエラー・メッセージを受け取る
['a1', 'unique', 'targetAttribute' => ['a2', 'a1' => 'a3']],
]
```
@ -652,13 +656,12 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている
- `targetAttribute`: `targetClass` において、入力値がユニークであることを検証するために使用される属性の名前。
設定されていない場合は、現在検証されている属性の名前が使用されます。
複数のカラムのユニーク性を同時に検証するために配列を使うことが出来ます。
配列の値はユニーク性を検証するのに使用される属性であり、配列のキーはその値が検証される属性です。
配列の値はユニーク性を検証するのに使用される属性であり、配列のキーはその入力値が検証される属性です。
キーと値が同じ場合は、値だけを指定することが出来ます。
- `filter`: 入力値のユニーク性をチェックするのに使用される DB クエリに適用される追加のフィルタ。
これには、文字列、または、追加のクエリ条件を表現する配列を使うことが出来ます
(クエリ条件の書式については、[[yii\db\Query::where()]] を参照してください)。
または、`function ($query)` というシグニチャを持つ無名関数でも構いません。
`$query` は関数の中で修正できる [[yii\db\Query|Query]] オブジェクトです。
または、`function ($query)` というシグニチャを持つ無名関数でも構いません。`$query` は関数の中で修正できる [[yii\db\Query|Query]] オブジェクトです。
## [[yii\validators\UrlValidator|url]] <span id="url"></span>
@ -677,12 +680,10 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている
デフォルト値は `['http', 'https']` であり、`http` と `https` の URL がともに有効と見なされることを意味します。
- `defaultScheme`: 入力値がスキームの部分を持たないときに前置されるデフォルトの URI スキーム。
デフォルト値は `null` であり、入力値を修正しないことを意味します。
- `enableIDN`: バリデータが IDN (国際化ドメイン名) を考慮すべきか否か。
デフォルト値は `false`
- `enableIDN`: バリデータが IDN (国際化ドメイン名) を考慮すべきか否か。デフォルト値は `false`
IDN の検証を使用するためには、`intl` PHP 拡張をインストールして有効化する必要があることに注意してください。
そうしないと、例外が投げられます。
> Note: このバリデータは URL スキームとホスト部分が正しいものであることを検証します。
URL の残りの部分はチェックしません。また、XSS や他の攻撃に対して防御するように設計されてもいません。
アプリケーション開発における脅威に対する防御について更に学習するために
[セキュリティのベスト・プラクティス](security-best-practices.md) を参照して下さい。
アプリケーション開発における脅威に対する防御について更に学習するために[セキュリティのベスト・プラクティス](security-best-practices.md) を参照して下さい。

7
docs/guide-ja/tutorial-docker.md

@ -1,9 +1,7 @@
Yii と Docker
=============
開発および配備の際に Yii アプリケーションを Docker コンテナとして実行することが出来ます。
コンテナは隔絶された軽量の仮想マシンのようなもので、そのサービスをホストのポートにマップします。
例えば、コンテナ内の 80 番ポートにあるウェブ・サーバが(ローカル)ホストの 8888 番で利用できます。
開発および配備の際に Yii アプリケーションを Docker コンテナとして実行することが出来ます。コンテナは隔絶された軽量の仮想マシンのようなもので、そのサービスをホストのポートにマップします。例えば、コンテナ内の 80 番ポートにあるウェブ・サーバが(ローカル)ホストの 8888 番で利用できます。
コンテナによって、開発用コンピュータと実運用サーバでソフトウェアのバージョンを全く同一にすること、迅速な配備、開発時におけるマルチ・サーバ・アーキテクチャのシミュレーションなど、数多くの問題を解決することが出来ます。
@ -82,7 +80,7 @@ Docker の基本的なコマンド:
*実行中の* `php` サービスの中で bash を実行
## Advanced topics
## 高度なトピック
### Yii フレームワークのテスト
@ -91,6 +89,7 @@ Docker の基本的なコマンド:
### データベース管理ツール
MySQL を (`mysql`) として実行するときは、以下のようにして phpMyAdmin コンテナをスタックに追加することが出来ます。
```
phpmyadmin:
image: phpmyadmin/phpmyadmin

132
docs/guide-ja/tutorial-i18n.md

@ -1,7 +1,8 @@
国際化
======
国際化 (I18N) とは、工学的な変更を伴わずにさまざまな言語と地域に順応できるように、ソフトウェア・アプリケーションを設計するプロセスを指します。
国際化 (I18N) とは、工学的な変更を伴わずにさまざまな言語と地域に順応できるように、
ソフトウェア・アプリケーションを設計するプロセスを指します。
潜在的なユーザが世界中にいるウェブ・アプリケーションにとっては、このことは特に重要な意味を持ちます。
Yii は、全ての領域にわたる国際化機能を提供し、メッセージの翻訳、ビューの翻訳、日付と数字の書式設定をサポートします。
@ -10,14 +11,18 @@ Yii は、全ての領域にわたる国際化機能を提供し、メッセー
### ロケール
ロケールとは、ユーザの言語、国、そして、ユーザが彼らのユーザ・インタフェイスにおいて目にすることを期待するすべての変異形式を定義する一連のパラメータです。
ロケールとは、ユーザの言語、国、そして、ユーザが彼らのユーザ・インタフェイスにおいて目にすることを期待する
すべての変異形式を定義する一連のパラメータです。
ロケールは、通常、言語 ID と地域 ID から成るロケール ID によって定義されます。
例えば、`en-US` という ID は、「英語とアメリカ合衆国」というロケールを意味します。
Yii アプリケーションで使用される全てのロケール ID は、一貫性のために、`ll-CC` の形式に正規化されなければなりません。
ここで `ll` は [ISO-639](http://www.loc.gov/standards/iso639-2/) に従った小文字二つまたは三つの言語コードであり、`CC` は [ISO-3166](http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html) に従った二文字の国コードです。
ロケールに関する更なる詳細は [ICU プロジェクトのドキュメント](http://userguide.icu-project.org/locale#TOC-The-Locale-Concept) に述べられています。
Yii アプリケーションで使用される全てのロケール ID は、一貫性のために、
`ll-CC` の形式に正規化されなければなりません。
ここで `ll` は [ISO-639](http://www.loc.gov/standards/iso639-2/) に従った小文字二つまたは三つの言語コードであり、
`CC` は [ISO-3166](http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html) に従った二文字の国コードです。
ロケールに関する更なる詳細は [ICU プロジェクトのドキュメント](http://userguide.icu-project.org/locale#TOC-The-Locale-Concept)
に述べられています。
### 言語
@ -30,7 +35,6 @@ Yii のアプリケーションでは二つの言語を使用します。すな
いわゆるメッセージ翻訳サービスは、主として、テキスト・メッセージをソース言語からターゲット言語に翻訳するものです。
### 構成
アプリケーションの言語は、アプリケーションの構成情報で次のように構成することが出来ます。
```php
@ -49,7 +53,8 @@ return [
このデフォルト値は変えないことが **推奨** されます。
なぜなら、通常は、英語から他の言語への翻訳者を見つける方が、非英語から非英語への翻訳者を見つけるより、はるかに簡単だからです。
[[yii\base\Application::$language|ターゲット言語]] は、エンド・ユーザの言語選択など、さまざまな要因に基づいて、動的に設定しなければならないことがよくあります。
[[yii\base\Application::$language|ターゲット言語]] は、エンド・ユーザの言語選択など、
さまざまな要因に基づいて、動的に設定しなければならないことがよくあります。
アプリケーションの構成情報で構成するかわりに、次の文を使ってターゲット言語を変更することが出来ます。
```php
@ -60,37 +65,34 @@ return [
> Tip: ソース言語がコードの部分によって異なる場合は、メッセージ・ソースごとにソース言語をオーバーライドすることが出来ます。
> これについては、次の説で説明します。
## メッセージ翻訳 <span id="message-translation"></span>
### ソース言語からターゲット言語へ
メッセージ翻訳サービスは、テキスト・メッセージをある言語 (通常は [[yii\base\Application::$sourceLanguage|ソース言語]]) から別の言語 (通常は [[yii\base\Application::$language|ターゲット言語]]) に翻訳するものです。
メッセージ翻訳サービスは、テキスト・メッセージをある言語 (通常は [[yii\base\Application::$sourceLanguage|ソース言語]])
から別の言語 (通常は [[yii\base\Application::$language|ターゲット言語]]) に翻訳するものです。
翻訳は、元のメッセージと翻訳されたメッセージを格納するメッセージ・ソースの中から、翻訳対象となったメッセージを探すことにより行われます。
メッセージが見つかれば、対応する翻訳されたメッセージが返されます。
メッセージが見つからなければ、元のメッセージが翻訳されずに返されます。
メッセージが見つかれば、対応する翻訳されたメッセージが返されます。メッセージが見つからなければ、元のメッセージが翻訳されずに返されます。
### 実装の仕方
メッセージ翻訳サービスを使用するためには、主として次の作業をする必要があります。
1. 翻訳する必要のある全てのテキスト・メッセージを [[Yii::t()]] メソッドの呼び出しの中に包む。
2. メッセージ翻訳サービスが翻訳されたメッセージを探すことが出来る一つまたは複数のメッセージ・ソースを構成する。
3. 翻訳者にメッセージを翻訳させて、それをメッセージ・ソースに格納する。
#### 1. テキスト・メッセージを包む
#### 1. テキスト・メッセージを包む
[[Yii::t()]] メソッドは次のように使います。
```php
echo \Yii::t('app', 'This is a string to translate!');
```
ここで、二番目のパラメータが翻訳されるべきテキスト・メッセージを示し、最初のパラメータはメッセージを分類するのに使用されるカテゴリ名を示します。
ここで、二番目のパラメータが翻訳されるべきテキスト・メッセージを示し、
最初のパラメータはメッセージを分類するのに使用されるカテゴリ名を示します。
#### 2. 一つまたは複数のメッセージ・ソースを構成する
[[Yii::t()]] メソッドは `i18n` [アプリケーション・コンポーネント](structure-application-components.md) の `translate` メソッドを呼んで実際の翻訳作業を実行します。
このコンポーネントはアプリケーションの構成情報の中で次のようにして構成することが出来ます。
@ -117,7 +119,8 @@ echo \Yii::t('app', 'This is a string to translate!');
##### シンボル `*` によるカテゴリのワイルドカード
`app*` は、`app` で始まる全てのメッセージ・カテゴリがこのメッセージ・ソースを使って翻訳されるべきであることを示しています。
`app*` は、`app` で始まる全てのメッセージ・カテゴリが
このメッセージ・ソースを使って翻訳されるべきであることを示しています。
#### 3. 翻訳者にメッセージを翻訳させて、それをメッセージ・ソースに格納する
@ -128,8 +131,7 @@ echo \Yii::t('app', 'This is a string to translate!');
> このセクションで後で紹介します。
PHP ファイルは、それぞれ、一つのカテゴリのメッセージに対応します。
デフォルトでは、ファイル名はカテゴリ名と同じでなければなりません。
`app/messages/nl-NL/main.ph` の例を示します。
デフォルトでは、ファイル名はカテゴリ名と同じでなければなりません。`app/messages/nl-NL/main.ph` の例を示します。
```php
<?php
@ -143,16 +145,19 @@ return [
```
##### ファイルのマッピング
ただし、[[yii\i18n\PhpMessageSource::fileMap|fileMap]] を構成して、別の命名方法によってカテゴリを PHP ファイルにマップすることも可能です。
上記の例では、(`ja-JP` がターゲット言語であると仮定すると) `app/error` のカテゴリは `@app/messages/ja-JP/error.php` という PHP ファイルにマップされます。
上記の例では、(`ja-JP` がターゲット言語であると仮定すると) `app/error` のカテゴリは
`@app/messages/ja-JP/error.php` という PHP ファイルにマップされます。
`fileMap` を構成しなければ、このカテゴリは `@app/messages/ja-JP/app/error.php` にマップされることになります。
##### 他のストレージ・タイプ
翻訳メッセージを格納するのには、PHP ファイル以外に、次のメッセージ・ソースを使うことも可能です。
翻訳メッセージを格納するのには、PHP ファイル以外に、
次のメッセージ・ソースを使うことも可能です。
- [[yii\i18n\GettextMessageSource]] - 翻訳メッセージを保持するのに GNU Gettext の MO ファイルまたは PO ファイルを使用する
- [[yii\i18n\DbMessageSource]] - 翻訳メッセージを保存するのにデータベース・テーブルを使用する
@ -168,7 +173,8 @@ return [
### メッセージ・パラメータ <span id="message-parameters"></span>
翻訳対象となるメッセージには、一つまたは複数のパラメータ (プレースホルダとも呼びます) を埋め込んで、与えられたパラメータ値で置き換えられるようにすることが出来ます。
翻訳対象となるメッセージには、一つまたは複数のパラメータ (プレースホルダとも呼びます) を埋め込んで、
与えられたパラメータ値で置き換えられるようにすることが出来ます。
様々なパラメータ値のセットを与えることによって、翻訳されるメッセージを動的に変化させることが出来ます。
次の例では、`'Hello, {username}!'` というメッセージの中のプレースホルダ `{username}``'Alexander'``'Qiang'` にそれぞれ置き換えられます。
@ -193,11 +199,11 @@ echo \Yii::t('app', 'Hello, {username}!', [
// 日本語翻訳: '{username} さん、こんにちは!'
```
プレースホルダには、*名前付きプレースホルダ* と *序数プレースホルダ* のどちらかを使用する事が出来ます。
ただし、一つのメッセージに両方を使うことは出来ません。
プレースホルダには、*名前付きプレースホルダ* と *序数プレースホルダ* のどちらかを使用する事が出来ます。ただし、一つのメッセージに両方を使うことは出来ません。
上記の例は名前付きプレースホルダの使い方を示すものです。
すなわち、各プレースホルダは `{name}` という形式で書かれていますが、それに対して、キーが(波括弧なしの)プレースホルダ名であり、値がそのプレースホルダを置き換える値である連想配列を渡す訳です。
すなわち、各プレースホルダは `{name}` という形式で書かれていますが、それに対して、キーが(波括弧なしの)プレースホルダ名であり、
値がそのプレースホルダを置き換える値である連想配列を渡す訳です。
序数プレースホルダは、0 ベースの整数の序数をプレースホルダ名として使います。
このプレースホルダは、`Yii::t()` の呼び出しに出現する順序に従って、パラメータ値によって置き換えられます。
@ -226,7 +232,8 @@ echo \Yii::t('app', 'Price: {0}', $price);
### パラメータのフォーマット <span id="parameter-formatting"></span>
メッセージのプレースホルダにフォーマットの規則を追加して指定し、パラメータ値がプレースホルダを置き換える前に適切にフォーマットされるようにすることが出来ます。
メッセージのプレースホルダにフォーマットの規則を追加して指定し、
パラメータ値がプレースホルダを置き換える前に適切にフォーマットされるようにすることが出来ます。
次の例では、`price` のパラメータ値の型は数値として扱われ、通貨の形式でフォーマットされます。
```php
@ -249,9 +256,8 @@ echo \Yii::t('app', 'Price: {0,number,currency}', $price);
echo Yii::t('app', "Example of string with ''-escaped characters'': '{' '}' '{test}' {count,plural,other{''count'' value is # '#{}'}}", ['count' => 3]);
+```
このようなプレースホルダを指定する方法についての完全な説明は、[ICU ドキュメント](http://icu-project.org/apiref/icu4c/classMessageFormat.html) を参照してください。
このようなプレースホルダを指定する方法についての完全な説明は、[ICU ドキュメント](http://icu-project.org/apiref/icu4c/classMessageFormat.html)を参照してください。以下では、よくある使用方法をいくつか示します
以下では、よくある使用方法をいくつか示します。
#### 数値 <span id="number"></span>
@ -283,7 +289,9 @@ echo \Yii::t('app', 'Balance: {0,number,,000,000000}', $sum);
// 日本語出力: '差引残高: 000,012345'
```
カスタムフォーマットで使用される文字については、[ICU API リファレンス](http://icu-project.org/apiref/icu4c/classicu_1_1DecimalFormat.html) の "Special Pattern Characters" のセクションに記述されています。
カスタムフォーマットで使用される文字については、
[ICU API リファレンス](http://icu-project.org/apiref/icu4c/classicu_1_1DecimalFormat.html) の "Special Pattern Characters"
のセクションに記述されています。
数値は常に翻訳先のロケールに従ってフォーマットされます。
つまり、ロケールを変更せずに、小数点や桁区切りを変更することは出来ません。
@ -376,7 +384,8 @@ echo \Yii::t('app', 'I am {n,spellout,%spellout-ordinal} agent', ['n' => 47]);
'spellout,' と '%' の間に空白を入れてはならないことに注意してください。
あなたが使用しているロケールで利用可能なオプションのリストについては、[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Numbering schemas, Spellout" を参照してください。
あなたが使用しているロケールで利用可能なオプションのリストについては、
[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Numbering schemas, Spellout" を参照してください。
#### 序数 <span id="ordinal"></span>
@ -397,7 +406,8 @@ echo \Yii::t('app', '{n,ordinal,%digits-ordinal-feminine}', ['n' => 471]);
'ordinal,' と '%' の間に空白を入れてはならないことに注意してください。
あなたが使用しているロケールで利用可能なオプションのリストについては、[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Numbering schemas, Ordinal" を参照してください。
あなたが使用しているロケールで利用可能なオプションのリストについては、
[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Numbering schemas, Ordinal" を参照してください。
> Note: 上記のソース・メッセージを、プレースホルダのスタイルを守って日本語に翻訳すると、'あなたはこのサイトの{n,ordinal}の訪問者です' となります。
> しかし、その出力結果は、'あなたはこのサイトの第42の訪問者です' となり、意味は通じますが、日本語としては若干不自然なものになります。
@ -424,7 +434,8 @@ echo \Yii::t('app', '{n,duration,%in-numerals}', ['n' => 471227]);
'duration,' と '%' の間に空白を入れてはならないことに注意してください。
あなたが使用しているロケールで利用可能なオプションのリストについては、[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Numbering schemas, Duration" を参照してください。
あなたが使用しているロケールで利用可能なオプションのリストについては、
[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Numbering schemas, Duration" を参照してください。
> Note: このソース・メッセージを 'あなたはこのサイトに既に{n,duration}の間滞在しています' と翻訳した場合の出力結果は、'あなたはこのサイトに既に47の間滞在しています' となります。
> これも、プレースホルダのスタイルも含めて全体を翻訳し直す方が良いでしょう。
@ -433,8 +444,7 @@ echo \Yii::t('app', '{n,duration,%in-numerals}', ['n' => 471227]);
#### 複数形 <span id="plural"></span>
言語によって、複数形の語形変化はさまざまに異なります。
Yii は、さまざまな形式の複数形語形変化に対応したメッセージ翻訳のための便利な方法を提供しています。
言語によって、複数形の語形変化はさまざまに異なります。Yii は、さまざまな形式の複数形語形変化に対応したメッセージ翻訳のための便利な方法を提供しています。
それは、非常に複雑な規則に対しても、十分に機能するものです。
語形変化の規則を直接に処理する代りに、特定の状況における語形変化した言葉の翻訳を提供するだけで十分です。
@ -445,10 +455,8 @@ Yii は、さまざまな形式の複数形語形変化に対応したメッセ
echo \Yii::t('app', 'There {n,plural,=0{are no cats} =1{is one cat} other{are # cats}}!', ['n' => $n]);
```
上記の複数形規則の引数において、`=` はぴったりその値であることを意味します。
従って、`=0` はぴったりゼロ、`=1` はぴったり 1 を表します。
`other` はそれ以外の数を表します。
`#` は ターゲット言語に従ってフォーマットされた `n` の値によって置き換えられます。
上記の複数形規則の引数において、`=` はぴったりその値であることを意味します。従って、`=0` はぴったりゼロ、`=1` はぴったり 1 を表します。
`other` はそれ以外の数を表します。`#` は ターゲット言語に従ってフォーマットされた `n` の値によって置き換えられます。
複数形の規則が非常に複雑な言語もあります。
例えば、次のロシア語の例では、`=1` が `n = 1` にぴったりと一致するのに対して、`one` が `21``101` などに一致します。
@ -461,11 +469,11 @@ echo \Yii::t('app', 'There {n,plural,=0{are no cats} =1{is one cat} other{are #
特定のロケールに対してどんな引数を指定すべきかを学ぶためには、[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Plural Rules, Cardinal" を参照してください。
あるいは、その代りに、[unicode.org の規則のリファレンス](http://cldr.unicode.org/index/cldr-spec/plural-rules) を参照することも出来ます。
> Note: 上記のロシア語のメッセージのサンプルは、主として翻訳メッセージとして使用されるものです。
> アプリケーションの [[yii\base\Application::$sourceLanguage|ソース言語]] を `ru-RU` にしてロシア語から他の言語に翻訳するという設定にしない限り、オリジナルのメッセージとしては使用されることはありません。
>
> `Yii::t()` の呼び出しにおいて、オリジナルのメッセージに対する翻訳が見つからない場合は、[[yii\base\Application::$sourceLanguage|ソース言語]] の複数形規則がオリジナルのメッセージに対して適用されます。
> `Yii::t()` の呼び出しにおいて、オリジナルのメッセージに対する翻訳が見つからない場合は、
> [[yii\base\Application::$sourceLanguage|ソース言語]] の複数形規則がオリジナルのメッセージに対して適用されます。
文字列が以下のようなものである場合のために `offset` というパラメータがあります。
@ -662,8 +670,7 @@ class Menu extends Widget
### フレームワーク・メッセージを翻訳する <span id="framework-translation"></span>
Yii には、検証エラーとその他いくつかの文字列に対するデフォルトの翻訳メッセージが付属しています。
これらのメッセージは、全て 'yii' というカテゴリの中にあります。
Yii には、検証エラーとその他いくつかの文字列に対するデフォルトの翻訳メッセージが付属しています。これらのメッセージは、全て 'yii' というカテゴリの中にあります。
場合によっては、あなたのアプリケーションのために、デフォルトのフレームワーク・メッセージの翻訳を修正したいことがあるでしょう。
そうするためには、`i18n` [アプリケーション・コンポーネント](structure-application-components.md) を以下のように構成してください。
@ -684,8 +691,7 @@ Yii には、検証エラーとその他いくつかの文字列に対するデ
### 欠落している翻訳の処理 <span id="missing-translations"></span>
ソースに翻訳が欠落している場合でも、Yii はリクエストされたメッセージの内容を表示します。
この振舞いは、原文のメッセージが正当かつ詳細なテキストである場合には、非常に好都合です。
しかし、場合によっては、それだけでは十分ではありません。
この振舞いは、原文のメッセージが正当かつ詳細なテキストである場合には、非常に好都合です。しかし、場合によっては、それだけでは十分ではありません。
リクエストされた翻訳がソースに欠落しているときに、何らかの特別な処理を実行する必要がある場合もあります。
そういう処理は、[[yii\i18n\MessageSource]] の [[yii\i18n\MessageSource::EVENT_MISSING_TRANSLATION|missingTranslation]] イベントを使うことによって達成できます。
@ -735,8 +741,7 @@ class TranslationEventHandler
### `message` コマンドを使う <a name="message-command"></a>
翻訳は [[yii\i18n\PhpMessageSource|php ファイル]]、[[yii\i18n\GettextMessageSource|.po ファイル]]、または [[yii\i18n\DbMessageSource|database]] に保存することが出来ます。
追加のオプションについてはそれぞれのクラスを参照してください。
翻訳は [[yii\i18n\PhpMessageSource|php ファイル]]、[[yii\i18n\GettextMessageSource|.po ファイル]]、または [[yii\i18n\DbMessageSource|database]] に保存することが出来ます。追加のオプションについてはそれぞれのクラスを参照してください。
まず最初に、構成情報ファイルを作成する必要があります。
どこに保存したいかを決めて、次のコマンドを発行してください。
@ -745,12 +750,10 @@ class TranslationEventHandler
./yii message/config-template path/to/config.php
```
作成されたファイルを開いて、あなたの要求に合わせてパラメータを修正します。
特に、下記の項目に注意を払ってください。
作成されたファイルを開いて、あなたの要求に合わせてパラメータを修正します。特に、下記の項目に注意を払ってください。
* `languages`: あなたのアプリケーションが翻訳されるべき言語を表す配列。
* `messagePath`: メッセージファイルを保存するパス。
これは、アプリケーションの構成情報で記述されている `i18n``basePath` と合致しなければなりません。
* `messagePath`: メッセージファイルを保存するパス。これは、アプリケーションの構成情報で記述されている `i18n``basePath` と合致しなければなりません。
'./yii message/config' コマンドを使って、CLI 経由で、指定したオプションを持つ設定ファイルを動的に生成することも可能です。
例えば、`languages` と `messagePath` のパラメータは、次のようにして設定することが出来ます。
@ -771,6 +774,8 @@ class TranslationEventHandler
./yii message path/to/config.php
```
また、オプションを指定して、抽出のパラメータを動的に変更することも出来ます。
これで、(あなたがファイル・ベースの翻訳を選択していた場合は) `messagePath` ディレクトリにファイルが出現します。
@ -779,9 +784,12 @@ class TranslationEventHandler
個々のテキスト・メッセージを翻訳する代りに、ビュー・スクリプト全体を翻訳したい場合があるでしょう。
この目的を達するためには、ビューを翻訳して、ターゲット言語と同じ名前のサブ・ディレクトリに保存するだけで大丈夫です。
例えば、`views/site/index.php` というビューをターゲット言語 `ru-RU` に翻訳したい場合は、翻訳したビューを `views/site/ru-RU/index.php` というファイルとして保存します。
このようにすると、[[yii\base\View::renderFile()]] メソッド、または、このメソッドを呼び出す他のメソッド (例えば [[yii\base\Controller::render()]]) を呼んで `views/site/index.php` をレンダリングするたびに、翻訳された `views/site/ru-RU/index.php` が代りにレンダリングされるようになります。
このようにすると、[[yii\base\View::renderFile()]] メソッド、または、このメソッドを呼び出す他のメソッド
(例えば [[yii\base\Controller::render()]]) を呼んで `views/site/index.php` をレンダリングするたびに、
翻訳された `views/site/ru-RU/index.php` が代りにレンダリングされるようになります。
> Note: [[yii\base\Application::$language|ターゲット言語]] が [[yii\base\Application::$sourceLanguage|ソース言語]] と同じ場合は、翻訳されたビューの有無にかかわらず、オリジナルのビューがレンダリングされます。
> Note: [[yii\base\Application::$language|ターゲット言語]] が [[yii\base\Application::$sourceLanguage|ソース言語]] と同じ場合は、
> 翻訳されたビューの有無にかかわらず、オリジナルのビューがレンダリングされます。
## 数値と日付の値を書式設定する <span id="date-number"></span>
@ -789,6 +797,11 @@ class TranslationEventHandler
詳細は [データ・フォーマッタ](output-formatting.md) のセクションを参照してください。
## 日付と数値をフォーマットする <span id="date-number"></span>
詳細は [データのフォーマット](output-formatting.md) のセクションを参照して下さい。
## PHP 環境をセットアップする <span id="setup-environment"></span>
Yii は、[[yii\i18n\Formatter]] クラスの数値や日付の書式設定や、[[yii\i18n\MessageFormatter]] を使うメッセージのフォーマッティングなど、ほとんどの国際化機能を提供するために [PHP intl 拡張](http://php.net/manual/ja/book.intl.php) を使います。
@ -796,12 +809,13 @@ Yii は、[[yii\i18n\Formatter]] クラスの数値や日付の書式設定や
だだし、このフォールバックの実装は、英語がターゲット言語である場合にのみ十分に機能するものす。
従って、国際化機能が必要とされる場合は、`intl` をインストールすることが強く推奨されます。
[PHP intl 拡張](http://php.net/manual/ja/book.intl.php) は、さまざまに異なる全てのロケールについて知識と書式の規則を提供する [ICU ライブラリ](http://site.icu-project.org/) に基礎を置いています。
[PHP intl 拡張](http://php.net/manual/ja/book.intl.php) は、さまざまに異なる全てのロケールについて知識と書式の規則を提供する
[ICU ライブラリ](http://site.icu-project.org/) に基礎を置いています。
ICU のバージョンが異なると、日付や数値のフォーマットの結果も異なる場合があります。
あなたのウェブ・サイトが全ての環境で同じ出力をすることを保証するためには、全ての環境において同じバージョンの PHP intl 拡張 (従って同じバージョンの ICU) をインストールすることが推奨されます。
あなたのウェブ・サイトが全ての環境で同じ出力をすることを保証するためには、
全ての環境において同じバージョンの PHP intl 拡張 (従って同じバージョンの ICU) をインストールすることが推奨されます。
どのバージョンの ICU が PHP によって使われているかを知るために、次のスクリプトを走らせることが出来ます。
このスクリプトは、使用されている PHP と ICU のバージョンを出力します。
どのバージョンの ICU が PHP によって使われているかを知るために、次のスクリプトを走らせることが出来ます。このスクリプトは、使用されている PHP と ICU のバージョンを出力します。
```php
<?php
@ -810,12 +824,10 @@ echo "ICU: " . INTL_ICU_VERSION . "\n";
echo "ICU Data: " . INTL_ICU_DATA_VERSION . "\n";
```
さらに、バージョン 49 以上の ICU を使用する事も推奨されます。
そうすることによって、このドキュメントで説明されている全ての機能を使うことが出来るようになります。
さらに、バージョン 49 以上の ICU を使用する事も推奨されます。そうすることによって、このドキュメントで説明されている全ての機能を使うことが出来るようになります。
例えば、49 未満の ICU は、複数形規則における `#` プレースホルダをサポートしていません。
入手できる ICU バージョン については、<http://site.icu-project.org/download> を参照してください。
バージョン番号の採番方式が 4.8 リリースの後に変更されたことに注意してください
(すなわち、ICU 4.8、ICU 49、ICU 50、等々となっています)。
バージョン番号の採番方式が 4.8 リリースの後に変更されたことに注意してください (すなわち、ICU 4.8、ICU 49、ICU 50、等々となっています)。
これに加えて、ICU ライブラリとともに出荷されるタイム・ゾーン・データベースの情報も古くなっている可能性があります。
タイム・ゾーン・データベースの更新に関する詳細は [ICU マニュアル](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data) を参照してください。

9
docs/guide-ja/tutorial-mailing.md

@ -131,8 +131,7 @@ Yii::$app->mailer->compose([
ビュー名をスカラーの文字列として渡した場合は、そのレンダリング結果は HTML ボディとして使われます。
そして、平文テキストのボディは HTML のボディから全ての HTML 要素を削除することによって作成されます。
ビューのレンダリング結果はレイアウトで包むことが出来ます。
レイアウトは、[[yii\mail\BaseMailer::htmlLayout]] と [[yii\mail\BaseMailer::textLayout]] を使ってセットアップすることが可能です。
ビューのレンダリング結果はレイアウトで包むことが出来ます。レイアウトは、[[yii\mail\BaseMailer::htmlLayout]] と [[yii\mail\BaseMailer::textLayout]] を使ってセットアップすることが可能です。
レイアウトは、通常のウェブ・アプリケーションのレイアウトと同じように働きます。
レイアウトは、メールの CSS スタイルや、その他の共有されるコンテントをセットアップするために使うことが出来ます。
@ -216,7 +215,8 @@ Yii は、そのようなチェックが出来ることを `yii\mail\BaseMailer:
メール・メッセージのファイルは通常のテキストエディタで開くことが出来ますので、実際のメッセージ・ヘッダやコンテントなどを閲覧することが出来ます。
このメカニズムは、アプリケーションのデバッグや単体テストを実行する際に、真価を発揮するでしょう。
> Note: メール・メッセージのファイルの内容は `\yii\mail\MessageInterface::toString()` によって作成されますので、あなたのアプリケーションで使用している実際のメール・エクステンションに依存したものになります。
> Note: メール・メッセージのファイルの内容は `\yii\mail\MessageInterface::toString()` によって作成されますので、
あなたのアプリケーションで使用している実際のメール・エクステンションに依存したものになります。
あなた自身のメール・ソリューションを作成する
@ -225,7 +225,6 @@ Yii は、そのようなチェックが出来ることを `yii\mail\BaseMailer:
あなた自身のカスタム・メール・ソリューションを作成するためには、二つのクラスを作成する必要があります。
すなわち、一つは `Mailer` であり、もう一つは `Message` です。
`yii\mail\BaseMailer``yii\mail\BaseMessage` をあなたのソリューションの基底クラスとして使うことが出来ます。
これらのクラスが、このガイドで説明された基本的なロジックを既に持っています。
しかし、それを使用することは強制されていません。
これらのクラスが、このガイドで説明された基本的なロジックを既に持っています。しかし、それを使用することは強制されていません。
`yii\mail\MailerInterface``yii\mail\MessageInterface` のインタフェイスを実装すれば十分です。
そして、あなたのソリューションをビルドするために、全ての抽象メソッドを実装しなければなりません。

56
docs/guide-ja/tutorial-performance-tuning.md

@ -2,28 +2,29 @@
============================
あなたのウェブ・アプリケーションのパフォーマンスに影響を及ぼす要因は数多くあります。
環境の要因もありますし、あなたのコードに関係する要因もあります。
また、Yii そのものに関係する要因もあります。
環境の要因もありますし、あなたのコードに関係する要因もあります。また、Yii そのものに関係する要因もあります。
このセクションでは要因のほとんどを列挙して、どのようにそれらを修正すればあなたのアプリケーションのパフォーマンスを向上させることが出来るかを説明します。
## PHP 環境を最適化する <span id="optimizing-php"></span>
PHP 環境を正しく構成することは非常に重要です。
最大のパフォーマンスを得るためには、
PHP 環境を正しく構成することは非常に重要です。最大のパフォーマンスを得るためには、
- 最新の安定した PHP バージョンを使うこと。
使用する PHP のメジャー・リリースを上げると、顕著なパフォーマンスの改善がもたらされることがあります。
- [Opcache](http://php.net/opcache) (PHP 5.5 以降) または [APC](http://php.net/apc) (PHP 5.4) を使って、バイト・コード・キャッシュを有効にすること。
- 最新の安定した PHP バージョンを使うこと。使用する PHP のメジャー・リリースを上げると、顕著なパフォーマンスの改善がもたらされることがあります。
- [Opcache](http://php.net/opcache) (PHP 5.5 以降) または [APC](http://php.net/apc) (PHP 5.4) を使って、
バイト・コード・キャッシュを有効にすること。
バイト・コード・キャッシュによって、リクエストが入ってくるたびに PHP スクリプトを解析してインクルードする時間の浪費を避けることが出来ます。
- [`realpath()` キャッシュをチューニングする](https://github.com/samdark/realpath_cache_tuner).
## デバッグ・モードを無効にする <span id="disable-debug"></span>
本番環境でアプリケーションを実行するときには、デバッグ・モードを無効にしなければなりません。
Yii は、`YII_DEBUG` という名前の定数の値を使って、デバッグ・モードを有効にすべきか否かを示します。
デバッグ・モードが有効になっているときは、Yii はデバッグ情報の生成と記録のために時間を余計に費やします。
[エントリ・スクリプト](structure-entry-scripts.md) の冒頭に次のコード行を置くことによってデバッグ・モードを無効にすることが出来ます。
[エントリ・スクリプト](structure-entry-scripts.md) の冒頭に次のコード行を置くことによってデ
バッグ・モードを無効にすることが出来ます。
```php
defined('YII_DEBUG') or define('YII_DEBUG', false);
@ -32,6 +33,7 @@ defined('YII_DEBUG') or define('YII_DEBUG', false);
> Info: `YII_DEBUG` のデフォルト値は `false` です。
従って、アプリケーション・コードの他のどこかでこのデフォルト値を変更していないと確信できるなら、単に上記の行を削除してデバッグ・モードを無効にしても構いません。
## キャッシュのテクニックを使う <span id="using-caching"></span>
さまざまなキャッシュのテクニックを使うと、あなたのアプリケーションのパフォーマンスを目に見えて改善することが出来ます。
@ -39,14 +41,17 @@ defined('YII_DEBUG') or define('YII_DEBUG', false);
そうすれば、リクエストごとに毎回同じ Markdown テキストの解析を繰り返すことを回避できるでしょう。
Yii によって提供されているキャッシュのサポートについて学ぶためには [キャッシュ](caching-overview.md) のセクションを参照してください。
## スキーマ・キャッシュを有効にする <span id="enable-schema-caching"></span>
スキーマ・キャッシュは、[アクティブ・レコード](db-active-record.md) を使おうとする場合には、いつでも有効にすべき特別なキャッシュ機能です。
ご存じのように、アクティブ・レコードは、賢いことに、あなたがわざわざ記述しなくても、DB テーブルに関するスキーマ情報 (カラムの名前、カラムのタイプ、外部キー制約など) を自動的に検出します。
ご存じのように、アクティブ・レコードは、賢いことに、あなたがわざわざ記述しなくても、
DB テーブルに関するスキーマ情報 (カラムの名前、カラムのタイプ、外部キー制約など) を自動的に検出します。
アクティブ・レコードはこの情報を取得するために追加の SQL クエリを実行しています。
スキーマ・キャッシュを有効にすると、取得されたスキーマ情報はキャッシュに保存されて将来のクエリで再利用されるようになります。
スキーマ・キャッシュを有効にするためには、[アプリケーションの構成情報](concept-configurations.md) の中で、`cache` [アプリケーション・コンポーネント](structure-application-components.md) にスキーマ情報を保存するように構成し、[[yii\db\Connection::enableSchemaCache]] を `true` に設定します。
スキーマ・キャッシュを有効にするためには、[アプリケーションの構成情報](concept-configurations.md) の中で、
`cache` [アプリケーション・コンポーネント](structure-application-components.md) にスキーマ情報を保存するように構成し、[[yii\db\Connection::enableSchemaCache]] を `true` に設定します。
```php
return [
@ -73,6 +78,7 @@ return [
];
```
## アセットを結合して最小化する <span id="optimizing-assets"></span>
複雑なウェブ・ページでは、多数の CSS や JavaScript のアセット・ファイルをインクルードすることがよくあります。
@ -80,6 +86,7 @@ HTTP リクエストの回数、および、これらのアセットの全体と
これによって、ページのロードにかかる時間とサーバの負荷を大きく削減することが出来ます。
詳細については、[アセット](structure-assets.md) のセクションを参照してください。
## セッションのストレージを最適化する <span id="optimizing-session"></span>
デフォルトでは、セッションのデータはファイルに保存されます。
@ -101,8 +108,7 @@ return [
// 以下を設定する
// 'db' => 'mydb',
// デフォルトの session テーブルをオーバーライドするためには
// 以下を設定する
// デフォルトの session テーブルをオーバーライドするためには以下を設定する
// 'sessionTable' => 'my_session',
],
],
@ -126,26 +132,32 @@ CREATE TABLE session (
ただし、キャッシュ・ストレージの中には、容量の上限に達したときにキャッシュされたデータをフラッシュするものがあることに注意してください。
この理由により、主として容量の上限が無い種類のキャッシュ・ストレージを使用すべきです。
あなたのサーバに [Redis](http://redis.io/) がある場合は、[[yii\redis\Session]] によって redis をセッション・ストレージとして使用することを強く推奨します。
あなたのサーバに [Redis](http://redis.io/) がある場合は、[[yii\redis\Session]] によって redis
をセッション・ストレージとして使用することを強く推奨します。
## データベースを最適化する <span id="optimizing-databases"></span>
DB クエリの実行とデータベースからのデータ取得がウェブ・アプリケーションのパフォーマンスの主たるボトルネックになることがよくあります。
[データ・キャッシュ](caching-data.md) の使用によってパフォーマンスの劣化を緩和することは出来ますが、問題を完全に解決することは出来ません。
データベースが膨大なデータを抱えている場合、キャッシュされたデータが無効化されたときに最新のデータを取得するためのコストは、データベースとクエリが適切に設計されていないと、法外なものになり得ます。
データベースが膨大なデータを抱えている場合、キャッシュされたデータが無効化されたときに最新のデータを取得するためのコストは、
データベースとクエリが適切に設計されていないと、法外なものになり得ます。
DB クエリのパフォーマンスを向上させるための一般的なテクニックは、フィルタの対象になるテーブル・カラムにインデックスを作成することです。
例えば、`username` によってユーザのレコードを検索する必要があるなら、`username` に対してインデックスを作成するべきです。
ただし、インデックスを付けると SELECT クエリを非常に速くすることが出来る代りに、INSERT、UPDATE、または DELTE のクエリが遅くなることに注意してください。
複雑な DB クエリについては、クエリの解析と準備の時間を節約するために、データベース・ビューを作成することが推奨されます。
最後にもう一つ大事なことですが、SELECT クエリで LIMIT を使ってください。
こうすることで、大量のデータが返されて、PHP のために確保されたメモリを使い尽くすということがなくなります。
## プレーンな配列を使う <span id="using-arrays"></span>
[アクティブ・レコード](db-active-record.md) は非常に使い勝手のよいものですが、データベースから大量のデータを取得する必要がある場合は、プレーンな配列を使うほどには効率的ではありません。
そういう場合は、アクティブ・レコードを使ってデータを取得する際に `asArray()` を呼んで、取得したデータがかさばるアクティブ・レコードのオブジェクトではなく配列として表現されるようにすることを考慮するのが良いでしょう。
そういう場合は、アクティブ・レコードを使ってデータを取得する際に `asArray()` を呼んで、
取得したデータがかさばるアクティブ・レコードのオブジェクトではなく配列として表現されるようにすることを考慮するのが良いでしょう。
例えば、
```php
@ -160,8 +172,7 @@ class PostController extends Controller
}
```
上記において、`$posts` は、テーブル行の配列としてデータを代入されることになります。
各行はプレーンな配列になります。
上記において、`$posts` は、テーブル行の配列としてデータを代入されることになります。各行はプレーンな配列になります。
`$i` 番目の行の `title` カラムにアクセスするためには、`$posts[$i]['title']` という式を使うことが出来ます。
クエリを構築するのに [DAO](db-dao.md) を使って、データをプレーンな配列に取得することも出来ます。
@ -169,7 +180,8 @@ class PostController extends Controller
## Composer オートローダを最適化する <span id="optimizing-autoloader"></span>
Composer のオートローダは、ほとんどのサードパーティのクラス・ファイルをインクルードするのに使われますので、次のコマンドを実行して Composer のオートローダを最適化することを考慮すべきです。
Composer のオートローダは、ほとんどのサードパーティのクラス・ファイルをインクルードするのに使われますので、
次のコマンドを実行して Composer のオートローダを最適化することを考慮すべきです。
```
composer dumpautoload -o
@ -183,10 +195,10 @@ composer dumpautoload -o
## オフラインでデータを処理する <span id="processing-data-offline"></span>
リクエストが何らかのリソース集約的な操作を必要とするものである場合は、そういう操作が終るまでユーザを待たせずに、オフラインモードで操作を実行する方策を考えるべきです。
リクエストが何らかのリソース集約的な操作を必要とするものである場合は、そういう操作が終るまでユーザを待たせずに、
オフラインモードで操作を実行する方策を考えるべきです。
オフラインでデータを処理するための方法が二つあります。
すなわち、プルとプッシュです。
オフラインでデータを処理するための方法が二つあります。すなわち、プルとプッシュです。
プルの方法では、リクエストが何らかの複雑な操作を必要とするたびに、タスクを作成してデータベースなどの持続的ストレージに保存します。
そうしておいて、別の独立したプロセス (例えばクロンジョブ) を使い、タスクを引き出して処理します。
@ -203,7 +215,7 @@ composer dumpautoload -o
あなたは、あなたのコードをプロファイルして、パフォーマンスのボトルネックを発見し、それに応じた適切な手段を講じるべきです。
次のプロファイリング・ツールが役に立つでしょう。
- [Yii のデバッグ・ツールバーとデバッガ](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide-ja/README.md)
- [Yii のデバッグ・ツールバーとデバッガ](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide-ja/README.md)
- [Blackfire](https://blackfire.io/)
- [XHProf](http://www.php.net/manual/ja/book.xhprof.php)
- [XDebug プロファイラ](http://xdebug.org/docs/profiler)

13
docs/guide-ja/tutorial-shared-hosting.md

@ -7,7 +7,8 @@
## ベーシック・プロジェクト・テンプレートを配備する
通例、共有ホスティング環境では、一つのウェブ・ルートしかありませんので、可能であればベーシック・プロジェクト・テンプレートを使用して下さい。
まず、[Yii をインストールする](start-installation.md) のセクションを参照して、プロジェクト・テンプレートをローカル環境にインストールします。
まず、[Yii をインストールする](start-installation.md) のセクションを参照して、
プロジェクト・テンプレートをローカル環境にインストールします。
そして、ローカル環境でアプリケーションが動くようにした後で、共有ホスティング環境でホスト出来るようにいくつかの修正を行います。
### ウェブ・ルートの名前を変える <span id="renaming-webroot"></span>
@ -34,7 +35,8 @@ www
### ウェブ・サーバのための追加設定 <span id="add-extras-for-webserver"></span>
使用されているウェブ・サーバが Apache である場合は、次の内容を持つ `.htaccess` ファイルを `web` (または `public_html` など、要するに、`index.php` があるディレクトリ) に追加する必要があります。
使用されているウェブ・サーバが Apache である場合は、次の内容を持つ `.htaccess` ファイルを `web`
(または `public_html` など、要するに、`index.php` があるディレクトリ) に追加する必要があります。
```
Options +FollowSymLinks
@ -54,12 +56,9 @@ nginx の場合は、追加の構成ファイルは必要がない筈です。
### 必要条件をチェックする
Yii を走らせるためには、あなたのウェブ・サーバは Yii の必要条件を満たさなければなりません。
最低限の必要条件は PHP 5.4 です。
Yii を走らせるためには、あなたのウェブ・サーバは Yii の必要条件を満たさなければなりません。最低限の必要条件は PHP 5.4 です。
必要条件をチェックするために、`requirements.php` をルート・ディレクトリからウェブ・ルート・ディレクトリにコピーして、
`http://example.com/requirements.php` という URL を使ってブラウザ経由で走らせます。
後でファイルを削除するのを忘れないでください。
`http://example.com/requirements.php` という URL を使ってブラウザ経由で走らせます。後でファイルを削除するのを忘れないでください。
## アドバンスト・プロジェクト・テンプレートを配備する

11
docs/guide-ja/tutorial-start-from-scratch.md

@ -3,7 +3,9 @@
> Note: このセクションはまだ執筆中です。
[ベーシック](https://github.com/yiisoft/yii2-app-basic) と [アドバンスト](https://github.com/yiisoft/yii2-app-advanced) のプロジェクト・テンプレートは、あなたの要求をほとんどカバーする優れたものですが、あなたのプロジェクトを開始するためのあなた自身のテンプレートを作成したいこともあるでしょう。
[ベーシック](https://github.com/yiisoft/yii2-app-basic) と [アドバンスト](https://github.com/yiisoft/yii2-app-advanced)
のプロジェクト・テンプレートは、あなたの要求をほとんどカバーする優れたものですが、
あなたのプロジェクトを開始するためのあなた自身のテンプレートを作成したいこともあるでしょう。
Yii におけるプロジェクト・テンプレートは、`composer.json` ファイルを含み、Composer パッケージとして登録されたレポジトリであるに過ぎません。
どのようなレポジトリでも、Composer パッケージとして特定し、`create-project` Composer コマンドによってインストール可能なものにすることが出来ます。
@ -30,7 +32,8 @@ git clone git@github.com:yiisoft/yii2-app-basic.git
`name`、`description`、`keywords`、`homepage`、`license` および `support` の値を、あなたの新しいテンプレートを説明するものに変更します。
また、`require`、`require-dev`、`suggest` や、その他のオプションも、あなたのテンプレートの要求に合うように調整します。
> Note: `composer.json` ファイルで、`extra` の下の `writable` パラメータを使って、アプリケーションがテンプレートを使って作成された後に設定されるべきファイル単位のアクセス権限を指定してください。
> Note: `composer.json` ファイルで、`extra` の下の `writable` パラメータを使って、
> アプリケーションがテンプレートを使って作成された後に設定されるべきファイル単位のアクセス権限を指定してください。
次に、あなたが好むデフォルトの状態に合うように、アプリケーションの構造と内容を実際に修正します。
最後に、あなたのテンプレートに適用できるように、README ファイルを更新します。
@ -42,8 +45,7 @@ git clone git@github.com:yiisoft/yii2-app-basic.git
あなたのテンプレートをオープンソース化するつもりなら、レポジトリをホストするのには [Github](http://github.com) が最適の場所です。
テンプレートを共同作業に使わないつもりであれば、どんな Git レポジトリサイトでも構いません。
次に、Composer のためにパッケージを登録する必要があります。
パブリックなテンプレートであれば、パッケージは [Packagist](https://packagist.org/) に登録すべきです。
次に、Composer のためにパッケージを登録する必要があります。パブリックなテンプレートであれば、パッケージは [Packagist](https://packagist.org/) に登録すべきです。
プライベートなテンプレートは、パッケージの登録が少々トリッキーです。
その説明については [Composer ドキュメント](https://getcomposer.org/doc/05-repositories.md#hosting-your-own) を参照してください。
@ -54,6 +56,5 @@ Yii の新しいプロジェクト・テンプレートを作成するのに必
これで、あなたのテンプレートを使ってプロジェクトを作成することが出来ます。
```
composer global require "fxp/composer-asset-plugin:^1.4.1"
composer create-project --prefer-dist --stability=dev mysoft/yii2-app-coolone new-project
```

11
docs/guide-ja/tutorial-template-engines.md

@ -1,7 +1,8 @@
テンプレートエンジンを使う
==========================
デフォルトでは、Yii は PHP をテンプレート言語として使いますが、[Twig](http://twig.sensiolabs.org/) や [Smarty](http://www.smarty.net/) などの他のレンダリング・エンジンをサポートするように Yii を構成することが出来ます。
デフォルトでは、Yii は PHP をテンプレート言語として使いますが、[Twig](http://twig.sensiolabs.org/) や
[Smarty](http://www.smarty.net/) などの他のレンダリング・エンジンをサポートするように Yii を構成することが出来ます。
`view` コンポーネントがビューのレンダリングに責任を持っています。
このコンポーネントのビヘイビアを構成することによって、カスタム・テンプレート・エンジンを追加することが出来ます。
@ -40,11 +41,9 @@
"yiisoft/yii2-smarty": "~2.0.0",
"yiisoft/yii2-twig": "~2.0.0",
```
上のコードを `composer.json``require` セクションに追加します。
変更をファイルに保存した後、コマンドラインで `composer update --prefer-dist` を実行することによってエクステンションをインストールすることが出来ます。
上のコードを `composer.json``require` セクションに追加します。変更をファイルに保存した後、コマンドラインで `composer update --prefer-dist` を実行することによってエクステンションをインストールすることが出来ます。
具体的にテンプレート・エンジンを使用する方法については、それぞれのドキュメントで詳細を参照してください。
- [Twig ガイド](https://github.com/yiisoft/yii2-twig/tree/master/docs/guide-ja)
- [Smarty ガイド](https://github.com/yiisoft/yii2-smarty/tree/master/docs/guide-ja)
- [Twig ガイド](https://www.yiiframework.com/extension/yiisoft/yii2-twig/doc/guide/)
- [Smarty ガイド](https://www.yiiframework.com/extension/yiisoft/yii2-smarty/doc/guide/)

26
docs/guide-ja/tutorial-yii-as-micro-framework.md

@ -1,24 +1,19 @@
# Yii をマイクロ・フレームワークとして使う
Yii はベーシック・テンプレートやアドバンスト・テンプレートに含まれる機能なしで使うことが簡単にできます。
言葉を換えれば、Yii は既にマイクロ・フレームワークです。
Yii を使うためにテンプレートによって提供されているディレクトリ構造を持つことは要求されていません。
Yii はベーシック・テンプレートやアドバンスト・テンプレートに含まれる機能なしで使うことが簡単にできます。言葉を換えれば、Yii は既にマイクロ・フレームワークです。Yii を使うためにテンプレートによって提供されているディレクトリ構造を持つことは要求されていません。
このことは、アセットやビューなどの事前定義されたテンプレート・コードを必要としない場合には、特に好都合です。
そのような場合の一つが JSON API です。以下に続くセクションで、どのようにしてそれを実現するかを示します。
このことは、アセットやビューなどの事前定義されたテンプレート・コードを必要としない場合には、特に好都合です。そのような場合の一つが JSON API です。以下に続くセクションで、どのようにしてそれを実現するかを示します。
## Yii をインストールする
プロジェクト・ファイルのためのディレクトリを作成し、ワーキング・ディレクトリをそのパスに変更します。
例で使用されているコマンドは UNIX ベースのものですが、同様のコマンドが Windows にもあります。
プロジェクト・ファイルのためのディレクトリを作成し、ワーキング・ディレクトリをそのパスに変更します。例で使用されているコマンドは UNIX ベースのものですが、同様のコマンドが Windows にもあります。
```bash
mkdir micro-app
cd micro-app
```
> Note: 続けるためには Composer についての知識が多少必要です。
Composer の使い方をまだ知らない場合は、時間を取って、[Composer Guide](https://getcomposer.org/doc/00-intro.md) を読んでください。
> Note: 続けるためには Composer についての知識が多少必要です。Composer の使い方をまだ知らない場合は、時間を取って、[Composer Guide](https://getcomposer.org/doc/00-intro.md) を読んでください。
`micro-app` ディレクトリの下に `composer.json` ファイルを作成し、あなたの好みのエディタを使って、下記を追加します。
@ -40,9 +35,7 @@ cd micro-app
## プロジェクトの構造を作成する
フレームワークをインストールしたら、次は、アプリケーションの [エントリ・ポイント](structure-entry-scripts.md) を作成します。
エントリ・ポイントは、アプリケーションを開こうとしたときに、一番最初に実行されるファイルです。
セキュリティ上の理由により、エントリ・ポイントを置くディレクトリは別にして、それをウェブ・ルートとします。
フレームワークをインストールしたら、次は、アプリケーションの [エントリ・ポイント](structure-entry-scripts.md) を作成します。エントリ・ポイントは、アプリケーションを開こうとしたときに、一番最初に実行されるファイルです。セキュリティ上の理由により、エントリ・ポイントを置くディレクトリは別にして、それをウェブ・ルートとします。
`web` ディレクトリを作成して、下記の内容を持つ `index.php` をそこに置きます。
@ -80,8 +73,7 @@ return [
> Info: 構成情報を `index.php` ファイルに持つことも出来ますが、別のファイルに持つことを推奨します。
> そうすれば、後で示しているように、同じ構成情報をコンソール・アプリケーションから使うことが出来ます。
これであなたのプロジェクトはコーディングの準備が出来ました。
プロジェクトのディレクトリ構造を決定するのは、名前空間に注意する限り、あなた次第です。
これであなたのプロジェクトはコーディングの準備が出来ました。プロジェクトのディレクトリ構造を決定するのは、名前空間に注意する限り、あなた次第です。
## 最初のコントローラを作成する
@ -120,7 +112,8 @@ micro-app/
```
まだウェブ・サーバをセットアップしていない場合は、[ウェブ・サーバの構成ファイル例](start-installation.md#configuring-web-servers) を参照すると良いでしょう。
もう一つのオプションは、PHP の内蔵ウェブ・サーバを利用する `yii serve` コマンドを使うことです。`micro-app/` ディレクトリから、次のコマンドを実行します。
もう一つのオプションは、PHP の内蔵ウェブ・サーバを利用する `yii serve` コマンドを使うことです。
`micro-app/` ディレクトリから、次のコマンドを実行します。
vendor/bin/yii serve --docroot=./web
@ -150,7 +143,8 @@ micro-app/
> Info: ここでは話を簡単にするために sqlite データベースを使用します。他のオプションについては [データベースのガイド](db-dao.md) を参照してください。
次に、[データベース・マイグレーション](db-migrations.md) を作成して、記事のテーブルを作成します。
既に述べたように、独立した構成情報ファイルがあることを確認してください。下記のコンソール・コマンドを実行するためには、それが必要です。
既に述べたように、独立した構成情報ファイルがあることを確認してください。
下記のコンソール・コマンドを実行するためには、それが必要です。
次のコマンドを実行すると、データベース・マイグレーション・ファイルが作成され、そして、マイグレーションがデータベースに適用されます。
vendor/bin/yii migrate/create --appconfig=config.php create_post_table --fields="title:string,body:text"

66
docs/guide-ja/tutorial-yii-integration.md

@ -2,14 +2,14 @@
============================
時々、Yii アプリケーションの中でサードパーティのコードを使用する必要があることがあります。
あるいは、サードパーティのシステムの中で Yii をライブラリとして使用したいこともあるでしょう。
このセクションでは、こういう目的をどうやって達成するかを説明します。
あるいは、サードパーティのシステムの中で Yii をライブラリとして使用したいこともあるでしょう。このセクションでは、こういう目的をどうやって達成するかを説明します。
Yii の中でサードパーティのライブラリを使う <span id="using-libs-in-yii"></span>
------------------------------------------
Yii アプリケーションの中でサードパーティのライブラリを使うために主として必要なことは、そのライブラリのクラスが適切にインクルードされること、または、オートロード可能であることを保証することです。
Yii アプリケーションの中でサードパーティのライブラリを使うために主として必要なことは、
そのライブラリのクラスが適切にインクルードされること、または、オートロード可能であることを保証することです。
### Composer パッケージを使う <span id="using-composer-packages"></span>
@ -20,7 +20,8 @@ Yii アプリケーションの中でサードパーティのライブラリを
2. `composer install` を実行して、指定したパッケージをインストールする。
インストールされた Composer パッケージ内のクラスは、Composer のオートローダを使ってオートロードすることが出来ます。
アプリケーションの [エントリ・スクリプト](structure-entry-scripts.md) に、Composer のオートローダをインストールするための下記の行があることを確認してください。
アプリケーションの [エントリ・スクリプト](structure-entry-scripts.md) に、
Composer のオートローダをインストールするための下記の行があることを確認してください。
```php
// Composer のオートローダをインストール
@ -37,7 +38,8 @@ require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
ここで `BasePath` は、アプリケーションの [base path](structure-applications.md#basePath) を表すものです。
ライブラリがそれ自身のオートローダを持っている場合は、それをアプリケーションの [エントリ・スクリプト](structure-entry-scripts.md) でインストールすることが出来ます。
複数のオートローダ・クラスの中で Yii のクラス・オートローダが優先されるように、ライブラリのオートローダは `Yii.php` ファイルをインクルードする前にインストールすることを推奨します。
複数のオートローダ・クラスの中で Yii のクラス・オートローダが優先されるように、
ライブラリのオートローダは `Yii.php` ファイルをインクルードする前にインストールすることを推奨します。
ライブラリがクラスオートローダを提供していない場合でも、クラスの命名規約が [PSR-4](http://www.php-fig.org/psr/psr-4/) に従っている場合は、ライブラリのクラスをオートロードするのに Yii のクラス・オートローダを使うことが出来ます。
必要なことは、ライブラリのクラスによって使われている全てのルート名前空間に対して [ルート・エイリアス](concept-aliases.md#defining-aliases) を宣言することだけです。
@ -56,11 +58,12 @@ require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
上記のどちらにも当てはまらない場合、おそらくそのライブラリは、クラス・ファイルを探して適切にインクルードするために、PHP の include path 設定に依存しているのでしょう。
この場合は、PHP include path の設定に関するライブラリの指示に従うしかありません。
最悪の場合として、ライブラリが全てのクラス・ファイルを明示的にインクルードすることを要求している場合は、次の方法を使ってクラスを必要に応じてインクルードすることが出来るようになります。
最悪の場合として、ライブラリが全てのクラス・ファイルを明示的にインクルードすることを要求している場合は、
次の方法を使ってクラスを必要に応じてインクルードすることが出来るようになります。
* ライブラリに含まれるクラスを特定する。
* アプリケーションの [エントリ・スクリプト](structure-entry-scripts.md) において、クラスと対応するファイル・パスを `Yii::$classMap` としてリストアップする。
例えば、
* アプリケーションの [エントリ・スクリプト](structure-entry-scripts.md) において、
クラスと対応するファイル・パスを `Yii::$classMap` としてリストアップする。例えば、
```php
Yii::$classMap['Class1'] = 'path/to/Class1.php';
Yii::$classMap['Class2'] = 'path/to/Class2.php';
@ -70,41 +73,30 @@ Yii::$classMap['Class2'] = 'path/to/Class2.php';
サードパーティのシステムで Yii を使う <span id="using-yii-in-others"></span>
-------------------------------------
Yii は数多くの優れた機能を提供していますので、サードパーティのシステム (例えば、WordPress、Joomla、または、他の PHP フレームワークを使って開発されるアプリケーション) を開発したり機能拡張したりするのをサポートするために Yii の機能のいくつかを使用したいことがあるでしょう。
Yii は数多くの優れた機能を提供していますので、サードパーティのシステム (例えば、WordPress、Joomla、または、他の PHP フレームワークを使って開発されるアプリケーション)
を開発したり機能拡張したりするのをサポートするために Yii の機能のいくつかを使用したいことがあるでしょう。
例えば、[[yii\helpers\ArrayHelper]] クラスや [アクティブ・レコード](db-active-record.md) をサードパーティのシステムで使いたいことがあるでしょう。
この目的を達するためには、主として、二つのステップを踏む必要があります。
すなわち、Yii のインストールと、Yii のブートストラップです。
サードパーティのシステムが Composer を使って依存を管理している場合は、単に下記のコマンドを実行すれば Yii をインストールすることが出来ます。
サードパーティのシステムが Composer を使って依存を管理している場合は、
単に下記のコマンドを実行すれば Yii をインストールすることが出来ます。
composer global require "fxp/composer-asset-plugin:~1.3.1"
composer require yiisoft/yii2
composer install
最初のコマンドは [composer アセット・プラグイン](https://github.com/francoispluchino/composer-asset-plugin/) をインストールします。
これは、Composer によって bower と npm の依存パッケージを管理できるようにするものです。
このことは、データベースなど、アセットに関係しない Yii の機能を使いたいだけの場合でも、Yii の Composer パッケージをインストールするために必要とされます。
[Yii のアセット発行の機能](structure-assets.md) を使いたい場合は、あなたの `composer.json``extra` セクションに次の構成も追加しなければなりません。
```json
{
...
"extra": {
"asset-installer-paths": {
"npm-asset-library": "vendor/npm",
"bower-asset-library": "vendor/bower"
}
}
}
```bash
composer require yiisoft/yii2
```
Composer に関する更なる情報や、インストールの過程で出現しうる問題に対する解決方法については、一般的な [Composer によるインストール](start-installation.md#installing-via-composer) のセクションを参照してください。
データベース抽象レイヤなど、アセットに関係しない Yii の機能だけを使用したい場合は、
Bower および NPM のパッケージのインストールを阻止する特別な composer パッケージが必要になります。
詳細については [cebe/assetfree-yii2](https://github.com/cebe/assetfree-yii2) を参照して下さい。
Composer に関する更なる情報や、インストールの過程で出現しうる問題に対する解決方法については、
一般的な [Composer によるインストール](start-installation.md#installing-via-composer) のセクションを参照してください。
そうでない場合は、Yii のリリースを [ダウンロード](http://www.yiiframework.com/download/) して、`BasePath/vendor` ディレクトリに解凍してください。
そうでない場合は、Yii のリリースを [ダウンロード](http://www.yiiframework.com/download/) して、
`BasePath/vendor` ディレクトリに解凍してください。
次に、サードパーティのシステムのエントリ・スクリプトを修正します。
次のコードをエントリ・スクリプトの先頭に追加してください。
次に、サードパーティのシステムのエントリ・スクリプトを修正します。次のコードをエントリ・スクリプトの先頭に追加してください。
```php
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
@ -115,10 +107,12 @@ new yii\web\Application($yiiConfig); // ここで run() を呼ばない
ごらんのように、上記のコードは典型的な Yii アプリケーションの [エントリ・スクリプト](structure-entry-scripts.md) と非常に良く似ています。
唯一の違いは、アプリケーションのインスタンスが作成された後に `run()` メソッドが呼ばれない、という点です。
`run()` を呼ぶと Yii がリクエスト処理のワークフローを制御するようになりますが、この場合はリクエストを処理する別のアプリケーションが既に存在していますので、これは必要ではないからです。
`run()` を呼ぶと Yii がリクエスト処理のワークフローを制御するようになりますが、
この場合はリクエストを処理する別のアプリケーションが既に存在していますので、これは必要ではないからです。
Yii アプリケーションでの場合と同じように、サードパーティ・システムが走っている環境に基づいて Yii のアプリケーション・インスタンスを構成する必要があります。
例えば、[アクティブ・レコード](db-active-record.md) の機能を使うためには、サードパーティ・システムによって使用されている DB 接続の設定を使って `db` [アプリケーション・コンポーネント](structure-application-components.md) を構成しなければなりません。
例えば、[アクティブ・レコード](db-active-record.md) の機能を使うためには、サードパーティ・システムによって使用されている DB 接続の設定を使って
`db` [アプリケーション・コンポーネント](structure-application-components.md) を構成しなければなりません。
これで、Yii によって提供されているほとんどの機能を使うことが出来ます。
例えば、アクティブ・レコード・クラスを作成して、それを使ってデータベースを扱うことが出来ます。

2
docs/guide-ru/concept-components.md

@ -46,7 +46,7 @@ echo DatePicker::widget([
```php
<?php
namespace yii\components\MyClass;
namespace yii\components;
use yii\base\BaseObject;

18
docs/guide-ru/concept-configurations.md

@ -4,7 +4,7 @@
Конфигурации широко используются в Yii при создании новых объектов или при инициализации уже существующих объектов.
Обычно конфигурации включают в себя названия классов создаваемых объектов и список первоначальных значений,
которые должны быть присвоены [свойствам](concept-properties.md) объекта. Также в конфигурациях можно указать список
[обработчиков событий](concept-events.md) объекта, и/или список [поведений](concept-behaviors.md) объекта.
[обработчиков событий](concept-events.md) объекта и/или список [поведений](concept-behaviors.md) объекта.
Пример конфигурации подключения к базе данных и дальнейшей инициализации подключения:
@ -80,7 +80,7 @@ Yii::configure($object, $config);
## Использование конфигурации <span id="using-configurations"></span>
Конфигурации повсеместно используются в Yii. В самом начале данной главы мы узнали как
создать объект с необходимыми параметрами используя метод [[Yii::createObject()]].
создать объект с необходимыми параметрами, используя метод [[Yii::createObject()]].
В данном разделе речь пойдет о конфигурации приложения и конфигурациях виджетов — двух основных способов
использования конфигурации.
@ -155,15 +155,15 @@ $config = [
```
Чтобы узнать о возможных значениях `definitions` и `singletons`, а также о реальных примерах использования,
прочитайте подраздел [более сложное практическое применение](concept-di-container.md#advanced-practical-usage) раздела
[Dependency Injection Container](concept-di-container.md).
прочитайте подраздел [Более сложное практическое применение](concept-di-container.md#advanced-practical-usage) раздела
[Контейнер внедрения зависимостей](concept-di-container.md).
### Конфигурации виджетов <span id="widget-configurations"></span>
При использовании [виджетов](structure-widgets.md) часто возникает необходимость изменить параметры виджета с помощью
конфигурации. Для создания виджета можно использовать два метода: [[yii\base\Widget::widget()]] и
[[yii\base\Widget::begin()]]. Оба метода принимают конфигурацию в виде PHP массива:
[[yii\base\Widget::begin()]]. Оба метода принимают конфигурацию в виде PHP-массива:
```php
use yii\widgets\Menu;
@ -181,13 +181,13 @@ echo Menu::widget([
Данный код создает виджет `Menu` и устанавливает параметр виджета `activeItems` в значение `false`.
Также устанавливается параметр `items`, состоящий из элементов меню.
Обратите внимание что параметр `class` НЕ передается, так как полное имя уже указано.
Обратите внимание, что параметр `class` НЕ передается, так как полное имя уже указано.
## Конфигурационные файлы <span id="configuration-files"></span>
Если конфигурация очень сложная, то её, как правило, разделяют по нескольким PHP файлам. Такие файлы называют
*Конфигурационными файлами*. Конфигурационный файл возвращает массив PHP являющийся конфигурацией.
Если конфигурация очень сложная, то её, как правило, разделяют по нескольким PHP-файлам. Такие файлы называют
*конфигурационными файлами*. Конфигурационный файл возвращает массив PHP, являющийся конфигурацией.
Например, конфигурацию приложения можно хранить в отдельном файле `web.php`, как показано ниже:
```php
@ -240,7 +240,7 @@ $config = require 'path/to/web.php';
## Значения конфигурации по умолчанию <span id="default-configurations"></span>
Метод [[Yii::createObject()]] реализован с использованием [dependency injection container](concept-di-container.md).
Метод [[Yii::createObject()]] реализован с использованием [контейнера внедрения зависимостей](concept-di-container.md).
Это позволяет задавать так называемые *значения конфигурации по умолчанию*, которые будут применены ко ВСЕМ экземплярам классов во время их инициализации методом [[Yii::createObject()]]. Значения конфигурации по умолчанию указываются с помощью метода `Yii::$container->set()` на этапе [предварительной загрузки](runtime-bootstrapping.md).
Например, если мы хотим изменить виджет [[yii\widgets\LinkPager]] так, чтобы все виджеты данного вида показывали максимум

10
docs/guide-ru/concept-di-container.md

@ -206,7 +206,7 @@ $reader = $container->get('app\storage\DocumentsReader');
доступны с версии 2.0.11.
Ещё один шаг по оптимизации конфигурации — регистрировать некоторые зависимости как синглтоны. Зависимость, регистрируемая
через метод [[yii\di\Container::set()|set()]] будет созаваться каждый раз при обращении к ней. Некоторые классы не меняют
через метод [[yii\di\Container::set()|set()]], будет создаваться каждый раз при обращении к ней. Некоторые классы не меняют
своего состояния на протяжении всей работы приложения, поэтому могут быть зарегистрированы как синглтоны. Это увеличит
производительность приложения.
@ -283,7 +283,7 @@ $foo = $container->get('Foo');
```php
$container = new \yii\di\Container;
// регистрация имени класса, как есть. это может быть пропущено.
// регистрация имени класса, как есть. Это может быть пропущено.
$container->set('yii\db\Connection');
// регистрация интерфейса
@ -295,7 +295,7 @@ $container->set('yii\mail\MailInterface', 'yii\swiftmailer\Mailer');
// для создания экземпляра Connection
$container->set('foo', 'yii\db\Connection');
// Регистрация класса с конфигурацией. Конфигурация
// регистрация класса с конфигурацией. Конфигурация
// будет применена при создании экземпляра класса через get()
$container->set('yii\db\Connection', [
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
@ -445,13 +445,13 @@ Yii создаёт контейнер внедрения зависимосте
\Yii::$container->set('yii\widgets\LinkPager', ['maxButtonCount' => 5]);
```
Теперь, если вы вызовете в представлении виджет, используя следующий код, то свойство `maxButtonCount` будет инициализировано, как 5, вместо значения по умолчанию 10, как это определено в классе.
Теперь, если вы вызовете в представлении виджет, используя следующий код, то свойство `maxButtonCount` будет инициализировано как 5 вместо значения по умолчанию 10, как это определено в классе.
```php
echo \yii\widgets\LinkPager::widget();
```
Хотя, вы всё ещё можете переопределить установленное значение через контейнер внедрения зависимостей:
Хотя вы всё ещё можете переопределить установленное значение через контейнер внедрения зависимостей:
```php
echo \yii\widgets\LinkPager::widget(['maxButtonCount' => 20]);

8
docs/guide-ru/concept-service-locator.md

@ -2,7 +2,7 @@ Service Locator
=============
Service Locator является объектом, предоставляющим всевозможные сервисы (или компоненты), которые могут понадобиться
приложению. В Service Locator, каждый компонент представлен единственным экземпляром, имеющим уникальный ID.
приложению. В Service Locator каждый компонент представлен единственным экземпляром, имеющим уникальный ID.
Уникальный идентификатор (ID) может быть использован для получения компонента из Service Locator.
В Yii Service Locator является экземпляром класса [[yii\di\ServiceLocator]] или его дочернего класса.
@ -50,7 +50,7 @@ $cache = $locator->get('cache');
$cache = $locator->cache;
```
Как видно выше, [[yii\di\ServiceLocator]] позволяет обратиться к компоненту как к свойству используя его ID.
Как видно выше, [[yii\di\ServiceLocator]] позволяет обратиться к компоненту как к свойству, используя его ID.
При первом обращении к компоненту, [[yii\di\ServiceLocator]] создаст новый экземпляр компонента на основе регистрационной
информации и вернёт его. При повторном обращении к компоненту Service Locator вернёт тот же экземпляр.
@ -88,7 +88,7 @@ return [
```
Есть альтернативный приведённому выше способ настройки компонента `search`. Вместо анонимной функции, которая
отдаёт экземпляр `SolrService` можно использовать статический метод, возвращающий такую анонимную функцию:
отдаёт экземпляр `SolrService`, можно использовать статический метод, возвращающий такую анонимную функцию:
```php
class SolrServiceBuilder
@ -112,7 +112,7 @@ return [
];
```
Это особенно полезно если вы создаёте компонент для Yii, являющийся обёрткой над какой-либо сторонней библиотекой.
Это особенно полезно, если вы создаёте компонент для Yii, являющийся обёрткой над какой-либо сторонней библиотекой.
Подобный приведённому выше статический метод позволяет скрыть от конечного пользователя сложную логику настройки
сторонней библиотеки. Пользователю будет достаточно вызвать статический метод.

36
docs/guide-ru/helper-array.md

@ -1,6 +1,6 @@
ArrayHelper
===========
В добавок к [богатому набору функций](http://php.net/manual/en/book.array.php) для работы с массивами, которые есть в самом PHP, Yii Array helper предоставляет свои статические функции, которые могут быть вам полезны.
Вдобавок к [богатому набору функций](http://php.net/manual/ru/book.array.php) для работы с массивами, которые есть в самом PHP, хелпер Yii Array предоставляет свои статические функции, которые могут быть вам полезны.
## Получение значений <span id="getting-values"></span>
@ -31,7 +31,7 @@ $value = ArrayHelper::getValue($array, 'foo.bar.name');
Первый аргумент – массив или объект из которого мы извлекаем значение. Второй аргумент определяет как будут извлекаться данные и может выглядеть как один из таких вариантов:
- Имя ключа массива или свойства объекта, значение которого нужно вернуть
- Путь к нужному значению, разделенный точками, как в примере выше
- Callback-функция возвращающая значение
- Callback-функция, возвращающая значение
Callback-функция должна выглядеть примерно так:
@ -41,7 +41,7 @@ $fullName = ArrayHelper::getValue($user, function ($user, $defaultValue) {
});
```
Третий, необязательный, аргумент определяет значение по-умолчанию. Если не установлен – равен `null`. Используется так:
Третий необязательный аргумент определяет значение по умолчанию. Если не установлен – равен `null`. Используется так:
```php
$username = ArrayHelper::getValue($comment, 'user.username', 'Unknown');
@ -110,7 +110,7 @@ $type = ArrayHelper::remove($array, 'type');
## Проверка наличия ключей <span id="checking-existence-of-keys"></span>
`ArrayHelper::keyExists` работает так же как и стандартный [array_key_exists](http://php.net/manual/en/function.array-key-exists.php),
`ArrayHelper::keyExists` работает так же, как и стандартный [array_key_exists](http://php.net/manual/ru/function.array-key-exists.php),
но также может проверять ключи без учёта регистра:
```php
@ -123,7 +123,7 @@ $data2 = [
];
if (!ArrayHelper::keyExists('username', $data1, false) || !ArrayHelper::keyExists('username', $data2, false)) {
echo "Please provide username.";
echo "Пожалуйста, укажите имя пользователя.";
}
```
@ -164,13 +164,13 @@ $array = [
['id' => '345', 'data' => 'def'],
];
$result = ArrayHelper::index($array, 'id');
// the result is:
// результат будет таким:
// [
// '123' => ['id' => '123', 'data' => 'abc'],
// '345' => ['id' => '345', 'data' => 'def'],
// ]
// using anonymous function
// использование анонимной функции
$result = ArrayHelper::index($array, function ($element) {
return $element['id'];
});
@ -182,7 +182,7 @@ $result = ArrayHelper::index($array, function ($element) {
Для получения пар ключ-значение из многомерного массива или из массива объектов вы можете использовать метод `map`.
Параметры `$from` и `$to` определяют имена ключей или свойств, которые будут использованы в map. Так же, третьим необязательным параметром вы можете задать правила группировки.
Параметры `$from` и `$to` определяют имена ключей или свойств, которые будут использованы в map. Также третьим необязательным параметром вы можете задать правила группировки.
```php
$array = [
@ -192,7 +192,7 @@ $array = [
);
$result = ArrayHelper::map($array, 'id', 'name');
// the result is:
// результат будет таким:
// [
// '123' => 'aaa',
// '124' => 'bbb',
@ -200,7 +200,7 @@ $result = ArrayHelper::map($array, 'id', 'name');
// ]
$result = ArrayHelper::map($array, 'id', 'name', 'class');
// the result is:
// результат будет таким:
// [
// 'x' => [
// '123' => 'aaa',
@ -245,7 +245,7 @@ ArrayHelper::multisort($data, function($item) {
```
Третий аргумент определяет способ сортировки – от большего к меньшему или от меньшего к большему. В случае, если мы сортируем по одному ключу, передаем `SORT_ASC` или `SORT_DESC`. Если сортировка осуществляется по нескольким ключам, вы можете назначить направление сортировки для каждого из них с помощью массива.
Последний аргумент – это флаг, который используется в стандартной функции PHP `sort()`. Посмотреть его возможные значения можно [тут](http://php.net/manual/en/function.sort.php).
Последний аргумент – это флаг, который используется в стандартной функции PHP `sort()`. Посмотреть его возможные значения можно [тут](http://php.net/manual/ru/function.sort.php).
## Определение типа массива <span id="detecting-array-types"></span>
@ -253,11 +253,11 @@ ArrayHelper::multisort($data, function($item) {
Удобный способ для определения, является массив индексным или ассоциативным. Вот пример:
```php
// no keys specified
// ключи не определены
$indexed = ['Qiang', 'Paul'];
echo ArrayHelper::isIndexed($indexed);
// all keys are strings
// все ключи - строки
$associative = ['framework' => 'Yii', 'version' => '2.0'];
echo ArrayHelper::isAssociative($associative);
```
@ -295,9 +295,9 @@ $data = ArrayHelper::toArray($posts, [
'app\models\Post' => [
'id',
'title',
// the key name in array result => property name
// ключ в результирующем массиве => имя свойства
'createTime' => 'created_at',
// the key name in array result => anonymous function
// ключ в результирующем массиве => анонимная функция
'length' => function ($post) {
return strlen($post->content);
},
@ -305,7 +305,7 @@ $data = ArrayHelper::toArray($posts, [
]);
```
Первый аргумент содержит данные, которые вы хотите конвертировать. В нашем случае это Active Record модель `Post`.
Первый аргумент содержит данные, которые вы хотите конвертировать. В нашем случае это модель Active Record `Post`.
Второй аргумент служит для управления процессом конвертации и может быть трех видов:
@ -331,11 +331,11 @@ $data = ArrayHelper::toArray($posts, [
## Проверка на присутствие в массиве <span id="testing-arrays"></span>
Часто необходимо проверить, содержится ли элемент в массиве, или является ли массив подмножеством другого массива.
К сожалению, PHP функция `in_array()` не поддерживает подмножества объектов, реализующих интерфейс `\Traversable`.
К сожалению, PHP-функция `in_array()` не поддерживает подмножества объектов, реализующих интерфейс `\Traversable`.
Для таких случаев [[yii\helpers\ArrayHelper]] предоставляет [[yii\helpers\ArrayHelper::isIn()|isIn()]] и
[[yii\helpers\ArrayHelper::isSubset()|isSubset()]]. Методы принимают такие же параметры, что и
[in_array()](http://php.net/manual/en/function.in-array.php).
[in_array()](http://php.net/manual/ru/function.in-array.php).
```php
// true

18
docs/guide-ru/helper-overview.md

@ -3,10 +3,10 @@
> Note: Этот раздел находиться в стадии разработки.
Yii предоставляет много классов, которые помогают упростить общие задачи программирования, такие как манипуляция со строками или массивами, генерация HTML кода, и так далее. Все helper классы организованны в рамках пространства имен `yii\helpers` и являются статическими методами
Yii предоставляет много классов, которые помогают упростить общие задачи программирования, такие как манипуляция со строками или массивами, генерация HTML-кода, и так далее. Все helper-классы организованы в рамках пространства имен `yii\helpers` и являются статическими методами
(это означает, что они содержат в себе только статические свойства и методы и объекты статического класса создать нельзя).
Вы можете использовать helper класс с помощью вызова одного из статических методов, как показано ниже:
Вы можете использовать helper-класс с помощью вызова одного из статических методов, как показано ниже:
```php
use yii\helpers\Html;
@ -14,14 +14,14 @@ use yii\helpers\Html;
echo Html::encode('Test > test');
```
> Note: Помощь в [настройке helper классов](#customizing-helper-classes), в Yii каждый основной helper состоит из двух классов: базовый класс (например `BaseArrayHelper`) и конкретный класс (например `ArrayHelper`).
> Note: Помощь в [настройке helper-классов](#customizing-helper-classes), в Yii каждый основной helper состоит из двух классов: базовый класс (например, `BaseArrayHelper`) и конкретный класс (например, `ArrayHelper`).
Когда вы используете helper, вы должны использовать только конкретные версии классов и никогда не использовать базовые классы.
Встроенные хелперы
------------------
В этой версии Yii предоставляются следующие основные helper классы:
В этой версии Yii предоставляются следующие основные helper-классы:
- [ArrayHelper](helper-array.md)
- Console
@ -41,9 +41,9 @@ echo Html::encode('Test > test');
Настройка хелперов <span id="customizing-helper-classes"></span>
--------------------------
Для настройки основных helper классов (например [[yii\helpers\ArrayHelper]]), вы должны создать расширяющийся класс из помощников соответствующих базовых классов (например [[yii\helpers\BaseArrayHelper]]) и дать похожее название, вашему классу, с соответствующим конкретному классу (например [[yii\helpers\ArrayHelper]]), в том числе его пространство имен. Тогда созданный класс заменит оригинальную реализацию в фреимворке.
Для настройки основных helper-классов (например, [[yii\helpers\ArrayHelper]]), вы должны создать расширяющийся класс из помощников соответствующих базовых классов (например, [[yii\helpers\BaseArrayHelper]]) и дать похожее название вашему классу с соответствующим конкретному классу (например, [[yii\helpers\ArrayHelper]]), в том числе его пространство имен. Тогда созданный класс заменит оригинальную реализацию в фреймворке.
В следующих примерах показывается как настроить [[yii\helpers\ArrayHelper::merge()|merge()]] метод
В следующих примерах показывается как настроить метод [[yii\helpers\ArrayHelper::merge()|merge()]]
[[yii\helpers\ArrayHelper]] класса:
```php
@ -55,7 +55,7 @@ class ArrayHelper extends BaseArrayHelper
{
public static function merge($a, $b)
{
// your custom implementation
// ваша собственная реализация
}
}
```
@ -64,10 +64,10 @@ class ArrayHelper extends BaseArrayHelper
Далее, в приложении [входной скрипт](structure-entry-scripts.md), добавьте следующую строчку кода
после подключения `yii.php` файла, которая сообщит [автозагрузка классов Yii](concept-autoloading.md) загрузить
ваш класс вместо оригинального helper класса фреимворка:
ваш класс вместо оригинального helper-класса фреимворка:
```php
Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';
```
Обратите внимание что пользовательская настройка helper классов полезна только, если вы хотите изменить поведение существующей функции helper классов. Если вы хотите добавить дополнительные функции, для использования в вашем приложении, будет лучше создать отдельный helper.
Обратите внимание что пользовательская настройка helper-классов полезна только, если вы хотите изменить поведение существующей функции helper-классов. Если вы хотите добавить дополнительные функции, для использования в вашем приложении, будет лучше создать отдельный helper.

8
docs/guide-ru/helper-url.md

@ -1,7 +1,7 @@
Url хелпер
Url
==========
Url хелпер предоставляет набор статических методов для управления URL.
Хелпер Url предоставляет набор статических методов для управления URL.
## Получение общих URL <span id="getting-common-urls"></span>
@ -94,7 +94,7 @@ echo Url::toRoute('site/index', 'https');
В разделе [[toRoute()]] подробно описано как задавать роут;
- Строка, начинающаяся с `@`, будет обработана как псевдоним. Будет возвращено соответствующее значение псевдонима;
- Пустая строка: вернет текущий URL;
- Обычная строка: вернет строку без изменений
- Обычная строка: вернет строку без изменений.
Когда у метода задан второй параметр `$scheme` (строка или `true`), то сгенерированный URL будет с протоколом
(полученным из [[\yii\web\UrlManager::hostInfo]]). Если в `$url` указан протокол, то его значение будет заменено.
@ -128,7 +128,7 @@ echo Url::to('@web/images/logo.gif', 'https');
```
Начиная с версии 2.0.3, вы можете использовать [[yii\helpers\Url::current()]], чтобы создавать URL на основе текущего
запрошенного роута и его GET-параметров. Вы можете изменить, удалить или добавить новые GET-параметры передав в метод
запрошенного роута и его GET-параметров. Вы можете изменить, удалить или добавить новые GET-параметры, передав в метод
параметр `$params`. Например:
```php

22
docs/guide-ru/runtime-logging.md

@ -1,14 +1,14 @@
Логгирование
============
Yii предоставляет мощную, гибко настраиваемую и легко расширяемую систему логгирования. Эта система логгирования позволяет удобным способом сохранять сообщения разных типов и фильтровать их. Сообщения могут быть сохранены в файлы, базы данных или отправлены на email.
Yii предоставляет мощную, гибко настраиваемую и легко расширяемую систему логирования. Эта система логирования позволяет удобным способом сохранять сообщения разных типов и фильтровать их. Сообщения могут быть сохранены в файлы, базы данных или отправлены на email.
Использование Системы логгирования Yii включает следующие шаги:
Использование Системы логирования Yii включает следующие шаги:
* Запись [сообщений лога](#log-messages) в различных частях кода приложения;
* Настройка [целей лога](#log-targets) в конфигурации приложения;
* Изучение отфильтрованных сообщений лога, например, при помощи [Отладчика Yii](tool-debugger.md).
В данном разделе, будем рассматривать первые два шага.
В данном разделе будем рассматривать первые два шага.
## Сообщения лога <span id="log-messages"></span>
@ -25,9 +25,9 @@ Yii предоставляет мощную, гибко настраиваему
Yii::debug('start calculating average revenue');
```
> Note: Сообщение может быть как строкой так и объектом или массивом. За корректную работу с содержимым сообщения отвечают [цели лога](#log-targets). По умолчанию, если сообщение не является строкой, оно будет приведено к строковому типу при помощи [[yii\helpers\VarDumper::export()]].
> Note: Сообщение может быть как строкой, так и объектом или массивом. За корректную работу с содержимым сообщения отвечают [цели лога](#log-targets). По умолчанию, если сообщение не является строкой, оно будет приведено к строковому типу при помощи [[yii\helpers\VarDumper::export()]].
Для упрощения работы с сообщениями лога и их фильтрации, рекомендуется явно указывать подходящую категорию для каждого сообщения. Возможно использование иерархической системы именования категорий, что значительно упростит [целям лога](#log-targets) фильтрацию сообщений по категориям. Простым и эффективным способом именования категорий является использование магической PHP константы `__METHOD__`. Такой подход используется в ядре фреймворка Yii. Например,
Для упрощения работы с сообщениями лога и их фильтрации, рекомендуется явно указывать подходящую категорию для каждого сообщения. Возможно использование иерархической системы именования категорий, что значительно упростит [целям лога](#log-targets) фильтрацию сообщений по категориям. Простым и эффективным способом именования категорий является использование магической PHP-константы `__METHOD__`. Такой подход используется в ядре фреймворка Yii. Например,
```php
Yii::debug('начало вычисления среднего дохода', __METHOD__);
@ -35,7 +35,7 @@ Yii::debug('начало вычисления среднего дохода', __
Константа `__METHOD__` вычисляется как имя метода (включая полное имя класса), в котором она использована. Например, её значение будет вычислено как `'app\controllers\RevenueController::calculate'`, если показанный выше код вызывается в соответствующем методе.
> Info: методы логгирования, описанные выше являются, на самом деле, ярлыками для метода [[yii\log\Logger::log()|log()]] [[yii\log\Logger|объекта логгера]], который доступен как синглтон `Yii::getLogger()`.
> Info: методы логирования, описанные выше являются, на самом деле, ярлыками для метода [[yii\log\Logger::log()|log()]] [[yii\log\Logger|объекта логгера]], который доступен как синглтон `Yii::getLogger()`.
При определенном количестве записанных сообщений или завершении приложения, объект логгера вызывает [[yii\log\Dispatcher|message dispatcher]] для отправки записанных сообщений зарегистрированным [целям логов](#log-targets).
@ -129,7 +129,7 @@ return [
]
```
> Note: При обработке HTTP исключения [обработчиком ошибок](runtime-handling-errors.md), сообщение будет сохранено с категорией вида `yii\web\HttpException:ErrorCode`. Например, исключение [[yii\web\NotFoundHttpException]] вызовет сообщение об ошибке с категорией `yii\web\HttpException:404`.
> Note: При обработке HTTP-исключения [обработчиком ошибок](runtime-handling-errors.md), сообщение будет сохранено с категорией вида `yii\web\HttpException:ErrorCode`. Например, исключение [[yii\web\NotFoundHttpException]] вызовет сообщение об ошибке с категорией `yii\web\HttpException:404`.
### Форматирование сообщений <span id="message-formatting"></span>
@ -160,7 +160,7 @@ return [
```
Кроме префиксов сообщений, также возможно добавление общей информации для каждого набора сообщений лога.
По умолчанию, включаются значения следующих глобальных PHP переменных: `$_GET`, `$_POST`, `$_FILES`, `$_COOKIE`,
По умолчанию включаются значения следующих глобальных PHP-переменных: `$_GET`, `$_POST`, `$_FILES`, `$_COOKIE`,
`$_SESSION` и `$_SERVER`. Эта возможность настраивается при помощи свойства [[yii\log\Target::logVars]], содержащего массив имен переменных, которые необходимо включить в лог. Например, следующий код позволяет настроить цель логов так, чтобы к сообщениям присоединялось только содержимое переменной `$_SERVER`.
```php
@ -222,7 +222,7 @@ return [
]
```
Из-за того, что значения максимального количества сообщений для передачи и выгрузки по умолчанию достаточно велико, при вызове метода `Yii::debug()`, или любого другого метода логгирования, сообщение не появится сразу в файле или таблице базы данных. Такое поведение может стать проблемой, например, в консольных приложениях с большим временем исполнения. Для того, чтобы все сообщения логов сразу же попадали в лог, необходимо установить значения свойств [[yii\log\Dispatcher::flushInterval|flushInterval]] и [[yii\log\Target::exportInterval|exportInterval]] равными 1, например так:
Из-за того, что значения максимального количества сообщений для передачи и выгрузки по умолчанию достаточно велико, при вызове метода `Yii::debug()` или любого другого метода логирования, сообщение не появится сразу в файле или таблице базы данных. Такое поведение может стать проблемой, например, в консольных приложениях с большим временем исполнения. Для того, чтобы все сообщения логов сразу же попадали в лог, необходимо установить значения свойств [[yii\log\Dispatcher::flushInterval|flushInterval]] и [[yii\log\Target::exportInterval|exportInterval]] равными 1, например так:
```php
return [
@ -246,7 +246,7 @@ return [
### Переключение целей логов <span id="toggling-log-targets"></span>
Свойство [[yii\log\Target::enabled|enabled]] отвечает за включение или отключение цели логов. Возможно управлением этим свойством как в конфигурации приложения, так и при помощи следующего PHP кода:
Свойство [[yii\log\Target::enabled|enabled]] отвечает за включение или отключение цели логов. Возможно управлением этим свойством как в конфигурации приложения, так и при помощи следующего PHP-кода:
```php
Yii::$app->log->targets['file']->enabled = false;
@ -275,7 +275,7 @@ return [
### Создание новых целей <span id="new-targets"></span>
Создание новой цели логов не является сложной задачей. В общем случае, нужно реализовать метод [[yii\log\Target::export()]], выгружающий массив [[yii\log\Target::messages]] в место хранения логов. Возможно использование метода [[yii\log\Target::formatMessage()]] для форматирования сообщения. Детали реализации можно подсмотреть в исходном коде любого из классов целей логов, включенных в состав Yii.
Создание новой цели логов не является сложной задачей. В общем случае нужно реализовать метод [[yii\log\Target::export()]], выгружающий массив [[yii\log\Target::messages]] в место хранения логов. Возможно использование метода [[yii\log\Target::formatMessage()]] для форматирования сообщения. Детали реализации можно подсмотреть в исходном коде любого из классов целей логов, включенных в состав Yii.
## Профилирование производительности <span id="performance-profiling"></span>

38
docs/guide-ru/runtime-routing.md

@ -39,7 +39,7 @@ $url = Url::to(['post/view', 'id' => 100]);
- Обычный.
- Человекопонятные URL.
Обычный формат URL использует параметр `r` для передачи маршрута и любые другие параметры для передачи остальных параметров запроса. Например, URL `/index.php?r=post/view&id=100` задает маршрут `post/view` и параметр `id`, равный 100. Данный формат не требует специальной конфигурации [[yii\web\UrlManager|URL manager]] и работает с любыми настройками Веб сервера.
Обычный формат URL использует параметр `r` для передачи маршрута и любые другие параметры для передачи остальных параметров запроса. Например, URL `/index.php?r=post/view&id=100` задает маршрут `post/view` и параметр `id`, равный 100. Данный формат не требует специальной конфигурации [[yii\web\UrlManager|URL manager]] и работает с любыми настройками веб-сервера.
Человекопонятный формат URL представляет собой дополнительный путь, следующий за именем входного скрипта, описывающий маршрут и остальные параметров запроса. Например, дополнительный путь в URL `/index.php/post/100` - это `/post/100`, который может представлять маршрут `post/view` и параметр `id` со значением равным 100, при наличии соответствующего [[yii\web\UrlManager::rules|правила]]. Для использования ЧПУ, необходимо создать набор правил, соответствующих требованиям к URL.
@ -128,7 +128,7 @@ echo Url::to(['post/index'], 'https');
Обратите внимание, что в последнем примере подразумевается использование обычного формата URL. При использовании ЧПУ, будут созданы другие URL, соответствующие [[yii\web\UrlManager::rules|правилам создания URL]].
Маршрут, переданный методу [[yii\helpers\Url::to()]], является контекстно зависимым. Он может быть *относительным* или *абсолютным*, в зависимости от следующих правил:
Маршрут, переданный методу [[yii\helpers\Url::to()]], является контекстно-зависимым. Он может быть *относительным* или *абсолютным*, в зависимости от следующих правил:
- Если маршрут является пустой строкой, будет использован текущий [[yii\web\Controller::route|маршрут]];
- Если маршрут не содержит слешей вообще, он рассматривается как *идентификатор* действия текущего контроллера и будет дополнен значением [[\yii\web\Controller::uniqueId|uniqueId]] текущего контроллера в качестве префикса;
@ -159,7 +159,7 @@ echo Url::to(['@posts']);
В основе реализации метода [[yii\helpers\Url::to()]] лежит использование двух методов компонента [[yii\web\UrlManager|URL manager]]: [[yii\web\UrlManager::createUrl()|createUrl()]] и [[yii\web\UrlManager::createAbsoluteUrl()|createAbsoluteUrl()]]. Ниже будут рассмотрены способы конфигурации [[yii\web\UrlManager|URL manager]] для создания URL в различных форматах.
Метод [[yii\helpers\Url::to()]], так же, поддерживает создание URL не связанных с маршрутами приложения.
Метод [[yii\helpers\Url::to()]] также поддерживает создание URL, не связанных с маршрутами приложения.
В данном случае, нужно передать в качестве первого параметра строку, а не массив. Например,
```php
@ -185,7 +185,7 @@ use yii\helpers\Url;
echo Url::home();
// базовый URL, удобно использовать в случае, когда приложение расположено в подкаталоге
// относительно корневого каталога Веб сервера
// относительно корневого каталога веб-сервера
echo Url::base();
// канонический URL запрошенного URL
@ -217,13 +217,13 @@ echo Url::previous();
```
Свойство [[yii\web\UrlManager::enablePrettyUrl|enablePrettyUrl]] является ключевым, активирует формат ЧПУ.
Остальные свойства не обязательные. Однако, в примере выше, показан самый популярный вариант конфигурации ЧПУ.
Остальные свойства необязательные. Однако в примере выше показан самый популярный вариант конфигурации ЧПУ.
* [[yii\web\UrlManager::showScriptName|showScriptName]]: это свойство определяет необходимость включения имени входного скрипта в создаваемый URL. Например, при его значении `false`, вместо `/index.php/post/100`, будет сгенерирован URL `/post/100`.
* [[yii\web\UrlManager::enableStrictParsing|enableStrictParsing]]: это свойство позволяет включить строгий разбор URL. Если строгий разбор URL включен, запрошенный URL должен соответствовать хотя бы одному из [[yii\web\UrlManager::rules|правил]], иначе будет вызвано исключение [[yii\web\NotFoundHttpException]]. Если строгий разбор URL отключен и ни одно из [[yii\web\UrlManager::rules|правил]] не подходит для разбора запрошенного URL, часть этого URL, представляющая путь, будет использована как маршрут.
* [[yii\web\UrlManager::rules|rules]]: это свойство содержит набор правил для разбора и создания URL. Это основное свойство, с которым нужно работать, что бы URL создавались в формате, соответствующем требованиям приложения.
* [[yii\web\UrlManager::rules|rules]]: это свойство содержит набор правил для разбора и создания URL. Это основное свойство, с которым нужно работать, чтобы URL создавались в формате, соответствующем требованиям приложения.
> Note: Для того, чтобы скрыть имя входного скрипта в создаваемых URL, кроме установки значения свойства [[yii\web\UrlManager::showScriptName|showScriptName]] в `false`, необходимо настроить Веб сервер, чтобы он мог правильно определять PHP скрипт, который должен быть запущен, если в запрошенном URL он не указан явно. Рекомендованные настройки для Apache и Nginx описаны в разделе [Установка Yii](start-installation.md#rekomenduemye-nastrojki-apache).
> Note: Для того, чтобы скрыть имя входного скрипта в создаваемых URL, кроме установки значения свойства [[yii\web\UrlManager::showScriptName|showScriptName]] в `false`, необходимо настроить веб-сервер, чтобы он мог правильно определять PHP-скрипт, который должен быть запущен, если в запрошенном URL он не указан явно. Рекомендованные настройки для Apache и Nginx описаны в разделе [Установка Yii](start-installation.md#rekomenduemye-nastrojki-apache).
### Правила URL <span id="url-rules"></span>
@ -262,7 +262,7 @@ echo Url::previous();
Правило URL может содержать несколько именованных параметров запроса, которые указываются в шаблоне в следующем формате: `<ParamName:RegExp>`, где `ParamName` определяет имя параметра, а `RegExp` - необязательное регулярное выражение, используемое для определения значения параметра. В случае, если `RegExp` не указан, значением параметра будет любая последовательность символов кроме слешей.
> Note: Возможно указание только регулярного выражения для параметров. В таком случае, остальная часть шаблона будет считаться простым текстом.
> Note: Возможно указание только регулярного выражения для параметров. В таком случае остальная часть шаблона будет считаться простым текстом.
После разбора URL, параметры запроса, соответствующие шаблону правила, будут доступны в массиве `$_GET` через компонент приложения `request`.
При создании URL, значения указанных параметров будут вставлены в URL в соответствии с шаблоном правила.
@ -311,7 +311,7 @@ echo Url::previous();
> Note: Использование параметров в маршрутах позволяет значительно уменьшить количество правил URL и улучшить производительность компонента [[yii\web\UrlManager|URL manager]].
По умолчанию, все параметры, указанные в правиле, являются обязательными. Если запрошенный URL не содержит обязательный параметр, или если URL создается без обязательного параметра, данное правило не будет применено. Свойство [[yii\web\UrlRule::defaults]] позволяет сделать нужные параметры не обязательными. Параметры, перечисленные в данном свойстве, будут иметь заданные значения, в случае если они пропущены.
По умолчанию все параметры, указанные в правиле, являются обязательными. Если запрошенный URL не содержит обязательный параметр, или если URL создается без обязательного параметра, данное правило не будет применено. Свойство [[yii\web\UrlRule::defaults]] позволяет сделать нужные параметры не обязательными. Параметры, перечисленные в данном свойстве, будут иметь заданные значения, в случае если они пропущены.
В следующем правиле описаны необязательные параметры `page` и `tag`, которые примут значения `1` и `пустая строка` в случае, если они будут пропущены.
@ -338,7 +338,7 @@ echo Url::previous();
### Правила с именами серверов <span id="rules-with-server-names"></span>
Существует возможность включать имена серверов в шаблон правил URL. Главным образом, это удобно, когда требуется разное поведение приложения, в зависимости от разных имен Веб серверов. Например, следующее правило позволит разобрать URL `http://admin.example.com/login` в маршрут `admin/user/login` и `http://www.example.com/login` в `site/login`.
Существует возможность включать имена серверов в шаблон правил URL. Главным образом, это удобно, когда требуется разное поведение приложения, в зависимости от разных имен веб-серверов. Например, следующее правило позволит разобрать URL `http://admin.example.com/login` в маршрут `admin/user/login` и `http://www.example.com/login` в `site/login`.
```php
[
@ -359,7 +359,7 @@ echo Url::previous();
### Суффиксы в URL <span id="url-suffixes"></span>
Компонент предоставляет возможность добавления к URL суффиксов. Например, можно добавить к URL `.html`, что бы они выглядели как статические HTML страницы; можно добавить к URL суффикс `.json`, для указания на ожидаемый тип данных ответа. Настроить суффиксы в URL можно при помощи соответствующего свойства [[yii\web\UrlManager::suffix]] в конфигурации приложения:
Компонент предоставляет возможность добавления к URL суффиксов. Например, можно добавить к URL `.html`, чтобы они выглядели как статические HTML-страницы; можно добавить к URL суффикс `.json`, для указания на ожидаемый тип данных ответа. Настроить суффиксы в URL можно при помощи соответствующего свойства [[yii\web\UrlManager::suffix]] в конфигурации приложения:
```php
[
@ -413,7 +413,7 @@ echo Url::previous();
что позволяет справиться с вариациями одного и того же URL с присутствующим или отсутствующим слешем в конце.
Технически `http://example.com/path` и `http://example.com/path/` являются разными URL, отдача одинакового содержимого
в обоих вариантах может негативно повлиять на SEO. По умолчанию нормализатор заменяет повторяющиеся слеши на один и либо
убирает, либо добавляет завершающие слеши в зависимости от суффикса и производит [редирект 301](https://en.wikipedia.org/wiki/HTTP_301)
убирает, либо добавляет завершающие слеши в зависимости от суффикса и производит [редирект 301](https://ru.wikipedia.org/wiki/HTTP_301)
на нормализованный URL. Нормализатор может быть настроен как глобально для менеджера URL, так и индивидуально для
каждого правила. По умолчанию все правила используют нормализатор, заданный в менеджере URL. Вы можете выставить
[[yii\web\UrlRule::$normalizer|UrlRule::$normalizer]] в `false` для отключения нормализации для конкретного правила.
@ -456,9 +456,9 @@ echo Url::previous();
> Note: по умолчанию [[yii\web\UrlManager::$normalizer|UrlManager::$normalizer]] отключен. Чтобы использовать
нормализацию его необходимо сконфигурировать.
### HTTP методы <span id="http-methods"></span>
### Методы HTTP <span id="http-methods"></span>
При реализации RESTful API, зачастую бывает необходимость в том, чтобы один и тот же URL был разобран в разные маршруты, в зависимости от HTTP метода запроса. Это легко достигается указанием HTTP методов, поддерживаемых правилом в начале шаблона. Если правило поддерживает несколько HTTP методов, их имена разделяются запятыми. Например, следующие правила имеют шаблон `post/<id:\d+>` с разными поддерживаемыми HTTP методами. Запрос `PUT post/100` будет разобран в маршрут `post/create`, в то время, как запрос `GET post/100` будер разобран в `post/view`.
При реализации RESTful API, зачастую бывает необходимость в том, чтобы один и тот же URL был разобран в разные маршруты, в зависимости от HTTP-метода запроса. Это легко достигается указанием HTTP-методов, поддерживаемых правилом в начале шаблона. Если правило поддерживает несколько HTTP-методов, их имена разделяются запятыми. Например, следующие правила имеют шаблон `post/<id:\d+>` с разными поддерживаемыми HTTP-методами. Запрос `PUT post/100` будет разобран в маршрут `post/create`, в то время, как запрос `GET post/100` будер разобран в `post/view`.
```php
[
@ -468,7 +468,7 @@ echo Url::previous();
]
```
> Note: Если правило URL содержит HTTP метод в шаблоне, это правило будет использовано только при разборе URL. Такое правило не будет учитываться компонентом [[yii\web\UrlManager|URL manager]] при создании URL.
> Note: Если правило URL содержит HTTP-метод в шаблоне, это правило будет использовано только при разборе URL. Такое правило не будет учитываться компонентом [[yii\web\UrlManager|URL manager]] при создании URL.
> Tip: Для упрощения маршрутизации RESTful API, Yii предоставляет специальный класс [[yii\rest\UrlRule]], который достаточно эффективен и предоставляет такие удобные возможности, как автоматическое приведение идентификаторов контроллеров к множественной форме. Более подробную информацию можно найти в разделе Веб-сервисы REST [Роутинг](rest-routing.md).
@ -489,12 +489,12 @@ echo Url::previous();
]
```
> Info: По умолчанию, если в конфигурации правила явно незадан параметр `class`, будет создано правило класса [[yii\web\UrlRule]].
> Info: По умолчанию, если в конфигурации правила явно не задан параметр `class`, будет создано правило класса [[yii\web\UrlRule]].
### Добавление правил URL динамически <span id="adding-rules"></span>
Правила URL могут быть динамически добавлены в компонент [[yii\web\UrlManager|URL manager]]. Часто это необходимо подключаемым [модулям](structure-modules.md) для настройки своих правил URL. Для того, что бы динамически добавленные правила могли влиять на процесс роутинга, они должны быть добавлены в процессе [предзагрузки](runtime-bootstrapping.md). В частности, модули должны реализовываться интерфейс [[yii\base\BootstrapInterface]] и добавлять правила в методе [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]], например:
Правила URL могут быть динамически добавлены в компонент [[yii\web\UrlManager|URL manager]]. Часто это необходимо подключаемым [модулям](structure-modules.md) для настройки своих правил URL. Для того чтобы динамически добавленные правила могли влиять на процесс роутинга, они должны быть добавлены в процессе [предзагрузки](runtime-bootstrapping.md). В частности, модули должны реализовываться интерфейс [[yii\base\BootstrapInterface]] и добавлять правила в методе [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]], например:
```php
public function bootstrap($app)
@ -505,7 +505,7 @@ public function bootstrap($app)
}
```
Так же, необходимо включить данный модуль в [[yii\web\Application::bootstrap]], чтобы он смог участвовать в процессе [предзагрузки](runtime-bootstrapping.md).
Также необходимо включить данный модуль в [[yii\web\Application::bootstrap]], чтобы он смог участвовать в процессе [предзагрузки](runtime-bootstrapping.md).
### Создание классов правил <span id="creating-rules"></span>
@ -564,7 +564,7 @@ class CarUrlRule extends BaseObject implements UrlRuleInterface
## Производительность <span id="performance-consideration"></span>
При разработке сложных Веб приложений, важно оптимизировать правила URL так, чтобы разбор запросов и создание URL занимали минимальное время.
При разработке сложных веб-приложений, важно оптимизировать правила URL так, чтобы разбор запросов и создание URL занимали минимальное время.
Использование параметров в маршрутах позволяет уменьшить количество правил, что значительно увеличивает производительность.

6
docs/guide-ru/start-looking-ahead.md

@ -3,8 +3,8 @@
В итоге вы создали полноценное приложение на Yii и узнали, как реализовать некоторые
наиболее часто используемые функции, такие, как получение данных от пользователя
при помощи HTML форм, выборки данных из базы данных и их отображения в разбитом на страницы виде.
Так же вы узнали, как использовать [Gii](https://github.com/yiisoft/yii2-gii/blob/master/docs/guide/README.md) для
при помощи HTML-форм, выборки данных из базы данных и их отображения в разбитом на страницы виде.
Также вы узнали, как использовать [Gii](https://github.com/yiisoft/yii2-gii/blob/master/docs/guide/README.md) для
автоматической генерации кода, что превращает программирование в настолько простую задачу, как простое заполнение
какой-либо формы. В этом разделе мы обобщим ресурсы о Yii, которые помогут вам быть более продуктивным при использовании Yii.
@ -16,7 +16,7 @@
- Описание классов:
определяет использование каждого класса, представленного в Yii.
Им следует пользоваться, когда вы пишете код и хотите разобраться в использовании конкретного класса, метода, свойства.
- Вики статьи:
- Вики-статьи:
написаны пользователями Yii на основе их собственного опыта.
Большинство из них составлены для сборника рецептов, показывая, как решить конкретные проблемы с использованием Yii.
Причём качество этих статей может быть таким же хорошим, как в Подробном руководстве.

24
docs/guide-ru/test-fixtures.md

@ -41,14 +41,14 @@ class UserFixture extends ActiveFixture
> таблицу как через свойство [[yii\test\ActiveFixture::tableName]], так и через свойство [[yii\test\ActiveFixture::modelClass]].
> Если последнее, то в этом случае имя таблицы будет взято из модели `ActiveRecord`, указанной в `modelClass`.
> Note: [[yii\test\ActiveFixture]] используется только для реляционных баз данных. Для NoSQL решений Yii
> Note: [[yii\test\ActiveFixture]] используется только для реляционных баз данных. Для NoSQL-решений Yii
> предоставляет следующие классы `ActiveFixture`:
>
> - Mongo DB: [[yii\mongodb\ActiveFixture]]
> - MongoDB: [[yii\mongodb\ActiveFixture]]
> - Elasticsearch: [[yii\elasticsearch\ActiveFixture]] (начиная с версии 2.0.2)
Данные для фикстуры `ActiveFixture` как правило находятся в файле `FixturePath/data/TableName.php`,
где `FixturePath` указывает на директорию в которой располагается файл класса фикстуры, а `TableName` имя таблицы
Данные для фикстуры `ActiveFixture`, как правило, находятся в файле `FixturePath/data/TableName.php`,
где `FixturePath` указывает на директорию, в которой располагается файл класса фикстуры, а `TableName` на имя таблицы,
с которой она ассоциируется. Для примера выше, данные должны должны быть в файле `@app/tests/fixtures/data/user.php`.
Данный файл должен вернуть массив данных для строк, которые будут вставлены в таблицу пользователей. Например
@ -73,7 +73,7 @@ return [
Вы можете задать псевдоним строке для того, чтобы в будущем вы могли ссылаться на нее в ваших тестах. В примере выше
2 строки имеют псевдонимы `user1` и `user2`, соответственно.
Также вам не нужно указывать данные для столбцов с авто-инкрементом. Yii автоматически заполнит значения данных столбцов
Также вам не нужно указывать данные для столбцов с автоинкрементом. Yii автоматически заполнит значения данных столбцов
в момент загрузки фикстуры.
> Tip: вы можете указать свой путь до файла данных через свойство [[yii\test\ActiveFixture::dataFile]].
@ -99,7 +99,7 @@ class UserProfileFixture extends ActiveFixture
будет автоматически загружена до `UserProfileFixture`, тем самым гарантируя существование всех внешних ключей, и будет выгружена
после того как выгрузится `UserProfileFixture` по тем же причинам.
Выше мы показали как объявить фикстуру для таблицы базы данных. Для объявления фикстуры не связанной с базой данных (например,
Выше мы показали как объявить фикстуру для таблицы базы данных. Для объявления фикстуры, не связанной с базой данных (например,
фикстуры для определенных файлов и директорий), вам следует унаследовать ее от класса [[yii\test\Fixture]]
и переопределить методы [[yii\test\Fixture::load()|load()]] и [[yii\test\Fixture::unload()|unload()]].
@ -179,7 +179,7 @@ foreach ($this->profiles as $row) ...
фикстуры в методе [[yii\codeception\TestCase::globalFixtures()]], а не `fixtures()`. Когда тест-кейс загружает фикстуры, сначала
загружаются глобальные фикстуры, затем все остальные.
По умолчанию, фикстура `InitDbFixture` уже обяъвлена в методе `globalFixtures()` класса [[yii\codeception\DbTestCase]].
По умолчанию фикстура `InitDbFixture` уже обяъвлена в методе `globalFixtures()` класса [[yii\codeception\DbTestCase]].
Это означает, что вы должны работать только с файлом `@app/tests/fixtures/initdb.php`, если вы хотите чтобы перед каждым тестом
выполнялись определенные подготовительные работы. В противном случае вы просто можете сфокусироваться на разработке
конкретных тест-кейсов и соответствующих фикстур.
@ -188,7 +188,7 @@ foreach ($this->profiles as $row) ...
Организация классов фикстур и файлов с данными
----------------------------------------------
По умолчанию, классы фикстур ищут соответствующие файлы данных в директории `data`, которая является подпапкой папки, содержащей
По умолчанию классы фикстур ищут соответствующие файлы данных в директории `data`, которая является подпапкой папки, содержащей
файлы классов фикстур. Вы можете следовать этому соглашению при работе над простыми проектами. Есть вероятность, что на больших
проектах вам потребуется менять набор данных для одного и того же класса фикстур в разных тестах. Таким образом, мы рекомендуем
вам организовать файлы данных иерархически, подобно пространству имен ваших классов. Например,
@ -230,7 +230,7 @@ data\
1. Используйте команду `yii migrate` для обновления тестовой БД до последней версии;
2. Выполнить тест-кейс:
- Загрузка фикстур: очищение соответствующих таблиц БД и заполнение их данными фикстур;
- Загрузка фикстур: очистка соответствующих таблиц БД и заполнение их данными фикстур;
- Выполнение теста;
- Выгрузка фикстур.
3. Повторение шага 2 до тех пор, пока не выполнятся все тесты.
@ -308,7 +308,7 @@ yii fixture/load <fixture_name>
// загрузить фикстуру `User`
yii fixture/load User
// тоже что и выше, т.к. "load" является действие по умолчанию для команды "fixture"
// то же что и выше, т.к. "load" является действие по умолчанию для команды "fixture"
yii fixture User
// загрузить нескольких фикстур
@ -317,7 +317,7 @@ yii fixture "User, UserProfile"
// загрузить все фикстуры
yii fixture/load "*"
// тоже что и выше
// то же что и выше
yii fixture "*"
// загрузить все фикстуры кроме указанной
@ -338,7 +338,7 @@ yii fixture User --globalFixtures='some\name\space\Custom'
Для выгрузки фикстур выполните следующую команду:
```
// выгрузить фикстуру `Users`, по умолчанию будут удалены все данные из таблицы "users", или из коллекции "users" если это фикстура mongodb
// выгрузить фикстуру `Users`, по умолчанию будут удалены все данные из таблицы "users" или из коллекции "users", если это фикстура mongodb
yii fixture/unload User
// выгрузить несколько фикстур

8
docs/guide-ru/tutorial-template-engines.md

@ -1,10 +1,10 @@
Использование шаблонизаторов
======================
По умолчанию, Yii использует PHP в шаблонах, но вы можете настроить Yii на поддержку других шаблонизаторов,таких как
По умолчанию, Yii использует PHP в шаблонах, но вы можете настроить Yii на поддержку других шаблонизаторов, таких как
[Twig](http://twig.sensiolabs.org/) или [Smarty](http://www.smarty.net/), которые доступны в расширениях.
`view` компонент, отвественный за генерацию видов. Вы можете добавить шаблонизатор, с помощью перенастройки поведения компонента:
Компонент `view`, отвественный за генерацию видов. Вы можете добавить шаблонизатор с помощью перенастройки поведения компонента:
```php
[
@ -19,7 +19,7 @@
'twig' => [
'class' => 'yii\twig\ViewRenderer',
'cachePath' => '@runtime/Twig/cache',
// Array of twig options:
// Массив опций twig:
'options' => [
'auto_reload' => true,
],
@ -44,4 +44,4 @@
Для получения подробной информации об использовании конкретного шаблонизатора обратитесь в их документации:
- [Twig guide](https://github.com/yiisoft/yii2-twig/tree/master/docs/guide)
- [Smarty guide](https://github.com/yiisoft/yii2-smarty/tree/master/docs/guide)
- [Smarty guide](https://github.com/yiisoft/yii2-smarty/tree/master/docs/guide)

4
docs/guide-ru/tutorial-yii-as-micro-framework.md

@ -188,8 +188,8 @@ class PostController extends ActiveController
- `/index.php?r=post` - список всех сообщений
- `/index.php?r=post/view&id=1` - просмотр сообщения с ID 1
- `/index.php?r=post/create` - создание сообщения
- `/index.php?r=post/update&id=1` - обновление сообщения with ID 1
- `/index.php?r=post/delete&id=1` - удаление сообщения with ID 1
- `/index.php?r=post/update&id=1` - обновление сообщения с ID 1
- `/index.php?r=post/delete&id=1` - удаление сообщения с ID 1
Начиная с этого момента Вы можете посмотреть следующие руководства для дальнейшего развития своего приложения:

119
docs/guide-vi/structure-application-components.md

@ -0,0 +1,119 @@
Các thành phần ứng dụng
======================
Mỗi ứng dụng là hiện thực của [mẫu thiết kế Service Locators](concept-service-locator.md). Mỗi ứng dụng sẽ chứa các thành phần
được gọi là *thành phần ứng dụng* giúp cung cấp các dịch vụ cho các tiến trình xử lý. Chẳng hạn,
thành phần `urlManager` đảm nhiệm chức năng cho bộ định tuyến cho các yêu cầu xử lý tới các bộ điều khiển;
thành phần `db` cung cấp các dịch vụ để giao tiếp với cơ sở dữ liệu (CSDL); và các thành phần khác.
Mỗi thành phần ứng dụng đều có một định danh ID giúp xác định thành phần duy nhất trong cùng một ứng dụng
. Bạn có thể truy cập vào các thành phần ứng dụng qua câu lệnh sau.
```php
\Yii::$app->componentID
```
Ví dụ, sử dụng câu lệnh `\Yii::$app->db` để lấy thông tin [[yii\db\Connection|kết nối tới CSDL]],
và câu lệnh `\Yii::$app->cache` để lấy thông tin [[yii\caching\Cache|primary cache]] đã đăng ký trong ứng dụng.
Mỗi thành phần ứng dụng được tạo một lần và được truy cập trong ứng dụng. Và có bất kỳ sự truy cập nào
sau đó đều trả về cùng một thể hiện của thành phần đó.
Bất kỳ đối tượng nào cũng có thể là thành phần ứng dụng. Bạn có thể đăng ký chúng bằng việc thiết lập các
thuộc tính [[yii\base\Application::components]] vào trong [mục cấu hình ứng dụng](structure-applications.md#application-configurations).
Ví dụ,
```php
[
'components' => [
// Dung class để đăng ký thành phần "cache"
'cache' => 'yii\caching\ApcCache',
// Dùng mảng các tham số để đăng ký thành phần "db"
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=demo',
'username' => 'root',
'password' => '',
],
// Dùng hàm để đăng ký thành phần "search"
'search' => function () {
return new app\components\SolrService;
},
],
]
```
> Lưu ý: Bạn cần đăng ký các thành phần ứng dụng một cách cẩn thận.
Các thành phần ứng dụng cũng như các biến có phạm vi toàn cục. Sử dụng quá nhiều các thành phần ứng dụng có thể khiến mã nguồn
khó kiểm tra và bảo trì. Cách tốt nhất, bạn nên khởi tạo các thành phần ở phạm vi cục bộ
và khi cần thiết có thể thêm vào ứng dụng.
## Thành phần tải tự động (Bootstrapping) <span id="bootstrapping-components"></span>
Như đề cập ở trên, các thành phần ứng dụng chỉ được khởi tạo khi nó được truy cập vào lần đầu tiên.
Nếu thành phần không được truy cập tại các yêu cầu xử lý, thì sẽ không được khởi tạo. Tuy vậy , thỉnh thoảng, các thành phần ứng dụng
có thể được khởi tạo ở mỗi yêu cầu, thậm chí nó không được truy cập.
Để làm được như vậy, bạn cần liệt kê các định danh vào trong thuộc tinh [[yii\base\Application::bootstrap|bootstrap]] của ứng dụng application.
Ví dụ, thông tin cấu hình sau sẽ chắc chắn rằng thành phần `log` luôn luôn được tải:
```php
[
'bootstrap' => [
'log',
],
'components' => [
'log' => [
// Các thiết lập cho thành phần "log"
],
],
]
```
## Các thành phần ứng dụng chính <span id="core-application-components"></span>
Yii định nghĩa danh sách các thành phần ứng dụng chính cùng với nó là các định danh và thông tin cấu hình. Ví dụ,
thành phần [[yii\web\Application::request|request]] được dùng để lấy thông tin về các yêu cầu từ user
và xác minh rồi gửi tới các [bộ định tuyến (route)](runtime-routing.md); thành phần [[yii\base\Application::db|db]]
có chức năng thiết lập các kết nối và thông qua đó bạn có thể thực hiện các truy vấn vào CSDL.
Như vậy, các thành phần ứng dụng sẽ giúp ứng dụng Yii tiếp nhận các yêu cầu từ user.
Phần dưới là danh sách các thành phần ứng dụng chính được xác định trước. Bạn cần phải cấu hình và tùy biến chúng
như những thành phần ứng dụng khác. Mỗi khi bạn cấu hình các thành phần này,
nếu bạn không xác định các class, thì giá trị mặc định sẽ được dùng.
* [[yii\web\AssetManager|assetManager]]: quản lý các file tài nguyên (asset) được đóng gói và chia sẽ.
Tham khảo thêm mục [Quản lý các file tài nguyên](structure-assets.md) để biết thêm chi tiết.
* [[yii\db\Connection|db]]: thực hiện kết nối CSDL và dựa vào thành phần có thể thực hiện các câu lệnh truy vấn dữ liệu.
Lưu ý, khi bạn thiết lập thành phần này, bạn cần phải cung cấp các thông tin về các thuộc tính được yêu cầu
, như [[yii\db\Connection::dsn]].
Tham khảo thêm tại mục [Data Access Objects](db-dao.md) để biết thêm thông tin.
* [[yii\base\Application::errorHandler|errorHandler]]: nắm giữ các ngoại lệ và lỗi của PHP.
Tham khảo thêm mục [Bắt lỗi](runtime-handling-errors.md) để biết thêm thông tin.
* [[yii\i18n\Formatter|formatter]]: định dạng dữ liệu mỗi khi gửi tới user. Ví dụ, các số có thể được
hiển thị cùng với các dấu ngăn cách phần ngàn, ngày có thể được định dạng ở dạng ngày dài.
Tham khảo thêm tại mục [Định dạng dữ liệu](output-formatting.md) để biết thêm thông tin.
* [[yii\i18n\I18N|i18n]]: hỗ trợ định dạng và dịch đa ngôn ngữ.
Tham khảo thêm tại mục [Internationalization](tutorial-i18n.md) để biết thêm thông tin.
* [[yii\log\Dispatcher|log]]: quản lý mục log.
Tham khảo thêm tại mục [Logging](runtime-logging.md) để biết thêm thông tin.
* [[yii\swiftmailer\Mailer|mail]]: hỗ trợ soạn thảo và gửi email.
Tham khảo thêm tại mục [Mailing](tutorial-mailing.md) để biết thêm thông tin..
* [[yii\base\Application::response|response]]: represents the response being sent to end users.
Tham khảo thêm tại mục [Responses](runtime-responses.md) để biết thêm thông tin..
* [[yii\base\Application::request|request]]: tiếp nhận các yêu cầu từ user.
Tham khảo thêm tại mục [Requests](runtime-requests.md) để biết thêm thông tin..
* [[yii\web\Session|session]]: quản lý các phiên (session). Thành phần này chỉ được kích hoạt với
[[yii\web\Application|Ứng dụng Web]].
Tham khảo thêm tại mục [Sessions and Cookies](runtime-sessions-cookies.md) để biết thêm thông tin..
* [[yii\web\UrlManager|urlManager]]: xử lý thông tin về URL.
Tham khảo thêm tại mục [URL Parsing and Generation](runtime-routing.md) để biết thêm thông tin..
* [[yii\web\User|user]]: giúp xác thực người dùng. Thành phần này chỉ được kích hoạt với
[[yii\web\Application|Ứng dụng Web]]
Tham khảo thêm tại mục [Xác thực (Authentication)](security-authentication.md) để biết thêm thông tin..
* [[yii\web\View|view]]: hỗ trợ giao diện.
Tham khảo thêm tại mục[Views](structure-views.md) để biết thêm thông tin..

607
docs/guide-vi/structure-applications.md

@ -0,0 +1,607 @@
Ứng dụng
============
Mỗi ứng dụng là một đối tượng giúp quản lý tổng thể cấu trúc và vòng đời của ứng dụng Yii.
Mỗi ứng dụng Yii đều chứa một đối tượng ứng dụng, đối tượng này được khởi tạo tại mục
[entry script](structure-entry-scripts.md) và đồng thời được truy cập qua biểu thức `\Yii::$app`.
> Gợi ý: Phụ thuộc vào từng ngữ cảnh, có khi chúng ta gọi là "một application", có nghĩa là một đối tượng ứng dụng
hoặc một hệ thống ứng dụng.
Có 2 kiểu ứng dụng: [[yii\web\Application|Ứng dụng Web]] và
[[yii\console\Application|ứng dụng giao diện dòng lệnh]]. Tương tự như vậy, ứng dụng Web xử lý với các yêu cầu về Web,
, ứng dụng còn lại sẽ xử lý với các yêu cầu ở giao diện dòng lệnh.
## Cấu hình ứng dụng <span id="application-configurations"></span>
Mỗi khi [entry script](structure-entry-scripts.md) tạo ứng dụng mới, nó sẽ tải thêm thông tin về
[cấu hình](concept-configurations.md) và gán vào trong ứng dụng, như sau:
```php
require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
// tải các cấu hình ứng dụng
$config = require(__DIR__ . '/../config/web.php');
// gán cấu hình và khởi tạo ứng dụng
(new yii\web\Application($config))->run();
```
Thông thường việc [cấu hình](concept-configurations.md), ứng dụng sẽ xác định làm thế nào để
khởi tạo các thuộc tính và đối tượng ứng dụng. Do việc cấu hình ứng dụng khá phức tạp nên vậy
, chúng thường được lưu giữ tại [các file cấu hình](concept-configurations.md#configuration-files),
như file `web.php` ở ví dụ trên.
## Các thuộc tính của ứng dụng <span id="application-properties"></span>
Có nhiều thuộc tính quan trọng mà bạn cần phải cấu hình trong ứng dụng. Những thuộc tính này
thường được mô tả về môi trường mà ứng dụng đang chạy. Chẳng hạn, ứng dụng cần biết làm thế nào để tải các [controllers](structure-controllers.md),
nơi lưu trữ các file tạm, vv. Trong phần dưới này, chúng ta sẽ tổng hợp thông tin về thuộc tính.
### Thuộc tính bắt buộc <span id="required-properties"></span>
Ở mỗi ứng dụng, bạn cần cấu hình ít nhất 2 thuộc tính là: [[yii\base\Application::id|id]]
và [[yii\base\Application::basePath|basePath]].
#### [[yii\base\Application::id|id]] <span id="id"></span>
Thuộc tính [[yii\base\Application::id|id]] giúp đặc tả một định danh ID để phân biệt với các ứng dụng khác
. Thuộc tính chủ yếu được sử dụng trong chương trình. Mặc dù nó không được yêu cầu, để thích hợp cho khả năng tương tác
nên chỉ sử dụng các chữ cái chữ số khi mô tả một định danh của ứng dụng.
#### [[yii\base\Application::basePath|basePath]] <span id="basePath"></span>
Thuộc tính [[yii\base\Application::basePath|basePath]] dùng để mô tả thư mục gốc của ứng dụng.
Nó là thư mục chứa tất cả mã nguồn của ứng dụng. Bên trong thư mục,
bạn sẽ thấy các thư mục con như `models`, `views`, và `controllers`, các thư mục con này chứa các mã nguồn
tương ứng với các thành phần trong mô hình MVC.
Bạn phải cấu hình thuộc tính [[yii\base\Application::basePath|basePath]] bằng sử dụng các đường dẫn trực tiếp
hoặc [một bí danh](concept-aliases.md). Trong các trường hợp, các thư mục tương ứng phải tồn tại, nếu không sẽ phát sinh ra lỗi
. Đường dẫn trực tiếp được lấy qua việc gọi hàm `realpath()` .
Thuộc tính [[yii\base\Application::basePath|basePath]] thường được dùng để lấy được các đường dẫn quan trọng khác
(vd đường dẫn dành cho thực thi). Vì vậy, bí danh `@app` được xác định là đường dẫn gốc
. Các đường dẫn trong ứng dụng được lấy từ bí danh (vd `@app/runtime` tương ứng tới đường dẫn mục runtime).
### Các thuộc tính quan trọng <span id="important-properties"></span>
Các thuộc tính được mô tả trong phần này thường cần được cấu hình bởi vì mỗi ứng dụng có
các thuộc tính khác nhau.
#### [[yii\base\Application::aliases|aliases]] <span id="aliases"></span>
Thuộc tính cho phép khai báo các [bí danh(aliases)](concept-aliases.md) vào trong một mảng.
Các khóa lưu trữ tên bí danh, và giá trị trong mảng tương ứng với đường dẫn được khai báo.
Ví dụ:
```php
[
'aliases' => [
'@name1' => 'path/to/path1',
'@name2' => 'path/to/path2',
],
]
```
Thuộc tính này được cung cấp cho bạn việc khai báo các bí danh trong cấu hình ứng dụng thay vì gọi phương thức
[[Yii::setAlias()]].
#### [[yii\base\Application::bootstrap|bootstrap]] <span id="bootstrap"></span>
Thuộc tính này khá quan trọng. Nó cung cấp cho bạn thông tin về mảng các thành phần (components) mà cần được
chạy trong suốt chu trình ứng dụng [[yii\base\Application::bootstrap()|bootstrapping process]].
Ví dụ, nếu bạn muốn một [module](structure-modules.md) dùng để tùy biến các [URL](runtime-routing.md),
bạn có thể tùy biến các ID như phần tử trong các thuộc tính.
Mỗi thành phần được liệt kê ra có thể khai báo một trong các định dạng sau:
- một đinh danh về thành phần được tuân thủ qua [components](#components),
- một định danh về module tuân thủ theo quy định về [modules](#modules),
- một tên class,
- một mảng các cấu hình,
- một hàm dùng để khởi tạo và trả về một thành phần.
Ví dụ:
```php
[
'bootstrap' => [
// một định danh về thành phần hoặc module
'demo',
// tên class
'app\components\Profiler',
// mảng cấu hình
[
'class' => 'app\components\Profiler',
'level' => 3,
],
// hàm trả về một thành phần
function () {
return new app\components\Profiler();
}
],
]
```
> Lưu ý: Nếu định danh của module trùng với định danh của thành phần , ứng dụng sẽ sử dụng
> trong suốt tiền trình xử lý. Nếu bạn muốn chỉ sử dụng mỗi module, bạn cần lấy nó ở một hàm khác
> như sau:
>
> ```php
> [
> function () {
> return Yii::$app->getModule('user');
> },
> ]
> ```
Trong suốt quá trình xử lý, mỗi thành phần sẽ được khởi tạo. nếu lớp thành phần được hiện thực từ giao diện
[[yii\base\BootstrapInterface]], thì phương thức [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]]
sẽ đồng thời được gọi.
Một ví dụ khác trong việc cấu hình ứng dụng trong [Mẫu Basic Project](start-installation.md),
module `debug``gii` được cấu hình như những thành phần khi ứng dụng khởi chạy
ở môi trường phát triển:
```php
if (YII_ENV_DEV) {
// cấu hình được thiết lập trong môi trường phát triển 'dev'
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = 'yii\gii\Module';
}
```
> Lưu ý: Việc đưa quá nhiều các thành phần vào `bootstrap` sẽ làm giảm hiệu năng trong ứng dụng, bởi vì
mỗi khi có yêu cầu, các thành phần sẽ được chạy. Vì vậy việc sử dụng các thành phần cần sử dụng một cách khôn ngoan.
#### [[yii\web\Application::catchAll|catchAll]] <span id="catchAll"></span>
Thuộc tính này chỉ được hỗ trợ với [[yii\web\Application| ứng dụng Web]]. Nó mô tả một
[hành động](structure-controllers.md) và nhận xử lý mọi yêu cầu. Thường được sử dụng mỗi khi
ứng dụng đang ở chế độ bảo trì và cần xử lý mọi yêu cầu được gửi tới.
Thông tin được cấu hình bao gồm mảng và chứa thông tin về router và action.
Các thông tin mô tả các tham số (thông tin khóa-giá trị) để giới hạn các action. Ví dụ:
```php
[
'catchAll' => [
'offline/notice',
'param1' => 'value1',
'param2' => 'value2',
],
]
```
#### [[yii\base\Application::components|components]] <span id="components"></span>
Đây là thuộc tính quan trọng nhất. Nó cho phép đăng ký danh sách cách component để sử dụng ở các mục khác
được gọi là [application components](structure-application-components.md). Ví dụ:
```php
[
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
],
],
]
```
Mỗi thành phần ứng dụng đều xác định một mảng các thông tin chứa cặp key-value. Giá trị key đại diện cho định danh của thành phần,
trong khi đó value đại diện cho tên class hoặc thông tin về [cấu hình](concept-configurations.md).
Bạn có thể đăng ký bất kỳ thành phần nào vào ứng dụng, và các thành phần có thể truy cập ở phạm vi toàn cục
qua biểu thức `\Yii::$app->componentID`.
Xem thêm mục [Application Components](structure-application-components.md) để biết thêm thông tin.
#### [[yii\base\Application::controllerMap|controllerMap]] <span id="controllerMap"></span>
Thuộc tính này cho phép liên kết tới một định danh (ID) tới lớp của trình điều khiển. Mặc định, Yii sẽ liên kết
ID tới các lớp của trình điều khiển dựa trên [các nguyên tắc](#controllerNamespace) (chẳng hạn định danh ID của trình điều khiển `post` sẽ liên kết
tới lớp `app\controllers\PostController`). Bằng việc cấu hình những thuộc tính này, bạn có thay đổi các nguyên tắc này cho các trình điều khiển cụ thể
. Trong ví dụ sau, `account` sẽ được liên kết tới class
`app\controllers\UserController`, trong khi đó `article` sẽ liên kết tới class `app\controllers\PostController`.
```php
[
'controllerMap' => [
[
'account' => 'app\controllers\UserController',
'article' => [
'class' => 'app\controllers\PostController',
'enableCsrfValidation' => false,
],
],
],
]
```
Danh sách khóa của các thuộc tính trên đại diện cho ID của trình điều khiển, giá trị của mỗi khóa sẽ đại diện về thông tin
tên class của trình điều khiển hoặc [các thông tin về cấu hình](concept-configurations.md).
#### [[yii\base\Application::controllerNamespace|controllerNamespace]] <span id="controllerNamespace"></span>
Thuộc tính này xác định các thông tin tên lớp mặc định của trình điều khiển. Mặc định là
`app\controllers`. Nếu ID của trình điều khiển là `post`, theo quy ước thì tên class của trình điều khiển (không bao gồm
không gian tên) sẽ là `PostController`, và tên lớp đầy đủ sẽ là `app\controllers\PostController`.
Các lớp trình điều khiển thường được lưu trữ ở thư mục con của thư mục chính các không gian tên.
Chẳng hạn, với ID của trình điều khiển `admin/post`, tương ứng với tên lớp đầy đủ sẽ là
`app\controllers\admin\PostController`.
Điều này khá quan trọng vì các lớp điều khiển có thể được [tải tự động](concept-autoloading.md)
và các không gian tên của các lớp điều khiển sẽ khớp với giá trị của các thuộc tính. Nếu không thì,
bạn sẽ nhận thông báo lỗi "Không tìm thấy trang" khi truy cập vào ứng dụng.
Trong trường hợp khác, nếu bạn muốn bỏ các quy ước này như mổ tả ở trên, bạn có thể tùy chỉnh lại các thuộc tính trong phần [controllerMap](#controllerMap).
#### [[yii\base\Application::language|language]] <span id="language"></span>
Thuộc tính này mô tả thông tin về ngôn ngữ trong mỗi ứng dụng và nội dung được hiển thị tới user.
Giá trị mặc định của thuộc tính là `en`, có nghĩa là tiếng Anh. Bạn có thể tùy chỉnh thuộc tính này
rằng nếu ứng dụng của bạn hỗ trợ đa ngôn ngữ .
Giá trị của thuộc tính được xác định theo chuẩn [quốc tế hóa](tutorial-i18n.md),
bao gồm các thông tin, định dạng ngày giờ, số, vv. Ví dụ, widget [[yii\jui\DatePicker]]
sẽ sử dụng các giá trị thuộc tính qua việc xác định ngôn ngữ nào cần được hiển thị và định dạng ngày giờ như thế nào.
Khuyến khích bạn xác định các ngôn ngữ dựa theo [IETF language tag](http://en.wikipedia.org/wiki/IETF_language_tag).
Ví dụ, `en` là chuẩn cho tiếng anh, trong khi đó `en-US` chuẩn cho tiếng anh ở Mỹ (United States).
Xem thêm thông tin về thuộc tính này tại mục [Internationalization](tutorial-i18n.md).
#### [[yii\base\Application::modules|modules]] <span id="modules"></span>
Thuộc tính này mô tả các thông tin về [modules](structure-modules.md) được chứa trong ứng dụng.
Thuộc tính này chứa mảng các lớp về module hoặc thông tin về [cấu hình](concept-configurations.md) chứa mảng các khóa
về các định danh của module. Ví dụ:
```php
[
'modules' => [
// "booking" mô tả tên class
'booking' => 'app\modules\booking\BookingModule',
// "comment" được mô tả với mảng cấu hình
'comment' => [
'class' => 'app\modules\comment\CommentModule',
'db' => 'db',
],
],
]
```
Tham khảo thêm ở phần [Modules](structure-modules.md) để biết thêm thông tin.
#### [[yii\base\Application::name|name]] <span id="name"></span>
Thuộc tính này mô tả tên của ứng dụng và hiển thị tới user. Khác với thuộc tính
[[yii\base\Application::id|id]], cần phải là tên duy nhất, thì thuộc tính này dùng với mục đích để hiển thị tới user;
không cần thiết phải là tên duy nhất.
Nếu trong mã nguồn bạn không cần phải dùng tới nó thì bạn không cần phải thiết lập.
#### [[yii\base\Application::params|params]] <span id="params"></span>
Thuộc tính này là mảng chứa các tham số mà có thể truy cập trong ứng dụng ở phạm vi toàn cầu. Thay vì trong mã
nguồn của bạn cần được mã hóa bởi số và ký tự, đây là cách tốt để định nghĩa các tham số của ứng dụng, định nghĩa một lần
và có thể được truy cập ở mọi nơi. Ví dụ, bạn có thể định nghĩa kích thước ảnh thumbnail
với kích thước như sau:
```php
[
'params' => [
'thumbnail.size' => [128, 128],
],
]
```
Bạn có thể thực hiện dòng lệnh sau để lấy tham số về kích thước ảnh thumbnail:
```php
$size = \Yii::$app->params['thumbnail.size'];
$width = \Yii::$app->params['thumbnail.size'][0];
```
Bạn có thể thay đổi kích thước ảnh thumbnail sau đó, bạn chỉ cần thay đổi vào trong mục cấu hình ứng dụng;
bạn không cần phải đụng chạm vào mã nguồn của bạn.
#### [[yii\base\Application::sourceLanguage|sourceLanguage]] <span id="sourceLanguage"></span>
Thuộc tính mô tả về ngôn ngữ được sử dụng để viết mã nguồn của bạn. Giá trị mặc đinh là `'en-US'`,
nghĩa là tiếng Anh Mỹ(United States). Bạn nên cấu hình thuộc tính này nếu nội dung trong mã nguồn của bạn không phải là tiếng Anh.
Giống như thuộc tính [language](#language), you should configure this property in terms of
an [IETF language tag](http://en.wikipedia.org/wiki/IETF_language_tag). Ví dụ, `en` chuẩn cho tiếng Anh,
trong khi `en-US` chuẩn cho tiếng Anh Mỹ (United States).
Xem thêm trong phần [Quốc tế hóa](tutorial-i18n.md) để hiểu thêm thuộc tính này.
#### [[yii\base\Application::timeZone|timeZone]] <span id="timeZone"></span>
Thuộc tính này cung cấp cách khác để thiết lập time zone trong PHP.
Qua việc cấu hình thuộc tính này, chủ yếu được gọi qua hàm
[date_default_timezone_set()](http://php.net/manual/en/function.date-default-timezone-set.php). Ví dụ:
```php
[
'timeZone' => 'America/Los_Angeles',
]
```
#### [[yii\base\Application::version|version]] <span id="version"></span>
Thuộc tính mô tả về phiên bản của ứng dụng. Mặc định là `'1.0'`. Bạn không cần phải thiết lập thuộc tính này nếu như
trong mã nguồn của bạn không dùng tới.
### Các thuộc tính thông dụng <span id="useful-properties"></span>
Những thuộc tính được mô tả trong phần dưới thường có sự cấu hình khác nhau bởi vì các giá trị thường khác nhau
. Tuy nhiên, nêu bạn muốn thay đổi giá trị mặc định, bạn có thể cấu hình theo cách của bạn.
#### [[yii\base\Application::charset|charset]] <span id="charset"></span>
Thuộc tính này mô tả các bộ ký tự mà ứng dụng sử dụng. Mặc định là `'UTF-8'`, hầu hết các ứng dụng đều sử dụng.
#### [[yii\base\Application::defaultRoute|defaultRoute]] <span id="defaultRoute"></span>
Thuộc tính này mô tả các [route](runtime-routing.md), ứng dụng sẽ dùng route này để thực hiện khi có yêu cầu
gửi đến mà không được mô tả. Mỗi router gồm có các module ID, a controller ID, hoặc có thể là một action ID.
Ví dụ, `help`, `post/create`, hoặc `admin/post/create`. Nếu action ID không khai báo, thuộc tính sẽ lấy giá trị mặc định
được mô tả trong [[yii\base\Controller::defaultAction]].
Đối với [[yii\web\Application| Ứng dụng Web ]], giá trị mặc định của thuộc tính là `'site'`, nghĩa là
trình điều khiển `SiteController` được gọi và một hành động mặc định được sử dụng. Như vậy, nếu bạn
truy cập vào ứng dụng mà không cung cấp thông tin route, thì ứng dụng mặc định sẽ trả về hành động `app\controllers\SiteController::actionIndex()`.
Đối với [[yii\console\Application| Ứng dụng console]], thì giá trị mặc định là `'help'`, đồng nghĩa hành động
[[yii\console\controllers\HelpController::actionIndex()]] sẽ được gọi. Như vậy, nếu bạn chạy dòng lệnh `yii`
mà không cung cấp các tham số nào khác, thì nó sẽ hiển thị lên màn hình trợ giúp tương ứng kết quả của action index của trình điều khiển HelpController.
#### [[yii\base\Application::extensions|extensions]] <span id="extensions"></span>
Thuộc tính này mô tả về danh sách các [thành phần mở rộng (extensions)](structure-extensions.md) đã được cài và sử dụng trong ứng dụng.
Mặc định, thuộc tính sẽ nhận mảng được trả về từ file `@vendor/yiisoft/extensions.php`. File `extensions.php`
được sinh tự động khi bạn sử dụng [Composer](https://getcomposer.org) để cài các thành phần mở rộng.
Ở các trường hợp này, thuộc tính này có thể không cần cấu hình.
Trong trường hợp, khi bạn muốn cấu hình các extension một cách thủ công, bạn có thể cấu hình thuộc tính như sau:
```php
[
'extensions' => [
[
'name' => 'tên extension',
'version' => 'phiên bản',
'bootstrap' => 'BootstrapClassName', // mặc định, giá trị thường là mảng
'alias' => [ // mặc định
'@alias1' => 'to/path1',
'@alias2' => 'to/path2',
],
],
// ... các extensions khác ...
],
]
```
Như bạn thấy ở phần trên, thuộc tính sẽ nhận thông tin bao gồm mảng các cấu hình. Mỗi extension được mô tả là mảng
bao gồm các thành phần là`name` và `version`. Nêu muốn extension cần được chạy ở tiến trình [bootstrap](runtime-bootstrapping.md)
, mỗi `bootstrap` cần được mô tả về tên lớp hoặc mảng giá trị về [cấu hình](concept-configurations.md)
. Mỗi extension có thể định nghĩa thêm các [bí danh (aliases)](concept-aliases.md).
#### [[yii\base\Application::layout|layout]] <span id="layout"></span>
Thuộc tính này mô tả vê layout mặc định được dùng mỗi khi render dữ liệu ra [view](structure-views.md).
Giá trị mặc định là `'main'`, nghĩa là file `main.php` nằm trong [đường dẫn layout](#layoutPath) được dùng.
Nếu giá trị [layout path](#layoutPath) và [view path](#viewPath) nhận giá trị là mặc định,
giá trị mặc định của file layout có thể được thay thế qua bí danh `@app/views/layouts/main.php`.
Bạn có thể cấu hình thuộc tính với giá trị `false` nếu bạn muốn tắt giá trị mặc định của layout.
#### [[yii\base\Application::layoutPath|layoutPath]] <span id="layoutPath"></span>
Thuộc tính mô tả đường dẫn nơi lưu trữ file layout. Giá trị mặc định sẽ là
`layouts` thư mục con nằm trong [đường dẫn view](#viewPath). Nếu [đường dẫn view](#viewPath) nhận giá trị mặc định
, giá trị mặc định tới đường dẫn layout được thay thế như một đường dẫn của bí danh `@app/views/layouts`.
Bạn có thể cấu hình như đường dẫn hoặc một [bí danh](concept-aliases.md).
#### [[yii\base\Application::runtimePath|runtimePath]] <span id="runtimePath"></span>
Đường dẫn chứa đường dẫn tới các file tạm của ứng dụng, như file log và cache, cần được tạo ra.
Giá trị mặc định của đường dẫn có thể lấy qua bí danh `@app/runtime`.
Bạn có thể cấu hình thuộc tính với đường dẫn hoặc một [bí danh](concept-aliases.md). Đường dẫn này cần được quyền ghi đè lên
trong quá trình ứng dụng được chạy. Và user không thể truy cập vào đường dẫn
, bởi vì các tập tin này có thể chứa các thông tin nhạy cảm.
Yii cung cấp cách đơn giản nhất để truy cập vào đường dẫn này qua bí danh là `@runtime`.
#### [[yii\base\Application::viewPath|viewPath]] <span id="viewPath"></span>
Thuộc tính này chỉ định thư mục để lưu trữ những file view trong mô hình MVC. Giá trị mặc định là
là một bí danh `@app/views`. Bạn có thể cấu hình nó với thư mục hoặc đường dẫn [alias](concept-aliases.md).
#### [[yii\base\Application::vendorPath|vendorPath]] <span id="vendorPath"></span>
Thuộc tính này quy định cụ thể về thư mục được quản lý bởi [Composer](https://getcomposer.org). Thư mục này chứa các thư viện
được cung cấp bởi nhà phát triển và được dùng trong ứng dụng, bao gồm Yii framework. Giá trị mặc định là
một thư mục được cung cấp bởi bí danh `@app/vendor`.
Thuộc tính có thể được cấu hình là thư mục hoặc là đường dẫn [alias](concept-aliases.md). Mỗi khi bạn thay đổi thuộc tính này
, bạn cần phải thay đổi thông tin cấu hình Composer cho phù hợp.
Yii cung cấp cách thức đơn giản để truy cập vào đường dẫn này qua bí danh là `@vendor`.
#### [[yii\console\Application::enableCoreCommands|enableCoreCommands]] <span id="enableCoreCommands"></span>
Thuộc tính này chỉ được hỗ trợ bởi [[yii\console\Application|ứng dụng console]]. Nó được xác định
vị trí các dòng lệnh được kích hoạt lên trong phiên bản Yii. Giá trị mặc định là `true`.
## Sự kiện <span id="application-events"></span>
Ứng dụng trong chu trình hoạt động sẽ gán một vài sự kiện để nắm bắt các yêu cầu. Bạn cần liên kết tới các sự kiện
vào trong ứng dụng như sau:
```php
[
'on beforeRequest' => function ($event) {
// ...
},
]
```
Các mô tả về cú pháp của các sự kiện `on eventName` được mô tả ở trong mục [Cấu hình](concept-configurations.md#configuration-format).
Cách khác, bạn có thể nắm bắt các sự kiện tại [tiến trình bootstrapping](runtime-bootstrapping.md)
mỗi khi ứng dụng được khởi tạo. Ví dụ:
```php
\Yii::$app->on(\yii\base\Application::EVENT_BEFORE_REQUEST, function ($event) {
// ...
});
```
### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] <span id="beforeRequest"></span>
Sự kiện được gán *trước lúc* ứng dụng nhận các yêu cầu. Tên sự kiện gọi là `beforeRequest`.
Mỗi nắm bắt được sự kiện, ứng dụng sẽ tải các thông tin cấu hình và khởi tạo. So it is a good place
to insert your custom code via the event mechanism to intercept the request handling process. For example,
in the event handler, you may dynamically set the [[yii\base\Application::language]] property based on some parameters.
### [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]] <span id="afterRequest"></span>
Sự kiện được gán *sau khi* ứng dụng hoàn thành việc xử lý *trước lúc* đưa phản hồi.
Tên sự kiện là `afterRequest`.
Mỗi khi sự kiện được gán, việc nắm giữ yêu cầu xử lý thành công thì bạn có thể xử lý sau đó
các thông tin về yêu cầu xử lý hoặc nội dung phản hồi.
Lưu ý rằng thành phần [[yii\web\Response|response]] luôn được gán một vài sự kiện mỗi lúc gửi nội dung
tới user. Những sự kiện được gán *sau* sự kiện này là.
### [[yii\base\Application::EVENT_BEFORE_ACTION|EVENT_BEFORE_ACTION]] <span id="beforeAction"></span>
Sự kiện sẽ được gán *trước* khi thực hiện chạy một [hành động](structure-controllers.md).
Tên sự kiện là `beforeAction`.
Các tham số của sự kiện được khởi tạo từ [[yii\base\ActionEvent]]. Các sự kiện cần thiết lập thuộc tính
[[yii\base\ActionEvent::isValid]] về giá trị `false` để tạm ngưng hành động.
Ví dụ:
```php
[
'on beforeAction' => function ($event) {
if (some condition) {
$event->isValid = false;
} else {
}
},
]
```
Lưu ý, có một sự kiện tương tự `beforeAction` được gán bởi [modules](structure-modules.md)
và [controllers](structure-controllers.md). Ứng dụng sẽ nắm bắt sự kiện này trước
, tiếp sau đó bởi modules (nếu có), và cuối cùng là trình điều khiển. Nếu sự kiện đều thiết lập tham số
[[yii\base\ActionEvent::isValid]] là `false`, tất cả các yêu cầu nằm trong sự kiện sẽ không được nắm giữ.
### [[yii\base\Application::EVENT_AFTER_ACTION|EVENT_AFTER_ACTION]] <span id="afterAction"></span>
Tương tự, sự kiện này được gán *sau khi* khởi chạy một [hành động](structure-controllers.md).
Tên sự kiện là `afterAction`.
Các tham số của sự kiện được khởi tạo từ [[yii\base\ActionEvent]]. Xem thuộc tính
[[yii\base\ActionEvent::result]], sự kiện này có thể truy cập hoặc chỉnh sửa kết quả trả về.
Chẳng hạn:
```php
[
'on afterAction' => function ($event) {
if (điều kiện) {
// thay đổi kết quả $event->result
} else {
}
},
]
```
Lưu ý rằng với sự kiện `afterAction` được gán bởi [modules](structure-modules.md)
và [controllers](structure-controllers.md). Những đối tượng được gán vào trong sự kiện này được ưu tiên ngược lại
như sự kiện `beforeAction`. Đó là, trình điều khiển sẽ nắm giữ trước,
tiếp đến là module modules (nếu có), và cuối cùng là ứng dụng.
## Vòng đời ứng dụng <span id="application-lifecycle"></span>
![Vòng đời ứng dụng](images/application-lifecycle.png)
Khi một [entry script](structure-entry-scripts.md) được gọi và nắm giữ các yêu cầu,
vòng đời của ứng dụng sẽ được thực hiện như sau:
1. Entry script sẽ tải các thông tin cấu hình trong ứng dụng ra một mảng.
2. Entry script sẽ khởi tạo mới một ứng dụng:
* Phương thức [[yii\base\Application::preInit()|preInit()]] sẽ được gọi, nhằm tải các thông tin cấu hình mà có sự ưu tiên cao
, như thuộc tính [[yii\base\Application::basePath|basePath]].
* Đăng ký một [[yii\base\Application::errorHandler|error handler]].
* Cấu hình các thuộc tính trong ứng dụng.
* Phương thức [[yii\base\Application::init()|init()]] sẽ được gọi và phương thức
[[yii\base\Application::bootstrap()|bootstrap()]] sẽ tải thành phần bootstrapping.
3. Entry script sẽ gọi phương thức [[yii\base\Application::run()]] để chạy ứng dụng:
* Sự kiện [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] sẽ được gán sau đó.
* Xử lý các yêu cầu: chuyển các yêu cầu vào [bộ định tuyến (route)](runtime-routing.md) và các tham số liên quan;
khởi tạo đối tượng module, controller, và action như phần mô tả ở bộ định tuyến; và khởi chạy action.
* Gán sự kiện [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]].
* Gửi phản hồi tới user.
4. Entry script tiếp nhận trạng thái kết thúc từ ứng dụng hoàn tất xử lý tiến trình.

444
docs/guide-vi/structure-controllers.md

@ -0,0 +1,444 @@
Bộ điều khiển (Controller)
===========
Controller thuộc một phần trong mẫu thiết kế [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller).
Controller là đối tượng được kế thừa từ class [[yii\base\Controller]] và chịu trách nhiệm xứ lý các yêu cầu và gửi phản hồi
. Đặc biệt, sau khi tiếp nhận các yêu cầu điều khiển từ [ứng dụng](structure-applications.md),
controllers sẽ phân tích thông tin yêu cầu được gửi đến, gửi dữ liệu qua [models](structure-models.md) để xử lý, và gán kết quả xử lý từ model
vào [views](structure-views.md), và cuối cùng là gửi phản hồi.
## Hành động (Actions) <span id="actions"></span>
Mỗi Controller đều chứa các *action* để user có thế tìm thấy, gửi yêu cầu tới ứng dụng để xử lý
. Mỗi bộ điều khiển có thể có nhiều hành động.
Ví dụ dưới mô tả Controller `post` cùng với 2 action là : `view``create`:
```php
namespace app\controllers;
use Yii;
use app\models\Post;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
class PostController extends Controller
{
public function actionView($id)
{
$model = Post::findOne($id);
if ($model === null) {
throw new NotFoundHttpException;
}
return $this->render('view', [
'model' => $model,
]);
}
public function actionCreate()
{
$model = new Post;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
}
```
Với action `view` (được định nghĩa bởi phương thức `actionView()`), dòng đầu dùng [Model](structure-models.md)
để tải dữ liệu dựa theo định danh ID; Nếu Model được tải thành công, thì sẽ được hiển thị qua
[view](structure-views.md) là `view`. Còn không, ứng dụng sẽ thông báo ngoại lệ là không tìm thấy.
Với action `create` (được định nghĩa bởi phương thức `actionCreate()`), tương tự như vậy. Trước tiên
sẽ khởi tạo [Model](structure-models.md), Model sẽ thực hiện nhận dữ liệu và lưu thông tin. Nếu cả hai việc này thành công thì Controller
sẽ điều hướng trình duyệt tới View `view` cùng với định danh ID vừa được tạo bởi Model. Còn không, Controller sẽ gọi
View `create` có chức năng hiển thị form nhập liệu.
## Bộ định tuyến (Routes) <span id="routes"></span>
Người dùng có thể tìm thấy các actions qua các bộ định tuyến gọi là *routes*. Mỗi Route là chuỗi bao gồm các thông tin:
* Một định danh của Module: chỉ tồn tại nếu bộ điều khiển thuộc về thành phần [module](structure-modules.md);
* Một định danh của [Controller](#controller-ids): là một chuỗi xác định duy nhất của Controller trong ứng dụng
(hoặc có thể là Module nếu Controller tương ứng là một Module);
* Một [Action ](#action-ids):là một chuỗi xác định duy nhất của Action trong ứng dụng.
Mỗi Route có định dạng như sau:
```
ControllerID/ActionID
```
hoặc có định dạng sau nếu Controller được gán như một Module:
```php
ModuleID/ControllerID/ActionID
```
Như vậy nếu user truy cập vào đường dẫn sau `http://hostname/index.php?r=site/index`, thì hành động `index` nằm trong bộ điều khiển `site`
sẽ được thực hiện. Để biết thêm thông tin về cách bộ định tuyến xác định các hành động, vui lòng tham khảo tại mục
[Routing và URL Generation](runtime-routing.md).
## Tạo Controller <span id="creating-controllers"></span>
Trong mỗi [[yii\web\Application|Ứng dụng Web]], Controllers cần được kế thừa từ class [[yii\web\Controller]] hoặc các lớp con của nó
. Tương tự trong [[yii\console\Application|Ứng dụng console]], Controllers cần được kế thừa từ class
[[yii\console\Controller]] hoặc các lớp con của nó. Đoạn code sau được định nghĩa trong Controller `site` :
```php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
}
```
### Định danh Controller (Controller ID) <span id="controller-ids"></span>
Thông thường, Controller được thiết kế để xử lý các yêu cầu từ các nguồn tài nguyên cụ thể.
Vì lý do này, mỗi định danh của Controller thường là danh từ cập nhật tới kiểu tài nguyên được xử lý.
Ví dụ, sử dụng `article` như định danh của Controller nhằm lưu giữ các dữ liệu về bài viết.
Mặc định, Thông tin các định danh Controller nên chỉ chứa các ký tự : Các chữ cái viết thường, số,
dấu gạch dưới, dấu nối, và dấu gạch nghiêng phải. Ví dụ, `article``post-comment` đều là những định danh đúng,
trong khi đó `article?`, `PostComment`, `admin\post` đều không hợp lý.
Các định danh Controller ID nên chứa tiền tố trong thư mục con. Ví dụ, `admin/article` xác định cho Controller `article`
nằm trong thư mục `admin` được dựa theo [[yii\base\Application::controllerNamespace|controller namespace]].
Các ký tự hợp lệ dùng cho các tiền tố của thư mục con bao gồm: Các chữ cái viết thường, số, dấu gạch, và dấu gạch nghiêng phải
, dấu gạch nghiêng phải được dùng để phân cách như các thư mục con (vd. `panels/admin`).
### Tên lớp Controller <span id="controller-class-naming"></span>
Tên lớp của các Controller được khởi tạo từ các định danh Controller theo các bước sau:
1. Chuyển ký tự đầu tiên trong mỗi từ cách nhau bởi dấu gạch nối thành ký tự hoa. Lưu ý rằng nếu các định danh Controller
có chứa dấu gạch chéo, thì quy tắc này chỉ được áp dụng ở phần sau dấu gạch chéo cuối cùng trong các định danh.
2. Xoá các dấu gạch nối và thay thế các dấu gạch chéo xuôi(/) thành dấu gạch chéo ngược (\).
3. Thêm hậu tố `Controller`.
4. Thêm [[yii\base\Application::controllerNamespace|controller namespace]].
Xem ví dụ sau, giả sử [[yii\base\Application::controllerNamespace|controller namespace]]
nhận giá trị mặc định là `app\controllers`:
* `article` thành `app\controllers\ArticleController`;
* `post-comment` thành `app\controllers\PostCommentController`;
* `admin/post-comment` thành `app\controllers\admin\PostCommentController`;
* `adminPanels/post-comment` thành `app\controllers\adminPanels\PostCommentController`.
Các lớp Controller cần được [tự động tải](concept-autoloading.md). Vì vậy, trong ví dụ trên,
lớp của Controller `article` cần được lưu vào file có [bí danh](concept-aliases.md)
`@app/controllers/ArticleController.php`; trong khi đó `admin/post-comment` cần được lưu vào file
`@app/controllers/admin/PostCommentController.php`.
> Lưu ý: Ở ví dụ với định danh Controller `admin/post-comment` hướng dẫn bạn đặt các Controller vào trong thư mục con
của [[yii\base\Application::controllerNamespace|không gian tên Controller]]. Thông tin này khá là hữu ích
mỗi khi bạn muốn quản lý các Controllers và các chuyên mục và bạn không muốn sử dụng thành phần [Modules](structure-modules.md).
### Controller Map <span id="controller-map"></span>
Bạn có thể cấu hình thông tin về mục [[yii\base\Application::controllerMap|controller map]] để khắc phục những hạn chế về các định danh
và tên class của Controller được mô tả ở trên. Điều này khá hữu ích khi bạn muốn sử dụng
các Controller ở bên thứ ba và bạn không có quyền việc kiểm soát các class này.
Bạn có thể cấu hình [[yii\base\Application::controllerMap|controller map]] trong mục
[cấu hình ứng dụng](structure-applications.md#application-configurations). Ví dụ:
```php
[
'controllerMap' => [
// mô tả Controller "account" được sử dụng
'account' => 'app\controllers\UserController',
// mô tả về cấu hình Controller"article" dạng mảng
'article' => [
'class' => 'app\controllers\PostController',
'enableCsrfValidation' => false,
],
],
]
```
### Controller mặc định <span id="default-controller"></span>
Mỗi ứng dụng đều có một Controller mặc định được mô tả qua thuộc tính [[yii\base\Application::defaultRoute]].
Khi một yêu cầu không được mô tả cụ thể ở mục [route](#routes), thì route mặc định sẽ được gọi.
Chẳng hạn [[yii\web\Application|Web applications]], có giá trị là `'site'`, trong khi đó [[yii\console\Application|ứng dụng console]],
có route mặc định là `help`. Vì vậy, nếu truy cập vào URL sau `http://hostname/index.php`, thì Controller `site` sẽ được gọi và xử lý yêu cầu.
Bạn có thể thay đổi thông tin Controller mặc định tại mục [cấu hình ứng dung](structure-applications.md#application-configurations) như sau:
```php
[
'defaultRoute' => 'main',
]
```
## Tạo Actions <span id="creating-actions"></span>
Tạo mới một Action khá là đơn giản, bằng chỉ việc định nghĩa trong lớp Controller cùng với tên *action phương thức*. Các phương thức của mỗi Action
đều có phạm vi *toàn cục* tên của phương thức được bắt đầu bằng từ `action`. Kết quả trả về của mỗi action sẽ tương ứng với
dữ liệu được gửi tới user. Đoạn mã sau sẽ định nghĩa hai action là, `index``hello-world`:
```php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public function actionIndex()
{
return $this->render('index');
}
public function actionHelloWorld()
{
return 'Hello World';
}
}
```
### Định danh của Action (Action ID) <span id="action-ids"></span>
Mỗi action được dùng cho nhiệm vụ với tài nguyên cụ thể. Vì lý do này, mỗi
action ID thường là một đông từ, như `view`, `update`, vv.
Mặc định, mỗi action ID chỉ nên chứa các chữ cái: Chữ thường, số,
dấu gạch dưới, và dấu gạch ngang. (Bạn cũng có thể sử dụng các dấu gạch ngang để nối các từ lại với nhau.) Ví dụ,
`view`, `update2`, và `comment-post` đều là những định danh hợp lệ, còn `view?``Update` là không hợp lệ.
Có hai cách để tạo mới các action: inline actions và standalone actions. Với inline action được định nghĩa
như những phương thức trong lớp Controller, trong khi đó standalone action là lớp được kế thừa từ lớp
[[yii\base\Action]] hoặc là lớp con. Nếu bạn không muốn tái sử dụng các action thì bạn có thể dùng inline actions
, cách này thường hay được sử dụng hơn. Trong khi đó các standalone actions thường được tạo để sử dụng
ở những Controllers khác nhau và được dùng như [thành phần mở rộng](structure-extensions.md).
### Inline Actions <span id="inline-actions"></span>
Inline actions được định nghĩa vào trong các phương thức như chúng ta đã mô tả trên.
Tên của phương thức thường đặt tên theo định danh của action và theo các bước sau:
1. Chuyển ký tự đầu tiên trong mỗi từ định danh của action thành ký tự in hoa.
2. Xoá dấu gạch nối.
3. Thêm tiền tố `action`.
Ví dụ, `index` thành `actionIndex`, và `hello-world` thành `actionHelloWorld`.
> Lưu ý: Việc đặt tên của các phương thức cần phải *cẩn thận*. Nếu bạn có phương thức là `ActionIndex`,
thì phương thức của action sẽ không xác định, như vậy, khi có yêu cầu tới action `index`
thì sẽ sinh ra lỗi. Cũng lưu ý rằng các phương thức này phải ở phạm vi public (toàn cục). Các phạm vi private (riêng) hoặc protected (bảo vệ)
thì sẽ không được định nghĩa như một action.
Inline actions thường được hay sử dụng hơn bởi vì việc khởi tạo đơn giản hơn. Tuy nhiên,
nếu bạn muốn tái sử dụng action ở những vị trí khác, bạn có thể tham khảo thêm ở mục *standalone action*.
### Standalone Actions <span id="standalone-actions"></span>
Standalone actions được định nghĩa từ việc kế thừa từ class [[yii\base\Action]] hoặc các lớp con của nó.
Ví dụ, ở phiên bản Yii đã phát hành, các action [[yii\web\ViewAction]] và [[yii\web\ErrorAction]], đều là những
standalone actions.
Để sử dụng standalone action, bạn cần phải khai báo ở phần *liên kết các action* bằng việc ghi đè lên phương thức
[[yii\base\Controller::actions()]] ở lớp Controller như sau:
```php
public function actions()
{
return [
// khai báo action "error" bằng việc sử dụng tên class
'error' => 'yii\web\ErrorAction',
// khai báo action "view" bằng thông tin cấu hình dạng mảng
'view' => [
'class' => 'yii\web\ViewAction',
'viewPrefix' => '',
],
];
}
```
Như vậy, phương thức `actions()` sẽ trả về một mảng và chứa các khoá của các định danh action và giá trị tương ứng
tên class hoặc thông tin [cấu hình](concept-configurations.md). Không giống như inline actions, action ID được dùng cho standalone
actions có thể chứa các ký tự tuỳ ý, miễn là chúng được khai báo trong phương thức `actions()`.
Để tạo các class standalone action, bạn nên kế thừa từ lớp [[yii\base\Action]] hoặc lớp con của nó, và hiện thực
phương thức là `run()`. Vài trò của phương thức `run()` tương tự như một phương thức của action. Chẳng hạn,
```php
<?php
namespace app\components;
use yii\base\Action;
class HelloWorldAction extends Action
{
public function run()
{
return "Hello World";
}
}
```
### Kết quả trả về của Action <span id="action-results"></span>
Kết quả trả về của phương thức action hoặc phương thức `run()` của standalone action khá quan trọng. Nó là
kết quả tương ứng của từng action.
Giá trị trả về là đối tượng [phản hồi](runtime-responses.md) được gửi tới user như những phản hồi.
* Chẳng hạn với [[yii\web\Application|Ứng dụng Web]], kết quả trả về bao gồm dữ liệu được gán vào thuộc tính
[[yii\web\Response::data]] và chuyển sang dữ liệu là string chuyển tới nội dung phản hồi kết quả.
* Với [[yii\console\Application|ứng dụng console]], kết quả trả về là số nguyên tương ứng với thuộc tính
[[yii\console\Response::exitStatus|exit status]] của mỗi lần thực thi lệnh.
Ở ví dụ dưới, action sẽ trả về là chuỗi dữ liệu và được xử lý như nội dung phản hồi tới user
. Ví dụ dưới chỉ cách các action điều hướng tới trình duyệt một URL
bằng việc gửi một đối tượng phản hồi (vì phương thức [[yii\web\Controller::redirect()|redirect()]] sẽ trả về
một đối tượng):
```php
public function actionForward()
{
// điều hướng tới URL http://example.com
return $this->redirect('http://example.com');
}
```
### Các tham số của Action <span id="action-parameters"></span>
Các phương thức dành cho inline action và phương thức `run()` cho standalone actions có thể nhận các tham số,
được gọi là *các tham số action*. Giá trị nhận được từ các yêu cầu. Với [[yii\web\Application|Ứng dụng Web]],
giá trị của các tham số được nhận từ biến `$_GET` sử dụng các tham số như các khoá;
với [[yii\console\Application|ứng dụng console]], các tham số sẽ tương ứng với các đối số dòng lệnh.
Trong ví dụ sau, action `view` (là một inline action) được khai báo hai tham số là: `$id``$version`.
```php
namespace app\controllers;
use yii\web\Controller;
class PostController extends Controller
{
public function actionView($id, $version = null)
{
// ...
}
}
```
Các tham số cho action sẽ được dùng như sau và tương ứng với các yêu cầu khác nhau:
* `http://hostname/index.php?r=post/view&id=123`: biến `$id` sẽ nhận giá trị là
`'123'`, trong khi đó tham số `$version` nhận giá trị null vì không có đối số `version` được truyền lên.
* `http://hostname/index.php?r=post/view&id=123&version=2`: biến `$id``$version` sẽ nhận giá trị tương ứng là
`'123'``'2'`.
* `http://hostname/index.php?r=post/view`: ngoại lệ [[yii\web\BadRequestHttpException]] sẽ được gửi ra
vì tham số `$id` không được gửi lên.
* `http://hostname/index.php?r=post/view&id[]=123`: xảy ra ngoại lệ [[yii\web\BadRequestHttpException]] lý do vì
tham số `$id` nhận dữ liệu là một mảng do vậy không hợp lệ `['123']`.
Nếu bạn muốn tham số của action nhận dữ liệu là một mảng, bạn nên khai báo biên là `array`, như sau:
```php
public function actionView(array $id, $version = null)
{
// ...
}
```
Nếu yêu cầu là `http://hostname/index.php?r=post/view&id[]=123`, thì tham số `$id` sẽ nhận giá trị là
`['123']`. Nếu yêu cầu là `http://hostname/index.php?r=post/view&id=123`, tham số `$id` sẽ chỉ nhận
các giá trị trong mảng là giống nhau bởi vì giá trị `'123'` không là mảng và sẽ tự động chuyển vào mảng.
Ở ví dụ trên sẽ hướng dẫn các tham số trong mỗi action hoạt động trong ứng dụng Web. Với ứng dụng console,
vui lòng tham khảo tại mục [Console Commands](tutorial-console.md) để biết thêm thông tin.
### Action mặc định <span id="default-action"></span>
Mỗi controller đều có các action mặc định và đợc mô tả ở thuộc tính [[yii\base\Controller::defaultAction]].
Mỗi khi [route](#routes) chỉ nhận giá trị là định danh của controller, router sẽ tự hiểu rằng action mặc định
của controller sẽ được gọi.
Mặc định, action mặc định sẽ là `index`. nếu bạn muốn thay đổi giá trị này, cách đơn giản nhất là ghi đè thuộc tính
trong lớp controller, như sau:
```php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public $defaultAction = 'home';
public function actionHome()
{
return $this->render('home');
}
}
```
## Chu trình Controller <span id="controller-lifecycle"></span>
Khi xử lý yêu cầu, [ứng dụng](structure-applications.md) sẽ khởi tạo controller
dựa theo các yêu cầu tại [route](#routes). Controller sẽ được xử lý qua các chu trình sau để xử lý các yêu cầu:
1. Phương thức [[yii\base\Controller::init()]] sẽ được gọi sau khi controller được khởi tạo và thiết lập các cấu hình.
2. Controller sẽ tạo đối tượng action dựa trên các yêu cầu qua các định danh của action:
* Nếu định danh của action không được chỉ rõ , thì [[yii\base\Controller::defaultAction|action mặc định]] sẽ được sử dụng.
* Nếu định danh của action được tìm thấy trong phương thức [[yii\base\Controller::actions()|action map]], thì một standalone action
sẽ được khởi tạo;
* Nếu định danh của action được tìm thấy và khớp với phương thức của action, thì một inline action sẽ được;
* Mặt khác hệ thống sẽ gửi ngoại lê [[yii\base\InvalidRouteException]] ra.
3. Controller sẽ lần lượt được gọi tại phương thức `beforeAction()` trong ứng dụng, trong module (nếu controller
thuộc một module), và trong controller.
* Nếu một trong các phương thức không đợc gọi, các phần chưa được gọi trong phương thức `beforeAction()` sẽ được bỏ qua
và việc thực hiện action sẽ bị huỷ bỏ.
* Mặc định, mỗi phương thức `beforeAction()` sẽ được gán vào sự kiện `beforeAction` tới các action mà bạn cần xử lý.
4. Controller thực hiện chạy action.
* Các tham số của action sẽ được phân tích và gán từ các yêu cầu xử lý.
5. Controller sẽ thực hiện tuần tự gọi phương thức `afterAction()` trong Controller, module (nếu Controller
là module), và trong ứng dụng.
* Mặc định, mỗi phương thức `afterAction()` sẽ gọi tới một sự kiện `afterAction` tới các action mà bạn cần xử lý.
6. Ứng dụng sẽ nhận kết quả từ các action và chuyển tới thành phần [response](runtime-responses.md).
## Thực hành <span id="best-practices"></span>
Với mỗi ứng dụng được thiết kế tốt, thì Controllers thường rất gọn nhẹ, mỗi action chỉ chứa khá ít dòng code.
Nếu Controller trong ứng dụng của bản khá phức tạp, thì bạn nên cấu trúc lại và chuyển sang một lớp khác.
Sau đây gợi ý vài thủ thuật. Controllers
* có thể truy cập dữ liệu từ các [request](runtime-requests.md);
* gọi các phương thức từ [models](structure-models.md) và các thành phần khác cùng với dữ liệu được gửi;
* dùng thành phần [views](structure-views.md) để gửi phản hồi;
* KHÔNG NÊN xử lý dữ liệu - nên xử lý ở tầng [model](structure-models.md);
* không nên nhúng mã HTML vào hoặc đoạn mã khác - mã này nên nhũng ở thành phần [views](structure-views.md).

116
docs/guide-vi/structure-entry-scripts.md

@ -0,0 +1,116 @@
Entry Scripts
=============
Entry script là tiến trình đầu tiên của ứng dụng. Một ứng dụng (hoặc
ứng dụng Web hoặc ứng dụng console) đều có một entry script. Người dùng đầu cuối tạo các request tới entry script, entry script
sẽ khởi tạo ứng dụng và nhanh chóng chuyển các yêu cầu tới chúng.
Entry script dành cho các ứng dụng web cần được thiết lập ở dưới thư mục truy cập Web để người dùng cuối có thể truy cập
. Những mục này thường được đặt tên là `index.php`, tuy nhiên có thể sử dụng các tên khác,
được cung cấp và có thể xác định bởi các máy chủ Web.
Entry script cho các ứng dụng console thông thường được nằm ở [đường dẫn cơ sở](structure-applications.md)
của ứng dụng và có tên là `yii` (cùng với hậu tố `.php`). Chúng được xây dựng để thực thi các ứng dụng console
thông qua dòng lệnh `./yii <route> [arguments] [options]`.
Entry scripts có chức năng chính như sau:
* Khai báo các hằng số ở phạm vi toàn cục;
* Đăng ký [Composer autoloader](http://getcomposer.org/doc/01-basic-usage.md#autoloading);
* Tải các file class của [[Yii]];
* Tải cấu hình ứng dụng;
* Tạo và cấu hình các phiên bản [application](structure-applications.md);
* Gọi phương thức [[yii\base\Application::run()]] để xử lý các request được gọi tới.
## Ứng dụng Web <span id="web-applications"></span>
Mã nguồn dưới đây là các dòng lệnh trong mục script trong [Mẫu ứng dụng cơ bản](start-installation.md).
```php
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
// register Composer autoloader
require(__DIR__ . '/../vendor/autoload.php');
// include Yii class file
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
// load application configuration
$config = require(__DIR__ . '/../config/web.php');
// create, configure and run application
(new yii\web\Application($config))->run();
```
## Ứng dụng Console(dòng lệnh) <span id="console-applications"></span>
Tương tự, Mã nguồn dưới đây là các dòng lệnh trong mục script của ứng dụng console:
```php
#!/usr/bin/env php
<?php
/**
* Yii console bootstrap file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
defined('YII_DEBUG') or define('YII_DEBUG', true);
// fcgi doesn't have STDIN and STDOUT defined by default
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w'));
// register Composer autoloader
require(__DIR__ . '/vendor/autoload.php');
// include Yii class file
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
// load application configuration
$config = require(__DIR__ . '/config/console.php');
$application = new yii\console\Application($config);
$exitCode = $application->run();
exit($exitCode);
```
## Định nghĩa các hằng số <span id="defining-constants"></span>
Entry scripts thích hợp để định nghĩa các hằng ở phạm vi toàn cục. Yii hỗ trợ 3 hằng số sau:
* `YII_DEBUG`: xác định xem ứng dụng đang chay trong chế độ debug (gỡ lỗi). Khi ở chế độ debug, ứng dụng
sẽ log các thông tin, và sẽ thông báo chi tiết về các lỗi nếu có các ngoại lệ được gửi ra. Vì lý do này
, chế độ debug nên được dùng thường xuyên trong quá trình xây dựng ứng dụng. Giá trị mặc định của hằng `YII_DEBUG` là false.
* `YII_ENV`: xác định thông tin về môi trường của ứng dụng đang chạy (sản phẩm hay đang phát triển). Điều này sẽ mô tả chi tiết trong phần
[Cấu hình](concept-configurations.md#environment-constants). Giá trị mặc định của hằng số `YII_ENV``'prod'`, có nghĩa là ứng dụng đang chạy là phiển bản sản phẩm
đã phát hành.
* `YII_ENABLE_ERROR_HANDLER`: mô tả nơi cho phép được giữ (handler) các lỗi được cung cấp bởi Yii. Giá trị mặc đình của hằng
số là true.
Khi định nghĩa các hằng số, chúng ta thường sử dụng đoạn mã như sau:
```php
defined('YII_DEBUG') or define('YII_DEBUG', true);
```
Khai báo trên tương đương với đoạn code sau:
```php
if (!defined('YII_DEBUG')) {
define('YII_DEBUG', true);
}
```
Ta thấy đoạn code trên ngắn gọi và dễ hiểu hơn nhiều.
Việc định nghĩa các hằng số nên được thực hiện ở phần đầu của entry script để các hằng số này có thể được gọi
ở những file php khác.

529
docs/guide-vi/structure-models.md

@ -0,0 +1,529 @@
Model
======
Model là phần trong kiến trúc [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller).
Là đối tượng đại diện cho phần dữ liệu, phương thức xử lý và nghiệp vụ logic.
Bạn có thể tạo mới các lớp model bằng việc kế thừa từ lớp [[yii\base\Model]] hoặc các lớp con của nó. Lớp cơ sở
[[yii\base\Model]] hỗ trợ nhiều tính năng như:
* [Thuộc tính (Attributes)](#attributes): đại diện cho các dữ liệu nghiệp vụ và có thể truy cập như các thuộc tính
hoặc mảng các phần tử;
* [Attribute labels](#attribute-labels): tên hiển thị cho các thuộc tính;
* [Gán nhanh (Massive assignment)](#massive-assignment): hỗ trợ nhập dữ liệu cho thuộc tính trong một bước;
* [Quy tắc xác nhận (Validation rules)](#validation-rules): khai báo các quy tắc và xác thực dữ liệu được nhập vào;
* [Xuất dữ liệu (Data Exporting)](#data-exporting): cho phép xuất dữ liệu dưới dạng mảng hoặc tuỳ chọn khác.
Lớp `Model` thường dựa trên lớp để thực hiện chức năng nâng cao, chẳng hạn [Active Record](db-active-record.md).
Vui lòng tham khảo thêm tài liệu để biết thêm thông tin.
> Lưu ý: Model của bạn không phải bắt buộc kế thừa từ lớp [[yii\base\Model]]. Tuy nhiên, vì Yii chứa nhiều thành phần
dựng lên và hỗ trợ cho [[yii\base\Model]], vì thế nó là lớp cơ sở cho các lớp Model.
## Thuộc tính (Attribute) <span id="attributes"></span>
Model đại diện cho tầng xử lý nghiệp vụ và chứa các *thuộc tính*. Mỗi thuộc tính được truy cập toàn cục như phần tử của
model. Phương thức [[yii\base\Model::attributes()]] sẽ mô tả các thuộc tính trong lớp model hiện có.
Bạn có thể truy cập vào thuộc tính như các phần tử của các đối tượng:
```php
$model = new \app\models\ContactForm;
// "name" là tên thuộc tính của ContactForm
$model->name = 'example';
echo $model->name;
```
Bạn có thể truy cập các thuộc tính như truy cập mảng các phần tử, nhờ sự hỗ trợ từ lớp
[ArrayAccess](http://php.net/manual/en/class.arrayaccess.php) và [ArrayIterator](http://php.net/manual/en/class.arrayiterator.php)
bởi [[yii\base\Model]]:
```php
$model = new \app\models\ContactForm;
// truy cập các thuộc tính như mảng các phần tử
$model['name'] = 'example';
echo $model['name'];
// iterate attributes
foreach ($model as $name => $value) {
echo "$name: $value\n";
}
```
### Định nghĩa các thuộc tính <span id="defining-attributes"></span>
Mặc định, nếu Model của bạn được kế thừa từ lớp [[yii\base\Model]], và tất cả các biến có phạm vi *toàn cục trong lớp*
. Ví dụ, Model `ContactForm` sau có bốn thuộc tính là: `name`, `email`,
`subject``body`. Model `ContactForm` dùng để nhận dữ liệu từ form HTML.
```php
namespace app\models;
use yii\base\Model;
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $body;
}
```
Bạn có thể ghi đè phương thức [[yii\base\Model::attributes()]] để định nghĩa các thuộc tính theo các cách khác. Phương thức nên được trả
tên của thuộc tính trong Model. Ví dụ, lớp [[yii\db\ActiveRecord]] trả về
danh sách tên của các cột liên quan tới các bảng trong CSDL như tên các thuộc tính. Bạn có thể ghi đè các phương thức như
`__get()`, `__set()` để có thể truy cập các thuộc tính như các đối tượng thông thường.
### Nhãn của thuộc tính <span id="attribute-labels"></span>
Mỗi khi cần hiển thị giá trị hoặc nhận dữ liệu cho thuộc tính, bạn cần hiển thị nhãn tương ứng với các thuộc tính
. Ví dụ, với thuộc tính `firstName`, bạn cần hiển thị nhãn `First Name`
nhãn này sẽ thân thiện hơn khi hiển thị tới người dùng với việc nhập dữ liệu và hiện thông báo.
Bạn có thể lấy tên nhãn các thuộc tính quan việc gọi phương thức [[yii\base\Model::getAttributeLabel()]]. Ví dụ,
```php
$model = new \app\models\ContactForm;
// hiển thị "Name"
echo $model->getAttributeLabel('name');
```
Mặc định, nhãn thuộc tính sẽ tự động tạo từ tên của thuộc tính.
Phương thức [[yii\base\Model::generateAttributeLabel()]] sẽ tạo mới các nhãn cho các thuộc tính. Nó sẽ chuyển tên các biến thành các từ mới
qua việc chuyển ký tự đầu tiên thành ký tự in hoa. Ví dụ, `username` thành `Username`,
`firstName` thành `First Name`.
Nếu bạn không muốn việc tạo các nhản bằng cách tự động, bạn cần ghi đè phương thức [[yii\base\Model::attributeLabels()]]
để mô tả các thuộc tính. Chẳng hạn,
```php
namespace app\models;
use yii\base\Model;
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $body;
public function attributeLabels()
{
return [
'name' => 'Your name',
'email' => 'Your email address',
'subject' => 'Subject',
'body' => 'Content',
];
}
}
```
Với ứng dụng cần hỗ trợ đa ngôn ngữ, bạn cần dịch lại nhãn của các thuộc tính. Xem trong phương thức
[[yii\base\Model::attributeLabels()|attributeLabels()]] , như sau:
```php
public function attributeLabels()
{
return [
'name' => \Yii::t('app', 'Your name'),
'email' => \Yii::t('app', 'Your email address'),
'subject' => \Yii::t('app', 'Subject'),
'body' => \Yii::t('app', 'Content'),
];
}
```
Bạn có thể gán nhãn cho các thuộc tính. Chẳng hạn, dựa vào [scenario](#scenarios)của Model
đã được sử dụng , bạn có thể trả về các nhãn khác nhau cho các thuộc tính khác nhau.
> Lưu ý: Chính xác rằng, nhãn của thuộc tính là một phần của [views](structure-views.md). Tuy nhiên việc khai báo các nhãn
vào Model thường rất tiện lợi, code dễ nhìn và tái sử dụng.
## Kịch bản (Scenarios) <span id="scenarios"></span>
Model thường được sử dụng ở các *kịch bản* khác nhau . Ví dụ, Model `User` dùng để xử lý việc đăng nhập,
nhưng cũng có thể được dùng ở mục đăng ký. Ở các kịch bản khác nhau, Model có thể được dùng trong các nghiệp vụ
và xử lý logic khác nhau. Ví dụ,thuộc tính `email` có thể được yêu cầu trong mục đăng ký tài khoản mới,
nhưng không được yêu cầu khi xử lý đăng nhập.
Mỗi Model sử dụng thuộc tính [[yii\base\Model::scenario]] để xử lý tuỳ theo kịch bản cần đợc dùng.
Mặc định, Model sẽ hỗ trợ kịch bản là `default`. Xem đoạn mã sau để hiểu 2 cách thiết lập kịch bản cho Model.
setting the scenario of a model:
```php
// kịch bản được thiết lập qua thuộc tính
$model = new User;
$model->scenario = User::SCENARIO_LOGIN;
// kịch bản được thiết lập qua việc cấu hình khởi tạo
$model = new User(['scenario' => User::SCENARIO_LOGIN]);
```
Mặc định, các kịch bản được hỗ trợ bởi model được xác định qua [các nguyên tắc xác minh](#validation-rules) được
mô tả ở Model. Tuy nhiên, bạn có thê tuỳ biến bằng cách ghi đè phương thức [[yii\base\Model::scenarios()]],
như sau:
```php
namespace app\models;
use yii\db\ActiveRecord;
class User extends ActiveRecord
{
const SCENARIO_LOGIN = 'login';
const SCENARIO_REGISTER = 'register';
public function scenarios()
{
return [
self::SCENARIO_LOGIN => ['username', 'password'],
self::SCENARIO_REGISTER => ['username', 'email', 'password'],
];
}
}
```
> Lưu ý: Như phần trên và ví dụ vừa rồi, lớp Model được kế thừa từ lớp [[yii\db\ActiveRecord]]
bởi vì lớp [Active Record](db-active-record.md) thường được sử dụng nhiều kịch bản.
Phương thức `scenarios()` trả về một mảng có chứa các khóa là tên các kịch bản và các giá trị tương ứng là các
danh sách *thuộc tính được chọn*. An active attribute can be [massively assigned](#massive-assignment) và là đối tượng sẽ được
dùng để [xác thực (validation)](#validation-rules). Chẳng hạn ở ví dụ trên, thuộc tính `username``password` sẽ được chọn
ở kịch bản `login`; còn ở kịch bản `register`, sẽ có thêm thuộc tính `email` ngoài 2 thuộc tính `username``password`.
Việc triển khai phương thức `scenarios()` mặc định sẻ trả về các kịch bản tìm thấy trong phương thức
[[yii\base\Model::rules()]]. Khi khi đè phương thức `scenarios()`, nếu bạn muốn khai báo các kịch bản mới, ngoài các kịch bản mặc định
in addition to the default ones, bạn có thể viết mã như sau:
```php
namespace app\models;
use yii\db\ActiveRecord;
class User extends ActiveRecord
{
const SCENARIO_LOGIN = 'login';
const SCENARIO_REGISTER = 'register';
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios[self::SCENARIO_LOGIN] = ['username', 'password'];
$scenarios[self::SCENARIO_REGISTER] = ['username', 'email', 'password'];
return $scenarios;
}
}
```
Xây dựng các kịch bản được dùng vào việc [xác thực](#validation-rules) và [massive attribute assignment](#massive-assignment).
Tuy nhiên, bạn có thể dùng vào mục đích khác. Chẳng hạn, bạn có thể khai báo các [nhãn thuộc tính](#attribute-labels)
khác nhau được dựa trên kịch bản hiện tại.
## Các quy tắc xác nhận (Validation Rules) <span id="validation-rules"></span>
Khi dữ liệu cho model được chuyển lên từ người dùng cuối, dữ liệu này cần được xác thực để chắc chắn rằng dữ liệu này là hợp lệ
(được gọi là *quy tắc xác nhận*, có thể gọi *business rules*). Ví dụ, cho model `ContactForm`,
bạn muốn tất cả các thuộc tính không được để trống và thuộc tính `email` phải là địa chỉ email hợp lệ.
Nếu các giá trị cho các thuộc tính không được thỏa mãn với các quy tắc xác nhận, các thông báo lỗi sẽ được
được hiển thị để giúp người dùng sửa lỗi.
Bạn có thể gọi phương thức [[yii\base\Model::validate()]] để xác thực các dữ liệu đã nhận. Phương thức sẽ dùng các quy tắc xác nhận
được khai báo ở phương thức [[yii\base\Model::rules()]] để xác thực mọi thuộc tính liên quan. Nếu không có lỗi nào tìm thấy
, sẽ trả về giá trị `true`. Nếu không thì, phương thức sẽ giữ các thông báo lỗi tại thuộc tính [[yii\base\Model::errors]]
và trả kết quả`false`. Ví dụ,
```php
$model = new \app\models\ContactForm;
// gán các thuộc tính của model từ dữ liệu người dùng
$model->attributes = \Yii::$app->request->post('ContactForm');
if ($model->validate()) {
// tất cả các dữ liệu nhập vào hợp lệ
} else {
// xác nhận lỗi: biến $errors chứa mảng các nội dung thông báo lỗi
$errors = $model->errors;
}
```
Các quy tắc xác nhận được gắn vào model, việc ghi đè phương thức [[yii\base\Model::rules()]] cùng với việc trả về
có chứa các thuộc tính an toàn cần được xác thực. Ví dụ sau đây sẽ cho thấy các quy tắc xác nhận được khai báo cho model
`ContactForm`:
```php
public function rules()
{
return [
// the name, email, subject and body attributes are required
[['name', 'email', 'subject', 'body'], 'required'],
// the email attribute should be a valid email address
['email', 'email'],
];
}
```
Mỗi quy tắc được dùng để xác nhận một hoặc nhiều các thuộc tính, và một thuộc tính có thể được xác nhận một hoặc nhiều quy tắc.
Vui lòng tham khảo mục [Xác nhận đầu vào](input-validation.md) để biết thêm chi tiết về cách khai báo các quy tắc xác nhận.
Đôi khi, bạn muốn các quy tắc chỉ được áp dụng chỉ trong một số [kịch bản](#scenarios). Để làm như vậy, bạn có thể
thêm thông tin thuộc tính `on` ở mỗi quy tắc, giống như sau:
```php
public function rules()
{
return [
// thuộc tính username, email và password cần được nhập ở kịch bản "register"
[['username', 'email', 'password'], 'required', 'on' => self::SCENARIO_REGISTER],
// username và password cần được nhập ở kịch bản "login"
[['username', 'password'], 'required', 'on' => self::SCENARIO_LOGIN],
];
}
```
Nếu bạn không chỉ định thuộc tính `on`, quy tắc sẽ áp dụng trong tất cả các kịch bản. Một quy tắc được gọi
một *quy tắc hoạt động* nếu nó được áp dụng với kịch bản hiện tại [[yii\base\Model::scenario|scenario]].
Một thuộc tính được xác nhận nếu và chỉ nếu nó là thuộc tính được kích hoạt với khai báo tại phương thức `scenarios()`
được liên kết với một hoặc nhiều quy tắc được khai báo ở phương thức `rules()`.
## Gán nhanh (Massive Assignment) <span id="massive-assignment"></span>
Gán nhanh là cách tiện lợi cho việc nhập dữ liệu vào model từ người dùng với một dòng mã.
Nó nhập vào các thuộc tính của model bằng việc gán dữ liệu nhập vào qua thuộc tính [[yii\base\Model::$attributes]]
. 2 đoạn mã sau hoạt động giống nhau , cả 2 đều lấy dữ liệu trong form gửi lên từ người dùng
vào các thuộc tính của model `ContactForm`. Nhanh gọn, cách trên, sẽ dùng gán nhanh, mã của bạn trông sạch và ít lỗi hơn cách sau đó:
```php
$model = new \app\models\ContactForm;
$model->attributes = \Yii::$app->request->post('ContactForm');
```
```php
$model = new \app\models\ContactForm;
$data = \Yii::$app->request->post('ContactForm', []);
$model->name = isset($data['name']) ? $data['name'] : null;
$model->email = isset($data['email']) ? $data['email'] : null;
$model->subject = isset($data['subject']) ? $data['subject'] : null;
$model->body = isset($data['body']) ? $data['body'] : null;
```
### Thuộc tính an toàn (Safe Attributes) <span id="safe-attributes"></span>
Gán nhanh chỉ gán dữ liệu cho những thuộc tính gọi là *thuộc tính an toàn (safe attributes)* đó là các thuộc tính được liệt kê trong phương thức
[[yii\base\Model::scenarios()]] cho thuộc tính [[yii\base\Model::scenario|scenario]] của model.
Chẳng hạn, nếu model `User` có các kịch bản mô tả như sau, tiếp đến kịch bản
`login` đang được chọn, thì chỉ thuộc tính `username``password` có thể được gán nhanh. Bất kỳ các thuộc tính khác
sẽ được giữ nguyên.
```php
public function scenarios()
{
return [
self::SCENARIO_LOGIN => ['username', 'password'],
self::SCENARIO_REGISTER => ['username', 'email', 'password'],
];
}
```
> Thông tin: Lý do việc gán nhanh chỉ gán dữ liệu cho các thuộc tính an toàn là bởi vì bạn muốn kiểm soát
những thuộc tính có thể được thay đổi bởi người dùng. Chẳng hạn, nếu model `User`
có thuộc tính `permission` nhằm xác định các quyền hạn của người dùng, bạn chỉ muốn
thuộc tính này chỉ được thay đổi bởi quản trị viên thông qua giao diện phụ trợ.
Bởi vì mặc định phương thức [[yii\base\Model::scenarios()]] sẽ trả về tất cả các kịch bản và thuộc tính
nằm trong phương thức [[yii\base\Model::rules()]], nếu bạn không ghi đè phương thức này, có nghĩa là một thuộc tính là an toàn
miễn là có khai báo ở một trong các quy tắc xác nhận.
Vì lý do này, bí danh `safe` được đưa ra bạn có thể khai báo các thuộc tính an toàn
mà không thực sự xác nhận nó. Chẳng hạn, các quy tắc sau đây khai báo thuộc tính `title`
`description` là thuộc tính an toàn.
```php
public function rules()
{
return [
[['title', 'description'], 'safe'],
];
}
```
### Thuộc tính không an toàn (Unsafe Attributes) <span id="unsafe-attributes"></span>
Như mô tả trên, khai báo phương thức [[yii\base\Model::scenarios()]] có 2 mục đích: liệt kê thuộc tính cần được xác nhận
, và xác định các thuộc tính là an toàn. Trong một số trường hợp khác, bạn muốn xác nhận thuộc tính nhưng
không muốn đánh dấu là an toàn. bạn có thể thực hiện bằng việc đặt dấu chấm than `!` vào tên thuộc tính
khi khai báo tại phương thức `scenarios()`, giốn như thuộc tính `secret` như sau:
```php
public function scenarios()
{
return [
self::SCENARIO_LOGIN => ['username', 'password', '!secret'],
];
}
```
Khi model đang ở kịch bản `login`, cả 3 thuộc tính sẽ được xác nhận. Tuy nhiên, chỉ có thuộc tính `username`
`password` được gán nhanh. Để gán giá trị cho thuộc tính `secret`, bạn
cần được gán trực tiếp như sau,
```php
$model->secret = $secret;
```
Điều tương tự có thể được thực hiện trong phương thức `rules()`:
```php
public function rules()
{
return [
[['username', 'password', '!secret'], 'required', 'on' => 'login']
];
}
```
Trong trường hợp này các thuộc tính `username`, `password``secret` là yêu cầu nhập, nhưng thuộc tính `secret` phải cần được gán trực tiếp.
## Xuất dữ liệu (Data Exporting) <span id="data-exporting"></span>
Các model thường được cần trích xuất ra các định dạng khác nhau. Chẳng hạn, bạn cần chuyển dữ liệu sang của
models sang định dạng JSON hoặc Excel. Quá trình xuất có thể được chia nhỏ thành hai bước độc lập:
- models cần được chuyển sang định dạng mảng;
- các mảng cần được chuyển đổi thành các định dạng cần chuyển.
Bạn chỉ cần tập trung vào bước đầu tiên, bởi vì bước thứ 2 có thể được thực hiện bởi các trình định dạng dữ liệu
, chẳng hạn như [[yii\web\JsonResponseFormatter]].
Các đơn giản nhất để chuyển đổi model sang dạng mảng là sử dụng thuộc tính [[yii\base\Model::$attributes]].
For example,
```php
$post = \app\models\Post::findOne(100);
$array = $post->attributes;
```
Bởi mặc định, thuộc tính [[yii\base\Model::$attributes]] sẽ trả về các giá trị của *tất cả* các thuộc tính
được khai báo trong phương thức [[yii\base\Model::attributes()]].
Còn một cách linh hoạt và tiện lợi hơn trong việc chuyển đổi model sang định dạng mảng là sử dụng phương thức [[yii\base\Model::toArray()]]
. Cách chuyển đổi cũng tương tự như trong cách của thuộc tính [[yii\base\Model::$attributes]]. Tuy nhiên, nó cho phép bạn chọn các dữ liệu
, được gọi là *fields*, được đặt trong mảng kết quả và chúng được định dạng thế nào.
Trong thực tế, đó là cách trích xuất mặc định của các model ở việc phát triển các dịch vụ RESTful Web, như được mô tả trong
mục [Response Formatting](rest-response-formatting.md).
### Các trường (Fields) <span id="fields"></span>
Một trường đơn giản là tên của thành phần thu được nằm trong mảng khi gọi phương thức [[yii\base\Model::toArray()]]
của model.
Mặc định, tên trường sẽ tương đương với tên thuộc tính. Tuy nhiên, bạn có thể thay đổi bằng việc ghi đè
qua phương thức [[yii\base\Model::fields()|fields()]] và/hoặc phương thức [[yii\base\Model::extraFields()|extraFields()]]. Cả 2 phương thức
trả về danh sách các khai báo trường. Các trường được định nghĩa bởi phương thức `fields()` là các trường mặc định, nghĩa là phương thức
`toArray()` sẽ trả về những trường mặc định. Phương thức `extraFields()` sẽ khai báo thêm các trường bổ sung có thể được trả về
bởi phương thức `toArray()` miễn là bạn chỉ định chugns qua tham số `$expand`. Chẳng hạn,
đoạn mã sau sẽ trả về các trường được định nghĩa trong phương thức `fields()` và 2 trường `prettyName``fullAddress`
nếu chúng được định nghĩa trong phương thức `extraFields()`.
```php
$array = $model->toArray([], ['prettyName', 'fullAddress']);
```
Bạn có thể ghi đè phương thức `fields()` để thêm, xóa, cập nhật hoặc định nghĩa lại các trường. Phương thức `fields()`
sẽ trả về dữ liệu dạng mảng. Mảng này có các khóa là tên các trường, và các giá trị của mảng tương ứng
với các trường đã định nghĩa giá trị có thể là tên các thuộc tính/biến hoặc một hàm trả về các giá trị trường tương ứng
. Trong trường hợp đặc biệt khi tên trường giống với tên thuộc tính xác định của nó, bạn có thể bỏ qua khóa mảng. Ví dụ,
```php
// liệt kê rõ ràng các trường, sử dụng tốt nhất khi bạn nắm được các thay đổi
// trong bản CSDL hoặc các thuộc tính của model, không gây ra sự thay đổi của trường (để giữ tương thích với API).
public function fields()
{
return [
// tên trường giống với tên thuộc tính
'id',
// tên trường là "email", tương ứng với tên thuộc tính là "email_address"
'email' => 'email_address',
// tên trường là "name", giá trị được định nghĩa bởi hàm
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
];
}
// lọc ra một số trường, nên sử dụng khi bạn muốn kế thừa các trường
// thêm vào blacklist một số trường không cần thiết.
public function fields()
{
$fields = parent::fields();
// remove fields that contain sensitive information
unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);
return $fields;
}
```
> Cảnh báo: Bởi vì theo mặc định tất cả các thuộc tính của model sẽ liệt kê trong mảng trích xuất, bạn nên
> kiểm tra dữ liệu của bạn để chắc chắn rằng chúng không chứa các thông tin không cần thiết. Nếu có thông tin như vậy,
> bạn nên ghi đè phương thức `fields()` để lọc chúng ra. Tại ví dụ trên, chúng ta chọn
> các trường để lọc ra là `auth_key`, `password_hash``password_reset_token`.
## Bài thực hành <span id="best-practices"></span>
Các model là phần trung tâm đại diện cho tầng dữ liệu, chứa các quy tắc và logic. Model thường được tái sử dụng
tại một số nơi khác nhau. Với một ứng dụng được thiết kế tốt, thông thường các model được chú trọng hơn
[controllers](structure-controllers.md).
Tổng hợp mục, models
* có thể chứa các thuộc tính đại diện cho tầng dữ liệu (business data);
* có thể chứa các quy tắc xác nhận để đảm bảo tính hợp lệ và tính toàn vẹn của dữ liệu;;
* có thể chứa các phương thức tại tầng logic (business logic);
* không nên trực tiếp xử lý các yêu cầu, session, hoặc bất cứ dữ liệu môi trường. Những dữ liệu này nên được tiến hành xử lý
bởi [controllers](structure-controllers.md) vào model;
* tránh việc nhúng mã HTML hoặc các dữ liệu hiển thị - mã này nên được đặt tại [views](structure-views.md);
* tránh có quá nhiều kịch bản [scenarios](#scenarios) trong một model.
Bạn cần có sự xem xét các đề nghị trên mỗi khi bạn triển khai hệ thống lớn và phức tạp.
Trong các hệ thống này, cácmodel cần được chú trọng bởi vì chúng được sử dụng ở nhiều nơi và có thể chứa nhiều các quy tắc
và các xử lý nghiệp vụ. Điều này có sự ảnh hưởng tại tiến trình bảo trì mỗi thay đổi mã của bạn
có thể ảnh hưởng tới nhiều vị trí khác nhau. Để mã code của bạn dễ được bảo trì hơn,
bạn có thể được thực hiện các chiến lược sau:
* Định nghĩa tập các lớp model cơ sở (base model) lớp này được chia sẻ qua các [ứng dụng](structure-applications.md) hoặc
[modules](structure-modules.md) khác nhau. Các model này có thể chứa tập các quy tắc và logic có thể được
dùng rộng rãi ở các lớp cần được sử dụng.
* Tại mỗi [ứng dụng](structure-applications.md) hoặc [module](structure-modules.md) có dùng model,
ta định nghĩa lớp khung model bằng việc kế thừa từ lớp model cơ sở. Lớp khung model này
có thể chứa các quy tắc logic được mô tả cụ thể chi ứng dụng hoặc module này.
Ví dụ, với [Mẫu Dự án Advanced](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md), bạn có thể định nghĩa lớp cơ sở model
`common\models\Post`. Tiếp đến tại ứng dụng front end, bạn định nghĩa lớp khung là
`frontend\models\Post` lớp này kế thừa từ lớp `common\models\Post`. Và tương tự cho ứng dụng back end,
bạn định nghĩa model `backend\models\Post`. Với cách giải quyết này, bạn sẽ chắc chắn rằng mã của bạn tại model `frontend\models\Post`
chỉ dùng cho ứng dụng front end, và nếu bạn thực hiện với bất kỳ thay đổi nào, bạn không cần lo lắng về
việc thay đổi này có ảnh hưởng tới ứng dụng back end.

16
docs/guide/README.md

@ -169,14 +169,14 @@ Special Topics
Widgets
-------
* [[yii\grid\GridView|GridView]]
* [[yii\widgets\ListView|ListView]]
* [[yii\widgets\DetailView|DetailView]]
* [[yii\widgets\ActiveForm|ActiveForm]]
* [[yii\widgets\Pjax|Pjax]]
* [[yii\widgets\Menu|Menu]]
* [[yii\widgets\LinkPager|LinkPager]]
* [[yii\widgets\LinkSorter|LinkSorter]]
* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Bootstrap Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [jQuery UI Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)

18
docs/guide/db-active-record.md

@ -741,9 +741,10 @@ To use optimistic locking,
1. Create a column in the DB table associated with the Active Record class to store the version number of each row.
The column should be of big integer type (in MySQL it would be `BIGINT DEFAULT 0`).
2. Override the [[yii\db\ActiveRecord::optimisticLock()]] method to return the name of this column.
3. In the Web form that takes user inputs, add a hidden field to store the current version number of the row being updated.
Be sure your version attribute has input validation rules and validates successfully.
4. In the controller action that updates the row using Active Record, try and catch the [[yii\db\StaleObjectException]]
3. Implement [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] inside your model class to automatically parse its value from received requests.
4. In the Web form that takes user inputs, add a hidden field to store the current version number of the row being updated.
Remove the version attribute from validation rules as [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] should handle it.
5. In the controller action that updates the row using Active Record, try and catch the [[yii\db\StaleObjectException]]
exception. Implement necessary business logic (e.g. merging the changes, prompting staled data) to resolve the conflict.
For example, assume the version column is named as `version`. You can implement optimistic locking with the code like
@ -778,6 +779,17 @@ public function actionUpdate($id)
// logic to resolve the conflict
}
}
// ------ model code -------
use yii\behaviors\OptimisticLockBehavior;
public function behaviors()
{
return [
OptimisticLockBehavior::className(),
];
}
```

2
docs/guide/db-query-builder.md

@ -237,7 +237,7 @@ guide article. For example the following code is vulnerable:
```php
// Vulnerable code:
$column = $request->get('column');
$value = $request->get('value);
$value = $request->get('value');
$query->where([$column => $value]);
// $value is safe, but $column name won't be encoded!
```

4
docs/guide/tutorial-template-engines.md

@ -45,5 +45,5 @@ That code would be added to the `require` section of `composer.json`. After maki
For details about using concrete template engine please refer to its documentation:
- [Twig guide](https://github.com/yiisoft/yii2-twig/tree/master/docs/guide)
- [Smarty guide](https://github.com/yiisoft/yii2-smarty/tree/master/docs/guide)
- [Twig guide](https://www.yiiframework.com/extension/yiisoft/yii2-twig/doc/guide/)
- [Smarty guide](https://www.yiiframework.com/extension/yiisoft/yii2-smarty/doc/guide/)

5
docs/internals-ja/README.md

@ -24,7 +24,7 @@ Yii 開発者ドキュメント
フレームワーク開発
------------------
- [プルリクエストの品質保証](pull-request-qa.md)
- [プルリクエストの品質保証](pull-request-qa.md)
- [自動化されるタスク](automation.md) コード・スタイルの修正、ドキュメントやファイルの自動生成など。
- [設計上の決定](design-decisions.md) - よく議論される事柄についての FAQ 形式の声明リスト。
@ -45,5 +45,4 @@ Yii 開発者ドキュメント
### データベースのテスト
[こちら](https://gist.github.com/sergeymakinen/0696a5952f160ea28d7b64c3adfecf6f) に、
Yii がサポートする全てのデータベースのためのテスト環境構成があります。
[こちら](https://gist.github.com/sergeymakinen/0696a5952f160ea28d7b64c3adfecf6f) に、Yii がサポートする全てのデータベースのためのテスト環境構成があります。

3
docs/internals-ja/automation.md

@ -17,7 +17,6 @@ Yii の開発に取り組む際に、自動化できるタスクがいくつか
- Mime タイプ・マジック・ファイル (`framework/helpers/mimeTypes.php`) の Apache HTTPd レポジトリによる更新。
`./build/build mime-type` を実行してファイルを更新して下さい。
- CHANGELOG ファイルのエントリの出現順序は、`./build/build release/sort-changelog framework`
を実行することで更新することが出来ます。
- CHANGELOG ファイルのエントリの出現順序は、`./build/build release/sort-changelog framework` を実行することで更新することが出来ます。
上記のコマンドの全てが [リリースの工程]() に含まれています。これらをリリースとリリースの間に実行しても構いませんが、必要ではありません。

85
docs/internals-ja/core-code-style.md

@ -3,19 +3,16 @@ Yii 2 コア・フレームワーク・コード・スタイル
下記のコード・スタイルが Yii 2.x コアと公式エクステンションの開発に用いられています。
コアに対してコードをプル・リクエストをしたいときは、これを使用することを考慮してください。
私たちは、あなたが自分のアプリケーションにこのコード・スタイルを使うことを強制するものではありません。
あなたにとってより良いコード・スタイルを自由に選んでください。
私たちは、あなたが自分のアプリケーションにこのコード・スタイルを使うことを強制するものではありません。あなたにとってより良いコード・スタイルを自由に選んでください。
なお、CodeSniffer のための設定をここで入手できます: https://github.com/yiisoft/yii2-coding-standards
> Note: 以下では、説明のために、サンプル・コードのドキュメントやコメントを日本語に翻訳しています。
しかし、コア・コードや公式エクステンションに対して実際に寄稿する場合には、それらを英語で書く必要があります。
## 1. 概要
全体として、私たちは [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) 互換のスタイルを使っていますので、
[PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) に適用されることは、すべて私たちのコード・スタイルにも適用されます。
全体として、私たちは [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
互換のスタイルを使っていますので、
[PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) に適用されることは、
すべて私たちのコード・スタイルにも適用されます。
- ファイルは `<?php` または `<?=` のタグを使わなければならない。
- ファイルの末尾には一個の改行があるべきである。
@ -59,7 +56,7 @@ PHP コードは BOM 無しの UTF-8 のみを使わなければなりません
```php
/**
* ドキュメント
* Documentation
*/
class MyClass extends \yii\base\BaseObject implements MyInterface
{
@ -91,7 +88,8 @@ class Foo
- より読みやすいように、プロパティの宣言は空行を挟まずに続け、プロパティ宣言とメソッド宣言のブロック間には2行の空行を挟むべきです。
また、異なる可視性のグループの間に、1行の空行を追加するべきです。
- Private 変数は `$_varName` のように名付けるべきです。
- Public なクラス・メンバとスタンドアロンな変数は、先頭を小文字にした `$camelCase` で名付けるべきです。
- Public なクラス・メンバとスタンドアロンな変数は、
先頭を小文字にした `$camelCase` で名付けるべきです。
- 説明的な名前を使うこと。`$i` や `$j` のような変数は使わないようにしましょう。
例えば、
@ -119,17 +117,18 @@ class Foo
- 関数およびメソッドは、先頭を小文字にした `camelCase` で名付けるべきです。
- 名前は、関数の目的を示す自己説明的なものであるべきです。
- クラスのメソッドは常に修飾子 `private`、`protected` または `public` を使って、可視性を宣言すべきです。`var` は許可されません。
- クラスのメソッドは常に修飾子 `private`、`protected` または `public` を使って、可視性を宣言すべきです。
`var` は許可されません。
- 関数の開始の中括弧は関数宣言の次の行に置くべきです。
```php
/**
* ドキュメント
* Documentation
*/
class Foo
{
/**
* ドキュメント
* Documentation
*/
public function bar()
{
@ -145,8 +144,7 @@ class Foo
`Model` または `ActiveRecord` のようなクラス名を使うことも出来ます。
- 型付きの配列に対しては `ClassName[]` を使います。
- PHPDoc の最初の行には、メソッドの目的を記述しなければなりません。
- メソッドが何かをチェックする (たとえば、`isActive`, `hasClass` など) ものである場合は、
最初の行は `Checks whether` で始まらなければなりません。
- メソッドが何かをチェックする (たとえば、`isActive`, `hasClass` など) ものである場合は、最初の行は `Checks whether` で始まらなければなりません。
- `@return` は、厳密に何が返されるのかを明示的に記述しなければなりません。
```php
@ -164,7 +162,6 @@ class Foo
}
```
### 4.5 コンストラクタ
- PHP 4 スタイルのコンストラクタの代りに、`__construct` が使われるべきです。
@ -199,14 +196,14 @@ $str = 'こんな具合に。';
#### 変数置換
```php
$str1 = "こんにちは $username さん";
$str2 = "こんにちは {$username} さん";
$str1 = "Hello $username!";
$str2 = "Hello {$username}!";
```
下記は許可されません。
```php
$str3 = "こんにちは ${username} さん";
$str3 = "Hello ${username}!";
```
#### 連結
@ -367,23 +364,27 @@ $mul = array_reduce($numbers, function($r, $x) use($n) {
- ドキュメントの文法については [phpDoc](http://phpdoc.org/) を参照してください。
- ドキュメントの無いコードは許容されません。
- 全てのクラス・ファイルは、ファイル・レベルの doc ブロックを各ファイルの先頭に持ち、クラス・レベルの doc ブロックを各クラスの直前に持たなければなりません。
- 全てのクラス・ファイルは、ファイル・レベルの doc ブロックを各ファイルの先頭に持ち、
クラス・レベルの doc ブロックを各クラスの直前に持たなければなりません。
- メソッドが実際に何も返さないときは `@return` を使う必要はありません。
- `yii\base\BaseObject` から派生するクラスのすべての仮想プロパティは、クラスの doc ブロックで `@property` タグでドキュメントされます。
これらの注釈は、`build` ディレクトリで `./build php-doc` コマンドを走らせることにより、対応する getter や setter の `@return``@param` タグから自動的に生成されます。
getter や setter に `@property` タグを追加することによって、これらのメソッドによって導入されるプロパティに対してドキュメントのメッセージを明示的に与えることが出来ます。
- `yii\base\BaseObject` から派生するクラスのすべての仮想プロパティは、クラスの doc ブロックで
`@property` タグでドキュメントされます。
これらの注釈は、`build` ディレクトリで `./build php-doc` コマンドを走らせることにより、
対応する getter や setter の `@return``@param` タグから自動的に生成されます。
getter や setter に `@property` タグを追加することによって、これらのメソッドによって導入されるプロパティに対して
ドキュメントのメッセージを明示的に与えることが出来ます。
これは `@return` で記述されているのとは違う説明を与えたい場合に有用です。
下記が一例です。
```php
<?php
/**
* 全ての属性または一つの属性についてエラーを返す。
* @param string $attribute 属性の名前。全ての属性についてエラーを取得するためには null を使う。
* @property array 全ての属性に対するエラーの配列。エラーが無い場合は空の配列が返される。
* 結果は二次元の配列である。詳細な説明は [[getErrors()]] を参照。
* @return array 全ての属性または特定の属性に対するエラー。エラーが無い場合は空の配列が返される。
* 全ての属性に対するエラーを返す場合、結果は、下記のような二次元の配列になる。
* Returns the errors for all attribute or a single attribute.
* @param string $attribute attribute name. Use null to retrieve errors for all attributes.
* @property array An array of errors for all attributes. Empty array is returned if no error.
* The result is a two-dimensional array. See [[getErrors()]] for detailed description.
* @return array errors for all attributes or the specified attribute. Empty array is returned if no error.
* Note that when returning errors for all attributes, the result is a two-dimensional array, like the following:
* ...
*/
public function getErrors($attribute = null)
@ -404,7 +405,7 @@ $mul = array_reduce($numbers, function($r, $x) use($n) {
```php
/**
* Component *property*、*event* および *behavior* の機能を提供する基底クラスである。
* Component is the base class that provides the *property*, *event* and *behavior* features.
*
* @include @yii/docs/base-Component.md
*
@ -419,23 +420,25 @@ class Component extends \yii\base\BaseObject
```php
/**
* イベントに対してアタッチされたイベント・ハンドラのリストを返す。
* 返された [[Vector]] オブジェクトを操作して、ハンドラを追加したり削除したり出来る。
* 例えば、
* Returns the list of attached event handlers for an event.
* You may manipulate the returned [[Vector]] object by adding or removing handlers.
* For example,
*
* ```
* $component->getEventHandlers($eventName)->insertAt(0, $eventHandler);
* ```
*
* @param string $name イベントの名前
* @return Vector イベントにアタッチされたハンドラのリスト
* @throws Exception イベントが定義されていない場合
* @param string $name the event name
* @return Vector list of attached event handlers for the event
* @throws Exception if the event is not defined
*/
public function getEventHandlers($name)
{
if (!isset($this->_e[$name])) {
$this->_e[$name] = new Vector;
}
$this->ensureBehaviors();
return $this->_e[$name];
}
```
@ -453,7 +456,7 @@ public function getEventHandlers($name)
上記のリンクにクラス名やメソッド名以外のラベルを付けるためには、次の例で示されている文法を使うことが出来ます。
```
... [[header|ヘッダ・セル]] に表示されているように
... as displayed in the [[header|header cell]].
```
`|` の前の部分がメソッド、プロパティ、クラスへの参照であり、`|` の後ろの部分がリンクのラベルです。
@ -461,8 +464,8 @@ public function getEventHandlers($name)
下記の文法を使ってガイドにリンクすることも可能です。
```markdown
[ガイドへのリンク](guide:file-name.md)
[ガイドへのリンク](guide:file-name.md#subsection)
[link to guide](guide:file-name.md)
[link to guide](guide:file-name.md#subsection)
```
@ -492,8 +495,7 @@ public function getEventHandlers($name)
### 「何かをするな」を示す値
コンポーネントに対して「何かをしない」という設定を許可するプロパティは `false` の値を受け入れるべきです。
`null`、`''`、または `[]` がそういう値であると見なされるべきではありません。
コンポーネントに対して「何かをしない」という設定を許可するプロパティは `false` の値を受け入れるべきです。`null`、`''`、または `[]` がそういう値であると見なされるべきではありません。
### ディレクトリ/名前空間の名前
@ -502,3 +504,4 @@ public function getEventHandlers($name)
- 機能や特徴を表す名前には単数形を使います (例えば、web)。
- 出来れば単一の語の名前空間にします。
- 単一の語が適切でない場合は、camelCase を使います。

7
docs/internals-ja/design-decisions.md

@ -25,8 +25,5 @@
<https://github.com/yiisoft/yii/pull/1923#issuecomment-11881967>
6. [ヘルパか、独立した非スタティックなクラスか](https://github.com/yiisoft/yii2/pull/12661#issuecomment-251599463)
7. **セッター・メソッド・チェイニング** は、意味のある値を返すメソッドがそのクラスに存在する場合は、避けるべきである。
チェイニングは、クラスがビルダーであり、全てのセッターが内部状態を修正するものである場合にサポートされうる。
https://github.com/yiisoft/yii2/issues/13026
8. ローカルな try-catch の替りに **グローバルな例外/エラーハンドラ** が使われる。
なぜなら、その方が、ブートストラップなどのように `run()` メソッドのスコープ外で発生するデストラクタなど全てのものをキャッチする点において信頼性が高いからである。
[#14348](https://github.com/yiisoft/yii2/issues/14348) を参照。
チェイニングは、クラスがビルダーであり、全てのセッターが内部状態を修正するものである場合にサポートされうる。https://github.com/yiisoft/yii2/issues/13026
8. ローカルな try-catch の替りに **グローバルな例外/エラーハンドラ** が使われる。なぜなら、その方が、ブートストラップなどのように `run()` メソッドのスコープ外で発生するデストラクタなど全てのものをキャッチする点において信頼性が高いからである。[#14348](https://github.com/yiisoft/yii2/issues/14348) を参照。

56
docs/internals-ja/git-workflow.md

@ -3,7 +3,8 @@ Yii 2 寄稿者のための Git ワークフロー
で、Yii の開発に貢献したい、と。すばらしい。
でも、あなたの修正案が速やかに採用されるチャンスを増やすために、以下のステップを踏むようにしてください。
あなたが git と github については初めてだという場合は、最初に [github help](http://help.github.com/) や [try git](https://try.github.com) を精査したり、[git internal data model](http://nfarina.com/post/9868516270/git-is-simpler) についていくらか学習したりする必要があるかもしれません。
あなたが git と github については初めてだという場合は、最初に [github help](http://help.github.com/) や [try git](https://try.github.com) を精査したり、
[git internal data model](http://nfarina.com/post/9868516270/git-is-simpler) についていくらか学習したりする必要があるかもしれません。
あなたの開発環境を準備する
--------------------------
@ -17,7 +18,8 @@ Yii 2 寄稿者のための Git ワークフロー
git clone git@github.com:YOUR-GITHUB-USERNAME/yii2.git
```
Linux において、GitHub で GIT を設定するのに問題が生じたり、"Permission Denied (publickey)" のようなエラーが発生したりする場合は、[setup your GIT installation to work with GitHub](http://help.github.com/linux-set-up-git/) に従ってください。
Linux において、GitHub で GIT を設定するのに問題が生じたり、"Permission Denied (publickey)" のようなエラーが発生したりする場合は、
[setup your GIT installation to work with GitHub](http://help.github.com/linux-set-up-git/) に従ってください。
> Tip: あなたが Git に精通していない場合は、素晴らしい無料の [プロ Git ブック](https://git-scm.com/book/en/v2) を読むことをお勧めします。
@ -37,16 +39,14 @@ git remote add upstream git://github.com/yiisoft/yii2.git
JavaScript を扱おうとしている場合は、
- `npm install` を実行して JavaScript テスト・ツール群とその依存ライブラリをインストールします
([Node.js と NPM のインストール](https://nodejs.org/en/download/package-manager/) は完了しているものとします)。
- `npm install` を実行して JavaScript テスト・ツール群とその依存ライブラリをインストールします ([Node.js と NPM のインストール](https://nodejs.org/en/download/package-manager/) は完了しているものとします)。
> Note: JavaScript のテストが依存している [jsdom](https://github.com/tmpvar/jsdom) ライブラリは、Node.js 4 以降を必要とします。
Node.js 6 または 7 を使用することをより強く推奨します。
- `php build/build dev/app basic <fork>` を実行し、ベーシック・アプリケーションをクローンし、ベーシック・アプリケーションのための composer 依存パッケージをインストールします
- `php build/build dev/app basic <fork>` を実行し、ベーシック・アプリケーションをクローンし、ベーシック・アプリケーションのための composer 依存パッケージをインストールします
ここで `<fork>` は、`git@github.com:my_nickname/yii2-app-basic.git` のような、あなたのレポジトリのフォークの URL です。
あなたがコア・フレームワークの貢献者である場合は、フォークの指定を省略しても構いません。
このコマンドは外部 composer パッケージは通常どおりインストールしますが、yii2 レポジトリは現在チェックアウトされているものをリンクします。
あなたがコア・フレームワークの貢献者である場合は、フォークの指定を省略しても構いません。このコマンドは外部 composer パッケージは通常どおりインストールしますが、yii2 レポジトリは現在チェックアウトされているものをリンクします。
これで、インストールされる全てのコードについて、一つのインスタンスを持つことになります。
必要であれば、アドバンスト・アプリケーションについても同様にします: `php build/build dev/app advanced <fork>`
@ -68,24 +68,20 @@ phpunit をグローバルにインストールしていない場合は、代り
テストによっては、データベースの設定と構成が必要なものがあります。
`tests/data/config.local.php` を作成して、`tests/data/config.php` において構成されている設定を上書きすることが出来ます。
取り組んでいるグループのものだけにテストを限定することが出来ます。
例えば、バリデータと redis のためのテストだけを走らせるためには、`phpunit --group=validators,redis` とします。
取り組んでいるグループのものだけにテストを限定することが出来ます。例えば、バリデータと redis のためのテストだけを走らせるためには、`phpunit --group=validators,redis` とします。
利用できるグループのリストを取得するためには、`phpunit --list-groups` を実行してください。
JavaScript の単体テストは、レポジトリのルート・ディレクトリで `npm test` を走らせることによって実行することが出来ます。
### エクステンション
エクステンションに取り組むためには、エクステンションのレポジトリをクローンする必要があります。
私たちは、あなたに代ってそれをするコマンドを作っています。
エクステンションに取り組むためには、エクステンションのレポジトリをクローンする必要があります。私たちは、あなたに代ってそれをするコマンドを作っています。
```
php build/build dev/ext <extension-name> <fork>
```
ここで `<extension-name>` がエクステンションの名前、例えば `redis` です。
そして `<fork>` は、`git@github.com:my_nickname/yii2-redis.git` のような、あなたのエクステンションのフォークの URL です。
あなたがコア・フレームワークの貢献者である場合は、フォークの指定を省略しても構いません。
ここで `<extension-name>` がエクステンションの名前、例えば `redis` です。そして `<fork>` は、`git@github.com:my_nickname/yii2-redis.git` のような、あなたのエクステンションのフォークの URL です。あなたがコア・フレームワークの貢献者である場合は、フォークの指定を省略しても構いません。
エクステンションをアプリケーション・テンプレートのどちらかでテストしたい場合は、通常そうするように、アプリケーションの `composer.json` にそれを追加するだけです。
例えば、ベーシック・アプリケーションの `require` セクションに `"yiisoft/yii2-redis": "~2.0.0"` を追加します。
@ -95,6 +91,7 @@ php build/build dev/ext <extension-name> <fork>
> Note: デフォルトの git レポジトリの Url を使うため、SSH 経由で github からクローンすることになります。
> `build` コマンドに `--useHttp` フラグを追加すれば、代りに HTTP を使うことが出来ます。
バグ修正と機能改良に取り組む
----------------------------
@ -109,8 +106,7 @@ php build/build dev/ext <extension-name> <fork>
単純な修正であれば、直接にプル・リクエストをしてください。
こうすることで、開発チームはあなたの提案をレビューし、将来にわたって適切なフィードバックを提供することが可能になります。
> 小さな変更や、ドキュメントの問題、または単純な修正については、課題を作成する必要はありません。
それらについては、プル・リクエストだけで十分です。
> 小さな変更や、ドキュメントの問題、または単純な修正については、課題を作成する必要はありません。それらについては、プル・リクエストだけで十分です。
### 2. メインの Yii ブランチから最新のコードをプルする
@ -122,12 +118,12 @@ git pull upstream
### 3. 現在の Yii のマスター・ブランチに基いて、あなたの寄稿のための新しいブランチを作成する
> これは非常に重要です。なぜなら、master ブランチを使うと、あなたのアカウントからは一つ以上のプル・リクエストを送信することが出来なくなるからです。
> これは非常に重要です。なぜなら、master ブランチを使うと、
あなたのアカウントからは一つ以上のプル・リクエストを送信することが出来なくなるからです。
独立したバグ修正や変更は、各々、それ自身のブランチに入れるべきです。
ブランチの名前は説明的なものにし、あなたのコードが関係する課題の番号で始まるようにしてください。
特定の課題を修正するものでない場合は、番号を省略してください。
例えば、
特定の課題を修正するものでない場合は、番号を省略してください。例えば、
```
git checkout upstream/master
@ -143,8 +139,7 @@ git checkout -b 999-name-of-your-branch-goes-here
### 5. CHANGELOG を更新する
CHANGELOG ファイルを編集して、あなたの修正を追加します。
新しい行は、ファイル冒頭の最初の見出し (現在開発中のバージョン) の下に挿入してください。
CHANGELOG ファイルを編集して、あなたの修正を追加します。新しい行は、ファイル冒頭の最初の見出し (現在開発中のバージョン) の下に挿入してください。
チェンジログの行は、下記のどちらかのように書いてください。
```
@ -196,7 +191,8 @@ git push -u origin 999-name-of-your-branch-goes-here
### 9. upstream に対して [プルリクエスト](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) を発行する
github 上のあなたのリポジトリに入って、"Pull Request" をクリックし、右側にあるブランチを選び、コメント・ボックスにもう少し詳細を記述します。
github 上のあなたのリポジトリに入って、"Pull Request" をクリックし、右側にあるブランチを選び、
コメント・ボックスにもう少し詳細を記述します。
プル・リクエストを課題とリンクさせるために、プル・コメントのどこかに `#999` という書式で課題番号を記載します。
> 全てのプル・リクエストはそれぞれ一つの課題を解決すべきものであることに注意してください。
@ -204,15 +200,14 @@ github 上のあなたのリポジトリに入って、"Pull Request" をクリ
### 10. 誰かがあなたのコードをレビューする
誰かがあなたのコードをレビューします。あなたは修正を求められるかも知れません。その場合は、ステップ #6 に戻ってください
(現在のプル・リクエストが open である限りは、別の新しいプル・リクエストをする必要はありません)。
あなたのコードが受け入れられた場合は、コードはメイン・ブランチにマージされて、次回の Yii のリリースの一部となります。
受け入れられなくても、落胆しないでください。
必要とする機能は人によってさまざまに異なりますし、Yii は全ての人に対して全てを提供することは出来ません。
(現在のプル・リクエストが open である限りは、別の新しいプル・リクエストをする必要はありません)。あなたのコードが受け入れられた場合は、コードはメイン・ブランチにマージされて、次回の Yii のリリースの一部となります。
受け入れられなくても、落胆しないでください。必要とする機能は人によってさまざまに異なりますし、Yii は全ての人に対して全てを提供することは出来ません。
また、却下された場合でも、あなたのコードはそれを必要とする人々から参照されるように github 上で公開され続けます。
### 11. クリーンアップする
あなたのコードが受け入れられるか却下されるかした後、あなたが作業してきたブランチをローカル・レポジトリおよび `origin` から削除することが出来ます。
あなたのコードが受け入れられるか却下されるかした後、あなたが作業してきたブランチをローカル・レポジトリおよび
`origin` から削除することが出来ます。
```
git checkout master
@ -223,15 +218,14 @@ git push origin --delete 999-name-of-your-branch-goes-here
### 注意:
退行 (regression) を早期に発見するために、github 上の Yii コード・ベースへのマージは、すべて [Travis CI](http://travis-ci.org) に取り上げられて、自動化されたテストにかけられます。
コア・チームとしては、このサービスに過大な負担をかけたくないために、以下の場合にはマージの説明に [`[ci skip]`](https://docs.travis-ci.com/user/customizing-the-build/#Skipping-a-build) が含まれるようにしてください。
すなわち、プル・リクエストが、
コア・チームとしては、このサービスに過大な負担をかけたくないために、以下の場合にはマージの説明に
[`[ci skip]`](https://docs.travis-ci.com/user/customizing-the-build/#Skipping-a-build) が含まれるようにしてください。
すなわち、プル・リクエストが下記のものである場合がそうです。
* javascript、css または画像ファイルだけに影響する場合
* ドキュメントを更新する場合
* 固定の文字列だけを修正する (例えば、翻訳をアップデートする) 場合
がそうです。
このようにすることによって、そもそもテストによってカバーされない変更に対しては、travis がテスト・ランを開始しないようにすることが出来ます。
### コマンド概要 (上級の寄稿者向け)

15
docs/internals-ja/project-organization.md

@ -3,18 +3,19 @@
このドキュメントは Yii 2 開発レポジトリの編成を説明するものです。
1. 個々のコア・エクステンションとアプリケーション・テンプレートは、[yiisoft](https://github.com/yiisoft) Github オーガニゼーションの下の *独立した* 別の Github プロジェクトとして保守されます。
1. 個々のコア・エクステンションとアプリケーション・テンプレートは、[yiisoft](https://github.com/yiisoft) Github オーガニゼーションの下の
*独立した* 別の Github プロジェクトとして保守されます。
エクステンションのプロジェクト名は、先頭に `yii2-` を付けます。例えば、`gii` エクステンションは `yii2-gii` です。
エクステンションのレポジトリ名は、先頭に `yii2-` を付けます。例えば、`gii` エクステンションは `yii2-gii` です。
Composer のパッケージ名は Github レポジトリ名と同じで、例えば `yiisoft/yii2-gii` です。
アプリケーション・テンプレートのプロジェクト名は、先頭に `yii2-app-` を付けます。例えば、`basic` アプリケーション・テンプレートは `yii2-app-basici` です。
アプリケーション・テンプレートのレポジトリ名は、先頭に `yii2-app-` を付けます。例えば、`basic` アプリケーション・テンプレートは `yii2-app-basici` です。
Composer のパッケージ名は Github レポジトリ名と同じで、例えば `yiisoft/yii2-app-basic` です。
各々のエクステンション/アプリケーションのプロジェクトは、
* "docs" フォルダにおいてそのチュートリアル・ドキュメントを保守します。API ドキュメントは、エクステンション/アプリケーションがリリースされるときにその場で生成されます。
* "tests" フォルダにおいてそれ自身のテストコードを保守します。
* "tests" フォルダにおいてそれ自身のテストコードを保守します。
* それ自身のメッセージ翻訳やその他全ての関係するメタコードを保守します。
* 対応する Github プロジェクトによって、課題 (issue) を追跡します。
@ -28,6 +29,8 @@
コア・フレームワークのバグと機能要望は、この Github プロジェクトのイッシュー・トラッカーによって追跡されます。
3. `yiisoft/yii2-framework` レポジトリは、開発プロジェクト・レポジトリの `framework` ディレクトリのリード・オンリーな git subsplit です。
このレポジトリが、フレームワークのインストールに使用される Composer 公式パッケージである [yiisoft/yii2](https://packagist.org/packages/yiisoft/yii2) を提供します。
このレポジトリが、フレームワークのインストールに使用される Composer 公式パッケージである
[yiisoft/yii2](https://packagist.org/packages/yiisoft/yii2) を提供します。
4. 開発するときには、[build dev/app](git-workflow.md#prepare-the-test-environment) コマンドを使って、アプリケーションとエクステンションを開発プロジェクトの構成に含めることが出来ます。
4. 開発するときには、[build dev/app](git-workflow.md#prepare-the-test-environment) コマンドを使って、
アプリケーションとエクステンションを開発プロジェクトの構成に含めることが出来ます。

3
docs/internals-ja/pull-request-qa.md

@ -7,4 +7,5 @@ PR をマージできるか否かをチェックするときには、特に以
- 単体テスト。必須ではありませんが、大いに歓迎されます。PR によって修正されるコードが無ければ失敗する、というテストであること。
- CHANGELOG のエントリがあること。エントリは次のリリースのセクションに、課題のタイプと番号の順に書き入れます。
担当した者のニックネームがあること。
- [コード・スタイル](core-code-style.md) および [ビュー・コード・スタイル](view-code-style.md) が OK であること。これらは、マージされる際に、マージする者の判断に従って修正される場合があります。
- [コード・スタイル](core-code-style.md) および [ビュー・コード・スタイル](view-code-style.md) が OK であること。
これらは、マージされる際に、マージする者の判断に従って修正される場合があります。

16
docs/internals-ja/release.md

@ -12,9 +12,11 @@
リリース・コマンド
------------------
リリースの手順は、フレームワークの開発レポジトリに含まれている [release コンソール・コマンド](../../build/controllers/ReleaseController.php) によって自動化されています。
リリースの手順は、フレームワークの開発レポジトリに含まれている [release コンソール・コマンド](../../build/controllers/ReleaseController.php)
によって自動化されています。
リリース・コマンドは、フレームワークの `build` ディレクトリに含まれている Yii アプリケーションを使って呼び出すことが出来ます。
リリース・コマンドは、フレームワークの `build` ディレクトリに含まれている Yii
アプリケーションを使って呼び出すことが出来ます。
./build/build help release # このコマンドをフレームワークのレポジトリのルートで実行します
@ -36,7 +38,8 @@
./build/build dev/app basic
このインストール方法によって、エクステンションが現在のレポジトリの状態と同じフレームワーク・コードを使用する事を保証することが出来ます。
このインストール方法によって、エクステンションが現在のレポジトリの状態と同じフレームワーク・コードを使用する事を
保証することが出来ます。
### バージョンの概要
@ -65,8 +68,10 @@
#### 新しいメジャー・バージョン、例えば 2.1.0 をリリースする
新しいメジャー・バージョンのリリースは、[バージョン規約](versions.md) で説明されているように、ブランチの変更を伴います。
以下は、`master` から派生した `2.1` ブランチ上で開発されている `2.1.0` バージョンをリリースする例を示すものです。
新しいメジャー・バージョンのリリースは、[バージョン規約](versions.md) で説明されているように、
ブランチの変更を伴います。
以下は、`master` から派生した `2.1` ブランチ上で開発されている
`2.1.0` バージョンをリリースする例を示すものです。
リリース前においては `master``2.0.x` の諸バージョンを含んでいます。
- `master` から新しいブランチ `2.0` を作成する
@ -77,3 +82,4 @@
- `2.1` ブランチを削除する
`master` をチェックアウトし、`--version=2.1.0` オプションを付けて、リリース・コマンドを実行する。

3
docs/internals-ja/report-an-issue.md

@ -18,5 +18,4 @@
**課題の重複を避ける**
課題を報告する前に、[既存の課題](https://github.com/yiisoft/yii2/issues) を検索して、あなたが報告しようとしている課題が既に報告されていたり解決されていたりしないかを確かめ、重複した課題を報告しないようにしてください。
さらにまた、Yii の最新のバージョンを使ってみて、それでもまだ問題が残っているかどうかを確かめてください。
課題を報告する前に、[既存の課題](https://github.com/yiisoft/yii2/issues) を検索して、あなたが報告しようとしている課題が既に報告されていたり解決されていたりしないかを確かめ、重複した課題を報告しないようにしてください。さらにまた、Yii の最新のバージョンを使ってみて、それでもまだ問題が残っているかどうかを確かめてください。

9
docs/internals-ja/translation-workflow.md

@ -14,7 +14,8 @@ Yii は国際的なアプリケーションと開発者にとって役に立つ
1. `framework/messages/config.php` をチェックして、あなたの言語が `languages` のリストに載っていることを確認してください。
もし無ければ、あなたの言語をそこに追加します (リストをアルファベット順に保つことを忘れないでください)。
言語コードの形式は、例えば `ru``zh-CN` のように、[IETF言語タグ](http://ja.wikipedia.org/wiki/IETF%E8%A8%80%E8%AA%9E%E3%82%BF%E3%82%B0) に従うべきです。
言語コードの形式は、例えば `ru``zh-CN` のように、
[IETF言語タグ](http://ja.wikipedia.org/wiki/IETF%E8%A8%80%E8%AA%9E%E3%82%BF%E3%82%B0) に従うべきです。
2. `framework` に入って、`./yii message/extract @yii/messages/config.php --languages=<your_language>` を走らせます。
3. `framework/messages/your_language/yii.php` のメッセージを翻訳します。ファイルは必ず UTF-8 エンコーディングを使って保存してください。
4. [プル・リクエスト](git-workflow.md) をします。
@ -25,8 +26,7 @@ Yii は国際的なアプリケーションと開発者にとって役に立つ
翻訳ファイルの中で、配列の各要素は、メッセージ(キー)と翻訳(値)をあらわします。
値が空文字列の場合は、メッセージは翻訳されないものと見なされます。
翻訳が不要になったメッセージは、翻訳が一組の '@@' マークで囲まれます。
メッセージ文字列は複数形書式とともに使うことが出来ます。
詳細はガイドの [国際化](../guide-ja/tutorial-i18n.md) の節を参照してください。
メッセージ文字列は複数形書式とともに使うことが出来ます。詳細はガイドの [国際化](../guide-ja/tutorial-i18n.md) の節を参照してください。
ドキュメント
------------
@ -35,7 +35,8 @@ Yii は国際的なアプリケーションと開発者にとって役に立つ
ここで `<original>` は、`guide` や `internals` などの元の文書の名前であり、`<language>` は文書の翻訳先の言語コードです。
例えば、ロシア語のガイドの翻訳は `docs/guide-ru` です。
初期の仕事が完了した後は、最新の翻訳以後に変更されたソース文書の箇所を取得するために、`build` ディレクトリにある専用のコマンドを使うことが出来ます。
初期の仕事が完了した後は、最新の翻訳以後に変更されたソース文書の箇所を取得するために、
`build` ディレクトリにある専用のコマンドを使うことが出来ます。
```
php build translation "../docs/guide" "../docs/guide-ru" "Russian guide translation report" > report_guide_ru.html

13
docs/internals-ja/versions.md

@ -29,6 +29,7 @@ Yii バージョン規約
* プレ・リリースが必要: `2.X.0-alpha`, `2.X.0-beta`, `2.X.0-rc`
* 大きなニュース・リリースとマーケティング努力を必要とする。
## `2.x.Y`: マイナー・リリース
ほぼ後方互換であるマイナー・リリースです。
@ -36,14 +37,15 @@ Yii バージョン規約
しかし、すべてを 100% 後方互換に保つことが常に可能である訳ではありませんので、アップグレードに関するノートが `UPGRADE.md` に記録されます。
実際の運用では、2.0.x はより頻繁にリリースされるので、小さな機能改良の追加も行って、ユーザが新機能をより早く享受できるようにしています。
* 主としてバグ修正と小さな機能強化を含む。
* 大きな機能拡張や修正はしない。
* 不安無しのアップグレードを保証するために、100% 後方互換でなければならない。ごく少数の例外は許容されるが、その場合は `UPGRADE.md` に記録される。
* 主としてバグ修正と機能強化を含む。
* 不安無しのアップグレードを保証するために、ほぼ後方互換でなければならない。
ごく少数の例外は許容されるが、その場合は `UPGRADE.md` に記録される。
* リリースのサイクルは1~2ヶ月程度。
* プレ・リリース (alpha, beta, RC) は不要。
* 継続的に (少なくとも週に一回は手作業で) マスター・ブランチにマージ・バックされるべき。
* ニュースによる広報を伴う。プロジェクト・サイトがアップデートされる。
### `2.x.y.Z`: パッチ・リリース
バグ修正のみを含む、100% 後方互換であるべき、パッチ・リリースです。
@ -62,7 +64,7 @@ Yii バージョン規約
* `master` ブランチは、現在の安定版メジャー・リリースの開発ブランチで、現在は `2.0.x` バージョンです。
* 各メジャー・リリースは、そのバージョン番号の名前を持つブランチ上で開発されます。例えば、`2.1`。
* メジャー・リリース `2.n` の準備が出来たら、`master` から `2.(n-1).x` と名付けられた保守ブランチを作成します。
例えば、バージョン `2.1.0` が安定版としてリリースされ、`master` 上で開発されるようになると、`2.0` ブランチが作成されます。
例えば、バージョン `2.1.0` が安定版としてリリースされ、`master` 上で開発されるようになると、`2.0` ブランチが作成されます。
([composer branch naming schema](https://getcomposer.org/doc/02-libraries.md#branches) を参照).
* パッチ・リリースをマークするために `2.x.y.z` というタグと `2.x.y` ブランチを作成します。`0` は省略されます。
* `2.n.x` 保守ブランチ上の変更は、継続的に `master` ブランチにマージ・バックされます。
@ -74,8 +76,7 @@ Yii バージョン規約
## リリース
フレームワークと公式エクステンションのプロジェクトは、お互いに独立にリリースされます。
すなわち、すなわち、フレームワークとエクステンションの間で、バージョン番号が異なることが予想されます。
フレームワークと公式エクステンションのプロジェクトは、お互いに独立にリリースされます。すなわち、フレームワークとエクステンションの間で、バージョン番号が異なることが予想されます。
アプリケーション・テンプレートは、常に、フレームワークと同時にリリースされます。
上記で説明されたリリース・サイクルは、コア・フレームワークにのみ適用されます。

5
docs/internals-ja/view-code-style.md

@ -1,10 +1,7 @@
Yii 2 ビュー・コード・スタイル
==============================
下記のコード・スタイルが Yii 2.x コアと公式エクステンションのビュー・ファイルに用いられています。
私たちは、あなたが自分のアプリケーションにこのコード・スタイルを使うことを強制するものではありません。
あなたにとってより良いコード・スタイルを自由に選んでください。
下記のコード・スタイルが Yii 2.x コアと公式エクステンションのビュー・ファイルに用いられています。私たちは、あなたが自分のアプリケーションにこのコード・スタイルを使うことを強制するものではありません。あなたにとってより良いコード・スタイルを自由に選んでください。
```php
<?php

10
framework/CHANGELOG.md

@ -58,6 +58,9 @@ Yii Framework 2 Change Log
2.0.16 under development
------------------------
- Enh #9133: Added `yii\behaviors\OptimisticLockBehavior` (tunecino)
- Bug #16193: Fixed `yii\filters\Cors` to not reflect origin header value when configured to wildcard origins (Jianjun Chen)
- Bug #16068: Fixed `yii\web\CookieCollection::has` when an expiration param is set to 'until the browser is closed' (OndrejVasicek)
- Bug #16006: Handle case when `X-Forwarded-Host` header have multiple hosts separated with a comma (pgaultier)
- Bug #16010: Fixed `yii\filters\ContentNegotiator` behavior when GET parameters contain an array (rugabarbo)
- Bug #14660: Fixed `yii\caching\DbCache` concurrency issue when set values with the same key (rugabarbo)
@ -68,7 +71,14 @@ Yii Framework 2 Change Log
- Bug #16073: Fixed regression in Oracle `IN` condition builder for more than 1000 items (cebe)
- Bug #16120: FileCache: rebuild cache file before touch when different file owner (Slamdunk)
- Bug #16091: Make `yii\test\InitDbFixture` work with non-SQL DBMS (cebe)
- Bug #16184: Fixed `yii\base\Widget` to access `stack` property with `self` instead of `static` (yanggs07)
- Bug #16039: Fixed implicit conversion from `char` to `varbinnary` in MSSQL (vsivsivsi)
- Bug #16217: Fixed `yii\console\controllers\HelpController` to work well in Windows environment (samdark)
- Bug #14636: Views can now use relative paths even when using themed views (sammousa)
- Bug #16245: Fixed `__isset()` in `BaseActiveRecord` not catching errors (sammousa)
- Bug #16266: Fixed `yii\helpers\BaseStringHelper` where explode would not allow 0 as trim string (Thoulah)
- Enh #16191: Enhanced `yii\helpers\Inflector` to work correctly with UTF-8 (silverfire)
- Bug: Fixed bad instnaceof check in `yii\db\Schema::getTableMetadata()` (samdark)
2.0.15.1 March 21, 2018

20
framework/base/View.php

@ -175,7 +175,7 @@ class View extends Component implements DynamicContentAwareInterface
}
} elseif ($context instanceof ViewContextInterface) {
$file = $context->getViewPath() . DIRECTORY_SEPARATOR . $view;
} elseif (($currentViewFile = $this->getViewFile()) !== false) {
} elseif (($currentViewFile = $this->getRequestedViewFile()) !== false) {
$file = dirname($currentViewFile) . DIRECTORY_SEPARATOR . $view;
} else {
throw new InvalidCallException("Unable to resolve view file for view '$view': no active view context.");
@ -213,7 +213,7 @@ class View extends Component implements DynamicContentAwareInterface
*/
public function renderFile($viewFile, $params = [], $context = null)
{
$viewFile = Yii::getAlias($viewFile);
$viewFile = $requestedFile = Yii::getAlias($viewFile);
if ($this->theme !== null) {
$viewFile = $this->theme->applyTo($viewFile);
@ -229,7 +229,10 @@ class View extends Component implements DynamicContentAwareInterface
$this->context = $context;
}
$output = '';
$this->_viewFiles[] = $viewFile;
$this->_viewFiles[] = [
'resolved' => $viewFile,
'requested' => $requestedFile
];
if ($this->beforeRender($viewFile, $params)) {
Yii::debug("Rendering view file: $viewFile", __METHOD__);
@ -258,7 +261,16 @@ class View extends Component implements DynamicContentAwareInterface
*/
public function getViewFile()
{
return end($this->_viewFiles);
return empty($this->_viewFiles) ? false : end($this->_viewFiles)['resolved'];
}
/**
* @return string|bool the requested view currently being rendered. False if no view file is being rendered.
* @since 2.0.16
*/
protected function getRequestedViewFile()
{
return empty($this->_viewFiles) ? false : end($this->_viewFiles)['requested'];
}
/**

6
framework/base/Widget.php

@ -87,7 +87,7 @@ class Widget extends Component implements ViewContextInterface
$config['__class'] = get_called_class();
/* @var $widget Widget */
$widget = Yii::createObject($config);
static::$stack[] = $widget;
self::$stack[] = $widget;
return $widget;
}
@ -101,8 +101,8 @@ class Widget extends Component implements ViewContextInterface
*/
public static function end()
{
if (!empty(static::$stack)) {
$widget = array_pop(static::$stack);
if (!empty(self::$stack)) {
$widget = array_pop(self::$stack);
if (get_class($widget) === get_called_class()) {
/* @var $widget Widget */
if ($widget->beforeRun()) {

160
framework/behaviors/OptimisticLockBehavior.php

@ -0,0 +1,160 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\behaviors;
use Yii;
use yii\db\BaseActiveRecord;
use yii\base\InvalidCallException;
use yii\validators\NumberValidator;
/**
* OptimisticLockBehavior automatically upgrades a model's lock version using the column name
* returned by [[\yii\db\BaseActiveRecord::optimisticLock()|optimisticLock()]].
*
* Optimistic locking allows multiple users to access the same record for edits and avoids
* potential conflicts. In case when a user attempts to save the record upon some staled data
* (because another user has modified the data), a [[StaleObjectException]] exception will be thrown,
* and the update or deletion is skipped.
*
* To use this behavior, first enable optimistic lock by following the steps listed in
* [[\yii\db\BaseActiveRecord::optimisticLock()|optimisticLock()]], remove the column name
* holding the lock version from the [[\yii\base\Model::rules()|rules()]] method of your
* ActiveRecord class, then add the following code to it:
*
* ```php
* use yii\behaviors\OptimisticLockBehavior;
*
* public function behaviors()
* {
* return [
* OptimisticLockBehavior::className(),
* ];
* }
* ```
*
* By default, OptimisticLockBehavior will use [[\yii\web\Request::getBodyParam()|getBodyParam()]] to parse
* the submitted value or set it to 0 on any fail. That means a request not holding the version attribute
* may achieve a first successful update to entity, but starting from there any further try should fail
* unless the request is holding the expected version number. You can also configure the [[value]] property
* with a PHP callable to implement a different logic.
*
* OptimisticLockBehavior also provides a method named [[upgrade()]] that increases a model's
* version by one, that may be useful when you need to mark an entity as stale among connected clients
* and avoid any change to it until they load it again:
*
* ```php
* $model->upgrade();
* ```
*
* @author Salem Ouerdani <tunecino@gmail.com>
* @since 2.0.16
* @see \yii\db\BaseActiveRecord::optimisticLock() for details on how to enable optimistic lock.
*/
class OptimisticLockBehavior extends AttributeBehavior
{
/**
* {@inheritdoc}
*
* In case of `null` value it will be directly parsed from [[\yii\web\Request::getBodyParam()|getBodyParam()]] or set to 0.
*/
public $value;
/**
* {@inheritdoc}
*/
public $skipUpdateOnClean = false;
/**
* @var string the attribute name holding the version value.
*/
private $_lockAttribute;
/**
* {@inheritdoc}
*/
public function attach($owner)
{
parent::attach($owner);
if (empty($this->attributes)) {
$lock = $this->getLockAttribute();
$this->attributes = array_fill_keys(array_keys($this->events()), $lock);
}
}
/**
* {@inheritdoc}
*/
public function events()
{
return Yii::$app->request instanceof \yii\web\Request ? [
BaseActiveRecord::EVENT_BEFORE_INSERT => 'evaluateAttributes',
BaseActiveRecord::EVENT_BEFORE_UPDATE => 'evaluateAttributes',
BaseActiveRecord::EVENT_BEFORE_DELETE => 'evaluateAttributes',
] : [];
}
/**
* Returns the column name to hold the version value as defined in [[\yii\db\BaseActiveRecord::optimisticLock()|optimisticLock()]].
* @return string the property name.
* @throws InvalidCallException if [[\yii\db\BaseActiveRecord::optimisticLock()|optimisticLock()]] is not properly configured.
* @since 2.0.16
*/
protected function getLockAttribute()
{
if ($this->_lockAttribute) {
return $this->_lockAttribute;
}
/* @var $owner BaseActiveRecord */
$owner = $this->owner;
$lock = $owner->optimisticLock();
if ($lock === null || $owner->hasAttribute($lock) === false) {
throw new InvalidCallException("Unable to get the optimistic lock attribute. Probably 'optimisticLock()' method is misconfigured.");
}
$this->_lockAttribute = $lock;
return $lock;
}
/**
* {@inheritdoc}
*
* In case of `null`, value will be parsed from [[\yii\web\Request::getBodyParam()|getBodyParam()]] or set to 0.
*/
protected function getValue($event)
{
if ($this->value === null) {
$lock = $this->getLockAttribute();
$input = Yii::$app->getRequest()->getBodyParam($lock);
$isValid = $input && (new NumberValidator())->validate($input);
return $isValid ? $input : 0;
}
return parent::getValue($event);
}
/**
* Upgrades the version value by one and stores it to database.
*
* ```php
* $model->upgrade();
* ```
* @throws InvalidCallException if owner is a new record.
* @since 2.0.16
*/
public function upgrade()
{
/* @var $owner BaseActiveRecord */
$owner = $this->owner;
if ($owner->getIsNewRecord()) {
throw new InvalidCallException('Upgrading the model version is not possible on a new record.');
}
$lock = $this->getLockAttribute();
$version = $owner->$lock ?: 0;
$owner->updateAttributes([$lock => $version + 1]);
}
}

10
framework/console/controllers/HelpController.php

@ -116,13 +116,13 @@ class HelpController extends Controller
}
foreach ($controller->getActionArgsHelp($action) as $argument => $help) {
$description = str_replace("\n", '', addcslashes($help['comment'], ':')) ?: $argument;
$description = preg_replace("~\R~", '', addcslashes($help['comment'], ':')) ?: $argument;
$this->stdout($argument . ':' . $description . "\n");
}
$this->stdout("\n");
foreach ($controller->getActionOptionsHelp($action) as $argument => $help) {
$description = str_replace("\n", '', addcslashes($help['comment'], ':'));
$description = preg_replace("~\R~", '', addcslashes($help['comment'], ':'));
$this->stdout('--' . $argument . ($description ? ':' . $description : '') . "\n");
}
}
@ -251,16 +251,16 @@ class HelpController extends Controller
$file = $matches[0];
$relativePath = str_replace($controllerPath, '', $file);
$class = strtr($relativePath, [
DIRECTORY_SEPARATOR => '\\',
'/' => '\\',
'.php' => '',
]);
$controllerClass = $module->controllerNamespace . $class;
if ($this->validateControllerClass($controllerClass)) {
$dir = ltrim(pathinfo($relativePath, PATHINFO_DIRNAME), DIRECTORY_SEPARATOR);
$dir = ltrim(pathinfo($relativePath, PATHINFO_DIRNAME), '\\/');
$command = Inflector::camel2id(substr(basename($file), 0, -14), '-', true);
if (!empty($dir)) {
$command = $dir . DIRECTORY_SEPARATOR . $command;
$command = $dir . '/' . $command;
}
$commands[] = $prefix . $command;
}

6
framework/db/BaseActiveRecord.php

@ -221,7 +221,9 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
*
* 1. Create a column to store the version number of each row. The column type should be `BIGINT DEFAULT 0`.
* Override this method to return the name of this column.
* 2. Add a `required` validation rule for the version column to ensure the version value is submitted.
* 2. Ensure the version value is submitted and loaded to your model before any update or delete.
* Or add [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] to your model
* class in order to automate the process.
* 3. In the Web form that collects the user input, add a hidden field that stores
* the lock version of the recording being updated.
* 4. In the controller action that does the data updating, try to catch the [[StaleObjectException]]
@ -332,6 +334,8 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
{
try {
return $this->__get($name) !== null;
} catch (\Throwable $t) {
return false;
} catch (\Exception $e) {
return false;
}

2
framework/db/Schema.php

@ -732,7 +732,7 @@ abstract class Schema extends BaseObject
$cache = null;
if ($this->db->enableSchemaCache && !in_array($name, $this->db->schemaCacheExclude, true)) {
$schemaCache = is_string($this->db->schemaCache) ? Yii::$app->get($this->db->schemaCache, false) : $this->db->schemaCache;
if ($schemaCache instanceof Cache) {
if ($schemaCache instanceof CacheInterface) {
$cache = $schemaCache;
}
}

15
framework/filters/Cors.php

@ -159,9 +159,22 @@ class Cors extends ActionFilter
$responseHeaders = [];
// handle Origin
if (isset($requestHeaders['Origin'], $this->cors['Origin'])) {
if (in_array('*', $this->cors['Origin']) || in_array($requestHeaders['Origin'], $this->cors['Origin'])) {
if (in_array($requestHeaders['Origin'], $this->cors['Origin'], true)) {
$responseHeaders['Access-Control-Allow-Origin'] = $requestHeaders['Origin'];
}
if (in_array('*', $this->cors['Origin'], true)) {
// Per CORS standard (https://fetch.spec.whatwg.org), wildcard origins shouldn't be used together with credentials
if (isset($this->cors['Access-Control-Allow-Credentials']) && $this->cors['Access-Control-Allow-Credentials']) {
if (YII_DEBUG) {
throw new Exception("Allowing credentials for wildcard origins is insecure. Please specify more restrictive origins or set 'credentials' to false in your CORS configuration.");
} else {
Yii::error("Allowing credentials for wildcard origins is insecure. Please specify more restrictive origins or set 'credentials' to false in your CORS configuration.", __METHOD__);
}
} else {
$responseHeaders['Access-Control-Allow-Origin'] = '*';
}
}
}
$this->prepareAllowHeaders('Headers', $requestHeaders, $responseHeaders);

32
framework/helpers/BaseInflector.php

@ -342,7 +342,7 @@ class BaseInflector
{
$words = static::humanize(static::underscore($words), $ucAll);
return $ucAll ? ucwords($words) : ucfirst($words);
return $ucAll ? StringHelper::mb_ucwords($words, self::encoding()) : StringHelper::mb_ucfirst($words, self::encoding());
}
/**
@ -357,7 +357,7 @@ class BaseInflector
*/
public static function camelize($word)
{
return str_replace(' ', '', ucwords(preg_replace('/[^A-Za-z0-9]+/', ' ', $word)));
return str_replace(' ', '', StringHelper::mb_ucwords(preg_replace('/[^\pL\pN]+/u', ' ', $word), self::encoding()));
}
/**
@ -373,9 +373,9 @@ class BaseInflector
'-',
'_',
'.',
], ' ', preg_replace('/(\p{Lu})/u', ' \0', $name))));
], ' ', preg_replace('/(\p{Lu})/u', ' \0', $name))), self::encoding());
return $ucwords ? mb_convert_case($label, MB_CASE_TITLE) : $label;
return $ucwords ? StringHelper::mb_ucwords($label, self::encoding()) : $label;
}
/**
@ -389,12 +389,12 @@ class BaseInflector
*/
public static function camel2id($name, $separator = '-', $strict = false)
{
$regex = $strict ? '/[A-Z]/' : '/(?<![A-Z])[A-Z]/';
$regex = $strict ? '/\p{Lu}/u' : '/(?<!\p{Lu})\p{Lu}/u';
if ($separator === '_') {
return strtolower(trim(preg_replace($regex, '_\0', $name), '_'));
return mb_strtolower(trim(preg_replace($regex, '_\0', $name), '_'), self::encoding());
}
return strtolower(trim(str_replace('_', $separator, preg_replace($regex, $separator . '\0', $name)), $separator));
return mb_strtolower(trim(str_replace('_', $separator, preg_replace($regex, $separator . '\0', $name)), $separator), self::encoding());
}
/**
@ -407,7 +407,7 @@ class BaseInflector
*/
public static function id2camel($id, $separator = '-')
{
return str_replace(' ', '', ucwords(str_replace($separator, ' ', $id)));
return str_replace(' ', '', StringHelper::mb_ucwords(str_replace($separator, ' ', $id), self::encoding()));
}
/**
@ -417,7 +417,7 @@ class BaseInflector
*/
public static function underscore($words)
{
return strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $words));
return mb_strtolower(preg_replace('/(?<=\\pL)(\\p{Lu})/u', '_\\1', $words), self::encoding());
}
/**
@ -429,8 +429,9 @@ class BaseInflector
public static function humanize($word, $ucAll = false)
{
$word = str_replace('_', ' ', preg_replace('/_id$/', '', $word));
$encoding = self::encoding();
return $ucAll ? ucwords($word) : ucfirst($word);
return $ucAll ? StringHelper::mb_ucwords($word, $encoding) : StringHelper::mb_ucfirst($word, $encoding);
}
/**
@ -446,7 +447,7 @@ class BaseInflector
{
$word = static::camelize($word);
return strtolower($word[0]) . substr($word, 1);
return mb_strtolower(mb_substr($word, 0, 1, self::encoding())) . mb_substr($word, 1, null, self::encoding());
}
/**
@ -599,4 +600,13 @@ class BaseInflector
return implode($connector, array_slice($words, 0, -1)) . $lastWordConnector . end($words);
}
}
/**
* @return string
*/
private static function encoding()
{
return isset(Yii::$app) ? Yii::$app->charset : 'UTF-8';
}
}

38
framework/helpers/BaseStringHelper.php

@ -266,7 +266,7 @@ class BaseStringHelper
public static function explode($string, $delimiter = ',', $trim = true, $skipEmpty = false)
{
$result = explode($delimiter, $string);
if ($trim) {
if ($trim !== false) {
if ($trim === true) {
$trim = 'trim';
} elseif (!is_callable($trim)) {
@ -415,4 +415,40 @@ class BaseStringHelper
return preg_match($pattern, $string) === 1;
}
/**
* This method provides a unicode-safe implementation of built-in PHP function `ucfirst()`.
*
* @param string $string the string to be proceeded
* @param string $encoding Optional, defaults to "UTF-8"
* @return string
* @see http://php.net/manual/en/function.ucfirst.php
* @since 2.0.16
*/
public static function mb_ucfirst($string, $encoding = 'UTF-8')
{
$firstChar = mb_substr($string, 0, 1, $encoding);
$rest = mb_substr($string, 1, null, $encoding);
return mb_strtoupper($firstChar, $encoding) . $rest;
}
/**
* This method provides a unicode-safe implementation of built-in PHP function `ucwords()`.
*
* @param string $string the string to be proceeded
* @param string $encoding Optional, defaults to "UTF-8"
* @see http://php.net/manual/en/function.ucwords.php
* @return string
*/
public static function mb_ucwords($string, $encoding = 'UTF-8')
{
$words = preg_split("/\s/u", $string, -1, PREG_SPLIT_NO_EMPTY);
$titelized = array_map(function ($word) use ($encoding) {
return static::mb_ucfirst($word, $encoding);
}, $words);
return implode(' ', $titelized);
}
}

2
framework/http/CookieCollection.php

@ -113,7 +113,7 @@ class CookieCollection extends BaseObject implements \IteratorAggregate, \ArrayA
public function has($name)
{
return isset($this->_cookies[$name]) && $this->_cookies[$name]->value !== ''
&& ($this->_cookies[$name]->expire === null || $this->_cookies[$name]->expire >= time());
&& ($this->_cookies[$name]->expire === null || $this->_cookies[$name]->expire === 0 || $this->_cookies[$name]->expire >= time());
}
/**

20
tests/data/ar/Cat.php

@ -25,4 +25,24 @@ class Cat extends Animal
$record->does = 'meow';
}
/**
* This is to test if __isset catches the exception.
* @throw DivisionByZeroError
* @return float|int
*/
public function getException()
{
throw new \Exception('no');
}
/**
* This is to test if __isset catches the error.
* @throw DivisionByZeroError
* @return float|int
*/
public function getThrowable()
{
return 5/0;
}
}

30
tests/framework/base/ViewTest.php

@ -8,9 +8,11 @@
namespace yiiunit\framework\base;
use Yii;
use yii\base\Theme;
use yii\base\View;
use yii\caching\Cache;
use yii\caching\FileCache;
use yii\base\ViewEvent;
use yii\helpers\FileHelper;
use yiiunit\TestCase;
@ -122,4 +124,32 @@ PHP
}
$this->assertEquals('Undefined variable: a', $message);
}
public function testRelativePathInView()
{
$view = new View();
FileHelper::createDirectory($this->testViewPath . '/theme1');
\Yii::setAlias('@testviews', $this->testViewPath);
\Yii::setAlias('@theme', $this->testViewPath . '/theme1');
$baseView = "{$this->testViewPath}/theme1/base.php";
file_put_contents($baseView, <<<'PHP'
<?php
echo $this->render("sub");
?>
PHP
);
$subView = "{$this->testViewPath}/sub.php";
$subViewContent = "subviewcontent";
file_put_contents($subView, $subViewContent);
$view->theme = new Theme([
'pathMap' => [
'@testviews' => '@theme'
]
]);
$this->assertSame($subViewContent, $view->render('@testviews/base'));
}
}

22
tests/framework/base/WidgetTest.php

@ -56,6 +56,19 @@ class WidgetTest extends TestCase
}
/**
* @depends testBeginEnd
*/
public function testStackTrackingDisorder()
{
$this->expectException('yii\base\InvalidCallException');
TestWidgetA::begin();
TestWidgetB::begin();
TestWidgetA::end();
TestWidgetB::end();
}
/**
* @depends testWidget
*/
public function testEvents()
@ -100,3 +113,12 @@ class TestWidget extends Widget
return '<run-' . $this->id . '>';
}
}
class TestWidgetA extends Widget
{
public static $stack = [];
}
class TestWidgetB extends Widget
{
}

283
tests/framework/behaviors/OptimisticLockBehaviorTest.php

@ -0,0 +1,283 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yiiunit\framework\behaviors;
use Yii;
use yii\behaviors\OptimisticLockBehavior;
use yii\web\Request;
use yii\db\ActiveRecord;
use yii\db\Connection;
use yii\db\Expression;
use yii\db\ExpressionInterface;
use yiiunit\TestCase;
/**
* Unit test for [[\yii\behaviors\OptimisticLockBehavior]].
* @see OptimisticLockBehavior
*
* @group behaviors
*/
class OptimisticLockBehaviorTest extends TestCase
{
/**
* @var Connection test db connection
*/
protected $dbConnection;
public static function setUpBeforeClass()
{
if (!extension_loaded('pdo') || !extension_loaded('pdo_sqlite')) {
static::markTestSkipped('PDO and SQLite extensions are required.');
}
}
public function setUp()
{
$this->mockApplication([
'components' => [
'db' => [
'class' => '\yii\db\Connection',
'dsn' => 'sqlite::memory:',
],
],
]);
$columns = [
'id' => 'pk',
'version' => 'integer NOT NULL',
];
Yii::$app->getDb()->createCommand()->createTable('test_auto_lock_version', $columns)->execute();
$columns = [
'id' => 'pk',
'version' => 'string NOT NULL',
];
Yii::$app->getDb()->createCommand()->createTable('test_auto_lock_version_string', $columns)->execute();
}
public function tearDown()
{
Yii::$app->getDb()->close();
parent::tearDown();
gc_enable();
gc_collect_cycles();
}
// Tests :
public function testUpdateRecordWithinConsoleRequest()
{
ActiveRecordLockVersion::$behaviors = [
OptimisticLockBehavior::className(),
];
$model = new ActiveRecordLockVersion();
$model->version = 0;
$model->save(false);
// upgrade model
$model->upgrade();
$this->assertEquals(1, $model->version, 'updated version should equal 1');
// a console request should use the version number as loaded from database (the behavior should be omitted)
$model->markAttributeDirty('version');
$model->save(false);
$this->assertEquals(2, $model->version, 'updated version should equal 2');
}
public function testNewRecord()
{
// create a record without any version
$request = new Request();
Yii::$app->set('request', $request);
ActiveRecordLockVersion::$behaviors = [
OptimisticLockBehavior::className(),
];
$model = new ActiveRecordLockVersion();
$model->save(false);
$this->assertEquals(0, $model->version, 'init version should equal 0');
// create a record starting from version 5
$request->setBodyParams(['version' => 5]);
Yii::$app->set('request', $request);
$model = new ActiveRecordLockVersion();
$model->save(false);
$this->assertEquals(5, $model->version, 'init version should equal 5');
}
public function testUpdateRecord()
{
$request = new Request();
Yii::$app->set('request', $request);
ActiveRecordLockVersion::$behaviors = [
OptimisticLockBehavior::className(),
];
$model = new ActiveRecordLockVersion();
$model->save(false);
// upgrade model
$model->upgrade();
$this->assertEquals(1, $model->version, 'updated version should equal 1');
// save stale data without sending version
$thrown = false;
try {
$model->save(false);
} catch (\yii\db\StaleObjectException $e) {
$this->assertContains('The object being updated is outdated.', $e->getMessage());
$thrown = true;
}
$this->assertTrue($thrown, 'A StaleObjectException exception should have been thrown.');
// save stale data by sending an outdated version
$request->setBodyParams(['version' => 0]);
Yii::$app->set('request', $request);
$thrown = false;
try {
$model->save(false);
} catch (\yii\db\StaleObjectException $e) {
$this->assertContains('The object being updated is outdated.', $e->getMessage());
$thrown = true;
}
$this->assertTrue($thrown, 'A StaleObjectException exception should have been thrown.');
// save stale data by sending an 'invalid' version number
$request->setBodyParams(['version' => 'yii']);
Yii::$app->set('request', $request);
$thrown = false;
try {
$model->save(false);
} catch (\yii\db\StaleObjectException $e) {
$this->assertContains('The object being updated is outdated.', $e->getMessage());
$thrown = true;
}
$this->assertTrue($thrown, 'A StaleObjectException exception should have been thrown.');
// the behavior should set version to 0 when user input is not a valid number.
$this->assertEquals(0, $model->version, 'updated version should equal 0');
// a successful update by sending the correct version
$request->setBodyParams(['version' => '1']);
Yii::$app->set('request', $request);
$model->save(false);
$this->assertEquals(2, $model->version, 'updated version should equal 2');
}
public function testDeleteRecord()
{
$request = new Request();
Yii::$app->set('request', $request);
ActiveRecordLockVersion::$behaviors = [
OptimisticLockBehavior::className(),
];
$model = new ActiveRecordLockVersion();
$model->save(false);
// upgrade model version to 1
$model->upgrade();
// delete stale data without sending version
$thrown = false;
try {
$model->delete();
} catch (\yii\db\StaleObjectException $e) {
$this->assertContains('The object being deleted is outdated.', $e->getMessage());
$thrown = true;
}
$this->assertTrue($thrown, 'A StaleObjectException exception should have been thrown.');
// delete stale data by sending an outdated version
$request->setBodyParams(['version' => 0]);
Yii::$app->set('request', $request);
$thrown = false;
try {
$model->delete();
} catch (\yii\db\StaleObjectException $e) {
$this->assertContains('The object being deleted is outdated.', $e->getMessage());
$thrown = true;
}
$this->assertTrue($thrown, 'A StaleObjectException exception should have been thrown.');
// a successful update by sending the correct version
$request->setBodyParams(['version' => '1']);
Yii::$app->set('request', $request);
$model->delete();
$this->assertEquals(1, $model->version, 'deleted version should remain 1');
}
}
/**
* Test Active Record class with [[OptimisticLockBehavior]] behavior attached.
*
* @property int $id
* @property int $created_at
* @property int $updated_at
*/
class ActiveRecordLockVersion extends ActiveRecord
{
public static $behaviors;
public static $lockAttribute = 'version';
public static $tableName = 'test_auto_lock_version';
public function behaviors()
{
return static::$behaviors;
}
public function optimisticLock()
{
return static::$lockAttribute;
}
public static function tableName()
{
return static::$tableName;
}
}

16
tests/framework/db/ActiveRecordTest.php

@ -1791,4 +1791,20 @@ abstract class ActiveRecordTest extends DatabaseTestCase
$this->assertEquals(1, sizeof($order->orderItems));
}
public function testIssetException()
{
$cat = new Cat();
$this->assertFalse(isset($cat->exception));
}
/**
* @requires PHP 7
*/
public function testIssetThrowable()
{
$cat = new Cat();
$this->assertFalse(isset($cat->throwable));
}
}

22
tests/framework/filters/CorsTest.php

@ -42,4 +42,26 @@ class CorsTest extends TestCase
$request->setHeaders([]);
$this->assertTrue($cors->beforeAction($action));
}
public function testWildcardOrigin()
{
$this->mockWebApplication();
$controller = new Controller('id', Yii::$app);
$action = new Action('test', $controller);
$request = new Request();
$cors = new Cors([
'cors' => [
'Origin' => ['*',],
'Access-Control-Allow-Credentials' => false,
],
]);
$cors->request = $request;
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['HTTP_ORIGIN'] = 'http://foo.com';
$this->assertTrue($cors->beforeAction($action));
$this->assertEquals('*', $cors->response->getHeaders()->get('access-control-allow-origin'));
}
}

14
tests/framework/helpers/InflectorTest.php

@ -84,17 +84,20 @@ class InflectorTest extends TestCase
{
$this->assertEquals('Me my self and i', Inflector::titleize('MeMySelfAndI'));
$this->assertEquals('Me My Self And I', Inflector::titleize('MeMySelfAndI', true));
$this->assertEquals('Треба Більше Тестів!', Inflector::titleize('ТребаБільшеТестів!', true));
}
public function testCamelize()
{
$this->assertEquals('MeMySelfAndI', Inflector::camelize('me my_self-andI'));
$this->assertEquals('QweQweEwq', Inflector::camelize('qwe qwe^ewq'));
$this->assertEquals('ВідомоЩоТестиЗберігатьНашіНЕРВИ', Inflector::camelize('Відомо, що тести зберігать наші НЕРВИ! 🙃'));
}
public function testUnderscore()
{
$this->assertEquals('me_my_self_and_i', Inflector::underscore('MeMySelfAndI'));
$this->assertEquals('кожний_тест_особливий', Inflector::underscore('КожнийТестОсобливий'));
}
public function testCamel2words()
@ -109,24 +112,33 @@ class InflectorTest extends TestCase
{
$this->assertEquals('post-tag', Inflector::camel2id('PostTag'));
$this->assertEquals('post_tag', Inflector::camel2id('PostTag', '_'));
$this->assertEquals('єдиний_код', Inflector::camel2id('ЄдинийКод', '_'));
$this->assertEquals('post-tag', Inflector::camel2id('postTag'));
$this->assertEquals('post_tag', Inflector::camel2id('postTag', '_'));
$this->assertEquals('єдиний_код', Inflector::camel2id('єдинийКод', '_'));
$this->assertEquals('foo-ybar', Inflector::camel2id('FooYBar', '-', false));
$this->assertEquals('foo_ybar', Inflector::camel2id('fooYBar', '_', false));
$this->assertEquals('невже_іце_працює', Inflector::camel2id('НевжеІЦеПрацює', '_', false));
$this->assertEquals('foo-y-bar', Inflector::camel2id('FooYBar', '-', true));
$this->assertEquals('foo_y_bar', Inflector::camel2id('fooYBar', '_', true));
$this->assertEquals('foo_y_bar', Inflector::camel2id('fooYBar', '_', true));
$this->assertEquals('невже_і_це_працює', Inflector::camel2id('НевжеІЦеПрацює', '_', true));
}
public function testId2camel()
{
$this->assertEquals('PostTag', Inflector::id2camel('post-tag'));
$this->assertEquals('PostTag', Inflector::id2camel('post_tag', '_'));
$this->assertEquals('ЄдинийСвіт', Inflector::id2camel('єдиний_світ', '_'));
$this->assertEquals('PostTag', Inflector::id2camel('post-tag'));
$this->assertEquals('PostTag', Inflector::id2camel('post_tag', '_'));
$this->assertEquals('НевжеІЦеПрацює', Inflector::id2camel('невже_і_це_працює', '_'));
$this->assertEquals('ShouldNotBecomeLowercased', Inflector::id2camel('ShouldNotBecomeLowercased', '_'));
$this->assertEquals('FooYBar', Inflector::id2camel('foo-y-bar'));
$this->assertEquals('FooYBar', Inflector::id2camel('foo_y_bar', '_'));
@ -136,11 +148,13 @@ class InflectorTest extends TestCase
{
$this->assertEquals('Me my self and i', Inflector::humanize('me_my_self_and_i'));
$this->assertEquals('Me My Self And I', Inflector::humanize('me_my_self_and_i', true));
$this->assertEquals('Але й веселі ці ваші тести', Inflector::humanize('але_й_веселі_ці_ваші_тести'));
}
public function testVariablize()
{
$this->assertEquals('customerTable', Inflector::variablize('customer_table'));
$this->assertEquals('ひらがなHepimiz', Inflector::variablize('ひらがな_hepimiz'));
}
public function testTableize()

46
tests/framework/helpers/StringHelperTest.php

@ -16,6 +16,7 @@ use yiiunit\TestCase;
*/
class StringHelperTest extends TestCase
{
protected function setUp()
{
parent::setUp();
@ -266,6 +267,7 @@ class StringHelperTest extends TestCase
$this->assertEquals(['It', 'is', 'a test with trimmed digits', '0', '1', '2'], StringHelper::explode('It, is, a test with trimmed digits, 0, 1, 2', ',', true, true));
$this->assertEquals(['It', 'is', 'a second', 'test'], StringHelper::explode('It+ is+ a second+ test', '+'));
$this->assertEquals(['Save', '', '', 'empty trimmed string'], StringHelper::explode('Save, ,, empty trimmed string', ','));
$this->assertEquals(['44', '512'], StringHelper::explode('0 0 440 512', ' ', '0', true));
$this->assertEquals(['Здесь', 'multibyte', 'строка'], StringHelper::explode('Здесь我 multibyte我 строка', '我'));
$this->assertEquals(['Disable', ' trim ', 'here but ignore empty'], StringHelper::explode('Disable, trim ,,,here but ignore empty', ',', false, true));
$this->assertEquals(['It/', ' is?', ' a', ' test with rtrim'], StringHelper::explode('It/, is?, a , test with rtrim', ',', 'rtrim'));
@ -399,4 +401,48 @@ class StringHelperTest extends TestCase
{
$this->assertSame($expectedResult, StringHelper::matchWildcard($pattern, $string, $options));
}
public function dataProviderMb_ucfirst()
{
return [
['foo', 'Foo'],
['foo bar', 'Foo bar'],
['👍🏻 foo bar', '👍🏻 foo bar'],
['', ''],
[null, ''],
['здесь我 multibyte我 строка', 'Здесь我 multibyte我 строка'],
];
}
/**
* @param string $string
* @param string $expectedResult
* @dataProvider dataProviderMb_ucfirst
*/
public function testMb_ucfirst($string, $expectedResult)
{
$this->assertSame($expectedResult, StringHelper::mb_ucfirst($string));
}
public function dataProviderMb_ucwords()
{
return [
['foo', 'Foo'],
['foo bar', 'Foo Bar'],
['👍🏻 foo bar', '👍🏻 Foo Bar'],
['', ''],
[null, ''],
['здесь我 multibyte我 строка', 'Здесь我 Multibyte我 Строка'],
];
}
/**
* @param string $string
* @param string $expectedResult
* @dataProvider dataProviderMb_ucwords
*/
public function testMb_ucwords($string, $expectedResult)
{
$this->assertSame($expectedResult, StringHelper::mb_ucwords($string));
}
}

Loading…
Cancel
Save