Browse Source

Merge branch 'master' of github.com:yii2-chinesization/yii2

tags/2.0.1
Funson Lee 10 years ago
parent
commit
a8a012b94d
  1. 5
      README.md
  2. 1
      apps/advanced/tests/codeception/bin/yii
  3. 3
      apps/basic/tests/codeception/bin/yii
  4. 6
      composer.json
  5. 5
      docs/guide-es/README.md
  6. 0
      docs/guide-es/images/request-lifecycle.graphml
  7. 0
      docs/guide-es/images/request-lifecycle.png
  8. 101
      docs/guide-es/rest-authentication.md
  9. 85
      docs/guide-es/rest-error-handling.md
  10. 34
      docs/guide-es/rest-rate-limiting.md
  11. 188
      docs/guide-es/rest-resources.md
  12. 136
      docs/guide-es/rest-response-formatting.md
  13. 72
      docs/guide-es/rest-routing.md
  14. 95
      docs/guide-es/rest-versioning.md
  15. 2
      docs/guide-es/runtime-overview.md
  16. 2
      docs/guide-es/start-workflow.md
  17. 445
      docs/guide-es/tutorial-core-validators.md
  18. 142
      docs/guide-es/tutorial-yii-integration.md
  19. 63
      docs/guide-es/widget-bootstrap.md
  20. 27
      docs/guide-es/widget-jui.md
  21. 0
      docs/guide-fr/images/request-lifecycle.graphml
  22. 0
      docs/guide-fr/images/request-lifecycle.png
  23. 2
      docs/guide-fr/start-workflow.md
  24. 8
      docs/guide-ja/README.md
  25. 288
      docs/guide-ja/caching-data.md
  26. 140
      docs/guide-ja/caching-fragment.md
  27. 105
      docs/guide-ja/caching-http.md
  28. 13
      docs/guide-ja/caching-overview.md
  29. 32
      docs/guide-ja/caching-page.md
  30. 436
      docs/guide-ja/images/advanced-app-configs.graphml
  31. BIN
      docs/guide-ja/images/advanced-app-configs.png
  32. 513
      docs/guide-ja/images/application-lifecycle.graphml
  33. BIN
      docs/guide-ja/images/application-lifecycle.png
  34. 428
      docs/guide-ja/images/application-structure.graphml
  35. BIN
      docs/guide-ja/images/application-structure.png
  36. BIN
      docs/guide-ja/images/gii-entry.png
  37. BIN
      docs/guide-ja/images/gii-preview.png
  38. 368
      docs/guide-ja/images/rbac-access-check-1.graphml
  39. BIN
      docs/guide-ja/images/rbac-access-check-1.png
  40. 368
      docs/guide-ja/images/rbac-access-check-2.graphml
  41. BIN
      docs/guide-ja/images/rbac-access-check-2.png
  42. 368
      docs/guide-ja/images/rbac-access-check-3.graphml
  43. BIN
      docs/guide-ja/images/rbac-access-check-3.png
  44. 312
      docs/guide-ja/images/rbac-hierarchy-1.graphml
  45. BIN
      docs/guide-ja/images/rbac-hierarchy-1.png
  46. 368
      docs/guide-ja/images/rbac-hierarchy-2.graphml
  47. BIN
      docs/guide-ja/images/rbac-hierarchy-2.png
  48. 836
      docs/guide-ja/images/request-lifecycle.graphml
  49. BIN
      docs/guide-ja/images/request-lifecycle.png
  50. 22
      docs/guide-ja/intro-upgrade-from-v1.md
  51. 2
      docs/guide-ja/intro-yii.md
  52. 11
      docs/guide-ja/start-databases.md
  53. 2
      docs/guide-ja/start-forms.md
  54. 2
      docs/guide-ja/start-gii.md
  55. 20
      docs/guide-ja/start-hello.md
  56. 7
      docs/guide-ja/start-installation.md
  57. 8
      docs/guide-ja/start-looking-ahead.md
  58. 10
      docs/guide-ja/start-workflow.md
  59. 119
      docs/guide-ja/structure-application-components.md
  60. 52
      docs/guide-ja/structure-applications.md
  61. 453
      docs/guide-ja/structure-controllers.md
  62. 401
      docs/guide-ja/structure-filters.md
  63. 504
      docs/guide-ja/structure-models.md
  64. 262
      docs/guide-ja/structure-modules.md
  65. 763
      docs/guide-ja/structure-views.md
  66. 0
      docs/guide-pt-BR/images/request-lifecycle.graphml
  67. 0
      docs/guide-pt-BR/images/request-lifecycle.png
  68. 2
      docs/guide-pt-BR/start-workflow.md
  69. 6
      docs/guide-ru/caching-fragment.md
  70. 2
      docs/guide-ru/caching-http.md
  71. 4
      docs/guide-ru/caching-page.md
  72. 100
      docs/guide-ru/concept-configurations.md
  73. 8
      docs/guide-ru/concept-di-container.md
  74. 0
      docs/guide-ru/images/request-lifecycle.graphml
  75. 0
      docs/guide-ru/images/request-lifecycle.png
  76. 2
      docs/guide-ru/intro-upgrade-from-v1.md
  77. 4
      docs/guide-ru/intro-yii.md
  78. 2
      docs/guide-ru/rest-quick-start.md
  79. 2
      docs/guide-ru/rest-rate-limiting.md
  80. 4
      docs/guide-ru/rest-resources.md
  81. 126
      docs/guide-ru/runtime-requests.md
  82. 2
      docs/guide-ru/runtime-url-handling.md
  83. 75
      docs/guide-ru/start-installation.md
  84. 4
      docs/guide-ru/start-workflow.md
  85. 4
      docs/guide-ru/structure-application-components.md
  86. 170
      docs/guide-ru/structure-applications.md
  87. 14
      docs/guide-ru/structure-controllers.md
  88. 8
      docs/guide-ru/structure-views.md
  89. 4
      docs/guide-ru/structure-widgets.md
  90. 240
      docs/guide-ru/tutorial-advanced-app.md
  91. 2
      docs/guide-ru/tutorial-core-validators.md
  92. 147
      docs/guide-uk/caching-fragment.md
  93. 118
      docs/guide-uk/concept-aliases.md
  94. 8
      docs/guide-uk/concept-autoloading.md
  95. 2
      docs/guide-uk/start-workflow.md
  96. 87
      docs/guide-uk/structure-application-components.md
  97. 414
      docs/guide-uk/structure-controllers.md
  98. 2
      docs/guide-zh-CN/README.md
  99. 0
      docs/guide-zh-CN/images/request-lifecycle.graphml
  100. 0
      docs/guide-zh-CN/images/request-lifecycle.png
  101. Some files were not shown because too many files have changed in this diff Show More

5
README.md

@ -11,18 +11,13 @@ Yii 2 requires PHP 5.4 and embraces the best practices and protocols found in mo
[![Latest Stable Version](https://poser.pugx.org/yiisoft/yii2/v/stable.png)](https://packagist.org/packages/yiisoft/yii2)
[![Total Downloads](https://poser.pugx.org/yiisoft/yii2/downloads.png)](https://packagist.org/packages/yiisoft/yii2)
[![Reference Status](https://www.versioneye.com/php/yiisoft:yii2/reference_badge.svg)](https://www.versioneye.com/php/yiisoft:yii2/references)
[![Build Status](https://secure.travis-ci.org/yiisoft/yii2.png)](http://travis-ci.org/yiisoft/yii2)
[![Dependency Status](https://www.versioneye.com/php/yiisoft:yii2/dev-master/badge.png)](https://www.versioneye.com/php/yiisoft:yii2/dev-master)
[![HHVM Status](http://hhvm.h4cc.de/badge/yiisoft/yii2-dev.png)](http://hhvm.h4cc.de/package/yiisoft/yii2-dev)
[![Code Coverage](https://scrutinizer-ci.com/g/yiisoft/yii2/badges/coverage.png?s=31d80f1036099e9d6a3e4d7738f6b000b3c3d10e)](https://scrutinizer-ci.com/g/yiisoft/yii2/)
[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/yiisoft/yii2/badges/quality-score.png?s=b1074a1ff6d0b214d54fa5ab7abbb90fc092471d)](https://scrutinizer-ci.com/g/yiisoft/yii2/)
[![Code Climate](https://codeclimate.com/github/yiisoft/yii2.png)](https://codeclimate.com/github/yiisoft/yii2)
[![Issue Stats Issues](http://issuestats.com/github/yiisoft/yii2/badge/issue)](http://issuestats.com/github/yiisoft/yii2)
[![Issue Stats Pull request](http://issuestats.com/github/yiisoft/yii2/badge/pr)](http://issuestats.com/github/yiisoft/yii2)
DIRECTORY STRUCTURE
-------------------

1
apps/advanced/tests/codeception/bin/yii

@ -22,6 +22,7 @@ $config = yii\helpers\ArrayHelper::merge(
'class' => 'yii\faker\FixtureController',
'fixtureDataPath' => '@tests/codeception/common/fixtures/data',
'templatePath' => '@tests/codeception/common/templates/fixtures',
'namespace' => 'tests\codeception\common\fixtures',
],
],
]

3
apps/basic/tests/codeception/bin/yii

@ -18,7 +18,8 @@ $config = yii\helpers\ArrayHelper::merge(
'fixture' => [
'class' => 'yii\faker\FixtureController',
'fixtureDataPath' => '@tests/codeception/fixtures',
'templatePath' => '@tests/codeception/templates'
'templatePath' => '@tests/codeception/templates',
'namespace' => 'tests\codeception\fixtures',
],
],
]

6
composer.json

@ -82,15 +82,15 @@
"bower-asset/jquery.inputmask": "3.1.*",
"bower-asset/punycode": "1.3.*",
"bower-asset/yii2-pjax": "2.0.*",
"bower-asset/bootstrap": "3.2.* | 3.1.*",
"bower-asset/bootstrap": "3.3.* | 3.2.* | 3.1.*",
"bower-asset/jquery-ui": "1.11.*@stable",
"bower-asset/typeahead.js": "0.10.*"
},
"require-dev": {
"phpunit/phpunit": "3.7.*",
"twig/twig": "*",
"smarty/smarty": "*",
"imagine/imagine": "v0.5.0",
"smarty/smarty": "~3.1",
"imagine/imagine": "0.5.*",
"swiftmailer/swiftmailer": "*",
"fzaninotto/faker": "*",
"cebe/indent": "*"

5
docs/guide-es/README.md

@ -49,11 +49,10 @@ Gestión de las peticiones
* [Información general](runtime-overview.md)
* [Bootstrapping](runtime-bootstrapping.md)
* [Routing](runtime-routing.md)
* [Routing y Creación de las URL](runtime-routing.md)
* [Peticiones (Requests)](runtime-requests.md)
* [Respuestas (Responses)](runtime-responses.md)
* [Sesiones (Sessions) y Cookies](runtime-sessions-cookies.md)
* **TBD** [Procesamiento y generación de las URL](runtime-url-handling.md)
* **TBD** [Gestión de errores](runtime-handling-errors.md)
* **TBD** [Registro de anotaciones](runtime-logging.md)
@ -126,7 +125,7 @@ Caché
* [Caché HTTP](caching-http.md)
Servicios Web RESTful
Servicios Web RESTful
---------------------
* **TBD** [Guía breve](rest-quick-start.md)

0
docs/guide-es/images/application-lifecycle.graphml → docs/guide-es/images/request-lifecycle.graphml

0
docs/guide-es/images/application-lifecycle.png → docs/guide-es/images/request-lifecycle.png

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

101
docs/guide-es/rest-authentication.md

@ -0,0 +1,101 @@
Autenticación
==============
A diferencia de las aplicaciones Web, las API RESTful son usualmente sin estado (stateless), lo que permite que las sesiones o las cookies no sean usadas. Por lo tanto, cada petición debe llevar alguna suerte de credenciales de autenticación, porque la autenticación del usuario no puede ser mantenida por las sesiones o las cookies. Una práctica común es enviar una pieza (token) secreta de acceso con cada petición para autenticar al usuario. Dado que una pieza de autenticación puede ser usada para identificar y autenticar solamente a un usuario, **el API de peticiones tiene que ser siempre enviado vía HTTPS para prevenir ataques que intervengan en la transmisión "man-in-the-middle" (MitM) **.
> Tip: Sin estado (stateless) se refiere a un protocolo en el que cada petición es una transacción independiente del resto de peticiones y la comunicación consiste en pares de peticion y respuesta, por lo que no es necesario retener información en la sesión.
Hay muchas maneras de enviar una pieza (token) de acceso:
* [Autorización Básica HTTP (HTTP Basic Auth)](http://en.wikipedia.org/wiki/Basic_access_authentication): la pieza de acceso es enviada como nombre de usuario. Esto sólo debe de ser usado cuando la pieza de acceso puede ser guardada de forma segura en la parte del API del consumidor. Por ejemplo, el API del consumidor es un programa ejecutándose en un servidor.
* Parámetro de la consulta: la pieza de acceso es enviada como un parámetro de la consulta en la URL de la API, p.e.,
`https://example.com/users?access-token=xxxxxxxx`. Debido que muchos servidores dejan los parámetros de consulta en los logs del servidor esta aproximación suele ser usada principalmente para servir peticiones `JSONP` que no usen las cabeceras HTTP para enviar piezas de acceso.
* [OAuth 2](http://oauth.net/2/): la pieza de acceso es obtenida por el consumidor por medio de una autorización del servidor y enviada al API del servidor según el protocolo OAuth 2 [Piezas HTTP de la portadora (HTTP Bearer Tokens)](http://tools.ietf.org/html/rfc6750).
Yii soporta todos los métodos anteriores de autenticación. Puedes crear nuevos métodos de autenticación de una forma fácil.
Para activar la autenticación para tus APIs, sigue los pasos siguientes:
1. Configura la propiedad [[yii\web\User::enableSession|enableSession]] de el componente `user` de la aplicación a false.
2. Especifica cuál método de autenticación planeas usar configurando la funcionalidad `authenticator` en las clases de la controladora REST.
3. Implementa [[yii\web\IdentityInterface::findIdentityByAccessToken()]] en tu [[yii\web\User::identityClass|clase de identidad de usuario]].
El paso 1 no es necesario pero sí recomendable para las APIs RESTful, pues son sin estado (stateless). Cuando [[yii\web\User::enableSession|enableSession]]
es false, el estado de autenticación del usuario puede NO ser mantenido (persisted) durante varias peticiones usando sesiones. Si embargo, la autenticación puede ser realizada para cada petición, la cual es realizada por los pasos 2 y 3.
> Tip: Puede configurar [[yii\web\User::enableSession|enableSession]] del componente de la aplicación `user` en la configuración de las aplicaciones si estás desarrollando APIs RESTful en términos de un aplicación. Si desarrollas un módulo de las APIs RESTful, puedes poner la siguiente línea en el método del módulo `init()`, tal y como sigue:
> ```php
public function init()
{
parent::init();
\Yii::$app->user->enableSession = false;
}
```
Por ejemplo, para usar HTTP Basic Auth, puedes configurar `authenticator` como sigue,
```php
use yii\filters\auth\HttpBasicAuth;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::className(),
];
return $behaviors;
}
```
Si quires implementar las tres autenticaciones explicadas antes, puedes usar `CompositeAuth` de la siguiente manera,
```php
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'authMethods' => [
HttpBasicAuth::className(),
HttpBearerAuth::className(),
QueryParamAuth::className(),
],
];
return $behaviors;
}
```
Cada elemento en `authMethods` debe de ser el nombre de un método de autenticación de una clase o un array de configuración.
La implementación de `findIdentityByAccessToken()` es específico de la aplicación. Por ejemplo, en escenarios simples cuando cada usuario sólo puede terner una pieza (token) de acceso, puedes almacenar la pieza de acceso en la columna `access_token` en la tabla de usuario. El método debe de ser inmediatamente implementado en la clase `User` como sigue,
```php
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface
{
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['access_token' => $token]);
}
}
```
Después que la autenticación es activada, tal y como se describe arriba, para cada petición de la API, la controladora solicitada puede intentar autenticar al usuario en su paso `beforeAction()`.
Si la autenticación ocurre, la controladora puede realizar otras comprobaciones (como son límite del ratio, autorización) y entonces ejecutar la acción. La identidad del usuario autenticado puede ser recogida via `Yii::$app->user->identity`.
Si la autenticación falla, una respuesta con estado HTTP 401 puede ser devuelta junto con otras cabeceras apropiadas (como son la cabecera para autenticación básica HTTP `WWW-Authenticate` ).
## Autorización <a name="authorization"></a>
Después de que un usuario se ha autenticado, probablementer querrás comprobar si él o ella tiene los permisos para realizar la acción pedida para el recurso pedido. Este proceso es llamado *autorización (authorization)* y está cubierto en detalle en la [Sección de Autorización](security-authorization.md).
Si tus controladoras extienden de [[yii\rest\ActiveController]], puedes sobreescribir (override) el método [[yii\rest\Controller::checkAccess()|checkAccess()]] para realizar la comprobación de la autorización. El método será llamado por las acciones contenidas en [[yii\rest\ActiveController]].

85
docs/guide-es/rest-error-handling.md

@ -0,0 +1,85 @@
Manejo de errores
==============
Cuando se maneja una petición del API RESTful, si ocurre un error en la petición del usuario o si algo inesperado ocurre en el servidor, simplemente puedes lanzar una excepción para notificar al usuario que algo erróneo ocurrió.
Si puedes identificar la causa del error (p.e., el recurso pedido no existe), debes considerar lanzar una excepción con el apropiado códig HTTP de estado (p.e., [[yii\web\NotFoundHttpException]] representa un código de estado 404). Yii enviará la respuesta a continuación con el correspondiente código de estado HTTP y el texto. Yii puede incluir también la representación serializada de la excepción en el cuerpo de la respuesta. Por ejemplo:
```
HTTP/1.1 404 Not Found
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"name": "Not Found Exception",
"message": "El recurso solicitado no ha sido encontrado.",
"code": 0,
"status": 404
}
```
La siguiente lista sumariza los códigos de estado HTTP que son usados por el framework REST:
* `200`: OK. Todo ha funcionado como se esperaba.
* `201`: El recurso ha creado con éxito en respuesta a la petición `POST`. La cabecera de situación `Location` contiene la URL apuntando al nuevo recurso creado.
* `204`: La petición ha sido manejada con éxito y el cuerpo de la respuesta no tiene contenido (como una petición `DELETE`).
* `304`: El recurso no ha sido modificado. Puede usar la versión en caché.
* `400`: Petición errónea. Esto puede estar causado por varias acciones de el usuario, como proveer un JSON no válido en el cuerpo de la petición, proveyendo parámetros de acción no válidos, etc.
* `401`: Autenticación fallida.
* `403`: El usuario autenticado no tiene permitido acceder a la API final.
* `404`: El recurso pedido no existe.
* `405`: Método no permitido. Por favor comprueba la cabecera `Allow` por los métodos HTTP permitidos.
* `415`: Tipo de medio no soportado. El tipo de contenido pedido o el número de versión no es válido.
* `422`: La validación de datos ha fallado (en respuesta a una petición `POST` , por ejemplo). Por favor, comprobad en el cuerpo de la respuesta el mensaje detallado.
* `429`: Demasiadas peticiones. La petición ha sido rechazada debido a un limitación de rango.
* `500`: Error interno del servidor. Esto puede estar causado por errores internos del programa.
## Personalizando la Respuesta al Error <a name="customizing-error-response"></a>
A veces puedes querer personalizar el formato de la respuesta del error por defecto . Por ejemplo, en lugar de depender del uso de diferentes estados HTTP para indicar los diferentes errores, puedes querer usar siempre el estado HTTP 200 y encajonar el código de estado HTTP en la respuesta, tal y como se ve en lo que sigue,
```
HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"success": false,
"data": {
"name": "Not Found Exception",
"message": "The requested resource was not found.",
"code": 0,
"status": 404
}
}
```
Para lograr este objetivo, puedes responder al evento `beforeSend` de el componente `response` en la configuración de la aplicación:
```php
return [
// ...
'components' => [
'response' => [
'class' => 'yii\web\Response',
'on beforeSend' => function ($event) {
$response = $event->sender;
if ($response->data !== null && !empty(Yii::$app->request->get['suppress_response_code'])) {
$response->data = [
'success' => $response->isSuccessful,
'data' => $response->data,
];
$response->statusCode = 200;
}
},
],
],
];
```
El anterior código puede reformatear la respuesta (para ambas respuestas, exitosa o fallida) de forma aclaratoria cuando
`suppress_response_code` es pasado como un parámetro `GET`.

34
docs/guide-es/rest-rate-limiting.md

@ -0,0 +1,34 @@
Limitando el ratio (rate)
=============
Para prevenir el abuso, puedes considerar añadir un *límitación del ratio* (*rate limiting*) para tus APIs. Por ejemplo, puedes querer limitar el uso del API de cada usuario que no sea como mucho 100 llamadas al API dentro de un periodo de 10 minutos. Si demasiadas peticiones son recibidas de un usuario dentro del periodo de tiempo declarado , una respuesta con código de estado 429 (significa "Demasiadas peticiones") puede ser devuelto.
Para activar la limitación de ratio, la clase [[yii\web\User::identityClass|user identity class]] debe implementar [[yii\filters\RateLimitInterface]].
Este interface requiere la implementación de tres métodos:
* `getRateLimit()`: devuelve el número máximo de peticiones permitidas y el periodo de tiempo (p.e., `[100, 600]` significa que como mucho puede haber 100 llamadas al API dentro de 600 segundos).
* `loadAllowance()`: devuelve el número de peticiones que quedan permitidas y el tiempo (fecha/hora) UNIX con el último límite del ratio que ha sido comprobado.
* `saveAllowance()`: guarda ambos, el número que quedan de peticiones permitidas y el actual tiempo (fecha/hora) UNIX .
Tu puedes usar dos columnas en la tabla de usuario para guardar la información de lo permitido y la fecha/hora (timestamp). Con ambas definidas, entonces `loadAllowance()` y `saveAllowance()` pueden ser implementadas para leer y guardar los valores de las dos columnas correspondientes al actual usuario autenticado. Para mejorar el desempeño, también puedes considerar almacenar esas piezas de información en caché o almacenamiento NoSQL.
Una vez que la clase de identidad implementa el requerido interface, Yii puede usar automáticamente [[yii\filters\RateLimiter]] configurado como una acción de filtrado para [[yii\rest\Controller]] y mejorar la comprobación del limitador de ratio. El limitador de ratio puede lanzar una [[yii\web\TooManyRequestsHttpException]] cuando el límite del ratio es excedido.
Puedes configurar el limitador de ratio en tu clase REST de la controladora como sigue:
```php
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['rateLimiter']['enableRateLimitHeaders'] = false;
return $behaviors;
}
```
Cuando la limitación de ratio está activada, por defecto cada respuesta puede ser enviada con las siguientes cabeceras de HTTP conteniendo la información actual del límite de ratio:
* `X-Rate-Limit-Limit`, el máximo número de peticiones permitidas en un periodo de tiempo
* `X-Rate-Limit-Remaining`, el número de peticiones restantes en el periodo de tiempo actual
* `X-Rate-Limit-Reset`, el número de segundos a esperar para pedir el máximo número de peticiones permitidas
Puedes desactivar estas cabeceras configurando [[yii\filters\RateLimiter::enableRateLimitHeaders]] a false, tal y como en el anterior ejemplo.

188
docs/guide-es/rest-resources.md

@ -0,0 +1,188 @@
Recursos
=========
Las APIs RESTful lo son todos para acceder y manipular *recursos (resources)*. Puedes observar los recursos en el paradigma MVC en [Modelos (models)](structure-models.md) .
Mientras que no hay restricción a cómo representar un recurso, en YII usualmente, puedes representar recursos como objetos de la clase [[yii\base\Model]] o sus clases hijas (p.e. [[yii\db\ActiveRecord]]), por las siguientes razones:
* [[yii\base\Model]] implementa el interface [[yii\base\Arrayable]] , el cual te permite personalizar como exponer los datos de los recursos a travès de las APIs RESTful.
* [[yii\base\Model]] soporta [Validación de entrada (input validation)](input-validation.md), lo cual es muy usado en las APIs RESTful para soportar la entrada de datos.
* [[yii\db\ActiveRecord]] provee un poderoso soporte para el acceso a datos en bases de datos y su manipulación, lo que lo le hace servir perfectamente si sus recursos de datos están en bases de datos.
En esta sección, vamos principalmente a describir como la clase con recursos que extiende de [[yii\base\Model]] (o sus clases hijas) puede especificar qué datos puede ser devueltos vía las APIs RESTful. Si la clase de los recursos no extiende de [[yii\base\Model]], entonces todas las variables públicas miembro serán devueltas.
## Campos (fields) <a name="fields"></a>
Cuando incluimos un recurso en una respuesta de la API RESTful, el recurso necesita ser serializado en una cadena.
Yii divide este proceso en dos pasos. Primero, el recurso es convertido en un array por [[yii\rest\Serializer]].
Segundo, el array es serializado en una cadena en el formato requerido (p.e. JSON, XML) por [[yii\web\ResponseFormatterInterface|response formatters]]. El primer paso es en el que debes de concentrarte principalmente cuando desarrolles una clase de un recurso.
Sobreescribiendo [[yii\base\Model::fields()|fields()]] y/o [[yii\base\Model::extraFields()|extraFields()]],
puedes especificar qué datos, llamados *fields*, en el recursos, pueden ser colocados en el array que le representa.
La diferencia entre estos dos métodos es que el primero especifica el conjunto de campos por defecto que deben ser incluidos en el array que los representa, mientras que el último especifica campos adicionales que deben de ser incluidos en el array si una petición del usuario final para ellos vía el parámetro de consulta `expand`. Por ejemplo,
```
// devuelve todos los campos declarados en fields()
http://localhost/users
// sólo devuelve los campos id y email, provistos por su declaración en fields()
http://localhost/users?fields=id,email
// devuelve todos los campos en fields() y el campo profile siempre y cuando esté declarado en extraFields()
http://localhost/users?expand=profile
// sólo devuelve los campos id, email y profile, siempre y cuando ellos estén declarados en fields() y extraFields()
http://localhost/users?fields=id,email&expand=profile
```
### Sobreescribiendo `fields()` <a name="overriding-fields"></a>
Por defecto, [[yii\base\Model::fields()]] devuelve todos los atributos de los modelos como si fueran campos, mientras [[yii\db\ActiveRecord::fields()]] sólo devuelve los atributos que tengan datos en la base de datos.
Puedes sobreescribir `fields()` para añadir, quitar, renombrar o redefinir campos. El valor de retorno de `fields()` ha de estar en un array. Las claves del array son los nombres de los campos y los valores del array son las correspondientes definiciones de los campos que pueden ser tanto nombres de propiedades/atributos o funciones anónimas que devuelven los correspondientes valores del los campos. En el caso especial de que el nombre de un campo sea el mismo que su definición puedes omitir la clave en el array. Por ejemplo,
```php
// explícitamente lista cada campo, siendo mejor usarlo cuando quieras asegurarte que los cambios
// en una tabla de la base de datos o en un atributo del modelo no provoque el cambio de tu campo (para mantener la compatibilidad anterior).
public function fields()
{
return [
// el nombre de campo es el mismo nombre del atributo
'id',
// el nombre del campo es "email", su atributo se denomina "email_address"
'email' => 'email_address',
// el nombre del campo es "name", su valor es definido está definido por una función anónima de retrollamada (callback)
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
];
}
// el ignorar algunos campos, es mejor usarlo cuando heredas de una implementación padre
// y pones en la lista negra (blacklist) algunos campos sensibles
public function fields()
{
$fields = parent::fields();
// quita los campos con información sensible
unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);
return $fields;
}
```
> Atención: Dado que, por defecto, todos los atributos de un modelo pueden ser incluidos en la devolución del API, debes
> examinar tus datos para estar seguro de que no contiene información sensible. Si se da este tipo de información,
> debes sobreescribir `fields()` para filtrarlos. En el ejemplo anterior, escogemos
> quitar `auth_key`, `password_hash` y `password_reset_token`.
### Sobreescribiendo `extraFields()` <a name="overriding-extra-fields"></a>
Por defecto, [[yii\base\Model::extraFields()]] no devuelve nada, mientras que [[yii\db\ActiveRecord::extraFields()]] devuelve los nombres de las relaciones que tienen datos (populated) obtenidos de la base de datos.
El formato de devolución de los datos de `extraFields()` es el mismo que el de `fields()`. Usualmente, `extraFields()` es principalmente usado para especificar campos cuyos valores sean objetos. Por ejemplo, dado la siguiente declaración de campo,
```php
public function fields()
{
return ['id', 'email'];
}
public function extraFields()
{
return ['profile'];
}
```
la petición `http://localhost/users?fields=id,email&expand=profile` puede devolver los siguientes datos en formato JSON :
```php
[
{
"id": 100,
"email": "100@example.com",
"profile": {
"id": 100,
"age": 30,
}
},
...
]
```
## Enlaces (Links) <a name="links"></a>
[HATEOAS](http://en.wikipedia.org/wiki/HATEOAS), es una abreviación de Hipermedia es el Motor del Estado de la Aplicación (Hypermedia as the Engine of Application State), promueve que las APIs RESTfull devuelvan información que permita a los clientes descubrir las acciones que soportan los recursos devueltos. El sentido de HATEOAS es devolver un conjunto de hiperenlaces con relación a la información, cuando los datos de los recursos son servidos por las APIs.
Las clases con recursos pueden soportar HATEOAS implementando el interfaz [[yii\web\Linkable]] . El interfaz contiene sólo un método [[yii\web\Linkable::getLinks()|getLinks()]] el cual debe de de devolver una lista de [[yii\web\Link|links]].
Típicamente, debes devolver al menos un enlace `self` representando la URL al mismo recurso objeto. Por ejemplo,
```php
use yii\db\ActiveRecord;
use yii\web\Link;
use yii\web\Linkable;
use yii\helpers\Url;
class User extends ActiveRecord implements Linkable
{
public function getLinks()
{
return [
Link::REL_SELF => Url::to(['user/view', 'id' => $this->id], true),
];
}
}
```
Cuando un objeto `User` es devuelto en una respuesta, puede contener un elemento `_links` representando los enlaces relacionados con el usuario, por ejemplo,
```
{
"id": 100,
"email": "user@example.com",
// ...
"_links" => [
"self": "https://example.com/users/100"
]
}
```
## Colecciones <a name="collections"></a>
Los objetos de los recursos pueden ser agrupados en *collections*. Cada colección contiene una lista de recursos objeto del mismo tipo.
Las colecciones pueden ser representadas como arrays pero, es usualmente más deseable representarlas como [proveedores de datos (data providers)](output-data-providers.md). Esto es así porque los proveedores de datos soportan paginación y ordenación de los recursos, lo cual es comunmente necesario en las colecciones devueltas con las APIs RESTful. Por ejemplo, la siguiente acción devuelve un proveedor de datos sobre los recursos post:
```php
namespace app\controllers;
use yii\rest\Controller;
use yii\data\ActiveDataProvider;
use app\models\Post;
class PostController extends Controller
{
public function actionIndex()
{
return new ActiveDataProvider([
'query' => Post::find(),
]);
}
}
```
Cuando un proveedor de datos está enviando una respuesta con el API RESTful, [[yii\rest\Serializer]] llevará la actual página de los recursos y los serializa como un array de recursos objeto. Adicionalmente, [[yii\rest\Serializer]]
puede incluir también la información de paginación a través de las cabeceras HTTP siguientes:
* `X-Pagination-Total-Count`: Número total de recursos;
* `X-Pagination-Page-Count`: Número de páginas;
* `X-Pagination-Current-Page`: Página actual (iniciando en 1);
* `X-Pagination-Per-Page`: Número de recursos por página;
* `Link`: Un conjunto de enlaces de navegación permitiendo al cliente recorrer los recursos página a página.
Un ejemplo se puede ver en la sección [Inicio rápido (Quick Start)](rest-quick-start.md#trying-it-out).

136
docs/guide-es/rest-response-formatting.md

@ -0,0 +1,136 @@
Dando Formato a la Respuesta
===================
Cuando se maneja una petición al API RESTful, una aplicación realiza usualmente los siguientes pasos que están relacionados con el formato de la respuesta:
1. Determinar varios factores que pueden afectar al formato de la respuesta, como son el tipo de medio, lenguaje, versión, etc.
Este proceso es también conocido como [Negociación de contenido (content negotiation)](http://en.wikipedia.org/wiki/Content_negotiation).
2. La conversión de objetos recursos en arrays, está descrito en la sección [Recursos (Resources)](rest-resources.md).
Esto es realizado por el serializador [[yii\rest\Serializer]].
> Tip: Serializar es convertir un elemento a un formato que nos permita guardardarlo de forma permanente, de modo que posteriormente, al recuperarlo, nos de una copia igual a la del elemento antes de ser inicialmente serializado.
3. La conversión de arrays en cadenas con el formato determinado por el paso de negociación de contenido. Esto es realizado por [[yii\web\ResponseFormatterInterface|response formatters]] registrado con el componente de la aplicación [[yii\web\Response::formatters|response]].
## Negociación de contenido (Content Negotiation) <a name="content-negotiation"></a>
Yii soporta la negoiciación de contenido a través del filtro [[yii\filters\ContentNegotiator]]. La clase controladora base del API RESTful [[yii\rest\Controller]] está equipada con este filtro bajo el nombre `contentNegotiator`.
El filtro provee tanto un formato de respuesta de negociación como una negociación de lenguaje. Por ejemplo, si la petición API RESTful contiene la siguiente cabecera,
```
Accept: application/json; q=1.0, */*; q=0.1
```
puede obtener una respuesta en formato JSON, como lo que sigue:
```
$ curl -i -H "Accept: application/json; q=1.0, */*; q=0.1" "http://localhost/users"
HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
[
{
"id": 1,
...
},
{
"id": 2,
...
},
...
]
```
En la parte de atrás, antes de que sea ejecutada una acción de la controladora del API RESTful, el filtro [[yii\filters\ContentNegotiator]] comprobará en la cabecera HTTP el `Accept` de la petición y pondrá como `'json'` [[yii\web\Response::format|response format]]. Después de que la acción sea ejecutada y devuelva el recurso objeto resultante o una colección resultante,
[[yii\rest\Serializer]] convertirá el resultado en un array. Y finalmente, [[yii\web\JsonResponseFormatter]] serializará el array en una cadena JSON incluyéndola en el cuerpo de la respuesta.
Por defecto, el API RESTful soporta tanto el formato JSON como el XML. Para soportar un nuevo formato, debes configurar la propiedad [[yii\filters\ContentNegotiator::formats|formats]] del filtro `contentNegotiator` tal y como sigue, en las clases de la controladora del API:
```php
use yii\web\Response;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_HTML;
return $behaviors;
}
```
Las claves de la propiedad `formats` son los tipos MIME soportados, mientras que los valores son los nombre de formato de respuesta correspondientes, los cuales han de estar soportados en [[yii\web\Response::formatters]].
## Serialización de Datos <a name="data-serializing"></a>
Como hemos descrito antes, [[yii\rest\Serializer]] es la pieza central para convertir recursos objeto o colecciones en arrays. Reconoce objetos tanto implementando [[yii\base\ArrayableInterface]] como [[yii\data\DataProviderInterface]]. El primer formateador es implementado principalmente para recursos objeto, mientras que el segundo para recursos collección.
Puedes configurar el serializador poniendo la propiedad [[yii\rest\Controller::serializer]] con un array de configuración.
Por ejemplo, a veces puedes querer simplificar la ayuda al trabajo de desarrollo del cliente incluyendo información de la paginación directamente en el cuerpo de la respuesta. Para hacer esto, configura la propiedad [[yii\rest\Serializer::collectionEnvelope]] como sigue:
```php
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'app\models\User';
public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items',
];
}
```
Puedes obtener la respuesta que sigue para la petición `http://localhost/users`:
```
HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"items": [
{
"id": 1,
...
},
{
"id": 2,
...
},
...
],
"_links": {
"self": "http://localhost/users?page=1",
"next": "http://localhost/users?page=2",
"last": "http://localhost/users?page=50"
},
"_meta": {
"totalCount": 1000,
"pageCount": 50,
"currentPage": 1,
"perPage": 20
}
}
```

72
docs/guide-es/rest-routing.md

@ -0,0 +1,72 @@
Enrutado
=======
Con los recursos y las clases controladoras preparadas, puedes acceder a los recursos usando una URL como `http://localhost/index.php?r=user/create`, parecida a la que usas con aplicaciones Web normales.
En la práctica, querrás usualmente usar URLs más bonitas y obtener ventajas de los comandos de acciones (verbos) HTTP.
Por ejemplo, una petición `POST /users` puede permitir el acceso a la acción `user/create`.
Esto puede realizarse fácilmente configurando el componente de la aplicación `urlManager` en la configuración tal y como sigue:
```php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
],
]
```
En comparación con la gestión de URL en las aplicaciones Web, lo nuevo de lo anterior es el uso de [[yii\rest\UrlRule]] para el enrutado de las peticiones con el API RESTful. Esta clase especial que contiene la norma para gestionar las URLs puede crear todo un conjunto de URLs hijas para mantener el enrutado y la creación de URLs para la/s especificada/s controlador/as.
Por ejemplo, el código anterior es aproximadamente equivalente a las siguientes reglas:
```php
[
'PUT,PATCH users/<id>' => 'user/update',
'DELETE users/<id>' => 'user/delete',
'GET,HEAD users/<id>' => 'user/view',
'POST users' => 'user/create',
'GET,HEAD users' => 'user/index',
'users/<id>' => 'user/options',
'users' => 'user/options',
]
```
Y los siguientes puntos finales del API son mantenidos por la siguiente regla:
* `GET /users`: listado de todos los usuarios página a página;
* `HEAD /users`: enseña ĺa información resumén del usuario listado;
* `POST /users`: crea un nuevo usuario;
* `GET /users/123`: devuelve los detalles del usuario 123;
* `HEAD /users/123`: enseña la información resúmen del usuario 123;
* `PATCH /users/123` y `PUT /users/123`: actualizan al usuario 123;
* `DELETE /users/123`: borra el usuario 123;
* `OPTIONS /users`: presenta las acciones finales soportadas por `/users`;
* `OPTIONS /users/123`: presenta las acciones finales que soporta `/users/123`.
Puedes configurar las opciones `only` y `except` para explícitamente listar las acciones a soportar y cuales desabilitar, respectivamente. Por ejemplo,
```php
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user',
'except' => ['delete', 'create', 'update'],
],
```
También puedes configurar `patterns` o `extraPatterns` para redifinir patrones existentes o añadir nuevos patrones que soportan esta regla.
Por ejemplo, para soportar la nueva acción `search` por `GET /users/search`, configura la opción `extraPatterns` como sigue,
```php
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user',
'extraPatterns' => [
'GET search' => 'search',
],
```
Queda advertido que la ID de la controladora `user` aparece finalmente en plural tal que`users`.
Esto es debido a que [[yii\rest\UrlRule]] pluraliza de forma automáticalos IDs de las controladoras para ser usadas en los puntos finales.
Puedes desactivar este comportamiento poniendo a false [[yii\rest\UrlRule::pluralize]] , o si quieres usar algunos nombres especiales, debes configurar la propiedad [[yii\rest\UrlRule::controller]]. Dése cuenta que la pluralización de puntos finales del RESTful no siempre añade simplemente una "s" l final de la id de la controladora. Una controladora cuyo ID termina en "x", por ejemplo "BoxController" (con ID `box`), tiene el punto final del RESTful pluralizada a `boxes` por [[yii\rest\UrlRule]].

95
docs/guide-es/rest-versioning.md

@ -0,0 +1,95 @@
Versionado
==========
Una buena API ha de ser *versionada*: los cambios y las nuevas características son implementadas en las nuevas versiones del API, en vez de estar continuamente modificando sólo una versión. Al contrario que en las aplicaciones Web, en las cuales tienes total control del código de ambas partes lado del cliente y lado del servidor, las APIs están destinadas a ser usadas por los clientes fuera de tu control. Por esta razón, compatibilidades hacia atrás (BC Backward compatibility) de las APIs ha de ser mantenida siempre que sea posible. Si es necesario un cambio que puede romper la BC, debes de introducirla en la nueva versión del API, e incrementar el número de versión. Los clientes que la usan pueden continuar usando la antigua versión de trabajo del API; los nuevos y actualizados clientes pueden obtener la nueva funcionalidad de la nueva versión del API.
> Tip: referirse a [Semántica del versionado](http://semver.org/) para más información en el diseño del número de versión del API.
Una manera común de implementar el versionado de la API es embeber el número de versión en las URLs del AP.
Por ejemplo, `http://example.com/v1/users` se inicia por la versión 1 de la API del la parte final `/users`.
Otro método de versionado de la API , la cual está ganando predominancia recientemente, es poner el número de versión en las cabeceras de la petición HTTP. Esto se suele hacer típicamente a través la cabecera `Accept` :
```
// vía parámetros
Accept: application/json; version=v1
// vía de el tipo de contenido del vendedor
Accept: application/vnd.company.myapp-v1+json
```
Ambos métodos tienen sus pros y sus contras, y hay gran cantidad de debates sobre cada uno. Debajo puedes ver una estrategia práctica para el versionado de la API que es una mezcla de estos dos métodos:
* Pon cada versión superior del API en un módulo separado cuya ID es el número de la versión principal. (p.e. `v1`, `v2`).
Naturalmente, las URLs del API pueden contener números de versión superiores.
* Dentro de cada versión superior (y por tanto, dentro del correspondiente módulo), usa la cabecera de HTTP `Accept` para determinar el número de la menor versión y escribe código condicional para responder a la menor versión en consecuencia.
Para cada módulo sirviendo una versión superior, el módulo debe incluir los recursos y la clase controladora que especifican la versión. Para mejor separar la responsabilidad del código, puedes conservar un conjunto de recursos base y clases de controladores comunes, y hacer subclases de ellas en cada uno de los módulos de versión individual. Dentro de las subclases, impementa el código concreto como es `Model::fields()`.
Tu código puede estar organizado como lo que sigue:
```
api/
common/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
modules/
v1/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
v2/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
```
La configuración de su aplicación puede tener este aspecto:
```php
return [
'modules' => [
'v1' => [
'basePath' => '@app/modules/v1',
'controllerNamespace' => 'app\modules\v1\controllers',
],
'v2' => [
'basePath' => '@app/modules/v2',
'controllerNamespace' => 'app\modules\v2\controllers',
],
],
'components' => [
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => ['v1/user', 'v1/post']],
['class' => 'yii\rest\UrlRule', 'controller' => ['v2/user', 'v2/post']],
],
],
],
];
```
Como consecuencia de el anterior código, `http://example.com/v1/users` puede devolver la lista de usuarios de la versión 1, mientras
`http://example.com/v2/users` puede devolver la versión 2 de los usuarios.
Gracias a los módulos, el código de las diferentes principales versiónes puede ser aislado. Pero, los módulos, hacen posible reusar el código a través de los módulos vía clases base comunes y otros recursos compartidos.
Para traficar con los números de versión menores, puede obtener las ventajas de el contenido de las capacidades de las conductas de negociación provistas por el [[yii\filters\ContentNegotiator|contentNegotiator]]. La conducta `contentNegotiator` puede poner la propiead [[yii\web\Response::acceptParams]] cuando determina cuál tipo de contenido a soportar.
Por ejemplo, si una peticiónes enviada con la cabecera HTTP `Accept: application/json; version=v1`, entonces la conducta de negociación, [[yii\web\Response::acceptParams]] puede contener el valor `['version' => 'v1']`.
Basado en la información de versión contenida en `acceptParams`, puedes escribir código condicional en lugares como acciones, clases de recursos, serializadores, etc. para proveer la funcionalidad apropiada.
Desde la menor versión, por definición, es necesario mantener la compatibilidad hacia atrás, con suerte no tendrás demasiadas versiones a comporbar en tu código. De otra manera, probablemente puede ocurrir que necesites crear una versión principal.

2
docs/guide-es/runtime-overview.md

@ -17,6 +17,6 @@ Cada vez que una aplicación Yii gestiona una petición, se somete a un flujo de
El siguiente diagrama muestra como una aplicación gestiona una petición.
![Request Lifecycle](images/application-lifecycle.png)
![Request Lifecycle](images/request-lifecycle.png)
En esta sección, se describirá en detalle cómo funcionan algunos de estos pasos.

2
docs/guide-es/start-workflow.md

@ -79,7 +79,7 @@ Ciclo de Vida de una Petición (Request) <a name="request-lifecycle"></a>
El siguiente diagrama muestra cómo una aplicación maneja una petición.
![Ciclo de Vida de un Request](images/application-lifecycle.png)
![Ciclo de Vida de un Request](images/request-lifecycle.png)
1. Un usuario realiza una petición al [script de entrada](structure-entry-scripts.md) `web/index.php`.
2. El script de entrada carga la [configuración](concept-configurations.md) de la aplicación y crea

445
docs/guide-es/tutorial-core-validators.md

@ -0,0 +1,445 @@
Validadores del núcleo
======================
Yii provee en el núcleo un conjunto de validadores de uso común, que se pueden encontrar principalmente bajo el espacio de nombres (namespace) `yii\validators`.
En vez de utilizar interminables nombres de clases para los validadores, puedes usar *alias* para especificar el uso de esos validadores del núcleo. Por ejemplo, puedes usar el alias `required` para referirte a la clase [[yii\validators\RequiredValidator]] :
```php
public function rules()
{
return [
[['email', 'password'], 'required'],
];
}
```
La propiedad [[yii\validators\Validator::builtInValidators]] declara todos los aliases de los validadores soportados.
A continuación, vamos a describir el uso principal y las propiedades de cada validador del núcleo.
## [[yii\validators\BooleanValidator|boolean]] <a name="boolean"></a>
```php
[
// comprueba si "selected" es 0 o 1, sin mirar el tipo de dato
['selected', 'boolean'],
// comprueba si "deleted" es del tipo booleano, alguno entre true o false
['deleted', 'boolean', 'trueValue' => true, 'falseValue' => false, 'strict' => true],
]
```
Este validador comprueba si el valor de la entrada (input) es booleano.
- `trueValue`: El valor representando *true*. Valor por defecto a `'1'`.
- `falseValue`: El valor representando *false*. Valor por defecto a `'0'`.
- `strict`: Si el tipo del valor de la entrada (input) debe corresponder con `trueValue` y `falseValue`. Valor por defecto a `false`.
> Nota: Ya que los datos enviados con la entrada, vía formularios HTML,son todos cadenas (strings), usted debe normalmente dejar la propiedad [[yii\validators\BooleanValidator::strict|strict]] a false.
## [[yii\captcha\CaptchaValidator|captcha]] <a name="captcha"></a>
```php
[
['verificationCode', 'captcha'],
]
```
Este validador es usualmente usado junto con [[yii\captcha\CaptchaAction]] y [[yii\captcha\Captcha]] para asegurarse que una entrada es la misma que lo es el código de verificación que enseña el widget [[yii\captcha\Captcha|CAPTCHA]].
- `caseSensitive`: cuando la comparación del código de verificación depende de que sean mayúsculas y minúsculas (case sensitive). Por defecto a false.
- `captchaAction`: la [ruta](structure-controllers.md#routes) correspondiente a
[[yii\captcha\CaptchaAction|CAPTCHA action]] que representa (render) la imagen CAPTCHA. Por defecto`'site/captcha'`.
- `skipOnEmpty`: cuando la validación puede saltarse si la entrada está vacía. Por defecto a false, lo caul permite que la entrada sea necesaria (required).
## [[yii\validators\CompareValidator|compare]] <a name="compare"></a>
```php
[
// valida si el valor del atributo "password" es igual al "password_repeat"
['password', 'compare'],
// valida si la edad es mayor que o igual que 30
['age', 'compare', 'compareValue' => 30, 'operator' => '>='],
]
```
Este validador compara el valor especificado por la entrada con otro valor y, se asegura si su relación es la especificada por la propiedad `operator`.
- `compareAttribute`: El nombre del valor del atributo con el cual debe compararse. Cuando el validador está siendo usado para validar un atributo, el valor por defecto de esta propiedad debe de ser el nombre de el atributo con el sufijo `_repeat`. Por ejemplo, si el atributo a ser validado es `password`, entonces esta propiedad contiene por defecto `password_repeat`.
- `compareValue`: un valor constante con el que el valor de entrada debe ser comparado. Cuando ambos, esta propiedad y `compareAttribute` son especificados, esta preferencia tiene precedencia.
- `operator`: el operador de comparación. Por defecto vale `==`, permitiendo comprobar si el valor de entrada es igual al de `compareAttribute` o `compareValue`. Los siguientes operadores son soportados:
* `==`: comprueba si dos valores son iguales. La comparación se realiza en modo no estricto.
* `===`: comprueba si dos valores son iguales. La comparación se realiza en modo estricto.
* `!=`: comprueba si dos valores NO son iguales. La comparación se realiza en modo no estricto.
* `!==`: comprueba si dos valores NO son iguales. La comparación se realiza en modo estricto.
* `>`: comprueba si el valor siendo validado es mayor que el valor con el que se compara.
* `>=`: comprueba si el valor siendo validado es mayor o igual que el valor con el que se compara
* `<`: comprueba si el valor siendo validado es menor que el valor con el que se compara
* `<=`: comprueba si el valor siendo validado es menor o igual que el valor con el que se compara
## [[yii\validators\DateValidator|date]] <a name="date"></a>
```php
[
[['from', 'to'], 'date'],
]
```
Este validador comprueba si el valor de entrada es una fecha, tiempo or fecha/tiempo y tiempo en el formato correcto.
Opcionalmente, puede convertir el valor de entrada en una fecha/tiempo UNIX y almacenarla en un atributo especificado vía [[yii\validators\DateValidator::timestampAttribute|timestampAttribute]].
- `format`: el formato fecha/tiempo en el que debe estar el valor a ser validado.
Esto tiene que ser un patrón fecha/tiempo descrito en [manual ICU](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax).
Alternativamente tiene que ser una cadena con el prefijo `php:` representando un formato que ha de ser reconocido por la clase `Datetime` de PHP. Por favor, refiérase a <http://php.net/manual/en/datetime.createfromformat.php> sobre los formatos soportados.
Si no tiene ningún valor, ha de coger el valor de `Yii::$app->formatter->dateFormat`.
- `timestampAttribute`: el nombre del atributo al cual este validador puede asignar el fecha/hora UNIX convertida desde la entrada fecha/hora.
## [[yii\validators\DefaultValueValidator|default]] <a name="default"></a>
```php
[
// pone el valor de "age" a null si está vacío
['age', 'default', 'value' => null],
// pone el valor de "country" a "USA" si está vacío
['country', 'default', 'value' => 'USA'],
// asigna "from" y "to" con una fecha 3 días y 6 días a partir de hoy, si está vacía
[['from', 'to'], 'default', 'value' => function ($model, $attribute) {
return date('Y-m-d', strtotime($attribute === 'to' ? '+3 days' : '+6 days'));
}],
]
```
Este validador no valida datos. En cambio, asigna un valor por defecto a los atributos siendo validados, si los atributos están vacíos.
- `value`: el valor por defecto o un elemento llamable de PHP que devuelva el valor por defecto, el cual, va a ser asignado a los atributos siendo validados, si estos están vacíos. La signatura de la función PHP tiene que ser como sigue,
```php
function foo($model, $attribute) {
// ... calcula $value ...
return $value;
}
```
> Info: Cómo determinar si un valor está vacío o no, es un tópico separado cubierto en la sección [Valores Vacíos](input-validation.md#handling-empty-inputs) .
## [[yii\validators\NumberValidator|double]] <a name="double"></a>
```php
[
// comprueba si "salary" es un número de tipo doble
['salary', 'double'],
]
```
Esta validador comprueba si el valor de entrada es un número de tipo doble. Es equivalente a el validador [Número](#number) .
- `max`: el valor límite superior (incluido) de el valor. Si no tiene valor, significa que no se comprueba el valor superior.
- `min`: el valor límite inferior (incluido) de el valor. Si no tiene valor, significa que no se comprueba el valor inferior.
## [[yii\validators\EmailValidator|email]] <a name="email"></a>
```php
[
// comprueba si "email" es una dirección válida de email
['email', 'email'],
]
```
Este validador comprueba si el valor de entrada es una dirección válida de email.
- `allowName`: indica cuando permitir el nombre en la dirección de email (p.e. `John Smith <john.smith@example.com>`). Por defecto a false.
- `checkDNS`, comprobar cuando el dominio del email existe y tiene cualquier registro A o MX.
Es necesario ser consciente que esta comprobación puede fallar debido a problemas temporales de DNS, incluso si el la dirección es válida actualmente.
Por defecto a false.
- `enableIDN`, indica cuando el proceso de validación debe tener en cuenta el informe de IDN (internationalized domain names).
Por defecto a false. Dese cuenta que para poder usar la validación de IDN has de instalar y activar la extensión de PHP `intl`, o será lanzada una excepción.
## [[yii\validators\ExistValidator|exist]] <a name="exist"></a>
```php
[
// a1 necesita que exista una columna con el atributo "a1"
['a1', 'exist'],
// a1 necesita existir,pero su valor puede usar a2 para comprobar la existencia
['a1', 'exist', 'targetAttribute' => 'a2'],
// a1 y a2 necesitan existir ambos, y ambos pueden recibir un mensaje de error
[['a1', 'a2'], 'exist', 'targetAttribute' => ['a1', 'a2']],
// a1 y a2 necesitan existir ambos, sólo a1 puede recibir el mensaje de error
['a1', 'exist', 'targetAttribute' => ['a1', 'a2']],
// a1 necesita existir comprobando la existencia ambos a2 y a3 (usando el valor a1)
['a1', 'exist', 'targetAttribute' => ['a2', 'a1' => 'a3']],
// a1 necesita existir. Si a1 es un array, cada elemento de él tiene que existir.
['a1', 'exist', 'allowArray' => true],
]
```
Este validador comprueba si el valor de entrada puede ser encontrado en una columna de una tabla. Sólo funciona con los atributos del modelo [Registro Activo (Active Record)](db-active-record.md). Soporta validación tanto con una simple columna o múltiples columnas.
- `targetClass`: el nombre de la clase [Registro Activo (Active Record)](db-active-record.md) debe de ser usada para mirar por el valor de entrada siendo validado. Si no tiene valor, la clase del modelo actualmente siendo validado puede ser usada.
- `targetAttribute`: el nombre del atributo en `targetClass` que debe de ser usado para validar la existencia del valor de entrada. Si no tiene valor, puede usar el nombra del atributoactualmente siendo validado.
Puede usar una array para validar la existencia de múltiples columnas al mismo tiempo. El array de valores son los atributos que pueden ser usados para validar la existencia, mientras que las claves del array son los atributos a ser validados. Si la clave y el valor son los mismos, solo en ese momento puedes especificar el valor.
- `filter`: filtro adicional a aplicar a la consulta de la base de datos usado para comprobar la existencia de una valor de entrada.
Esto puede ser una cadena o un array representando la condición de la consulta (referirse a [[yii\db\Query::where()]] sobre el formato de la condición de consulta), o una función anónima con la signatura `function ($query)`, donde `$query` es el objeto [[yii\db\Query|Query]] que puedes modificar en la función.
- `allowArray`: indica cuando permitir que el valor de entrada sea un array. Por defecto a false.Si la propiedad es true y la entrada es un array, cada elemento del array debe existir en la columna destino. Nota que esta propiedad no puede ser true si estás validando, por el contrario, múltiple columnas poniendo el valor del atributo `targetAttribute` como que es un array.
## [[yii\validators\FileValidator|file]] <a name="file"></a>
```php
[
// comprueba si "primaryImage" es un fichero mde imagen en formato PNG, JPG o GIF.
// el tamaño del fichero ha de ser menor de 1MB
['primaryImage', 'file', 'extensions' => ['png', 'jpg', 'gif'], 'maxSize' => 1024*1024*1024],
]
```
Este validador comprueba que el fichero subido es el adecuado.
- `extensions`: una lista de extensiones de ficheros que pueden ser subidos. Esto puede ser tanto un array o una cadena conteniendo nombres de extensiones de ficheros separados por un espacio o coma (p.e. "gif, jpg").
Los nombres de las extensiones no diferencian mayúsculas de minúsculas (case-insensitive). Por defecto a null, permitiendo todas los nombres de extensiones de fichero.
- `mimeTypes`: una lista de tipos de ficheros MIME que están permitidos subir. Esto puede ser tanto un array como una cadena conteniendo tipos de fichero MIME separados por un espacio o una coma (p.e. "image/jpeg, image/png").
Los tipos Mime no diferencian mayúsculas de minúsculas (case-insensitive). Por defecto a null, permitiendo todos los tipos MIME.
- `minSize`: el número de bytes mínimo requerido para el fichero subido. El tamaño del fichero ha de ser superior a este valor. Por defecto a null, lo que significa sin límite inferior.
- `maxSize`: El número máximo de bytes del fichero a subir. El tamaño del fichero ha de ser inferior a este valor. Por defecto a null, significando no tener límite superior.
- `maxFiles`: el máximo número de ficheros que determinado atributo puede manejar. Por defecto a 1, lo que significa que la entrada debe de ser sólo un fichero. Si es mayor que 1, entonces la entrada tiene que ser un array conteniendo como máximo el número `maxFiles` de elementos que representan los ficheros a subir.
- `checkExtensionByMimeType`: cuando comprobar la extensión del fichero por el tipo MIME. Si la extensión producida por la comprobación del tipo MIME difiere la extensión del fichero subido, el fichero será considerado como no válido. Por defecto a true, significando que realiza este tipo de comprobación.
`FileValidator` es usado con [[yii\web\UploadedFile]]. Por favor, refiérase a la sección [Subida de ficheros](input-file-upload.md) para una completa cobertura sobre la subida de ficheros y llevar a cabo la validación de los ficheros subidos.
## [[yii\validators\FilterValidator|filter]] <a name="filter"></a>
```php
[
// recorta (trim) las entradas "username" y "email"
[['username', 'email'], 'filter', 'filter' => 'trim', 'skipOnArray' => true],
// normaliza la entrada de "phone"
['phone', 'filter', 'filter' => function ($value) {
// normaliza la entrada del teléfono aquí
return $value;
}],
]
```
Este validador no valida datos. En su lugar, aplica un filtro sobre el valor de entrada y le asigna de nuevo el atributo siendo validado.
- `filter`: una retrollamada (callback) de PHP que define un filtro. Tiene que ser un nombre de función global, una función anónima, etc.
La forma de la función ha de ser `function ($value) { return $newValue; }`. Tiene que contener un valor esta propiedad.
- `skipOnArray`: cuando evitar el filtro si el valor de la entrada es un array. Por defecto a false.
A tener en cuenta que si el filtro no puede manejar una entrada de un array, debes poner esta propiedad a true. En otro caso algún error PHP puede ocurrir.
> Consejo (Tip): Si quieres recortar los valores de entrada, puedes usar directamente el validador [Recorte (trim)](#trim).
## [[yii\validators\ImageValidator|image]] <a name="image"></a>
```php
[
// comprueba si "primaryImage" es una imágen vaĺida con el tamaño adecuado
['primaryImage', 'image', 'extensions' => 'png, jpg',
'minWidth' => 100, 'maxWidth' => 1000,
'minHeight' => 100, 'maxHeight' => 1000,
],
]
```
Este validador comprueba si el valor de entrada representa un fichero de imagen válido. Extiende al validador [Fichero (file)](#file) y, por lo tanto, hereda todas sus propiedades. Además, soporta las siguientes propiedades adicionales específicas para la validación de imágenes:
- `minWidth`: el mínimo ancho de la imagen. Por defecto a null, indicando que no hay límite inferior.
- `maxWidth`: el máximo ancho de la imagen. Por defecto a null, indicando que no hay límite superior.
- `minHeight`: el mínimo alto de la imagen. Por defecto a null, indicando que no hay límite inferior.
- `maxHeight`: el máximo alto de la imagen. Por defecto a null, indicando que no hay límite superior.
## [[yii\validators\RangeValidator|in]] <a name="in"></a>
```php
[
// comprueba si "level" es 1, 2 o 3
['level', 'in', 'range' => [1, 2, 3]],
]
```
Este validador comprueba si el valor de entrada puede encontrarse entre determinada lista de valores.
- `range`: una lista de determinados valores dentro de los cuales el valor de entrada debe de ser mirado.
- `strict`: cuando la comparación entre el valor de entrada y los valores determinados debe de ser estricta (ambos el tipo y el valor han de ser iguales). Por defecto a false.
- `not`: cuando el resultado de la validación debe de ser invertido. Por defecto a false. Cuando esta propiedad está a true, el validador comprueba que el valor de entrada NO ESTÁ en la determinada lista de valores.
- `allowArray`: si se permite que el valor de entrada sea un array. Cuando es true y el valor de entrada es un array, cada elemento en el array debe de ser encontrado en la lista de valores determinada,o la validación fallará.
## [[yii\validators\NumberValidator|integer]] <a name="integer"></a>
```php
[
// comrpueba si "age" es un entero
['age', 'integer'],
]
```
Esta validador comprueba si el valor de entrada es un entero.
- `max`: el valor superior (incluido) . Si no tiene valor, significa que el validador no comprueba el límite superior.
- `min`: el valor inferior (incluido). Si no tiene valor, significa que el validador no comprueba el límite inferior.
## [[yii\validators\RegularExpressionValidator|match]] <a name="match"></a>
```php
[
// comprueba si "username" comienza con una letra y contiene solamente caracteres en sus palabras
['username', 'match', 'pattern' => '/^[a-z]\w*$/i']
]
```
Este validador comprueba si el valor de entrada coincide con la expresión regular especificada.
- `pattern`: la expresión regular conla que el valor de entrada debe coincidir. Esta propiedad no puede estar vacía, o se lanzará una excepción.
- `not`: indica cuando invertir el resultado de la validación. Por defecto a false, significando que la validación es exitosa solamente si el valor de entrada coincide con el patrón. Si esta propiedad está a true, la validación es exitosa solamente si el valor de entrada NO coincide con el patrón.
## [[yii\validators\NumberValidator|number]] <a name="number"></a>
```php
[
// comprueba si "salary" es un número
['salary', 'number'],
]
```
Este validador comprueba si el valor de entrada es un número. Es equivalente al validador [Doble precisión (double)](#double).
- `max`: el valor superior límite (incluido) . Si no tiene valor, significa que el validador no comprueba el valor límite superior.
- `min`: el valor inferior límite (incluido) . Si no tiene valor, significa que el validador no comprueba el valor límite inferior.
## [[yii\validators\RequiredValidator|required]] <a name="required"></a>
```php
[
// comprueba si ambos "username" y "password" no están vacíos
[['username', 'password'], 'required'],
]
```
El validador comprueba si el valor de entrada es provisto y no está vacío.
- `requiredValue`: el valor deseado que la entrada debería tener. Si no tiene valor, significa que la entrada no puede estar vacía.
- `strict`: indica como comprobar los tipos de los datos al validar un valor. Por defecto a false.
Cuando `requiredValue` no tiene valor, si esta propiedad es true, el validador comprueba si el valor de entrada no es estrictamente null; si la propiedad es false, el validador puede usar una regla suelta para determinar si el valor está vacío o no.
Cuando `requiredValue` tiene valor, la comparación entre la entrada y `requiredValue` comprobará tambien los tipos de los datos si esta propiedad es true.
> Info: Como determinar si un valor está vacío o no es un tópico separado cubierto en la sección [Valores vacíos](input-validation.md#handling-empty-inputs).
## [[yii\validators\SafeValidator|safe]] <a name="safe"></a>
```php
[
// marca "description" como un atributo seguro
['description', 'safe'],
]
```
Este validador no realiza validación de datos. En lugar de ello, es usado para marcar un atributo como seguro [atributos seguros](structure-models.md#safe-attributes).
## [[yii\validators\StringValidator|string]] <a name="string"></a>
```php
[
// comprueba si "username" es una cadena cuya longitud está entre 4 Y 24
['username', 'string', 'length' => [4, 24]],
]
```
Este validador comprueba si el valor de entrada es una cadena válida con determinada longitud.
- `length`: especifica la longitud límite de la cadena de entrada a validar. Esto tiene que ser especificado del las siguientes formas:
* un entero: la longitud exacta que la cadena debe de tener;
* un array de un elemento: la longitud mínima de la cadena de entrada (p.e.`[8]`). Esto puede sobre escribir `min`.
* un array de dos elementos: las longitudes mínima y mmáxima de la cadena de entrada (p.e. `[8, 128]`).
Esto sobreescribe ambos valores de `min` y `max`.
- `min`: el mínimo valor de longitud de la cadena de entrada. Si no tiene valor, significa que no hay límite para longitud mínima.
- `max`: el máximo valor de longitud de la cadena de entrada. Si no tiene valor, significa que no hay límite para longitud máxima.
- `encoding`: la codificación de la cadena de entrada a ser validada. Si no tiene valor, usará el valor de la aplicación [[yii\base\Application::charset|charset]] que por defecto es `UTF-8`.
## [[yii\validators\FilterValidator|trim]] <a name="trim"></a>
```php
[
// recorta (trim) los espacios en blanco que rodean a "username" y "email"
[['username', 'email'], 'trim'],
]
```
Este validador no realiza validación de datos. En cambio, recorta los espacios que rodean el valor de entrada. Nota que si el valor de entrada es un array, se ignorará este validador.
## [[yii\validators\UniqueValidator|unique]] <a name="unique"></a>
```php
[
// a1 necesita ser único en la columna representada por el atributo "a1"
['a1', 'unique'],
// a1 necesita ser único, pero la columna a2 puede ser usado para comprobar la unicidad del valor a1
['a1', 'unique', 'targetAttribute' => 'a2'],
// a1 y a2 necesitan ambos ser únicos, y ambospueden recibir el mensaje de error
[['a1', 'a2'], 'unique', 'targetAttribute' => ['a1', 'a2']],
// a1 y a2 necesitan ser unicos ambos, solamente uno recibirá el mensaje de error
['a1', 'unique', 'targetAttribute' => ['a1', 'a2']],
// a1 necesita ser único comprobando la unicidad de ambos a2 y a3 (usando el valor)
['a1', 'unique', 'targetAttribute' => ['a2', 'a1' => 'a3']],
]
```
Este validador comprueba si el valor de entrada es único en una columna de una tabla. Solo funciona con los atributos del modelo [Registro Activo (Active Record)](db-active-record.md). Soporta validación contra cualquiera de los casos, una columna o múltiples columnas.
- `targetClass`: el nombre de la clase [Registro Activo (Active Record)](db-active-record.md) que debe de ser usada para mirar por el valor de entrada que está siendo validado. Si no tiene valor, la clase del modelo actualmente validado será usada.
- `targetAttribute`: el nombre de el atributo en `targetClass`que debe de ser usado para validar la unicidad de el valor de entrada. Si no tiene valor, puede usar el nombre del atributo actualmente siendo validado.
Puedes usar un array para validar la unicidad de múltiples columnas al mismo tiempo. Los valores del array son atributos que pueden ser usados para validar la unicidad, mientras que las claves del array son los atributos que cuyos valores van a ser validados. Si la clave y el valor son el mismo, entonces puedes especificar el valor.
- `filter`: filtro adicional puede ser aplicado a la consulta de la base de datos usado para comprobar la unicidad del valor de entrada.
Esto puede ser una cadena o un array representando la condición adicional a la consulta (Referirse a [[yii\db\Query::where()]] para el formato de la condición de la consulta), o una función anónima de la forma `function ($query)`, donde `$query` es el objeto [[yii\db\Query|Query]] que puedes modificar en la función.
## [[yii\validators\UrlValidator|url]] <a name="url"></a>
```php
[
// comprueba si "website" es una URL válida. Prefija con "http://" al atributo "website"
// si no tiene un esquema URI
['website', 'url', 'defaultScheme' => 'http'],
]
```
Este validador comprueba si el valor de entrada es una URL válida.
- `validSchemes`: un array especificando el esquema URI que debe ser considerado válido. Por defecto contiene `['http', 'https']`, significando que ambas URLS `http` y `https` son consideradas válidas.
- `defaultScheme`: el esquema de URI a poner como prefijo a la entrada si no tiene la parte del esquema.
Por defecto a null, significando que no modifica el valor de entrada.
- `enableIDN`: Si el validador debe formar parte del registro IDN (internationalized domain names).
Por defecto a false. Nota que para usar la validación IDN tienes que instalar y activar la extensión PHP `intl`, en otro caso una excepción será lanzada.

142
docs/guide-es/tutorial-yii-integration.md

@ -0,0 +1,142 @@
Trabajando con código de terceros
=================================
De tiempo en tiempo, puede necesitar usar algún código de terceros en sus aplicaciones Yii. O puedes querer usar Yii como una librería en otros sistemas de terceros. En esta sección, te enseñaremos cómo conseguir estos objetivos.
## Usando librerías de terceros en Yii <a name="using-libs-in-yii"></a>
Para usar una librería en una aplicación Yii, primeramente debes de asegurarte que las clases een la librería son incluidas adecuadamente o pueden ser cargadas de forma automática.
### Usando Paquetes de Composer <a name="using-composer-packages"></a>
Muchas librerías de terceros son liberadas en términos de paquetes [Composer](https://getcomposer.org/).
Puedes instalar este tipo de librerias siguiendo dos sencillos pasos:
1. modificar el fichero `composer.json` de tu aplicación y especificar que paquetes Composer quieres instalar.
2. ejecuta `composer install` para instalar los paquetes específicados.
Las clases en los paquetes Composer instalados pueden ser autocargados usando el cargador automatizado de Composer autoloader. Asegúrate que el fichero [script de entrada](structure-entry-scripts.md) de tu aplicación contiene las siguientes líneas para instalar el cargador automático de Composer:
```php
// instalar el cargador automático de Composer
require(__DIR__ . '/../vendor/autoload.php');
// incluir rl fichero de la clase Yii
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
```
### Usando librerías Descargadas <a name="using-downloaded-libs"></a>
Si la librería no es liberada como un paquete de Composer, debes de seguir sus instrucciones de instalación para instalarla.
En muchos casos, puedes necesitar descargar manualmente el fichero de la versión y desempaquetarlo en el directorio `BasePath/vendor` , donde `BasePath` representa el [camino base (base path)](structure-applications.md#basePath) de tu aplicación.
Si la librería lleva su propio cargador automático (autoloader), puedes instalarlo en [script de entrada](structure-entry-scripts.md) de tu aplicación. Es recomendable que la instalación se termine antes de incluir el fichero `Yii.php` de forma que el cargador automático tenga precedencia al cargar de forma automática las clases.
Si la librería no provee un cargador automático de clases, pero la denominación de sus clases sigue el [PSR-4](http://www.php-fig.org/psr/psr-4/), puedes usar el cargador automático de Yii para cargar de forma automática las clases. Todo lo que necesitas es declarar un [alias raiz](concept-aliases.md#defining-aliases) para cada espacio de nombres (namespace) raiz usado en sus clases. Por ejemplo, asume que has instalado una librería en el directorio `vendor/foo/bar`, y que las clases de la librería están bajo el espacio de nombres raiz `xyz`. Puedes incluir el siguiente código en la configuración de tu aplicación:
```php
[
'aliases' => [
'@xyz' => '@vendor/foo/bar',
],
]
```
Si ninguno de lo anterior es el caso, estaría bien que la librería dependa del camino de inclusión (include path) de configuración de PHP para localizar correctamente e incluir los ficheros de las clases. Simplemente siguiendo estas instrucciones de cómo configurar el camino de inclusión de PHP.
En el caso más grave en el que la librería necesite incluir cada uno de sus ficheros de clases, puedes usar el siguiente método para incluir las clases según se pidan:
* Identificar que clases contiene la librería.
* Listar las clases y el camino a los ficheros correspondientes en `Yii::$classMap` en el script de entrada [script de entrada](structure-entry-scripts.md) de la aplicación. Por ejemplo,
```php
Yii::$classMap['Class1'] = 'path/to/Class1.php';
Yii::$classMap['Class2'] = 'path/to/Class2.php';
```
## Usando Yii en Sistemas de Terceros <a name="using-yii-in-others"></a>
Debido a que Yii provee muchas posibilidades excelentes, a veces puedes querer usar alguna de sus características para permitir el desarrollo o mejora de sistemas de terceros, como es WordPress, Joomla, o aplicaciones desarrolladas usando otros frameworks de PHP. Por ejemplo, puedes queres usar la clase [[yii\helpers\ArrayHelper]] o usar la característica [Active Record](db-active-record.md) en un sistema de terceros. Para lograr este objetivo, principalmente necesitas realizar dos pasos: instalar Yii , e iniciar Yii.
Si el sistema de terceros usa Composer para manejar sus dependencias, simplemente ejecuta estos comandos para instalar Yii:
```
composer require "yiisoft/yii2:*"
composer install
```
En otro caso, puedes [descargar](http://www.yiiframework.com/download/) el fichero de la edición de Yii y desempaquetarla en el directorio `BasePath/vendor`.
Después, debes de modificar el script de entrada de sistema de terceros para incluir el siguiente código al principio:
```php
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
$yiiConfig = require(__DIR__ . '/../config/yii/web.php');
new yii\web\Application($yiiConfig); // No ejecutes run() aquí
```
Como puedes ver, el código anterior es muy similar al que puedes ver en [script de entrada](structure-entry-scripts.md) de una aplicación típica. La única diferencia es que después de que se crea la instancia de la aplicación, el método `run()` no es llamado. Esto es así porque llamando a `run()`, Yii se haría cargo del control del flujo de trabajo del manejo de las peticiones, lo cual no es necesario en este caso por estar ya es manejado por la aplicación existente.
Como en una aplicación Yii, debes configurar la instancia de la aplicación basándose en el entorno que se está ejecutando del sistema de terceros. Por ejemplo, para usar la característica [Active Record](db-active-record.md) , necesitas configurar `db` [componente de la aplicación](structure-application-components.md) con los parámetros de la conexión de base de datos usados por el sistema de terceros.
Ahora puedes usar muchas características provistas por Yii. Por ejemplo, puedes crear clases Active Record y usarlas para trabajar con bases de datos.
## Usando Yii 2 con Yii 1 <a name="using-both-yii2-yii1"></a>
Si estaba usando Yii 1 previamente, es como si tuvieras una aplicación Yii 1 funcionando. En vez de reescribir toda la aplicación en Yii 2, puedes solamente mejorarla usando alguna de las características sólo disponibles en Yii 2.
Esto se puede lograr tal y como se describe abajo.
> Nota: Yii 2 requiere PHP 5.4 o superior. Debes de estar seguro que tanto tu servidor como la aplicación existente lo soportan.
Primero, instala Yii 2 en tu aplicación siguiendo las instrucciones descritas en la [última subsección](#using-yii-in-others).
Segundo,modifica el script de entrada de la aplicación como sigue,
```php
// incluir la clase Yii personalizada descrita debajo
require(__DIR__ . '/../components/Yii.php');
// configuración para la aplicación Yii 2
$yii2Config = require(__DIR__ . '/../config/yii2/web.php');
new yii\web\Application($yii2Config); // No llamar a run()
// configuración para la aplicación Yii 1
$yii1Config = require(__DIR__ . '/../config/yii1/main.php');
Yii::createWebApplication($yii1Config)->run();
```
Debido a que ambos Yii 1 y Yii 2 tiene la clase `Yii` , debes crear una versión personalizada para combinarlas.
El código anterior incluye el fichero con la clase `Yii` personalizada, que tiene que ser creada como sigue.
```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php'); // Yii 2.x
$yii1path = '/path/to/yii1';
require($yii1path . '/YiiBase.php'); // Yii 1.x
class Yii extends \yii\BaseYii
{
// copy-paste the code from YiiBase (1.x) here
}
Yii::$classMap = include($yii2path . '/classes.php');
// registrar el autoloader de Yii2 autoloader via Yii1
Yii::registerAutoloader(['Yii', 'autoload']);
// crear el contenedor de inyección de dependencia
Yii::$container = new yii\di\Container;
```
¡Esto es todo!. Ahora, en cualquier parte de tu código, puedes usar `Yii::$app` para acceder a la instancia de la aplicación de Yii 2, mientras `Yii::app()` proporciona la instancia de la aplicación de Yii 1 :
```php
echo get_class(Yii::app()); // genera 'CWebApplication'
echo get_class(Yii::$app); // genera 'yii\web\Application'
```

63
docs/guide-es/widget-bootstrap.md

@ -0,0 +1,63 @@
Widgets de Bootstrap
====================
> Nota: Esta sección está bajo desarrollo.
Yii incluye soporta las marcas y componentes del framework [Bootstrap 3](http://getbootstrap.com/) (también conocido como "Twitter Bootstrap"). Bootstrap es un excelente, adaptable framework que puede aumentar la velocidad de desarrollo de los procesos del lado del cliente.
El núcleo de Bootstrap está represntado en dos partes:
- Elementos básicos de CSS, como son un sistema de diseño en formato cuadrícula , tipografía, clases de ayuda (helpers), y utilidades adapatables(responsive).
- Componentes preparados para su uso, tales como formularios, menús, paginación, cajas modales, pestañas, etc
Elementos básicos
------
Yii no hace uso de elementos básicos de boostrap en el código PHP ya que HTML es muy simple por sí mismo, en este caso. Puedes encontrar detalle del uso de estos elementos básicos en [sitio web de la documentación de bootstrap](http://getbootstrap.com/css/). Aún así Yii provee una manera conveniente de incluir los elementos básicos de los recursos de bootstrap en tus páginas con una simple línea añadida a `AppAsset.php` localizada en tu directorio `@app/assets` :
```php
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset', // Esta línea
];
```
Usar bootstrap a través de el gestor de recursos Yii te permite minimizar estos recursos y combinar con tus propios recursos cuando sea necesario..
Widgets de Yii
-----------
Componentes más complejos de bootstrap components están envueltos dentro de widgets de Yii para permitir una sintaxis más robusta e integrar con las posibilidades y características del framework. Todos los widgets pertenecen al espacio de nombres `\yii\bootstrap` :
- [[yii\bootstrap\ActiveForm|ActiveForm]]
- [[yii\bootstrap\Alert|Alert]]
- [[yii\bootstrap\Button|Button]]
- [[yii\bootstrap\ButtonDropdown|ButtonDropdown]]
- [[yii\bootstrap\ButtonGroup|ButtonGroup]]
- [[yii\bootstrap\Carousel|Carousel]]
- [[yii\bootstrap\Collapse|Collapse]]
- [[yii\bootstrap\Dropdown|Dropdown]]
- [[yii\bootstrap\Modal|Modal]]
- [[yii\bootstrap\Nav|Nav]]
- [[yii\bootstrap\NavBar|NavBar]]
- [[yii\bootstrap\Progress|Progress]]
- [[yii\bootstrap\Tabs|Tabs]]
Usando los ficheros .less de Bootstrap directamente
-------------------------------------------
Si quieres incluir el [Css Bootstrap directamente en tus ficheros less](http://getbootstrap.com/getting-started/#customizing) puedes necesitar desactivar la carga los ficheros css originales de bootstrap.
Esto lo puedes hacer poniendo la propiedad css de [[yii\bootstrap\BootstrapAsset|BootstrapAsset]] vacía.
Para esto necesitas configurar el `assetManager` [componente de la aplicación](structure-application-components.md) como sigue:
```php
'assetManager' => [
'bundles' => [
'yii\bootstrap\BootstrapAsset' => [
'css' => [],
]
]
]
```

27
docs/guide-es/widget-jui.md

@ -0,0 +1,27 @@
Widgets de Jquery UI
====================
> Nota: Esta sección está en desarrollo.
Además de lo anterior, Yii incluye soporte para la librería jquery [jQuery UI](http://api.jqueryui.com/). jQuery UI es un probado conjunto de interacciones con el interface de usuario, efectos, widgets, y temas sobre la librería JavaScript de jquery.
widgets de Yii
--------------
Los componentes más complejos de jQuery UI están envueltos dentro de los widgets de Yii para permitir una sintaxis más robusta e integralas con las características del framework. Todos los widgets pertenecen al espacio de nombre `\yii\jui` :
- [[yii\jui\Accordion|Accordion]]
- [[yii\jui\AutoComplete|AutoComplete]]
- [[yii\jui\DatePicker|DatePicker]]
- [[yii\jui\Dialog|Dialog]]
- [[yii\jui\Draggable|Draggable]]
- [[yii\jui\Droppable|Droppable]]
- [[yii\jui\Menu|Menu]]
- [[yii\jui\ProgressBar|ProgressBar]]
- [[yii\jui\Resizable|Resizable]]
- [[yii\jui\Selectable|Selectable]]
- [[yii\jui\Slider|Slider]]
- [[yii\jui\SliderInput|SliderInput]]
- [[yii\jui\Sortable|Sortable]]
- [[yii\jui\Spinner|Spinner]]
- [[yii\jui\Tabs|Tabs]]

0
docs/guide-fr/images/application-lifecycle.graphml → docs/guide-fr/images/request-lifecycle.graphml

0
docs/guide-fr/images/application-lifecycle.png → docs/guide-fr/images/request-lifecycle.png

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

2
docs/guide-fr/start-workflow.md

@ -74,7 +74,7 @@ Cycle de vie d'une requête <a name="request-lifecycle"></a>
Le diagramme suivant présente la manière dont une application traite une requête.
![Cycle de Vie d'une Requête](images/application-lifecycle.png)
![Cycle de Vie d'une Requête](images/request-lifecycle.png)
1. Un utilisateur fait une requête au [script de démarrage](structure-entry-scripts.md) `web/index.php`.
2. Le script de démarrage charge la [configuration](concept-configurations.md) de l'application et créé une instance d'[application](structure-applications.md) pour traiter la requête.

8
docs/guide-ja/README.md

@ -50,7 +50,7 @@ All Rights Reserved.
* [概要](runtime-overview.md)
* [ブートストラップ](runtime-bootstrapping.md)
* [ルーティング](runtime-routing.md)
* [ルーティングと URL 生成](runtime-routing.md)
* [リクエスト](runtime-requests.md)
* [レスポンス](runtime-responses.md)
* [セッションとクッキー](runtime-sessions-cookies.md)
@ -122,9 +122,9 @@ All Rights Reserved.
* [概要](caching-overview.md)
* [データキャッシュ](caching-data.md)
* [断片キャッシュ](caching-fragment.md)
* [フラグメントキャッシュ](caching-fragment.md)
* [ページキャッシュ](caching-page.md)
* [HTTP Caching](caching-http.md)
* [HTTP キャッシュ](caching-http.md)
RESTful ウェブサービス
@ -136,7 +136,7 @@ RESTful ウェブサービス
* [ルーティング](rest-routing.md)
* [レスポンスの書式設定](rest-response-formatting.md)
* [認証](rest-authentication.md)
* [速度制限](rest-rate-limiting.md)
* [転送レート制限](rest-rate-limiting.md)
* [バージョン管理](rest-versioning.md)
* [エラー処理](rest-error-handling.md)

288
docs/guide-ja/caching-data.md

@ -0,0 +1,288 @@
データキャッシュ
============
データキャッシュは PHP の変数をキャッシュに格納し、あとでキャッシュからそれらを読み込みます。
[クエリキャッシュ](#query-caching) や [ページキャッシュ](caching-page.md) などのより高度なキャッシュ機能の基礎でもあります。
以下はデータキャッシュの典型的な利用パターンを示したコードです。`$cache` は [キャッシュコンポーネント](#cache-components) を指します:
```php
// キャッシュから $data を取得しようと試みる
$data = $cache->get($key);
if ($data === false) {
// キャッシュの中に $data が見つからない場合は一から作る
// 次回はそれを取得できるように $data をキャッシュに格納する
$cache->set($key, $data);
}
// $data はここで利用できる
```
## キャッシュコンポーネント <a name="cache-components"></a>
データキャッシュはメモリ、ファイル、データベースなどさまざまなキャッシュストレージを表す、いわゆるキャッシュコンポーネントに依存しています。
キャッシュコンポーネントは通常グローバルに設定しアクセスできるように [アプリケーションコンポーネント](structure-application-components.md) として登録されています。以下のコードは [Memcached](http://memcached.org/) を使い 2 つのキャッシュサーバを用いて、`cache` コンポーネントをどのように設定するかを示したものです:
```php
'components' => [
'cache' => [
'class' => 'yii\caching\MemCache',
'servers' => [
[
'host' => 'server1',
'port' => 11211,
'weight' => 100,
],
[
'host' => 'server2',
'port' => 11211,
'weight' => 50,
],
],
],
],
```
上記のキャッシュコンポーネントには `Yii::$app->cache` でアクセスできます。
すべてのキャッシュコンポーネントは同じ API がセットされているので、アプリケーションのコンフィグレーション側で設定しなおせば、キャッシュを使っているコードに変更を加えなくても、異なるキャッシュコンポーネントに入れ替えることができます。例えば上記の設定を [[yii\caching\ApcCache|APC キャッシュ]] に変更する場合は以下のようにします:
```php
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
],
],
```
> ヒント: キャッシュコンポーネントは複数登録することができます。`cache` という名前のコンポーネントはキャッシュに依存したクラスによってデフォルトで使用されています (例えば [[yii\web\UrlManager]] など) 。
### サポートされているキャッシュストレージ <a name="supported-cache-storage"></a>
Yii はさまざまなキャッシュストレージをサポートしています。以下は概要です:
* [[yii\caching\ApcCache]]: PHP の [APC](http://php.net/manual/ja/book.apc.php) 拡張モジュールを使用します。集中型の分厚いアプリケーションのキャッシュを扱うときには最速の一つとして考えることができます (例えば、サーバが 1 台であったり、専用のロードバランサを持っていない、など) 。
* [[yii\caching\DbCache]]: キャッシュされたデータを格納するためにデータベースのテーブルを使用します。このキャッシュを使用するには [[yii\caching\DbCache::cacheTable]] で指定したテーブルを作成する必要があります。
* [[yii\caching\DummyCache]]: 実際にはキャッシュを行わない、キャッシュの代替を提供します。このコンポーネントの目的は、キャッシュが利用できることをチェックするためのコードを簡略化することです。たとえば、開発中やサーバに実際のキャッシュサポートがない場合に、このキャッシュコンポーネントを使用することができます。そして、実際のキャッシュサポートが有効になったときに、対応するキャッシュコンポーネントに切替えて使用します。 どちらの場合も、`Yii::$app->cache` が null かも知れないと心配せずに、データを取得するために同じコード `Yii::$app->cache->get($key)` を使用できます。
* [[yii\caching\FileCache]]: キャッシュされたデータを保存するために標準ファイルを使用します。これはページコンテンツなど大きなかたまりのデータに特に適しています。
* [[yii\caching\MemCache]]: PHP の [Memcache](http://php.net/manual/ja/book.memcache.php) と [Memcached](http://php.net/manual/ja/book.memcached.php) 拡張モジュールを使用します。分散型のアプリケーションでキャッシュを扱うときには最速の一つとして考えることができます (例えば、複数台のサーバ構成であったり、ロードバランサなど) 。
* [[yii\redis\Cache]]: [Redis](http://redis.io/) の key-value ストアに基づいてキャッシュコンポーネントを実装しています。(Redis の バージョン 2.6.12 以降が必要です) 。
* [[yii\caching\WinCache]]: PHP の [WinCache](http://iis.net/downloads/microsoft/wincache-extension) ([関連リンク](http://php.net/manual/ja/book.wincache.php)) 拡張モジュールを使用します。
* [[yii\caching\XCache]]: PHP の [XCache](http://xcache.lighttpd.net/) 拡張モジュールを使用します。
* [[yii\caching\ZendDataCache]]: キャッシュメディアして [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) を使用します。
> ヒント: 同じアプリケーション内で異なるキャッシュを使用することもできます。一般的なやり方として、小さくとも常に使用されるデータ (例えば、統計データなど) を格納する場合はメモリベースのキャッシュストレージを使用し、大きくて使用頻度の低いデータを格納する場合はファイルベース、またはデータベースのキャッシュストレージを使用します (例えば、ページコンテンツなど) 。
## キャッシュ API <a name="cache-apis"></a>
すべてのキャッシュコンポーネントが同じ基底クラス [[yii\caching\Cache]] を持っているので、以下の API をサポートしています。
* [[yii\caching\Cache::get()|get()]]: 指定されたキーを用いてキャッシュからデータを取得します。キャッシュが見つからないか、もしくは有効期限が切れていたり無効になっている場合は false を返します。
* [[yii\caching\Cache::set()|set()]]: キーによって識別されたデータをキャッシュに格納します。
* [[yii\caching\Cache::add()|add()]]: キーがキャッシュ内で見つからない場合に、キーによって識別されたデータをキャッシュに格納します。
* [[yii\caching\Cache::mget()|mget()]]: 指定されたキーを用いてキャッシュから複数のデータを取得します。
* [[yii\caching\Cache::mset()|mset()]]: キャッシュに複数のデータを格納します。各データはキーによって識別されます。
* [[yii\caching\Cache::madd()|madd()]]: キャッシュに複数のデータを格納します。各データはキーによって識別されます。もしキャッシュ内にキーがすでに存在する場合はスキップされます。
* [[yii\caching\Cache::exists()|exists()]]: 指定されたキーがキャッシュ内で見つかったかどうかを示す値を返します。
* [[yii\caching\Cache::delete()|delete()]]: キャッシュからキーによって識別されるデータを削除します。
* [[yii\caching\Cache::flush()|flush()]]: キャッシュからすべてのデータを削除します。
> 注意: [[yii\caching\Cache::get()|get()]] メソッドは、データがキャッシュ内に見つからないことを示すために戻り値として false を使用しているので、直接 boolean 型の `false` をキャッシュしないでください。代わり、配列内に `false` を置いてキャッシュすることによって、この問題を回避できます。
キャッシュされたデータを取得する際に発生するオーバーヘッドを減すために、MemCache, APC などのいくつかのキャッシュストレージはバッチモードで複数のキャッシュされた値の取得をサポートしています。[[yii\caching\Cache::mget()|mget()]] や [[yii\caching\Cache::madd()|madd()]] などの API はこの機能を十分に引き出すために提供されています。基礎となるキャッシュストレージがこの機能をサポートしていない場合には、シミュレートされます。
[[yii\caching\Cache]] は `ArrayAccess` インターフェイスを継承しているので、キャッシュコンポーネントは配列のように扱うことができます。以下はいくつかの例です:
```php
$cache['var1'] = $value1; // $cache->set('var1', $value1); と同等
$value2 = $cache['var2']; // $value2 = $cache->get('var2'); と同等
```
### キャッシュのキーについて <a name="cache-keys"></a>
キャッシュに格納される各データは、一意のキーによって識別されるため、キャッシュ内にデータを格納するときはキーを指定する必要があります。あとでキャッシュからデータを取得するときは、それに対応するキーを用意する、といった感じです。
文字列またはキャッシュのキーとして、任意の値を使用することができます。キーが文字列でない場合は、自動的に文字列にシリアライズされます。
キャッシュのキーを定義する一般的なやり方として、配列に決定要素を単位としてすべて含めることです。
例えば [[yii\db\Schema]] はデータベースのテーブルに関するキャッシュスキーマ情報に以下のキーを使用しています:
```php
[
__CLASS__, // クラス名
$this->db->dsn, // データベース接続のデータソース名
$this->db->username, // データベース接続のログインユーザ
$name, // テーブル名
];
```
見ての通り、キーは一意にデータベースのテーブルを指定するために必要なすべての情報が含まれています。
同じキャッシュストレージが異なるアプリケーションによって使用されているときは、キャッシュのキーの競合を避けるために、各アプリケーションではユニークなキーの接頭辞を指定する必要があります。これは [[yii\caching\Cache::keyPrefix]] プロパティを設定することでできます。例えば、アプリケーションのコンフィギュレーションで以下のように書くことができます:
```php
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
'keyPrefix' => 'myapp', // ユニークなキャッシュのキーの接頭辞
],
],
```
相互運用性を確保するために、英数字のみを使用する必要があります。
### キャッシュの有効期限 <a name="cache-expiration"></a>
キャッシュに格納されたデータは、いくつかのキャッシュポリシー (例えば、キャッシュスペースがいっぱいになったときは最も古いデータが削除される、など) の実施で除去されない限り、永遠に残り続けます。この動作を変えるために [[yii\caching\Cache::set()|set()]] で有効期限パラメータを指定することができます。パラメータはキャッシュ内に何秒間有効であるかを示します。[[yii\caching\Cache::get()|get()]] でデータを取得する際に有効期限が切れていた場合は、キャッシュ内にデータが見つからなかったことを示す false が返されます。例えば、
```php
// 最大で 45 秒間キャッシュ内にデータを保持する
$cache->set($key, $data, 45);
sleep(50);
$data = $cache->get($key);
if ($data === false) {
// $data は有効期限が切れているか、またはキャッシュ内に見つからない
}
```
### キャッシュの依存関係 <a name="cache-dependencies"></a>
有効期限の設定に加えて、キャッシュされたデータにはいわゆる *キャッシュの依存関係* の変化によって無効にすることもできます。例えば [[yii\caching\FileDependency]] はファイルの更新時刻の依存関係を表しています。依存関係が変更されたときに、対応するファイルが更新されることを意味しています。その結果、キャッシュ内で見つかった古いファイルのコンテンツは、無効とされるべきであり [[yii\caching\Cache::get()|get()]] は false を返します。
キャッシュの依存関係は [[yii\caching\Dependency]] 子孫クラスのオブジェクトとして表現されます。[[yii\caching\Cache::set()|set()]] でキャッシュにデータを格納する際に、関連するキャッシュの依存関係を知らせることができます。例えば、
```php
// example.txt ファイルの変更時間への依存関係を作成
$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);
// データは 30 秒で期限切れになります
// さらに、依存関係にあるファイルが変更された場合、有効期限内でも無効になります
$cache->set($key, $data, 30, $dependency);
// データが有効期限切れの場合はキャッシュがチェックされます
// 関連する依存関係が変更された場合にもチェックします
// これらの条件のいずれかが満たされている場合は false を返します
$data = $cache->get($key);
```
以下は利用可能なキャッシュの依存関係の概要です:
- [[yii\caching\ChainedDependency]]: チェーン上のいずれかの依存関係が変更された場合、依存関係が変更されます。
- [[yii\caching\DbDependency]]: 指定された SQL 文のクエリ結果が変更された場合、依存関係が変更されます。
- [[yii\caching\ExpressionDependency]]: 指定されたPHPの式の結果が変更された場合、依存関係が変更されます。
- [[yii\caching\FileDependency]]: ファイルの最終更新時刻が変更された場合、依存関係が変更されます。
- [[yii\caching\TagDependency]]: 一つまたは複数のタグを持つキャッシュされたデータを関連付けます。[[yii\caching\TagDependency::invalidate()]] を呼び出すことによって指定されたタグ(複数可)と、キャッシュされたデータを無効にすることができます。
## クエリキャッシュ <a name="query-caching"></a>
クエリキャッシュは、データキャッシュ上に構築された特別なキャッシュ機能で、データベースのクエリ結果をキャッシュするために提供されています。
クエリキャッシュは [[yii\db\Connection|データベース接続]] と有効な `cache` コンポーネントを必要とします。
`$db` を [[yii\db\Connection]] のインスタンスと仮定した場合、クエリキャッシュの基本的な使い方は以下のようになります:
```php
$result = $db->cache(function ($db) {
// クエリキャッシュが有効で、かつクエリ結果がキャッシュ内にある場合、
// SQL クエリ結果がキャッシュから提供されます
return $db->createCommand('SELECT * FROM customer WHERE id=1')->queryOne();
});
```
クエリキャッシュは [DAO](db-dao.md) だけではなく [アクティブレコード](db-active-record.md) でも使用することができます。
> 情報: いくつかの DBMS (例えば [MySQL](http://dev.mysql.com/doc/refman/5.1/ja/query-cache.html)) でもデータベースのサーバサイドのクエリキャッシュをサポートしています。どちらのクエリキャッシュメカニズムも選べますが、前述した Yii のクエリキャッシュを使用することによって、キャッシュの依存関係を柔軟に指定できたり、潜在的にもより効率的でしょう。
### 設定 <a name="query-caching-configs"></a>
クエリキャッシュは [[yii\db\Connection]] を通して 3 つのグローバルな設定可能オプションがあります:
* [[yii\db\Connection::enableQueryCache|enableQueryCache]]: クエリキャッシュを可能にするかどうか。デフォルトは true。実効的にクエリキャッシュをオンにするには [[yii\db\Connection::queryCache|queryCache]] によって指定し、さらに有効なキャッシュを持っている必要があることに注意してください。
* [[yii\db\Connection::queryCacheDuration|queryCacheDuration]]: これはクエリ結果がキャッシュ内に有効な状態として維持できる秒数を表します。クエリキャッシュを永遠にキャッシュに残したい場合は 0 を指定することができます。このプロパティは [[yii\db\Connection::cache()]] の持続時間を指定せず呼び出されたときに使用されるデフォルト値です。
* [[yii\db\Connection::queryCache|queryCache]]: これはキャッシュコンポーネントの ID を表します。デフォルトは `'cache'`。有効なキャッシュコンポーネントが存在する場合にのみ、クエリキャッシュが使用可能になります。
### 使い方 <a name="query-caching-usages"></a>
クエリキャッシュを使用する必要がある複数の SQL クエリを持っている場合は [[yii\db\Connection::cache()]] を使用することができます。使い方としては以下のように、
```php
$duration = 60; // クエリ結果を 60 秒間 キャッシュ
$dependency = ...; // 依存関係のオプション
$result = $db->cache(function ($db) {
// ... ここで SQL クエリを実行します ...
return $result;
}, $duration, $dependency);
```
無名関数内の任意の SQL クエリは、指定した依存関係とともに指定された期間キャッシュされます。もしキャッシュ内に有効なクエリ結果が見つかった場合、クエリはスキップされ、その結果、代わりにキャッシュから提供されます。`$duration` の指定がない場合 [[yii\db\Connection::queryCacheDuration|queryCacheDuration]] で指定されている値が使用されます。
また、`cache()` 内でいくつかの特定のクエリに対してクエリキャッシュを無効にすることもできます。この場合 [[yii\db\Connection::noCache()]] を使用します。
```php
$result = $db->cache(function ($db) {
// クエリキャッシュを使用する SQL クエリ
$db->noCache(function ($db) {
// クエリキャッシュを使用しない SQL クエリ
});
// ...
return $result;
});
```
単一のクエリのためにクエリキャッシュを使用する場合は、コマンドを構築するときに [[yii\db\Command::cache()]] を呼び出すことができます。例えば、
```php
// クエリキャッシュを使い、期間を 60 秒にセットする
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->cache(60)->queryOne();
```
また、ひとつのコマンドでクエリキャッシュを無効にするために [[yii\db\Command::noCache()]] を使用することもできます。例えば、
```php
$result = $db->cache(function ($db) {
// クエリキャッシュを使用する SQL クエリ
// このコマンドはクエリキャッシュを使用しない
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->noCache()->queryOne();
// ...
return $result;
});
```
### 制約 <a name="query-caching-limitations"></a>
リソースハンドルを返すようなクエリにはクエリキャッシュは働きません。例えばいくつかの DBMS において BLOB 型のカラムを用いる場合、クエリ結果はカラムデータについてリソースハンドルを返します。
いくつかのキャッシュストレージはサイズに制約があります。例えば Memcache では、各エントリのサイズは 1MB が上限値です。そのためクエリ結果のサイズがこの制約を越える場合、キャッシュは失敗します。

140
docs/guide-ja/caching-fragment.md

@ -0,0 +1,140 @@
フラグメントキャッシュ
================
フラグメントキャッシュは、ウェブページの断片をキャッシュすることを言います。例えば、ページ内の表に年間販売の概要が表示されている場合、リクエスト毎にこの表を生成するのにかかる時間を削減するために、キャッシュにこの表を格納することができます。フラグメントキャッシュは [データキャッシュ](caching-data.md) 上に構築されています。
フラグメントキャッシュを使用するには [ビュー](structure-views.md) で以下の構文を使用します:
```php
if ($this->beginCache($id)) {
// ... ここに生成するコンテンツを書く ...
$this->endCache();
}
```
つまり [[yii\base\View::beginCache()|beginCache()]] と [[yii\base\View::endCache()|endCache()]] をペアにして囲み、その中にコンテンツ生成ロジックを書いていきます。コンテンツがキャッシュ内で見つかった場合、キャッシュされたコンテンツをレンダリングし [[yii\base\View::beginCache()|beginCache()]] は false を返します。結果として、コンテンツ生成ロジックはスキップされます。それ以外の場合はコンテンツ生成ロジックが呼ばれ、そして [[yii\base\View::endCache()|endCache()]] が呼ばれたとき生成されたコンテンツがキャプチャされ、キャッシュに格納されます。
[データキャッシュ](caching-data.md) と同様に、キャッシュされたコンテンツを識別するためにユニークな `$id` が必要になります。
## キャッシュのオプション <a name="caching-options"></a>
[[yii\base\View::beginCache()|beginCache()]] メソッドの 2 番目のパラメータを配列にすることで、フラグメントキャッシュに関する追加のオプションを指定することもできます。裏で、この配列のオプションは実際にフラグメントキャッシュ機能を実装している [[yii\widgets\FragmentCache]] ウィジェットを構成するために使用されます。
### 持続時間 <a name="duration"></a>
おそらくフラグメントキャッシュで通常よく使われるであろうオプションは [[yii\widgets\FragmentCache::duration|duration]] でしょう。このオプションにはコンテンツがどれだけの時間キャッシュ内において有効であるかを指定します。以下のコードは最大で 1 時間コンテンツの断片をキャッシュします:
```php
if ($this->beginCache($id, ['duration' => 3600])) {
// ... ここに生成するコンテンツを書く ...
$this->endCache();
}
```
オプションがセットされていない場合は、デフォルトである 60 が使われ、つまり有効期限が 60 秒間のキャッシュされたコンテンツを意味します。
### 依存関係 <a name="dependencies"></a>
[データキャッシュ](caching-data.md#cache-dependencies) と同様に、キャッシュされたコンテンツの断片は依存関係を持つことができます。例えば、表示されている投稿の内容は、投稿が変更されたか否かに依存する、といった具合です。
依存関係を指定するには [[yii\widgets\FragmentCache::dependency|dependency]] オプションに [[yii\caching\Dependency]] オブジェクトを指定するか、または依存関係オブジェクトを作成するための配列構成を指定します。以下のコードはコンテンツの断片が `updated_at` カラムの値の変化に依存していることを指定しています:
```php
$dependency = [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT MAX(updated_at) FROM post',
];
if ($this->beginCache($id, ['dependency' => $dependency])) {
// ... ここに生成するコンテンツを書く ...
$this->endCache();
}
```
### バリエーション <a name="variations"></a>
キャッシュされたコンテンツはいくつかのパラメータによって変化させることもできます。例えば、複数の言語をサポートしているウェブアプリケーションに対して、ビューコードの同じ部分を、異なる言語で生成することができます。現在のアプリケーションの言語に応じて、キャッシュされたコンテンツに変更を加えるといったことが可能になります。
キャッシュのバリエーションを指定するには [[yii\widgets\FragmentCache::variations|variations]] オプションに配列で、それぞれが特定のバリエーションの要素を表すスカラー値をセットします。例えば、言語によってキャッシュされたコンテンツを変化させるには、以下のコードを使うことができます:
```php
if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {
// ... ここに生成するコンテンツを書く ...
$this->endCache();
}
```
### トグルキャッシュ <a name="toggling-caching"></a>
また、ある条件が満たされた場合にのみフラグメントキャッシュを有効にすることもできます。たとえば、フォームが表示されているページに対して、最初の (GET リクエストによる) リクエストの場合だけはキャッシュしたいと思いますが、その後の (POST リクエストによる) フォームの表示では、フォームにユーザ入力が含まれている可能性があるため、キャッシュをすべきではありません。これを行うには、以下のように [[yii\widgets\FragmentCache::enabled|enabled]] オプションをセットします:
```php
if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {
// ... ここに生成するコンテンツを書く ...
$this->endCache();
}
```
## キャッシュのネスト <a name="nested-caching"></a>
フラグメントキャッシュはネストすることができます。つまり、キャッシュされる断片を、より大きなキャッシュされる断片で囲むことができます。例えば、コメントが内側のフラグメントキャッシュ内にキャッシュされ、それらが外側のフラグメントキャッシュに記事内容と一緒にキャッシュされます。以下のコードは 2 つのフラグメントキャッシュをどのようにネストできるかを示したものです:
```php
if ($this->beginCache($id1)) {
// ...コンテンツ生成ロジック...
if ($this->beginCache($id2, $options2)) {
// ...コンテンツ生成ロジック...
$this->endCache();
}
// ...コンテンツ生成ロジック...
$this->endCache();
}
```
ネストされたキャッシュには、異なるキャッシュオプションを設定することができます。 たとえば、上記の例における内側のキャッシュと外側のキャッシュに対して、異なる持続期間の値を設定する事が可能です。 これによって、外側のキャッシュでキャッシュされたデータが無効になった場合でも、内側のキャッシュが有効な内側の断片を提供することが可能になります。 しかし、その逆は真ではありません。 外側のキャッシュが有効であると判断された場合には、内側のキャッシュが無効になった後でも、外側のキャッシュが古くなったコンテンツのコピーを提供し続けます。 ネストされたキャッシュの持続時間や依存関係の設定を間違うと、無効になった内側のキャッシュデータが外側のキャッシュに残り続けることになるので、注意が必要です。
## ダイナミックコンテンツ <a name="dynamic-content"></a>
フラグメントキャッシュを使用する際、出力全体が比較的静的で、一ヶ所ないし数ヶ所だけが例外的に動的であるというような状況に遭遇します。例えば、ページ上部にはメインメニューバーと現在のユーザの名前とが一緒に表示される場合があります。他には、リクエスト毎に実行しなければいけない PHP のコードが含まれている場合(例えば、アセットバンドルを登録するためのコード)などです。この両方の問題は、いわゆる *ダイナミックコンテンツ* 機能によって解決することができます。
ダイナミックコンテンツは、それがフラグメントキャッシュの中に含まれていても、キャッシュすべきではない出力の部分を意味します。コンテンツを常に動的にするためには、外側のコンテンツがキャッシュから提供されている場合でも、すべてのリクエストに対して、いくつかのPHP コードを実行することにより生成しなければいけません。
以下のように、ダイナミックコンテンツを目的の場所に挿入するには、キャッシュされた断片内で [[yii\base\View::renderDynamic()]] を呼び出します。
```php
if ($this->beginCache($id1)) {
// ...コンテンツ生成ロジック...
echo $this->renderDynamic('return Yii::$app->user->identity->name;');
// ...コンテンツ生成ロジック...
$this->endCache();
}
```
[[yii\base\View::renderDynamic()|renderDynamic()]] メソッドはパラメータとして PHP コードの一部を使用します。PHP コードの戻り値は、ダイナミックコンテンツとして扱われます。同じ PHP コードはすべてのリクエストに対して実行されますが、囲まれている断片がキャッシュから提供されているか否かは問いません。

105
docs/guide-ja/caching-http.md

@ -0,0 +1,105 @@
HTTP キャッシュ
============
前の節で説明したサーバーサイドのキャッシュに加えて、ウェブアプリケーションは、同じページコンテンツを生成し送信する時間を節約するために、クライアントサイドでもキャッシュを利用することができます。
クライアントサイドのキャッシュを使用するには、レンダリング結果をキャッシュできるように、コントローラアクションのフィルタとして [[yii\filters\HttpCache]] を設定します。[[yii\filters\HttpCache]] は `GET``HEAD` リクエストに対してのみ動作し、また、それらのリクエストは 3 種類のキャッシュ関連の HTTP ヘッダを扱うことができます:
* [[yii\filters\HttpCache::lastModified|Last-Modified]]
* [[yii\filters\HttpCache::etagSeed|Etag]]
* [[yii\filters\HttpCache::cacheControlHeader|Cache-Control]]
## `Last-Modified` ヘッダ <a name="last-modified"></a>
`Last-Modified` ヘッダは、クライアントがそれをキャッシュする時から、ページが変更されたかどうかを示すために、タイムスタンプを使用しています。
`Last-Modified` ヘッダの送信を有効にするには [[yii\filters\HttpCache::lastModified]] プロパティを、ページの変更時間に関する UNIX タイムスタンプを返す PHP の callable 型で、以下のようなシグネチャで構成していきます。
```php
/**
* @param Action $action 現在扱っているアクションオブジェクト
* @param array $params "params" プロパティの値
* @return integer ページの更新時刻を表す UNIX タイムスタンプ
*/
function ($action, $params)
```
以下は `Last-Modified` ヘッダを使用する例です:
```php
public function behaviors()
{
return [
[
'class' => 'yii\filters\HttpCache',
'only' => ['index'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('post')->max('updated_at');
},
],
];
}
```
上記のコードは `index` アクションでのみ HTTP キャッシュを有効にしている状態です。投稿の最終更新時刻に基づいて `Last-Modified` を生成する必要があります。ブラウザが初めて `index` ページにアクセスすると、ページはサーバ上で生成されブラウザに送信されます。もしブラウザが再度同じページにアクセスし、その期間中に投稿に変更がない場合は、ブラウザはクライアントサイドにキャッシュしたものを使用するので、サーバはページを再生成することはありません。その結果、サーバサイドのレンダリング処理とページコンテンツの送信は両方ともスキップされます。
## `ETag` ヘッダ <a name="etag"></a>
"Entity Tag" (略して `ETag`) ヘッダはページコンテンツを表すためにハッシュを使用します。ページが変更された場合ハッシュも同様に変更されます。サーバサイドで生成されたハッシュとクライアントサイドで保持しているハッシュを比較することによって、ページが変更されたかどうか、また再送信するべきかどうかを決定します。
`ETag` ヘッダの送信を有効にするには [[yii\filters\HttpCache::etagSeed]] プロパティを設定します。プロパティは ETag のハッシュを生成するためのシードを返す PHP の callable 型で、以下のようなシグネチャで構成していきます。
```php
/**
* @param Action $action 現在扱っているアクションオブジェクト
* @param array $params "params" プロパティの値
* @return string ETag のハッシュを生成するためのシードとして使用する文字列
*/
function ($action, $params)
```
以下は `ETag` ヘッダを使用している例です:
```php
public function behaviors()
{
return [
[
'class' => 'yii\filters\HttpCache',
'only' => ['view'],
'etagSeed' => function ($action, $params) {
$post = $this->findModel(\Yii::$app->request->get('id'));
return serialize([$post->title, $post->content]);
},
],
];
}
```
上記のコードは `view` アクションでのみ HTTP キャッシュを有効にしている状態です。リクエストされた投稿のタイトルとコンテンツに基づいて HTTP の `Etag` ヘッダを生成しています。ブラウザが初めて `view` ページにアクセスするときに、ページがサーバ上で生成されブラウザに送信されます。ブラウザが再度同じページにアクセスし、投稿のタイトルやコンテンツに変更がない場合には、サーバはページを再生成せず、ブラウザはクライアントサイトにキャッシュしたものを使用します。その結果、サーバサイドのレンダリング処理とページコンテンツ送信の両方ともスキップされます。
ETag は `Last-Modified` ヘッダよりも複雑かつ、より正確なキャッシング方式を可能にします。例えば、サイトが別のテーマに切り替わった場合には ETag を無効化する、といったことができます。
ETag はリクエスト毎に再評価する必要があるため、負荷の高いもの生成すると `HttpCache` の本来の目的を損なって不必要なオーバーヘッドが生じる場合があるので、ページのコンテンツが変更されたときにキャッシュを無効化するための式は単純なものを指定するようにして下さい。
> 注意: [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4) に準拠して `Etag``Last-Modified` ヘッダの両方を設定した場合、`HttpCache` はその両方とも送信します。また、もし `If-None-Match` ヘッダと `If-Modified-Since` ヘッダの両方を送信した場合は前者のみが尊重されます。
## `Cache-Control` ヘッダ <a name="cache-control"></a>
`Cache-Control` ヘッダはページのための一般的なキャッシュポリシーを指定します。ヘッダ値に [[yii\filters\HttpCache::cacheControlHeader]] プロパティを設定することで、それを送ることができます。デフォルトでは、以下のヘッダーが送信されます:
```
Cache-Control: public, max-age=3600
```
## セッションキャッシュリミッタ<a name="session-cache-limiter"></a>
ページでセッションを使用している場合、PHP はいくつかのキャッシュ関連の HTTP ヘッダ(PHP の設定ファイル内で指定されている session.cache_limiter など)を自動的に送信します。これらのヘッダは `HttpCache` で妨害したり、必要なキャッシュを無効にしたりできます。この動作を変更したい場合は [[yii\filters\HttpCache::sessionCacheLimiter]] プロパティを設定します。プロパティには `public`、`private`、`private_no_expire`、そして `nocache` などの文字列の値を使用することができます。これらの値についての説明は [session_cache_limiter()](http://www.php.net/manual/ja/function.session-cache-limiter.php) を参照してください。
## SEO への影響 <a name="seo-implications"></a>
検索エンジンのボットはキャッシュヘッダを尊重する傾向があります。 クローラの中には、一定期間内に処理するドメインごとのページ数に制限を持っているものもあるため、キャッシュヘッダを導入して、処理の必要があるページ数を減らしてやると、サイトのインデックスの作成を促進できるかも知れません。

13
docs/guide-ja/caching-overview.md

@ -0,0 +1,13 @@
キャッシュ
=======
ウェブアプリケーションのパフォーマンスを向上させるための簡単で効果的な方法としてキャッシュというものがあります。比較的静的なデータをキャッシュに格納し、必要に応じてキャッシュからそれらを取得することによって、アプリケーションは一からデータを生成するのに必要な時間を節約することができます。
キャッシュはさまざまなレベルのものを、アプリケーション内のさまざまな場所で使用することができます。例えばサーバサイドでの低いレベルでは、データベースから取得した最新の記事情報リストのような基本的なデータを格納するために使用したり、高いレベルでは、レンダリング結果の一部分、最新の記事であったり、またウェブページ全体を格納するためなどにも使用できます。クライアントサイドでは、ブラウザのキャッシュに最近訪れたことのあるページの内容を格納するために HTTP キャッシュを使用することもできます。
Yii では以下のリストに挙げられているキャッシュ機構をサポートしています:
* [データキャッシュ](caching-data.md)
* [フラグメントキャッシュ](caching-fragment.md)
* [ページキャッシュ](caching-page.md)
* [HTTP キャッシュ](caching-http.md)

32
docs/guide-ja/caching-page.md

@ -0,0 +1,32 @@
ページキャッシュ
============
ページキャッシュはサーバサイドでページ全体のコンテンツをキャッシュすることを言います。あとで、同じページに再度リクエストがあった場合、その内容を一から再び生成させるのではなく、キャッシュから提供するようにします。
ページキャッシュは [[yii\filters\PageCache]]、 [アクションフィルタ](structure-filters.md) によってサポートされています。これは、コントローラクラスで以下のように使用することができます:
```php
public function behaviors()
{
return [
[
'class' => 'yii\filters\PageCache',
'only' => ['index'],
'duration' => 60,
'variations' => [
\Yii::$app->language,
],
'dependency' => [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT COUNT(*) FROM post',
],
],
];
}
```
上記のコードは、ページキャッシュが `index` アクションのみで使用され、そのページのコンテンツは最大 60 秒間キャッシュし、現在のアプリケーションの言語によって変化し、投稿の総数に変化があった場合キャッシュされたページが無効になる、ということを示しています。
見てわかるように、ページキャッシュは [フラグメントキャッシュ](caching-fragment.md) ととてもよく似ています。それらは両方とも `duration`、`dependencies`、`variations`、そして `enabled` などのオプションをサポートしています。主な違いとしては、ページキャッシュは [アクションフィルタ](structure-filters.md) として、フラグメントキャッシュは [ウィジェット](structure-widgets.md) として実装されているということです。
また、ページキャッシュと一緒に [ダイナミックコンテンツ](caching-fragment.md#dynamic-content) だけでなく [フラグメントキャッシュ](caching-fragment.md) も使用することができます。

436
docs/guide-ja/images/advanced-app-configs.graphml

@ -0,0 +1,436 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yFiles for Java 2.11-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Beschreibung" attr.type="string" for="graph" id="d7"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d7"/>
<node id="n0" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="409.0" width="148.0" x="290.953299818952" y="148.6669921875"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="148.0" x="0.0" y="0.0">console</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 4</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n0:"/>
</node>
<node id="n1" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="409.0" width="148.0" x="310.2342794220951" y="167.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="148.0" x="0.0" y="0.0">backend</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="310.2342794220951" y="167.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 3</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n1:"/>
</node>
<node id="n2">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="62.0" width="118.0" x="348.0" y="628.9999999999999"/>
<y:Fill color="#FFCC00" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="32.6875" x="42.65625" y="21.6494140625">index<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n3" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="402.37646484375" width="148.0" x="333.0" y="188.62353515625"/>
<y:Fill color="#DDFFDD" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#DDFFDD" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="148.0" x="0.0" y="0.0">frontend</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 1</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n3:">
<node id="n3::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="62.0" width="118.0" x="348.0" y="226.0"/>
<y:Fill color="#FFCCCC" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="44.013671875" x="36.9931640625" y="21.6494140625">params<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n3::n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="62.0" width="118.0" x="348.0" y="322.0"/>
<y:Fill color="#FFCCCC" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="72.689453125" x="22.6552734375" y="21.6494140625">params-local<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n3::n2">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="62.0" width="118.0" x="348.0" y="418.0"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="30.009765625" x="43.9951171875" y="21.6494140625">main<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n3::n3">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="62.0" width="118.0" x="348.0" y="514.0"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="58.685546875" x="29.6572265625" y="21.6494140625">main-local<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<node id="n4">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="62.0" width="223.21580824827026" x="7.0" y="628.9999999999999"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="41.353515625" x="90.93114631163513" y="21.6494140625">aliases<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n5" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="306.37646484375" width="311.0" x="7.0" y="188.62353515625"/>
<y:Fill color="#DDFFDD" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#DDFFDD" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="311.0" x="0.0" y="0.0">common</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="-8.0" y="189.333984375"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 2</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n5:">
<node id="n5::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="62.0" width="118.0" x="185.0" y="226.0"/>
<y:Fill color="#FFCCCC" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="72.689453125" x="22.6552734375" y="21.6494140625">params-local<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n5::n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="62.0" width="118.0" x="185.0" y="418.0"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="58.685546875" x="29.6572265625" y="21.6494140625">main-local<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n5::n2">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="62.0" width="118.0" x="22.0" y="226.0"/>
<y:Fill color="#FFCCCC" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="44.013671875" x="36.9931640625" y="21.6494140625">params<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n5::n3">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="62.0" width="118.0" x="22.0" y="418.0"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="30.009765625" x="43.9951171875" y="21.6494140625">main<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<edge id="e0" source="n3::n3" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="2.0"/>
<y:Arrows source="none" target="delta"/>
<y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="side_slider" preferredPlacement="right" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="2.0" y="10.125">
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="right" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n4" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-111.48005839096935" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="3.0"/>
<y:Arrows source="none" target="delta"/>
<y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="side_slider" preferredPlacement="right" ratio="0.25" textColor="#000000" visible="true" width="4.0" x="33.47449351530429" y="-2.0000000000001137">
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="right" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n5::n1" target="n3::n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="5.6843418860808015E-14" tx="0.0" ty="0.0">
<y:Point x="218.8251533742331" y="449.00000000000006"/>
<y:Point x="218.8251533742331" y="449.0"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="2.0"/>
<y:Arrows source="none" target="delta"/>
<y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="side_slider" preferredPlacement="right" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="10.089752197265625" y="-6.0">
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="right" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n5::e0" source="n5::n2" target="n5::n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="side_slider" preferredPlacement="right" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="10.125" y="-6.0">
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="right" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n5::e1" source="n5::n3" target="n5::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="2.0"/>
<y:Arrows source="none" target="delta"/>
<y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="side_slider" preferredPlacement="right" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="10.125" y="-6.0">
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="right" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n3::e0" source="n3::n0" target="n3::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="2.0"/>
<y:Arrows source="none" target="delta"/>
<y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="side_slider" preferredPlacement="right" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="2.0" y="10.125">
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="right" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n3::e1" source="n3::n1" target="n3::n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="2.0"/>
<y:Arrows source="none" target="delta"/>
<y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="side_slider" preferredPlacement="right" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="2.0" y="10.125">
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="right" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n3::e2" source="n3::n2" target="n3::n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="2.0"/>
<y:Arrows source="none" target="delta"/>
<y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="side_slider" preferredPlacement="right" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="2.0" y="10.125">
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="right" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n5::n0" target="n3::n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="-5.6843418860808015E-14" tx="0.0" ty="0.0">
<y:Point x="218.8251533742331" y="256.99999999999994"/>
<y:Point x="218.8251533742331" y="257.0"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="2.0"/>
<y:Arrows source="none" target="delta"/>
<y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="side_slider" preferredPlacement="right" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="10.089752197265625" y="-6.0">
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="right" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d0">
<y:Resources/>
</data>
</graphml>

BIN
docs/guide-ja/images/advanced-app-configs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

513
docs/guide-ja/images/application-lifecycle.graphml

@ -0,0 +1,513 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.13-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Description" attr.type="string" for="graph" id="d7"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d7"/>
<node id="n0" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="571.4472707112631" width="763.2772213171534" x="-1269.9373595143054" y="-207.17439524332679"/>
<y:Fill color="#FFCC0024" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="node_width" backgroundColor="#FFCC00" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="763.2772213171534" x="0.0" y="0.0">エントリスクリプト (index.php またはr yii)</y:NodeLabel>
<y:Shape type="rectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="313.2978515625" y="225.33495140075684"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 4</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n0:">
<node id="n0::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="324.9258883570935" x="-1249.511914911339" y="-169.79793039957679"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="292.0" x="16.46294417854665" y="5.6494140625">アプリケーションのコンフィギュレーションをロード<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n0::n1" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="309.37646484374994" width="330.35133296005984" x="-1254.9373595143054" y="35.272875467936274"/>
<y:Fill color="#FFEFD6" transparent="false"/>
<y:BorderStyle hasColor="false" type="dashed" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="node_width" backgroundColor="#FF9900" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="330.35133296005984" x="0.0" y="0.0">アプリケーションのインスタンスを作成</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="19" bottomF="19.15489692687993" left="5" leftF="5.425444602966309" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 5</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n0::n1:">
<node id="n0::n1::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="294.92588835709347" x="-1234.511914911339" y="72.64934031168627"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="45.34375" x="124.79106917854665" y="5.6494140625">preInit()<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n0::n1::n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="294.92588835709347" x="-1234.511914911339" y="122.64524027506516"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="124.0" x="85.46294417854665" y="5.6494140625">エラーハンドラを登録<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n0::n1::n2">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="294.92588835709347" x="-1234.511914911339" y="174.96110788981125"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="208.0" x="43.46294417854665" y="5.6494140625">アプリケーションのプロパティを構成<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n0::n1::n3">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="294.92588835709347" x="-1234.511914911339" y="226.56779181162517"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="27.33203125" x="133.79692855354665" y="5.6494140625">init()<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n0::n1::n4">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="294.9258883570935" x="-1234.511914911339" y="280.4944433848063"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.025390625" x="116.45024886604665" y="5.6494140625">bootstrap()<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<node id="n0::n2" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="411.6943410237631" width="324.9258883570935" x="-846.5860265542456" y="-169.79793039957679"/>
<y:Fill color="#FFEFD6" transparent="false"/>
<y:BorderStyle hasColor="false" type="dashed" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="node_width" backgroundColor="#FF9900" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="324.9258883570935" x="0.0" y="0.0">アプリケーションを走らせる</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="1.1368683772161603E-13"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 3</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n0::n2:">
<node id="n0::n2::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="294.9258883570935" x="-831.5860265542456" y="-132.42146555582667"/>
<y:Fill color="#99CC00" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="164.705078125" x="65.11040511604676" y="5.6494140625">EVENT_BEFORE_REQUEST<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n0::n2::n1" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="204.37646484375" width="294.9258883570935" x="-831.5860265542456" y="-78.79793039957679"/>
<y:Fill color="#99336635" transparent="false"/>
<y:BorderStyle hasColor="false" type="dashed" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="node_width" backgroundColor="#993366" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#FFFFFF" visible="true" width="294.9258883570935" x="0.0" y="0.0">リクエストを処理</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="8" bottomF="7.929194132486941" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 4</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n0::n2::n1:">
<node id="n0::n2::n1::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="264.9258883570935" x="-816.5860265542456" y="-41.421465555826785"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="220.0" x="22.462944178546763" y="5.6494140625">リクエストをルートとパラメータに解決<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n0::n2::n1::n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="264.9258883570935" x="-816.5860265542456" y="18.578534444173215"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="256.0" x="4.462944178546763" y="5.6494140625">モジュール、コントローラ、アクションを作成<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n0::n2::n1::n2">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="264.9258883570935" x="-816.5860265542456" y="72.64934031168627"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="124.0" x="70.46294417854676" y="5.6494140625">アクションを走らせる<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<node id="n0::n2::n2">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="294.9258883570935" x="-831.5860265542456" y="149.20206960042316"/>
<y:Fill color="#99CC00" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="154.697265625" x="70.11431136604676" y="5.6494140625">EVENT_AFTER_REQUEST<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n0::n2::n3">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="294.92588835709347" x="-831.5860265542456" y="196.89641062418633"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="184.0" x="55.46294417854676" y="5.6494140625">エンドユーザにレスポンスを送信<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<node id="n0::n3">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="324.9258883570935" x="-846.5860265542456" y="319.2728754679363"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="136.0" x="94.46294417854676" y="5.6494140625">リクエストの処理を完了<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<edge id="e0" source="n0" target="n0::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-179.83580569315376" sy="-180.3944529152355" tx="-13.869777491410105" ty="-154.8008369539754"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::e0" source="n0::n0" target="n0::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#99CCFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="33.40234375" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="136.0" x="-145.73495249688403" y="70.83422851562506">コンフィギュレーション
配列<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="77.04379339868619" distanceToCenter="true" position="right" ratio="0.5" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::n1::e0" source="n0::n1::n0" target="n0::n1::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::n1::e1" source="n0::n1::n1" target="n0::n1::n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::n1::e2" source="n0::n1::n2" target="n0::n1::n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::n1::e3" source="n0::n1::n3" target="n0::n1::n4">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::e1" source="n0::n1" target="n0::n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="2.8060680342755404" sy="-48.37646484374994" tx="-162.49660512430125" ty="105.53540293375653"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::n2::e0" source="n0::n2::n0" target="n0::n2::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::n2::n1::e0" source="n0::n2::n1::n0" target="n0::n2::n1::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::n2::n1::e1" source="n0::n2::n1::n1" target="n0::n2::n1::n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::n2::e1" source="n0::n2::n1" target="n0::n2::n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::n2::e2" source="n0::n2::n2" target="n0::n2::n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n0::e2" source="n0::n2" target="n0::n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#99CCFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="88.0" x="-107.99997446554255" y="28.318773905436274">終了ステータス<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="63.99999999999999" distanceToCenter="true" position="right" ratio="0.47945569632951074" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d0">
<y:Resources/>
</data>
</graphml>

BIN
docs/guide-ja/images/application-lifecycle.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 38 KiB

428
docs/guide-ja/images/application-structure.graphml

@ -0,0 +1,428 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.13-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Description" attr.type="string" for="graph" id="d7"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d7"/>
<node id="n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="35.0" width="100.0" x="872.1807999999999" y="-14.764159999999947"/>
<y:Fill color="#FFCC99" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="10" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="28.501953125" modelName="custom" textColor="#000000" visible="true" width="84.0" x="8.0" y="3.2490234375">アプリケーション
コンポーネント<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="35.0" width="100.0" x="702.4223999999999" y="-91.97375999999994"/>
<y:Fill color="#FFCC00" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="10" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="16.2509765625" modelName="custom" textColor="#000000" visible="true" width="94.0" x="3.0" y="9.37451171875">エントリスクリプト<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n2">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="35.0" width="100.0" x="702.4223999999999" y="-14.764159999999947"/>
<y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="10" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="16.2509765625" modelName="custom" textColor="#000000" visible="true" width="84.0" x="8.0" y="9.37451171875">アプリケーション<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n3">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="35.0" width="100.0" x="702.4223999999999" y="62.44544000000004"/>
<y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="10" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="16.2509765625" modelName="custom" textColor="#000000" visible="true" width="64.0" x="18.0" y="9.374511718750007">コントローラ<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n4">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="35.0" width="100.0" x="872.1807999999999" y="62.44544000000005"/>
<y:Fill color="#FFCC99" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="10" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="16.2509765625" modelName="custom" textColor="#000000" visible="true" width="44.0" x="28.0" y="9.37451171875">フィルタ<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n5">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="35.0" width="100.0" x="532.664" y="23.901600000000087"/>
<y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="10" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="16.2509765625" modelName="custom" textColor="#000000" visible="true" width="54.0" x="23.0" y="9.37451171875">モジュール<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n6">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="35.0" width="100.0" x="618.4047999999991" y="139.65504000000004"/>
<y:Fill color="#99CC00" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="10" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="16.2509765625" modelName="custom" textColor="#000000" visible="true" width="34.0" x="33.0" y="9.37451171875">ビュー<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n7">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="35.0" width="100.0" x="786.161599999999" y="139.65504000000004"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="10" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="16.2509765625" modelName="custom" textColor="#000000" visible="true" width="34.0" x="33.0" y="9.37451171875">モデル<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n8">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="35.0" width="100.0" x="532.664" y="216.86464000000004"/>
<y:Fill color="#99CC00" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="76.0" x="12.0" y="8.1494140625">ウィジェット<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n9">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="35.0" width="100.0" x="702.4223999999999" y="216.86464000000004"/>
<y:Fill color="#99CC00" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="10" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="16.2509765625" modelName="custom" textColor="#000000" visible="true" width="84.0" x="8.0" y="9.37451171875">アセットバンドル<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<edge id="e0" source="n2" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="20.681640625" x="3.684755371093729" y="-26.101202829100025">1:1<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="14.025600000000054" distanceToCenter="true" position="right" ratio="0.17992697197425173" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n0" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="-47.638518923284664" y="-23.37618601966852">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="14.025599999999994" distanceToCenter="true" position="right" ratio="0.5470891790487767" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n5" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="16.6705249668222" y="30.389885834361735">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="44.894496863129426" distanceToCenter="true" position="right" ratio="0.25416574623968574" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n3" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="4.248516308593707" y="-26.494264459837467">1..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="15.254400000000032" distanceToCenter="true" position="right" ratio="0.2090245199765919" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n3" target="n5">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="-57.21845160906594" y="-64.42636347296329">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="43.47658308018222" distanceToCenter="true" position="right" ratio="0.881412889692355" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e5" source="n5" target="n5">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
<y:Point x="582.664" y="-3.598399999999913"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="-16.411943066406252" y="-42.70266007995597">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="16.483200000000004" distanceToCenter="true" position="right" ratio="5.822600000000001" segment="-2"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e6" source="n6" target="n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="-10.471163234315782" y="-25.304719149604495">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="11.385360101663515" distanceToCenter="true" position="left" ratio="0.10670293331985262" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e7" source="n7" target="n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="-8.09331897615914" y="-26.61891685238112">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="14.669798038586146" distanceToCenter="true" position="right" ratio="0.1670192242704811" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e8" source="n9" target="n6">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="-8.582034677365982" y="-26.348798499628572">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="14.15599378957306" distanceToCenter="true" position="right" ratio="0.15481212573620068" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e9" source="n8" target="n6">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="-13.858375192872018" y="-24.603393693996793">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="13.24330808446041" distanceToCenter="true" position="left" ratio="0.05506723556297327" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e10" source="n4" target="n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="-45.861058691406356" y="-22.966588137206998">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="13.616000000000007" distanceToCenter="true" position="right" ratio="0.5" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e11" source="n9" target="n8">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="-42.528297905071895" y="-19.894585219726537">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="10.543999999999983" distanceToCenter="true" position="right" ratio="0.4117077892835431" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e12" source="n7" target="n6">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="diamond"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.01171875" x="-43.20232446859063" y="-19.894590493164003">0..*<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="10.543999999999983" distanceToCenter="true" position="right" ratio="0.4531592446547025" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d0">
<y:Resources/>
</data>
</graphml>

BIN
docs/guide-ja/images/application-structure.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/guide-ja/images/gii-entry.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
docs/guide-ja/images/gii-preview.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

368
docs/guide-ja/images/rbac-access-check-1.graphml

@ -0,0 +1,368 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.12.2-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Description" attr.type="string" for="graph" id="d7"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d7"/>
<node id="n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="34.0" y="-11.5"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#FF0000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="36.68359375" x="33.158203125" y="25.1494140625">admin<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="193.0" y="-11.5"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#FF0000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="38.025390625" x="32.4873046875" y="25.1494140625">author<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n2">
<data key="d6">
<y:SVGNode>
<y:Geometry height="64.53585815429688" width="56.560157775878906" x="216.21992111206055" y="-132.03585815429688"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.37109375" x="-2.905467987060547" y="-27.814727783203125">John, ID=2<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.113555908203125" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="1"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3">
<data key="d6">
<y:SVGNode>
<y:Geometry height="66.76200103759766" width="56.554100036621094" x="57.22294998168945" y="-133.14892959594727"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.37109375" x="-2.908496856689453" y="-27.701656341552734">Jane, ID=1<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.000484466552734" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n4">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="34.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="64.71484375" x="19.142578125" y="25.1494140625">updatePost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n5">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="193.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="89.388671875" x="6.8056640625" y="25.1494140625">updateOwnPost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n6">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="352.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#FF0000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="61.36328125" x="20.818359375" y="25.1494140625">createPost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n7">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="29.535858154296875" width="103.0" x="193.0" y="167.96414184570312"/>
<y:Fill color="#FFCC00" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="64.03515625" x="19.482421875" y="5.4173431396484375">AuthorRule<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<edge id="e0" source="n4" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n4" target="n5">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n1" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FF0000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n6" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
<y:Point x="403.5" y="23.0"/>
</y:Path>
<y:LineStyle color="#FF0000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n1" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e5" source="n0" target="n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FF0000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e6" source="n7" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d0">
<y:Resources>
<y:Resource id="1">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="65px" viewBox="0 0 57 65" enable-background="new 0 0 57 65" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3398" y1="3115.7266" x2="27.5807" y2="3145.5239" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;path id="body_18_" fill="#ECECEC" stroke="#9B9B9B" stroke-miterlimit="10" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-11.244-6.146-11.244-6.146
c-1.771,1.655-5.61,3.802-10.063,3.802c-4.453,0-8.292-2.146-10.063-3.802c0,0-5.755,0.586-11.189,6.021
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;radialGradient id="SVGID_2_" cx="22.6621" cy="21.707" r="17.7954" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_2_)" stroke="#E55E03" d="M28.106,33.486c-8.112,0-12.688,4.313-12.688,10.438
c0,7.422,12.688,10.438,12.688,10.438s14.688-3.016,14.688-10.438C42.793,38.75,36.215,33.486,28.106,33.486z M26.288,53.051
c0,0-7.135-2.093-8.805-7.201c-0.222-0.682,0.147-1.156,0.795-1.521V37.8h20.188v6.663c0.235,0.352,1.109,0.737,1.229,1.387
C40.445,49.917,26.288,53.051,26.288,53.051z"/&gt;
&lt;radialGradient id="SVGID_3_" cx="15.2056" cy="831.1875" r="32.3071" gradientTransform="matrix(1 0 0 1 0.0801 -773.6914)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_3_)" stroke="#E55E03" d="M49.529,51.225c-2.239-2.24-5.041-3.724-7.396-4.67
c-2.854,5.51-14.021,7.807-14.021,7.807s-10.472-2.483-12.387-8.514c-2.439,0.771-5.787,2.287-8.749,5.25
c-5.592,5.592-6.47,11.67-6.47,11.67c0,1.938,1.575,3.492,3.523,3.492h48.51c1.946,0,3.521-1.558,3.521-3.492
C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;radialGradient id="SVGID_4_" cx="17.0723" cy="18.4907" r="11.8931" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_4_)" stroke="#E55E03" d="M13.404,44.173c1.15-1.81,2.039-3.832,3.332-5.397
c-0.514,1.027-1.669,4.084-1.669,5.148c0,5.186,10.366,9.079,14.688,10.438c-3.472,1.627-9.134-1.498-11.334-2.359
c-3.601-1.419-4.071-3.063-5.89-4.854C12.523,47.135,12.878,45,13.404,44.173z"/&gt;
&lt;radialGradient id="SVGID_5_" cx="31.8184" cy="19.3525" r="14.63" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_5_)" stroke="#E55E03" d="M45.777,43.924c-1.317-1.568-5.11-9.424-6.604-6.617
c0.516,1.025,3.617,3.693,3.617,6.617c0,5.186-10.271,8.576-16.699,9.145c1.429,4.938,11.373,1.293,13.805-0.313
c3.563-2.354,4.563-5.133,7.854-3.705C47.754,49.045,48.006,46.574,45.777,43.924z"/&gt;
&lt;radialGradient id="SVGID_6_" cx="30.4893" cy="4.8721" r="5.2028" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_6_)" stroke="#E55E03" d="M30.777,54.167c0.357,0.836-0.153,1.983-0.352,2.813
c-0.256,1.084-0.072,2.104,0.102,3.186c0.164,1.02,0.156,2.107,0.25,3.167c0.082,0.916,0.482,1.849,0.357,2.75"/&gt;
&lt;radialGradient id="SVGID_7_" cx="23.2871" cy="5.3008" r="5.5143" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_7_)" stroke="#E55E03" d="M23.695,53.417c-0.508,0.584-0.476,2.209-0.398,3
c0.116,1.183,0.456,2.099,0.333,3.333c-0.192,1.943,0.154,4.479-0.436,6.333"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.5835" cy="3117.4922" r="23.425" fx="23.0139" fy="3115.0024" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.2-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="6468.501" y1="-12291.5195" x2="6492.1304" y2="-12384.9688" gradientTransform="matrix(0.275 0 0 -0.2733 -1752.8849 -3351.7349)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M28.415,5.625c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.54,13.244,36.729,5.56,28.415,5.625z"/&gt;
&lt;path id="Hair_Young_Black_1_" fill="#5C5C5C" stroke="#353535" stroke-linecap="round" stroke-linejoin="round" d="M20.278,13.25
c3.417,4.333,9.333,6.917,9.333,6.917l-1.417-3.5c0,0,7.094,4.691,8.083,4.333c0.968-0.2-1.082-3.807-1.082-3.807
s3.138,1.795,4.854,3.969c1.803,2.28,4.285,3.504,4.285,3.504S47.027,2.719,27.289,2.744C8.278,2.709,12.058,27.678,12.058,27.678
L14.695,17c0,0,0.914,5.757,1.399,4.875C17.861,15.211,18.861,11.5,20.278,13.25z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
<y:Resource id="2">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="67px" viewBox="0 0 57 67" enable-background="new 0 0 57 67" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3398" y1="3115.7266" x2="27.5807" y2="3145.5239" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.5835" cy="3117.4922" r="23.425" fx="23.0139" fy="3115.0024" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.199-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="6468.5" y1="-12286.8594" x2="6492.1294" y2="-12380.3086" gradientTransform="matrix(0.275 0 0 -0.2733 -1752.8849 -3350.4617)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M28.415,5.625c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.54,13.244,36.729,5.56,28.415,5.625z"/&gt;
&lt;path id="Hair_Female_1_Red_1_" fill="#FAE1AA" stroke="#E2B354" stroke-linecap="round" stroke-linejoin="round" d="M28.372,0.5
C17.537,0.5,8.269,7.748,9.153,26.125c0.563,6.563,5.862,12.042,9.366,13.531c-2.929-10.968-0.304-25.021-0.585-25.526
c-0.281-0.505,3.536,6.728,3.536,6.728l3.183-8.312c5.541,4.28,0.393,11.309,1.049,11.058c4.26-1.631,5.34-9.228,5.34-9.228
s2.729,3.657,2.701,5.504c-0.054,3.562,2.194-6.067,2.194-6.067l1.027,2.031c6.727,9.822,3.684,16.208,1.648,22.781
c15.666-0.703,12.291-10.48,9.66-18.407C43.59,6.092,39.206,0.5,28.372,0.5z"/&gt;
&lt;linearGradient id="body_1_" gradientUnits="userSpaceOnUse" x1="95.9063" y1="-3134.2153" x2="31.5133" y2="-3134.2153" gradientTransform="matrix(0.9852 0 0 -0.9852 -34.4844 -3031.9851)"&gt;
&lt;stop offset="0" style="stop-color:#49AD33"/&gt;
&lt;stop offset="1" style="stop-color:#C2DA92"/&gt;
&lt;/linearGradient&gt;
&lt;path id="body_8_" fill="url(#body_1_)" stroke="#008D33" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-8.244-5.146-8.244-5.146
c-1.444,6.983-8.555,8.786-13.007,8.786s-11.322-2.643-11.941-9.439c0,0-4.559,1.199-9.367,5.674
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
</y:Resources>
</data>
</graphml>

BIN
docs/guide-ja/images/rbac-access-check-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

368
docs/guide-ja/images/rbac-access-check-2.graphml

@ -0,0 +1,368 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.12.2-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Description" attr.type="string" for="graph" id="d7"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d7"/>
<node id="n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="34.0" y="-11.5"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="36.68359375" x="33.158203125" y="25.1494140625">admin<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="193.0" y="-11.5"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#FF0000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="38.025390625" x="32.4873046875" y="25.1494140625">author<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n2">
<data key="d6">
<y:SVGNode>
<y:Geometry height="64.53585815429688" width="56.560157775878906" x="216.21992111206055" y="-132.03585815429688"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.37109375" x="-2.905467987060547" y="-27.814727783203125">John, ID=2<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.113555908203125" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="1"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3">
<data key="d6">
<y:SVGNode>
<y:Geometry height="66.76200103759766" width="56.554100036621094" x="57.22294998168945" y="-133.14892959594727"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.37109375" x="-2.908496856689453" y="-27.701656341552734">Jane, ID=1<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.000484466552734" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n4">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="34.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#FF0000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="64.71484375" x="19.142578125" y="25.1494140625">updatePost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n5">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="193.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#FF0000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="89.388671875" x="6.8056640625" y="25.1494140625">updateOwnPost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n6">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="352.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="61.36328125" x="20.818359375" y="25.1494140625">createPost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n7">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="29.535858154296875" width="103.0" x="193.0" y="167.96414184570312"/>
<y:Fill color="#FFCC00" transparent="false"/>
<y:BorderStyle color="#FF0000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="64.03515625" x="19.482421875" y="5.4173431396484375">AuthorRule<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<edge id="e0" source="n4" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n4" target="n5">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FF0000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n1" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n6" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
<y:Point x="403.5" y="23.0"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n1" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FF0000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e5" source="n0" target="n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e6" source="n7" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FF0000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d0">
<y:Resources>
<y:Resource id="1">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="65px" viewBox="0 0 57 65" enable-background="new 0 0 57 65" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3398" y1="3115.7266" x2="27.5807" y2="3145.5239" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;path id="body_18_" fill="#ECECEC" stroke="#9B9B9B" stroke-miterlimit="10" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-11.244-6.146-11.244-6.146
c-1.771,1.655-5.61,3.802-10.063,3.802c-4.453,0-8.292-2.146-10.063-3.802c0,0-5.755,0.586-11.189,6.021
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;radialGradient id="SVGID_2_" cx="22.6621" cy="21.707" r="17.7954" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_2_)" stroke="#E55E03" d="M28.106,33.486c-8.112,0-12.688,4.313-12.688,10.438
c0,7.422,12.688,10.438,12.688,10.438s14.688-3.016,14.688-10.438C42.793,38.75,36.215,33.486,28.106,33.486z M26.288,53.051
c0,0-7.135-2.093-8.805-7.201c-0.222-0.682,0.147-1.156,0.795-1.521V37.8h20.188v6.663c0.235,0.352,1.109,0.737,1.229,1.387
C40.445,49.917,26.288,53.051,26.288,53.051z"/&gt;
&lt;radialGradient id="SVGID_3_" cx="15.2056" cy="831.1875" r="32.3071" gradientTransform="matrix(1 0 0 1 0.0801 -773.6914)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_3_)" stroke="#E55E03" d="M49.529,51.225c-2.239-2.24-5.041-3.724-7.396-4.67
c-2.854,5.51-14.021,7.807-14.021,7.807s-10.472-2.483-12.387-8.514c-2.439,0.771-5.787,2.287-8.749,5.25
c-5.592,5.592-6.47,11.67-6.47,11.67c0,1.938,1.575,3.492,3.523,3.492h48.51c1.946,0,3.521-1.558,3.521-3.492
C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;radialGradient id="SVGID_4_" cx="17.0723" cy="18.4907" r="11.8931" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_4_)" stroke="#E55E03" d="M13.404,44.173c1.15-1.81,2.039-3.832,3.332-5.397
c-0.514,1.027-1.669,4.084-1.669,5.148c0,5.186,10.366,9.079,14.688,10.438c-3.472,1.627-9.134-1.498-11.334-2.359
c-3.601-1.419-4.071-3.063-5.89-4.854C12.523,47.135,12.878,45,13.404,44.173z"/&gt;
&lt;radialGradient id="SVGID_5_" cx="31.8184" cy="19.3525" r="14.63" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_5_)" stroke="#E55E03" d="M45.777,43.924c-1.317-1.568-5.11-9.424-6.604-6.617
c0.516,1.025,3.617,3.693,3.617,6.617c0,5.186-10.271,8.576-16.699,9.145c1.429,4.938,11.373,1.293,13.805-0.313
c3.563-2.354,4.563-5.133,7.854-3.705C47.754,49.045,48.006,46.574,45.777,43.924z"/&gt;
&lt;radialGradient id="SVGID_6_" cx="30.4893" cy="4.8721" r="5.2028" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_6_)" stroke="#E55E03" d="M30.777,54.167c0.357,0.836-0.153,1.983-0.352,2.813
c-0.256,1.084-0.072,2.104,0.102,3.186c0.164,1.02,0.156,2.107,0.25,3.167c0.082,0.916,0.482,1.849,0.357,2.75"/&gt;
&lt;radialGradient id="SVGID_7_" cx="23.2871" cy="5.3008" r="5.5143" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_7_)" stroke="#E55E03" d="M23.695,53.417c-0.508,0.584-0.476,2.209-0.398,3
c0.116,1.183,0.456,2.099,0.333,3.333c-0.192,1.943,0.154,4.479-0.436,6.333"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.5835" cy="3117.4922" r="23.425" fx="23.0139" fy="3115.0024" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.2-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="6468.501" y1="-12291.5195" x2="6492.1304" y2="-12384.9688" gradientTransform="matrix(0.275 0 0 -0.2733 -1752.8849 -3351.7349)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M28.415,5.625c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.54,13.244,36.729,5.56,28.415,5.625z"/&gt;
&lt;path id="Hair_Young_Black_1_" fill="#5C5C5C" stroke="#353535" stroke-linecap="round" stroke-linejoin="round" d="M20.278,13.25
c3.417,4.333,9.333,6.917,9.333,6.917l-1.417-3.5c0,0,7.094,4.691,8.083,4.333c0.968-0.2-1.082-3.807-1.082-3.807
s3.138,1.795,4.854,3.969c1.803,2.28,4.285,3.504,4.285,3.504S47.027,2.719,27.289,2.744C8.278,2.709,12.058,27.678,12.058,27.678
L14.695,17c0,0,0.914,5.757,1.399,4.875C17.861,15.211,18.861,11.5,20.278,13.25z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
<y:Resource id="2">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="67px" viewBox="0 0 57 67" enable-background="new 0 0 57 67" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3398" y1="3115.7266" x2="27.5807" y2="3145.5239" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.5835" cy="3117.4922" r="23.425" fx="23.0139" fy="3115.0024" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.199-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="6468.5" y1="-12286.8594" x2="6492.1294" y2="-12380.3086" gradientTransform="matrix(0.275 0 0 -0.2733 -1752.8849 -3350.4617)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M28.415,5.625c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.54,13.244,36.729,5.56,28.415,5.625z"/&gt;
&lt;path id="Hair_Female_1_Red_1_" fill="#FAE1AA" stroke="#E2B354" stroke-linecap="round" stroke-linejoin="round" d="M28.372,0.5
C17.537,0.5,8.269,7.748,9.153,26.125c0.563,6.563,5.862,12.042,9.366,13.531c-2.929-10.968-0.304-25.021-0.585-25.526
c-0.281-0.505,3.536,6.728,3.536,6.728l3.183-8.312c5.541,4.28,0.393,11.309,1.049,11.058c4.26-1.631,5.34-9.228,5.34-9.228
s2.729,3.657,2.701,5.504c-0.054,3.562,2.194-6.067,2.194-6.067l1.027,2.031c6.727,9.822,3.684,16.208,1.648,22.781
c15.666-0.703,12.291-10.48,9.66-18.407C43.59,6.092,39.206,0.5,28.372,0.5z"/&gt;
&lt;linearGradient id="body_1_" gradientUnits="userSpaceOnUse" x1="95.9063" y1="-3134.2153" x2="31.5133" y2="-3134.2153" gradientTransform="matrix(0.9852 0 0 -0.9852 -34.4844 -3031.9851)"&gt;
&lt;stop offset="0" style="stop-color:#49AD33"/&gt;
&lt;stop offset="1" style="stop-color:#C2DA92"/&gt;
&lt;/linearGradient&gt;
&lt;path id="body_8_" fill="url(#body_1_)" stroke="#008D33" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-8.244-5.146-8.244-5.146
c-1.444,6.983-8.555,8.786-13.007,8.786s-11.322-2.643-11.941-9.439c0,0-4.559,1.199-9.367,5.674
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
</y:Resources>
</data>
</graphml>

BIN
docs/guide-ja/images/rbac-access-check-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

368
docs/guide-ja/images/rbac-access-check-3.graphml

@ -0,0 +1,368 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.12.2-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Description" attr.type="string" for="graph" id="d7"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d7"/>
<node id="n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="34.0" y="-11.5"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#FF0000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="36.68359375" x="33.158203125" y="25.1494140625">admin<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="193.0" y="-11.5"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="38.025390625" x="32.4873046875" y="25.1494140625">author<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n2">
<data key="d6">
<y:SVGNode>
<y:Geometry height="64.53585815429688" width="56.560157775878906" x="216.21992111206055" y="-132.03585815429688"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.37109375" x="-2.905467987060547" y="-27.814727783203125">John, ID=2<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.113555908203125" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="1"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3">
<data key="d6">
<y:SVGNode>
<y:Geometry height="66.76200103759766" width="56.554100036621094" x="57.22294998168945" y="-133.14892959594727"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.37109375" x="-2.908496856689453" y="-27.701656341552734">Jane, ID=1<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.000484466552734" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n4">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="34.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#FF0000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="64.71484375" x="19.142578125" y="25.1494140625">updatePost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n5">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="193.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="89.388671875" x="6.8056640625" y="25.1494140625">updateOwnPost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n6">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="352.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="61.36328125" x="20.818359375" y="25.1494140625">createPost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n7">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="29.535858154296875" width="103.0" x="193.0" y="167.96414184570312"/>
<y:Fill color="#FFCC00" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="64.03515625" x="19.482421875" y="5.4173431396484375">AuthorRule<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<edge id="e0" source="n4" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FF0000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n4" target="n5">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n1" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n6" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
<y:Point x="403.5" y="23.0"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n1" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e5" source="n0" target="n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#FF0000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e6" source="n7" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d0">
<y:Resources>
<y:Resource id="1">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="65px" viewBox="0 0 57 65" enable-background="new 0 0 57 65" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3398" y1="3115.7266" x2="27.5807" y2="3145.5239" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;path id="body_18_" fill="#ECECEC" stroke="#9B9B9B" stroke-miterlimit="10" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-11.244-6.146-11.244-6.146
c-1.771,1.655-5.61,3.802-10.063,3.802c-4.453,0-8.292-2.146-10.063-3.802c0,0-5.755,0.586-11.189,6.021
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;radialGradient id="SVGID_2_" cx="22.6621" cy="21.707" r="17.7954" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_2_)" stroke="#E55E03" d="M28.106,33.486c-8.112,0-12.688,4.313-12.688,10.438
c0,7.422,12.688,10.438,12.688,10.438s14.688-3.016,14.688-10.438C42.793,38.75,36.215,33.486,28.106,33.486z M26.288,53.051
c0,0-7.135-2.093-8.805-7.201c-0.222-0.682,0.147-1.156,0.795-1.521V37.8h20.188v6.663c0.235,0.352,1.109,0.737,1.229,1.387
C40.445,49.917,26.288,53.051,26.288,53.051z"/&gt;
&lt;radialGradient id="SVGID_3_" cx="15.2056" cy="831.1875" r="32.3071" gradientTransform="matrix(1 0 0 1 0.0801 -773.6914)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_3_)" stroke="#E55E03" d="M49.529,51.225c-2.239-2.24-5.041-3.724-7.396-4.67
c-2.854,5.51-14.021,7.807-14.021,7.807s-10.472-2.483-12.387-8.514c-2.439,0.771-5.787,2.287-8.749,5.25
c-5.592,5.592-6.47,11.67-6.47,11.67c0,1.938,1.575,3.492,3.523,3.492h48.51c1.946,0,3.521-1.558,3.521-3.492
C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;radialGradient id="SVGID_4_" cx="17.0723" cy="18.4907" r="11.8931" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_4_)" stroke="#E55E03" d="M13.404,44.173c1.15-1.81,2.039-3.832,3.332-5.397
c-0.514,1.027-1.669,4.084-1.669,5.148c0,5.186,10.366,9.079,14.688,10.438c-3.472,1.627-9.134-1.498-11.334-2.359
c-3.601-1.419-4.071-3.063-5.89-4.854C12.523,47.135,12.878,45,13.404,44.173z"/&gt;
&lt;radialGradient id="SVGID_5_" cx="31.8184" cy="19.3525" r="14.63" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_5_)" stroke="#E55E03" d="M45.777,43.924c-1.317-1.568-5.11-9.424-6.604-6.617
c0.516,1.025,3.617,3.693,3.617,6.617c0,5.186-10.271,8.576-16.699,9.145c1.429,4.938,11.373,1.293,13.805-0.313
c3.563-2.354,4.563-5.133,7.854-3.705C47.754,49.045,48.006,46.574,45.777,43.924z"/&gt;
&lt;radialGradient id="SVGID_6_" cx="30.4893" cy="4.8721" r="5.2028" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_6_)" stroke="#E55E03" d="M30.777,54.167c0.357,0.836-0.153,1.983-0.352,2.813
c-0.256,1.084-0.072,2.104,0.102,3.186c0.164,1.02,0.156,2.107,0.25,3.167c0.082,0.916,0.482,1.849,0.357,2.75"/&gt;
&lt;radialGradient id="SVGID_7_" cx="23.2871" cy="5.3008" r="5.5143" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_7_)" stroke="#E55E03" d="M23.695,53.417c-0.508,0.584-0.476,2.209-0.398,3
c0.116,1.183,0.456,2.099,0.333,3.333c-0.192,1.943,0.154,4.479-0.436,6.333"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.5835" cy="3117.4922" r="23.425" fx="23.0139" fy="3115.0024" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.2-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="6468.501" y1="-12291.5195" x2="6492.1304" y2="-12384.9688" gradientTransform="matrix(0.275 0 0 -0.2733 -1752.8849 -3351.7349)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M28.415,5.625c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.54,13.244,36.729,5.56,28.415,5.625z"/&gt;
&lt;path id="Hair_Young_Black_1_" fill="#5C5C5C" stroke="#353535" stroke-linecap="round" stroke-linejoin="round" d="M20.278,13.25
c3.417,4.333,9.333,6.917,9.333,6.917l-1.417-3.5c0,0,7.094,4.691,8.083,4.333c0.968-0.2-1.082-3.807-1.082-3.807
s3.138,1.795,4.854,3.969c1.803,2.28,4.285,3.504,4.285,3.504S47.027,2.719,27.289,2.744C8.278,2.709,12.058,27.678,12.058,27.678
L14.695,17c0,0,0.914,5.757,1.399,4.875C17.861,15.211,18.861,11.5,20.278,13.25z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
<y:Resource id="2">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="67px" viewBox="0 0 57 67" enable-background="new 0 0 57 67" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3398" y1="3115.7266" x2="27.5807" y2="3145.5239" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.5835" cy="3117.4922" r="23.425" fx="23.0139" fy="3115.0024" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.199-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="6468.5" y1="-12286.8594" x2="6492.1294" y2="-12380.3086" gradientTransform="matrix(0.275 0 0 -0.2733 -1752.8849 -3350.4617)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M28.415,5.625c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.54,13.244,36.729,5.56,28.415,5.625z"/&gt;
&lt;path id="Hair_Female_1_Red_1_" fill="#FAE1AA" stroke="#E2B354" stroke-linecap="round" stroke-linejoin="round" d="M28.372,0.5
C17.537,0.5,8.269,7.748,9.153,26.125c0.563,6.563,5.862,12.042,9.366,13.531c-2.929-10.968-0.304-25.021-0.585-25.526
c-0.281-0.505,3.536,6.728,3.536,6.728l3.183-8.312c5.541,4.28,0.393,11.309,1.049,11.058c4.26-1.631,5.34-9.228,5.34-9.228
s2.729,3.657,2.701,5.504c-0.054,3.562,2.194-6.067,2.194-6.067l1.027,2.031c6.727,9.822,3.684,16.208,1.648,22.781
c15.666-0.703,12.291-10.48,9.66-18.407C43.59,6.092,39.206,0.5,28.372,0.5z"/&gt;
&lt;linearGradient id="body_1_" gradientUnits="userSpaceOnUse" x1="95.9063" y1="-3134.2153" x2="31.5133" y2="-3134.2153" gradientTransform="matrix(0.9852 0 0 -0.9852 -34.4844 -3031.9851)"&gt;
&lt;stop offset="0" style="stop-color:#49AD33"/&gt;
&lt;stop offset="1" style="stop-color:#C2DA92"/&gt;
&lt;/linearGradient&gt;
&lt;path id="body_8_" fill="url(#body_1_)" stroke="#008D33" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-8.244-5.146-8.244-5.146
c-1.444,6.983-8.555,8.786-13.007,8.786s-11.322-2.643-11.941-9.439c0,0-4.559,1.199-9.367,5.674
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
</y:Resources>
</data>
</graphml>

BIN
docs/guide-ja/images/rbac-access-check-3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

312
docs/guide-ja/images/rbac-hierarchy-1.graphml

@ -0,0 +1,312 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.12.2-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Description" attr.type="string" for="graph" id="d7"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d7"/>
<node id="n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="34.0" y="-11.5"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="36.68359375" x="33.158203125" y="25.1494140625">admin<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="193.0" y="-11.5"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="38.025390625" x="32.4873046875" y="25.1494140625">author<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n2">
<data key="d6">
<y:SVGNode>
<y:Geometry height="64.53585815429688" width="56.560157775878906" x="216.21992111206055" y="-132.03585815429688"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.37109375" x="-2.905467987060547" y="-27.814727783203125">John, ID=2<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.113555908203125" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="1"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3">
<data key="d6">
<y:SVGNode>
<y:Geometry height="66.76200103759766" width="56.554100036621094" x="57.22294998168945" y="-133.14892959594727"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.37109375" x="-2.908496856689453" y="-27.701656341552734">Jane, ID=1<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.000484466552734" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n4">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="34.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="64.71484375" x="19.142578125" y="25.1494140625">updatePost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n5">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="193.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="61.36328125" x="20.818359375" y="25.1494140625">createPost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<edge id="e0" source="n4" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n1" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n1" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n0" target="n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n5" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d0">
<y:Resources>
<y:Resource id="1">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="65px" viewBox="0 0 57 65" enable-background="new 0 0 57 65" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3398" y1="3115.7266" x2="27.5807" y2="3145.5239" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;path id="body_18_" fill="#ECECEC" stroke="#9B9B9B" stroke-miterlimit="10" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-11.244-6.146-11.244-6.146
c-1.771,1.655-5.61,3.802-10.063,3.802c-4.453,0-8.292-2.146-10.063-3.802c0,0-5.755,0.586-11.189,6.021
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;radialGradient id="SVGID_2_" cx="22.6621" cy="21.707" r="17.7954" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_2_)" stroke="#E55E03" d="M28.106,33.486c-8.112,0-12.688,4.313-12.688,10.438
c0,7.422,12.688,10.438,12.688,10.438s14.688-3.016,14.688-10.438C42.793,38.75,36.215,33.486,28.106,33.486z M26.288,53.051
c0,0-7.135-2.093-8.805-7.201c-0.222-0.682,0.147-1.156,0.795-1.521V37.8h20.188v6.663c0.235,0.352,1.109,0.737,1.229,1.387
C40.445,49.917,26.288,53.051,26.288,53.051z"/&gt;
&lt;radialGradient id="SVGID_3_" cx="15.2056" cy="831.1875" r="32.3071" gradientTransform="matrix(1 0 0 1 0.0801 -773.6914)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_3_)" stroke="#E55E03" d="M49.529,51.225c-2.239-2.24-5.041-3.724-7.396-4.67
c-2.854,5.51-14.021,7.807-14.021,7.807s-10.472-2.483-12.387-8.514c-2.439,0.771-5.787,2.287-8.749,5.25
c-5.592,5.592-6.47,11.67-6.47,11.67c0,1.938,1.575,3.492,3.523,3.492h48.51c1.946,0,3.521-1.558,3.521-3.492
C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;radialGradient id="SVGID_4_" cx="17.0723" cy="18.4907" r="11.8931" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_4_)" stroke="#E55E03" d="M13.404,44.173c1.15-1.81,2.039-3.832,3.332-5.397
c-0.514,1.027-1.669,4.084-1.669,5.148c0,5.186,10.366,9.079,14.688,10.438c-3.472,1.627-9.134-1.498-11.334-2.359
c-3.601-1.419-4.071-3.063-5.89-4.854C12.523,47.135,12.878,45,13.404,44.173z"/&gt;
&lt;radialGradient id="SVGID_5_" cx="31.8184" cy="19.3525" r="14.63" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_5_)" stroke="#E55E03" d="M45.777,43.924c-1.317-1.568-5.11-9.424-6.604-6.617
c0.516,1.025,3.617,3.693,3.617,6.617c0,5.186-10.271,8.576-16.699,9.145c1.429,4.938,11.373,1.293,13.805-0.313
c3.563-2.354,4.563-5.133,7.854-3.705C47.754,49.045,48.006,46.574,45.777,43.924z"/&gt;
&lt;radialGradient id="SVGID_6_" cx="30.4893" cy="4.8721" r="5.2028" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_6_)" stroke="#E55E03" d="M30.777,54.167c0.357,0.836-0.153,1.983-0.352,2.813
c-0.256,1.084-0.072,2.104,0.102,3.186c0.164,1.02,0.156,2.107,0.25,3.167c0.082,0.916,0.482,1.849,0.357,2.75"/&gt;
&lt;radialGradient id="SVGID_7_" cx="23.2871" cy="5.3008" r="5.5143" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_7_)" stroke="#E55E03" d="M23.695,53.417c-0.508,0.584-0.476,2.209-0.398,3
c0.116,1.183,0.456,2.099,0.333,3.333c-0.192,1.943,0.154,4.479-0.436,6.333"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.5835" cy="3117.4922" r="23.425" fx="23.0139" fy="3115.0024" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.2-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="6468.501" y1="-12291.5195" x2="6492.1304" y2="-12384.9688" gradientTransform="matrix(0.275 0 0 -0.2733 -1752.8849 -3351.7349)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M28.415,5.625c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.54,13.244,36.729,5.56,28.415,5.625z"/&gt;
&lt;path id="Hair_Young_Black_1_" fill="#5C5C5C" stroke="#353535" stroke-linecap="round" stroke-linejoin="round" d="M20.278,13.25
c3.417,4.333,9.333,6.917,9.333,6.917l-1.417-3.5c0,0,7.094,4.691,8.083,4.333c0.968-0.2-1.082-3.807-1.082-3.807
s3.138,1.795,4.854,3.969c1.803,2.28,4.285,3.504,4.285,3.504S47.027,2.719,27.289,2.744C8.278,2.709,12.058,27.678,12.058,27.678
L14.695,17c0,0,0.914,5.757,1.399,4.875C17.861,15.211,18.861,11.5,20.278,13.25z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
<y:Resource id="2">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="67px" viewBox="0 0 57 67" enable-background="new 0 0 57 67" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3398" y1="3115.7266" x2="27.5807" y2="3145.5239" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.5835" cy="3117.4922" r="23.425" fx="23.0139" fy="3115.0024" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.199-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="6468.5" y1="-12286.8594" x2="6492.1294" y2="-12380.3086" gradientTransform="matrix(0.275 0 0 -0.2733 -1752.8849 -3350.4617)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M28.415,5.625c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.54,13.244,36.729,5.56,28.415,5.625z"/&gt;
&lt;path id="Hair_Female_1_Red_1_" fill="#FAE1AA" stroke="#E2B354" stroke-linecap="round" stroke-linejoin="round" d="M28.372,0.5
C17.537,0.5,8.269,7.748,9.153,26.125c0.563,6.563,5.862,12.042,9.366,13.531c-2.929-10.968-0.304-25.021-0.585-25.526
c-0.281-0.505,3.536,6.728,3.536,6.728l3.183-8.312c5.541,4.28,0.393,11.309,1.049,11.058c4.26-1.631,5.34-9.228,5.34-9.228
s2.729,3.657,2.701,5.504c-0.054,3.562,2.194-6.067,2.194-6.067l1.027,2.031c6.727,9.822,3.684,16.208,1.648,22.781
c15.666-0.703,12.291-10.48,9.66-18.407C43.59,6.092,39.206,0.5,28.372,0.5z"/&gt;
&lt;linearGradient id="body_1_" gradientUnits="userSpaceOnUse" x1="95.9063" y1="-3134.2153" x2="31.5133" y2="-3134.2153" gradientTransform="matrix(0.9852 0 0 -0.9852 -34.4844 -3031.9851)"&gt;
&lt;stop offset="0" style="stop-color:#49AD33"/&gt;
&lt;stop offset="1" style="stop-color:#C2DA92"/&gt;
&lt;/linearGradient&gt;
&lt;path id="body_8_" fill="url(#body_1_)" stroke="#008D33" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-8.244-5.146-8.244-5.146
c-1.444,6.983-8.555,8.786-13.007,8.786s-11.322-2.643-11.941-9.439c0,0-4.559,1.199-9.367,5.674
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
</y:Resources>
</data>
</graphml>

BIN
docs/guide-ja/images/rbac-hierarchy-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

368
docs/guide-ja/images/rbac-hierarchy-2.graphml

@ -0,0 +1,368 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.12.2-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Description" attr.type="string" for="graph" id="d7"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d7"/>
<node id="n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="34.0" y="-11.5"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="36.68359375" x="33.158203125" y="25.1494140625">admin<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="193.0" y="-11.5"/>
<y:Fill color="#ADF4A6" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="38.025390625" x="32.4873046875" y="25.1494140625">author<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n2">
<data key="d6">
<y:SVGNode>
<y:Geometry height="64.53585815429688" width="56.560157775878906" x="216.21992111206055" y="-132.03585815429688"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.37109375" x="-2.905467987060547" y="-27.814727783203125">John, ID=2<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.113555908203125" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="1"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3">
<data key="d6">
<y:SVGNode>
<y:Geometry height="66.76200103759766" width="56.554100036621094" x="57.22294998168945" y="-133.14892959594727"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="62.37109375" x="-2.908496856689453" y="-27.701656341552734">Jane, ID=1<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.000484466552734" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n4">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="34.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="64.71484375" x="19.142578125" y="25.1494140625">updatePost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n5">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="193.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="89.388671875" x="6.8056640625" y="25.1494140625">updateOwnPost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n6">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="69.0" width="103.0" x="352.0" y="197.5"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="61.36328125" x="20.818359375" y="25.1494140625">createPost<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n7">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="29.535858154296875" width="103.0" x="193.0" y="167.96414184570312"/>
<y:Fill color="#FFCC00" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="64.03515625" x="19.482421875" y="5.4173431396484375">AuthorRule<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<edge id="e0" source="n4" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n4" target="n5">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n1" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n6" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
<y:Point x="403.5" y="23.0"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n1" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e5" source="n0" target="n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e6" source="n7" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d0">
<y:Resources>
<y:Resource id="1">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="65px" viewBox="0 0 57 65" enable-background="new 0 0 57 65" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3398" y1="3115.7266" x2="27.5807" y2="3145.5239" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;path id="body_18_" fill="#ECECEC" stroke="#9B9B9B" stroke-miterlimit="10" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-11.244-6.146-11.244-6.146
c-1.771,1.655-5.61,3.802-10.063,3.802c-4.453,0-8.292-2.146-10.063-3.802c0,0-5.755,0.586-11.189,6.021
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;radialGradient id="SVGID_2_" cx="22.6621" cy="21.707" r="17.7954" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_2_)" stroke="#E55E03" d="M28.106,33.486c-8.112,0-12.688,4.313-12.688,10.438
c0,7.422,12.688,10.438,12.688,10.438s14.688-3.016,14.688-10.438C42.793,38.75,36.215,33.486,28.106,33.486z M26.288,53.051
c0,0-7.135-2.093-8.805-7.201c-0.222-0.682,0.147-1.156,0.795-1.521V37.8h20.188v6.663c0.235,0.352,1.109,0.737,1.229,1.387
C40.445,49.917,26.288,53.051,26.288,53.051z"/&gt;
&lt;radialGradient id="SVGID_3_" cx="15.2056" cy="831.1875" r="32.3071" gradientTransform="matrix(1 0 0 1 0.0801 -773.6914)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_3_)" stroke="#E55E03" d="M49.529,51.225c-2.239-2.24-5.041-3.724-7.396-4.67
c-2.854,5.51-14.021,7.807-14.021,7.807s-10.472-2.483-12.387-8.514c-2.439,0.771-5.787,2.287-8.749,5.25
c-5.592,5.592-6.47,11.67-6.47,11.67c0,1.938,1.575,3.492,3.523,3.492h48.51c1.946,0,3.521-1.558,3.521-3.492
C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;radialGradient id="SVGID_4_" cx="17.0723" cy="18.4907" r="11.8931" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_4_)" stroke="#E55E03" d="M13.404,44.173c1.15-1.81,2.039-3.832,3.332-5.397
c-0.514,1.027-1.669,4.084-1.669,5.148c0,5.186,10.366,9.079,14.688,10.438c-3.472,1.627-9.134-1.498-11.334-2.359
c-3.601-1.419-4.071-3.063-5.89-4.854C12.523,47.135,12.878,45,13.404,44.173z"/&gt;
&lt;radialGradient id="SVGID_5_" cx="31.8184" cy="19.3525" r="14.63" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_5_)" stroke="#E55E03" d="M45.777,43.924c-1.317-1.568-5.11-9.424-6.604-6.617
c0.516,1.025,3.617,3.693,3.617,6.617c0,5.186-10.271,8.576-16.699,9.145c1.429,4.938,11.373,1.293,13.805-0.313
c3.563-2.354,4.563-5.133,7.854-3.705C47.754,49.045,48.006,46.574,45.777,43.924z"/&gt;
&lt;radialGradient id="SVGID_6_" cx="30.4893" cy="4.8721" r="5.2028" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_6_)" stroke="#E55E03" d="M30.777,54.167c0.357,0.836-0.153,1.983-0.352,2.813
c-0.256,1.084-0.072,2.104,0.102,3.186c0.164,1.02,0.156,2.107,0.25,3.167c0.082,0.916,0.482,1.849,0.357,2.75"/&gt;
&lt;radialGradient id="SVGID_7_" cx="23.2871" cy="5.3008" r="5.5143" gradientTransform="matrix(1 0 0 -1 0.04 64.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FCB57A"/&gt;
&lt;stop offset="1" style="stop-color:#FF8C36"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_7_)" stroke="#E55E03" d="M23.695,53.417c-0.508,0.584-0.476,2.209-0.398,3
c0.116,1.183,0.456,2.099,0.333,3.333c-0.192,1.943,0.154,4.479-0.436,6.333"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.5835" cy="3117.4922" r="23.425" fx="23.0139" fy="3115.0024" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.2-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="6468.501" y1="-12291.5195" x2="6492.1304" y2="-12384.9688" gradientTransform="matrix(0.275 0 0 -0.2733 -1752.8849 -3351.7349)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M28.415,5.625c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.54,13.244,36.729,5.56,28.415,5.625z"/&gt;
&lt;path id="Hair_Young_Black_1_" fill="#5C5C5C" stroke="#353535" stroke-linecap="round" stroke-linejoin="round" d="M20.278,13.25
c3.417,4.333,9.333,6.917,9.333,6.917l-1.417-3.5c0,0,7.094,4.691,8.083,4.333c0.968-0.2-1.082-3.807-1.082-3.807
s3.138,1.795,4.854,3.969c1.803,2.28,4.285,3.504,4.285,3.504S47.027,2.719,27.289,2.744C8.278,2.709,12.058,27.678,12.058,27.678
L14.695,17c0,0,0.914,5.757,1.399,4.875C17.861,15.211,18.861,11.5,20.278,13.25z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
<y:Resource id="2">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="67px" viewBox="0 0 57 67" enable-background="new 0 0 57 67" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3398" y1="3115.7266" x2="27.5807" y2="3145.5239" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.5835" cy="3117.4922" r="23.425" fx="23.0139" fy="3115.0024" gradientTransform="matrix(1 0 0 1 0.3203 -3091.7656)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.199-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="6468.5" y1="-12286.8594" x2="6492.1294" y2="-12380.3086" gradientTransform="matrix(0.275 0 0 -0.2733 -1752.8849 -3350.4617)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M28.415,5.625c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.54,13.244,36.729,5.56,28.415,5.625z"/&gt;
&lt;path id="Hair_Female_1_Red_1_" fill="#FAE1AA" stroke="#E2B354" stroke-linecap="round" stroke-linejoin="round" d="M28.372,0.5
C17.537,0.5,8.269,7.748,9.153,26.125c0.563,6.563,5.862,12.042,9.366,13.531c-2.929-10.968-0.304-25.021-0.585-25.526
c-0.281-0.505,3.536,6.728,3.536,6.728l3.183-8.312c5.541,4.28,0.393,11.309,1.049,11.058c4.26-1.631,5.34-9.228,5.34-9.228
s2.729,3.657,2.701,5.504c-0.054,3.562,2.194-6.067,2.194-6.067l1.027,2.031c6.727,9.822,3.684,16.208,1.648,22.781
c15.666-0.703,12.291-10.48,9.66-18.407C43.59,6.092,39.206,0.5,28.372,0.5z"/&gt;
&lt;linearGradient id="body_1_" gradientUnits="userSpaceOnUse" x1="95.9063" y1="-3134.2153" x2="31.5133" y2="-3134.2153" gradientTransform="matrix(0.9852 0 0 -0.9852 -34.4844 -3031.9851)"&gt;
&lt;stop offset="0" style="stop-color:#49AD33"/&gt;
&lt;stop offset="1" style="stop-color:#C2DA92"/&gt;
&lt;/linearGradient&gt;
&lt;path id="body_8_" fill="url(#body_1_)" stroke="#008D33" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-8.244-5.146-8.244-5.146
c-1.444,6.983-8.555,8.786-13.007,8.786s-11.322-2.643-11.941-9.439c0,0-4.559,1.199-9.367,5.674
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
</y:Resources>
</data>
</graphml>

BIN
docs/guide-ja/images/rbac-hierarchy-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

836
docs/guide-ja/images/request-lifecycle.graphml

@ -0,0 +1,836 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.13-->
<key for="graphml" id="d0" yfiles.type="resources"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key attr.name="Description" attr.type="string" for="graph" id="d7"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d7"/>
<node id="n0">
<data key="d6">
<y:SVGNode>
<y:Geometry height="70.13700103759766" width="56.558998107910156" x="198.38633947503078" y="261.099458694458"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="26.279499053955078" y="74.13700103759766">
<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="4.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="40.0" x="-35.30331532610154" y="25.717914581298828">ユーザ<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.3825828831525385" labelRatioY="0.0" nodeRatioX="-0.5" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="1"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="45.0" width="119.0" x="789.0653619766235" y="637.1271178722382"/>
<y:Fill color="#99CCFF" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="40.0" x="39.5" y="13.1494140625">モデル<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n2">
<data key="d6">
<y:SVGNode>
<y:Geometry height="46.887996673583984" width="39.527000427246094" x="828.8018617630005" y="544.9831195354463"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="76.0" x="-18.236499786376953" y="-30.723247528076172">データベース<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-12.022075653076172" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="17.763500213623047" y="21.443998336791992">
<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="45.0" width="119.0" x="789.0653619766235" y="713.6271178722382"/>
<y:Fill color="#99CC00" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="40.0" x="39.5" y="13.1494140625">ビュー<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n4" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="377.0372841596604" width="219.27949905395508" x="527.4919853210449" y="407.9266515731811"/>
<y:Fill color="#FFEFD6" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="node_width" backgroundColor="#FF9900" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="219.27949905395508" x="0.0" y="0.0">コントローラ</y:NodeLabel>
<y:Shape type="rectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="2" leftF="1.7335329055786133" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="313.2978515625" y="412.2765645980835"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 1</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n4:">
<node id="n4::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="150.55899810791016" x="563.2124862670898" y="445.3031164169311"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="100.0" x="25.279499053955078" y="5.6494140625">アクションを作成<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n4::n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="45.0" width="159.91864204406738" x="558.5326642990112" y="521.8166599273682"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="88.0" x="35.95932102203369" y="13.1494140625">フィルタを実行<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="diamond"/>
</y:ShapeNode>
</data>
</node>
<node id="n4::n2" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="162.71328270435333" width="187.54596614837646" x="544.2255182266235" y="607.2506530284882"/>
<y:Fill color="#99336635" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="node_width" backgroundColor="#993366" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#FFFFFF" visible="true" width="187.54596614837646" x="0.0" y="0.0">アクション</y:NodeLabel>
<y:Shape type="rectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="4" bottomF="3.8368178606033325" left="4" leftF="3.9869680404663086" right="3" rightF="3.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 3</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n4::n2:">
<node id="n4::n2::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="150.55899810791016" x="563.2124862670898" y="644.6271178722382"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="88.0" x="31.279499053955078" y="5.6494140625">モデルをロード<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n4::n2::n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="150.55899810791016" x="563.2124862670898" y="721.1271178722382"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="124.0" x="13.279499053955078" y="5.6494140625">ビューをレンダリング<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
</graph>
</node>
<node id="n5">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="45.0" width="119.0" x="198.3863394750308" y="713.6271178722382"/>
<y:Fill color="#FFCC99" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="33.40234375" modelName="custom" textColor="#000000" visible="true" width="88.0" x="15.5" y="5.798828125">レスポンス
コンポーネント<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n6">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="45.0" width="119.0" x="789.0653619766235" y="254.50096702575684"/>
<y:Fill color="#FFCC99" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="33.40234375" modelName="custom" textColor="#000000" visible="true" width="88.0" x="15.5" y="5.798828125">リクエスト
コンポーネント<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n7" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="144.132230758667" width="219.27949905395508" x="527.4919853210449" y="222.86873626708984"/>
<y:Fill color="#FFEFD6" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="node_width" backgroundColor="#FF9900" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="219.27949905395508" x="0.0" y="0.0">アプリケーション</y:NodeLabel>
<y:Shape type="rectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="21" leftF="20.720500946044922" right="18" rightF="18.0" top="2" topF="1.7557659149169922"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 2</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n7:">
<node id="n7::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="150.55899810791016" x="563.2124862670898" y="262.00096702575684"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="76.0" x="37.27949905395508" y="5.6494140625">ルートを解決<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n7::n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="150.55899810791016" x="563.2124862670898" y="322.00096702575684"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="112.0" x="19.279499053955078" y="5.6494140625">コントローラを作成<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<node id="n8" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="142.37646484375" width="199.93387606143483" x="292.6574954986572" y="224.62450218200684"/>
<y:Fill color="#FFCC0024" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="node_width" backgroundColor="#FFCC00" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="199.93387606143483" x="0.0" y="0.0">エントリスクリプト</y:NodeLabel>
<y:Shape type="rectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="313.2978515625" y="225.33495140075684"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="59.02685546875" x="-4.513427734375" y="0.0">Folder 4</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n8:">
<node id="n8::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="169.93387606143483" x="307.6574954986572" y="262.00096702575684"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="160.0" x="4.966938030717415" y="5.6494140625">アプリのコンフィグをロード<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n8::n1">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="169.93387606143483" x="307.6574954986572" y="322.00096702575684"/>
<y:Fill color="#FFFFFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="160.0" x="4.966938030717415" y="5.6494140625">アプリケーションを走らせる<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<edge id="e0" source="n2" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n5" target="n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-31.22050094604495" sy="-22.49430537223816" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="4.0" x="28.00000600945461" y="-193.17557203769684">
<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="right" ratio="0.5" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="17.34765625" x="-8.673822115545391" y="-200.52615797519684">11<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n6" target="n7::n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="10.673828125" x="-29.525518994973595" y="-10.349628448486328">3<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="0.9990329742431641" distanceToCenter="true" position="right" ratio="0.25395048761528816" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n7::e0" source="n7::n0" target="n7::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n0" target="n8">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="-86.58565098150827" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="10.673828125" x="17.89324407708159" y="-9.454540677880914">1<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n7::n1" target="n4">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="2.408647025755731" ty="-181.21658369302781"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="10.673828125" x="-4.962140296002758" y="18.61224679946895">4<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="30.0" distanceToCenter="false" position="center" ratio="0.5" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e5" source="n3" target="n4::n2::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="10.673828125" x="-30.100868416252297" y="-9.35060429573059">9<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="10.0" distanceToCenter="false" position="center" ratio="0.26448415477215953" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e6" source="n4::n2::n1" target="n5">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="-2.2737367544323206E-13" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="17.34765625" x="-83.18526519030615" y="-9.350604295730818">10<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.2786124840137136" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e7" source="n8::n1" target="n7">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="60.77427719662158" sy="0.355224609375" tx="-109.63961141576266" ty="42.066115379333496"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="10.673828125" x="19.602683079240364" y="-9.470142300213183">2<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e8" source="n1" target="n4::n2::n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="10.673828125" x="-31.270312699786246" y="-10.35060429573059">8<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="1.0" distanceToCenter="true" position="right" ratio="0.2858946861565087" segment="-1"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e9" source="n4::n1" target="n5">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-79.9882439360951" sy="2.2737367544323206E-13" tx="30.048898971244075" ty="-1.4999999999999991">
<y:Point x="287.93523844627487" y="544.3166599273684"/>
</y:Path>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="10.673828125" x="-76.70009317381192" y="-9.350576400756609">6<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="30.0" distanceToCenter="true" position="center" ratio="0.23459266172695797" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n4::e0" source="n4::n0" target="n4::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#FFEFD6" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="10.673828125" x="-5.336933135986328" y="4.999985313415493">5<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n4::e1" source="n4::n1" target="n4::n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="-81.01828954355172"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" backgroundColor="#FFEFD6" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="18.701171875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="10.673828125" x="-5.4491733540852465" y="5.039560317993164">7<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="30.0" distanceToCenter="false" position="center" ratio="0.0" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n4::n2::e0" source="n4::n2::n0" target="n4::n2::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n8::e0" source="n8::n0" target="n8::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#666666" type="line" width="2.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d0">
<y:Resources>
<y:Resource id="1">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="57px" height="66px" viewBox="0 0 57 66" enable-background="new 0 0 57 66" xml:space="preserve"&gt;
&lt;g&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="26.3799" y1="-2276.8809" x2="27.6209" y2="-2306.6792" gradientTransform="matrix(1 0 0 -1 0.2803 -2252.9199)"&gt;
&lt;stop offset="0.2711" style="stop-color:#FFAB4F"/&gt;
&lt;stop offset="1" style="stop-color:#FFD28F"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;path id="body_13_" fill="#ECECEC" stroke="#9B9B9B" stroke-miterlimit="10" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494h48.51
c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-11.244-6.146-11.244-6.146
c-1.771,1.655-5.61,3.802-10.063,3.802c-4.453,0-8.292-2.146-10.063-3.802c0,0-5.755,0.586-11.189,6.021
C1.378,56.689,0.5,62.768,0.5,62.768z"/&gt;
&lt;path fill="#2068A3" stroke="#2068A3" d="M28.106,33.487c-8.112,0-12.688,4.312-12.688,10.437c0,7.422,12.688,10.438,12.688,10.438
s14.688-3.016,14.688-10.438C42.793,38.75,36.215,33.487,28.106,33.487z M26.288,53.051c0,0-7.135-2.093-8.805-7.201
c-0.222-0.682,0.147-1.156,0.795-1.521V37.8h20.188v6.663c0.235,0.352,1.109,0.737,1.229,1.387
C40.445,49.917,26.288,53.051,26.288,53.051z"/&gt;
&lt;radialGradient id="SVGID_2_" cx="14.2417" cy="9.1006" r="53.247" gradientTransform="matrix(1 0 0 -1 0.04 65.1543)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#74AEEE"/&gt;
&lt;stop offset="1" style="stop-color:#2068A3"/&gt;
&lt;/radialGradient&gt;
&lt;path fill="url(#SVGID_2_)" stroke="#2068A3" stroke-miterlimit="10" d="M49.529,51.225c-2.239-2.24-5.041-3.724-7.396-4.67
c-2.854,5.51-14.022,7.807-14.022,7.807s-10.472-2.484-12.387-8.514c-2.439,0.771-5.787,2.287-8.749,5.25
c-5.592,5.592-6.47,11.67-6.47,11.67c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492
C56.055,62.768,54.211,55.906,49.529,51.225z"/&gt;
&lt;path fill="#5491CF" stroke="#2068A3" d="M13.404,44.173c1.15-1.81,2.039-3.832,3.332-5.397c-0.514,1.027-1.669,4.084-1.669,5.148
c0,5.186,10.366,9.079,14.688,10.438c-3.472,1.627-9.134-1.498-11.335-2.36c-3.601-1.419-4.071-3.063-5.89-4.854
C12.523,47.135,12.878,45,13.404,44.173z"/&gt;
&lt;path fill="#5491CF" stroke="#2068A3" d="M45.777,43.924c-1.317-1.568-5.11-9.424-6.604-6.617c0.516,1.025,3.617,3.693,3.617,6.617
c0,5.186-10.27,8.576-16.698,9.145c1.429,4.938,11.372,1.293,13.804-0.313c3.563-2.354,4.563-5.133,7.854-3.705
C47.754,49.045,48.006,46.574,45.777,43.924z"/&gt;
&lt;path fill="none" stroke="#2068A3" stroke-linecap="round" d="M30.777,54.167c0.357,0.836-0.153,1.983-0.352,2.813
c-0.256,1.084-0.072,2.104,0.102,3.186c0.164,1.02,0.156,2.107,0.25,3.167c0.082,0.916,0.482,1.849,0.357,2.75"/&gt;
&lt;path fill="none" stroke="#2068A3" stroke-linecap="round" d="M23.695,53.417c-0.508,0.584-0.476,2.209-0.398,3
c0.116,1.183,0.456,2.099,0.333,3.333c-0.192,1.943,0.154,4.479-0.436,6.333"/&gt;
&lt;radialGradient id="face_x5F_white_1_" cx="27.623" cy="-2278.646" r="23.425" fx="23.0534" fy="-2281.1357" gradientTransform="matrix(1 0 0 -1 0.2803 -2252.9199)" gradientUnits="userSpaceOnUse"&gt;
&lt;stop offset="0" style="stop-color:#FFD28F"/&gt;
&lt;stop offset="1" style="stop-color:#FFAB4F"/&gt;
&lt;/radialGradient&gt;
&lt;path id="face_x5F_white_3_" fill="url(#face_x5F_white_1_)" stroke="#ED9135" stroke-miterlimit="10" d="M43.676,23.357
c0.086,10.2-6.738,18.52-15.25,18.586c-8.5,0.068-15.464-8.146-15.55-18.344C12.794,13.4,19.618,5.079,28.123,5.012
C36.627,4.945,43.59,13.158,43.676,23.357z"/&gt;
&lt;linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="5761.7578" y1="11330.6484" x2="5785.3872" y2="11424.0977" gradientTransform="matrix(0.275 0 0 0.2733 -1558.9874 -3088.4209)"&gt;
&lt;stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/&gt;
&lt;stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/&gt;
&lt;/linearGradient&gt;
&lt;path id="face_highlight_3_" fill="url(#face_highlight_1_)" d="M27.958,6.333c-6.035,0.047-10.747,4.493-12.787,10.386
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
c2.274-0.592,3.988-2.459,4.375-4.766c0.187-1.094,0.293-2.289,0.283-3.553C42.083,13.952,36.271,6.268,27.958,6.333z"/&gt;
&lt;path id="Hair_Young_Brown_1_" fill="#CC9869" stroke="#99724F" stroke-linecap="round" stroke-linejoin="round" d="M20.278,13.25
c3.417,4.333,9.333,6.917,9.333,6.917l-1.417-3.5c0,0,7.094,4.691,8.083,4.333c0.968-0.2-1.082-3.807-1.082-3.807
s3.138,1.795,4.854,3.969c1.803,2.28,4.285,3.504,4.285,3.504S47.027,2.719,27.289,2.744C8.278,2.709,12.058,27.678,12.058,27.678
L14.695,17c0,0,0.914,5.757,1.399,4.875C17.861,15.211,18.861,11.5,20.278,13.25z"/&gt;
&lt;path fill="#4B4B4B" stroke="#4B4B4B" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M28.105,2
C22.464,2,20.2,4.246,18.13,5.533C29.753,2.865,41.152,10.375,44.46,20.5C44.459,16.875,44.459,2,28.105,2z"/&gt;
&lt;path fill="#9B9B9B" stroke="#4B4B4B" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M11.151,17.751
C12.878,8.25,18.686,6.309,25.273,7.127C31.295,7.875,36.93,10.491,44.459,20.5C37.777,7.125,20.278-3.375,9.903,3.921
C5.569,6.97,4.903,13.375,11.151,17.751z"/&gt;
&lt;/g&gt;
&lt;/svg&gt;
</y:Resource>
<y:Resource id="2">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="41px" height="48px" viewBox="-0.875 -0.887 41 48" enable-background="new -0.875 -0.887 41 48"
xml:space="preserve"&gt;
&lt;defs&gt;
&lt;/defs&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-979.1445" x2="682.0508" y2="-979.1445" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#3C89C9"/&gt;
&lt;stop offset="0.1482" style="stop-color:#60A6DD"/&gt;
&lt;stop offset="0.3113" style="stop-color:#81C1F0"/&gt;
&lt;stop offset="0.4476" style="stop-color:#95D1FB"/&gt;
&lt;stop offset="0.5394" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.636" style="stop-color:#98D4FD"/&gt;
&lt;stop offset="0.7293" style="stop-color:#8DCAF6"/&gt;
&lt;stop offset="0.8214" style="stop-color:#79BBEB"/&gt;
&lt;stop offset="0.912" style="stop-color:#5EA5DC"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" d="M19.625,36.763C8.787,36.763,0,34.888,0,32.575v10c0,2.313,8.787,4.188,19.625,4.188
c10.839,0,19.625-1.875,19.625-4.188v-10C39.25,34.888,30.464,36.763,19.625,36.763z"/&gt;
&lt;linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-973.1445" x2="682.0508" y2="-973.1445" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.0039" style="stop-color:#9DD7FF"/&gt;
&lt;stop offset="0.2273" style="stop-color:#BDE5FF"/&gt;
&lt;stop offset="0.4138" style="stop-color:#D1EEFF"/&gt;
&lt;stop offset="0.5394" style="stop-color:#D9F1FF"/&gt;
&lt;stop offset="0.6155" style="stop-color:#D5EFFE"/&gt;
&lt;stop offset="0.6891" style="stop-color:#C9E7FA"/&gt;
&lt;stop offset="0.7617" style="stop-color:#B6DAF3"/&gt;
&lt;stop offset="0.8337" style="stop-color:#9AC8EA"/&gt;
&lt;stop offset="0.9052" style="stop-color:#77B0DD"/&gt;
&lt;stop offset="0.9754" style="stop-color:#4D94CF"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_2_)" d="M19.625,36.763c10.839,0,19.625-1.875,19.625-4.188l-1.229-2c0,2.168-8.235,3.927-18.396,3.927
c-9.481,0-17.396-1.959-18.396-3.927l-1.229,2C0,34.888,8.787,36.763,19.625,36.763z"/&gt;
&lt;path fill="#3C89C9" d="M19.625,26.468c10.16,0,19.625,2.775,19.625,2.775c-0.375,2.721-5.367,5.438-19.554,5.438
c-12.125,0-18.467-2.484-19.541-4.918C-0.127,29.125,9.465,26.468,19.625,26.468z"/&gt;
&lt;linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-965.6948" x2="682.0508" y2="-965.6948" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#3C89C9"/&gt;
&lt;stop offset="0.1482" style="stop-color:#60A6DD"/&gt;
&lt;stop offset="0.3113" style="stop-color:#81C1F0"/&gt;
&lt;stop offset="0.4476" style="stop-color:#95D1FB"/&gt;
&lt;stop offset="0.5394" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.636" style="stop-color:#98D4FD"/&gt;
&lt;stop offset="0.7293" style="stop-color:#8DCAF6"/&gt;
&lt;stop offset="0.8214" style="stop-color:#79BBEB"/&gt;
&lt;stop offset="0.912" style="stop-color:#5EA5DC"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_3_)" d="M19.625,23.313C8.787,23.313,0,21.438,0,19.125v10c0,2.313,8.787,4.188,19.625,4.188
c10.839,0,19.625-1.875,19.625-4.188v-10C39.25,21.438,30.464,23.313,19.625,23.313z"/&gt;
&lt;linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-959.6948" x2="682.0508" y2="-959.6948" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.0039" style="stop-color:#9DD7FF"/&gt;
&lt;stop offset="0.2273" style="stop-color:#BDE5FF"/&gt;
&lt;stop offset="0.4138" style="stop-color:#D1EEFF"/&gt;
&lt;stop offset="0.5394" style="stop-color:#D9F1FF"/&gt;
&lt;stop offset="0.6155" style="stop-color:#D5EFFE"/&gt;
&lt;stop offset="0.6891" style="stop-color:#C9E7FA"/&gt;
&lt;stop offset="0.7617" style="stop-color:#B6DAF3"/&gt;
&lt;stop offset="0.8337" style="stop-color:#9AC8EA"/&gt;
&lt;stop offset="0.9052" style="stop-color:#77B0DD"/&gt;
&lt;stop offset="0.9754" style="stop-color:#4D94CF"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_4_)" d="M19.625,23.313c10.839,0,19.625-1.875,19.625-4.188l-1.229-2c0,2.168-8.235,3.926-18.396,3.926
c-9.481,0-17.396-1.959-18.396-3.926l-1.229,2C0,21.438,8.787,23.313,19.625,23.313z"/&gt;
&lt;path fill="#3C89C9" d="M19.476,13.019c10.161,0,19.625,2.775,19.625,2.775c-0.375,2.721-5.367,5.438-19.555,5.438
c-12.125,0-18.467-2.485-19.541-4.918C-0.277,15.674,9.316,13.019,19.476,13.019z"/&gt;
&lt;linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-952.4946" x2="682.0508" y2="-952.4946" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#3C89C9"/&gt;
&lt;stop offset="0.1482" style="stop-color:#60A6DD"/&gt;
&lt;stop offset="0.3113" style="stop-color:#81C1F0"/&gt;
&lt;stop offset="0.4476" style="stop-color:#95D1FB"/&gt;
&lt;stop offset="0.5394" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.636" style="stop-color:#98D4FD"/&gt;
&lt;stop offset="0.7293" style="stop-color:#8DCAF6"/&gt;
&lt;stop offset="0.8214" style="stop-color:#79BBEB"/&gt;
&lt;stop offset="0.912" style="stop-color:#5EA5DC"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_5_)" d="M19.625,10.113C8.787,10.113,0,8.238,0,5.925v10c0,2.313,8.787,4.188,19.625,4.188
c10.839,0,19.625-1.875,19.625-4.188v-10C39.25,8.238,30.464,10.113,19.625,10.113z"/&gt;
&lt;linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-946.4946" x2="682.0508" y2="-946.4946" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.0039" style="stop-color:#9DD7FF"/&gt;
&lt;stop offset="0.2273" style="stop-color:#BDE5FF"/&gt;
&lt;stop offset="0.4138" style="stop-color:#D1EEFF"/&gt;
&lt;stop offset="0.5394" style="stop-color:#D9F1FF"/&gt;
&lt;stop offset="0.6155" style="stop-color:#D5EFFE"/&gt;
&lt;stop offset="0.6891" style="stop-color:#C9E7FA"/&gt;
&lt;stop offset="0.7617" style="stop-color:#B6DAF3"/&gt;
&lt;stop offset="0.8337" style="stop-color:#9AC8EA"/&gt;
&lt;stop offset="0.9052" style="stop-color:#77B0DD"/&gt;
&lt;stop offset="0.9754" style="stop-color:#4D94CF"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_6_)" d="M19.625,10.113c10.839,0,19.625-1.875,19.625-4.188l-1.229-2c0,2.168-8.235,3.926-18.396,3.926
c-9.481,0-17.396-1.959-18.396-3.926L0,5.925C0,8.238,8.787,10.113,19.625,10.113z"/&gt;
&lt;linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="644.0293" y1="-943.4014" x2="680.8223" y2="-943.4014" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;ellipse fill="url(#SVGID_7_)" cx="19.625" cy="3.926" rx="18.396" ry="3.926"/&gt;
&lt;path opacity="0.24" fill="#FFFFFF" enable-background="new " d="M31.04,45.982c0,0-4.354,0.664-7.29,0.781
c-3.125,0.125-8.952,0-8.952,0l-2.384-10.292l0.044-2.108l-1.251-1.154L9.789,23.024l-0.082-0.119L9.5,20.529l-1.65-1.254
L5.329,8.793c0,0,4.213,0.903,7.234,1.07s8.375,0.25,8.375,0.25l3,9.875l-0.25,1.313l1.063,2.168l2.312,9.645l-0.521,1.416
l1.46,1.834L31.04,45.982z"/&gt;
&lt;/svg&gt;
</y:Resource>
</y:Resources>
</data>
</graphml>

BIN
docs/guide-ja/images/request-lifecycle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

22
docs/guide-ja/intro-upgrade-from-v1.md

@ -45,7 +45,7 @@ Yii 2.0 は PHP 5.4 以上を必要とします。PHP 5.4 は、Yii 1.1 によ
Yii 2.0 での最も明らかな変更は名前空間の使用です。
ほとんど全てのコアクラスが、例えば、`yii\web\Request` のように名前空間に属します。
クラス名に "C" のプレフィックスはもう使われません。
クラス名に "C" の接頭辞はもう使われません。
命名のスキームはディレクトリ構造に従うようになりました。
例えば、`yii\web\Request` は、対応するクラスファイルが Yii フレームワークフォルダの下の `web/Request.php` であることを示します。
@ -151,12 +151,12 @@ Yii 2.0 は、パスエイリアスの使用を、ファイル/ディレクト
------
Yii 2 のビューについての最も顕著な変更は、ビューの中で `$this` という特殊な変数がカレントコントローラやウィジェットを指すものではなくなったということです。
今や `$this` は 2.0 で新しく導入された概念である *ビュー*オブジェクトを指します。
*ビュー*オブジェクトは [[yii\web\View]] という型であり、MVC パターンのビューの部分を表すものです。
今や `$this` は 2.0 で新しく導入された概念である *ビュー* オブジェクトを指します。
*ビュー* オブジェクトは [[yii\web\View]] という型であり、MVC パターンのビューの部分を表すものです。
ビューにおいてコントローラやウィジェットにアクセスしたい場合は、`$this->context` を使うことが出来ます。
パーシャルビューを別のビューの中で表示するためには、`$this->renderPartial()` ではなく、`$this->render()` を使います。
`render` の呼び出しは、2.0 では明示的に echo しなくてはなりません。と言うのは、`render)` メソッドは、直接に表示するのではなく、レンダリング結果を文字列として返すものだからです。
`render` の呼び出しは、2.0 では明示的に echo しなくてはなりません。と言うのは、`render()` メソッドは、直接に表示するのではなく、レンダリング結果を文字列として返すものだからです。
例えば:
```php
@ -176,8 +176,8 @@ Yii 2.0 は [[yii\base\Model]] を 1.1 における `CModel` と同様な基底
`CFormModel` というクラスは完全に廃止されました。
Yii 2 では、それの代りに、[yii\base\Model]] を拡張してフォームモデルクラスを作成すべきです。
Yii 2.0 は シナリオを宣言するための [[yii\base\Model::scenarios()|scenarios()]] というメソッドを導入しました。
このメソッドを使って、どのようなシナリオがサポートされるか、また、どのシナリオの下である属性が検証される必要があるか、安全とみなされるか否か、などを宣言します。
Yii 2.0 は サポートされるシナリオを宣言するための [[yii\base\Model::scenarios()|scenarios()]] というメソッドを導入しました。
このメソッドを使って、あるシナリオの下で、どの属性が検証される必要があるか、また、どの属性が安全とみなされるか否か、などを宣言することが出来ます。
例えば:
```php
@ -193,12 +193,12 @@ public function scenarios()
上記では二つのシナリオが宣言されています: `backend``frontend` です。
`backend` シナリオでは、`email` と `role` の属性が両方とも安全であり、一括代入が可能です。
`frontend` シナリオでは、`email` は一括代入が可能ですが、`role` は不可能です。
`email``role` は、両方とも、ルールを使って検証されなければなりません。
`email``role` は、両方とも、規則を使って検証されなければなりません。
[[yii\base\Model::rules()|rules()]] メソッドが Yii 1.1 同様に検証ルールを宣言するために使われます。
[[yii\base\Model::rules()|rules()]] メソッドが Yii 1.1 同様に検証規則を宣言するために使われます。
[[yii\base\Model::scenarios()|scenarios()]] が導入されたことにより、`unsafe` バリデータが無くなったことに注意してください。
ほとんどの場合、[[yii\base\Model::rules()|rules()]] メソッドが存在し得るシナリオを十全に記述することが出来るなら、そして `unsafe` な属性を宣言する必要が無いなら、[[yii\base\Model::scenarios()|scenarios()]] をオーバーライドする必要はありません。
ほとんどの場合、[[yii\base\Model::rules()|rules()]] メソッドが在り得るシナリオを十分に既定しているなら、そして `unsafe` な属性を宣言する必要が無いなら、[[yii\base\Model::scenarios()|scenarios()]] をオーバーライドする必要はありません。
モデルについてさらに詳細を学習するために、[モデル](structure-models.md) の節を参照してください。
@ -389,7 +389,7 @@ $sql = $command->sql;
$rows = $command->queryAll();
```
何より良いのは、このようなクエリ構築メソッドが [Active Record](db-active-record.md) を扱う時にも使える、ということです。
何より良いのは、このようなクエリ構築メソッドが [アクティブレコード](db-active-record.md) を扱う時にも使える、ということです。
更なる詳細については [クエリビルダ](db-query-builder.md) の節を参照してください。
@ -397,7 +397,7 @@ $rows = $command->queryAll();
アクティブレコード
------------------
Yii 2.0 は [Active Record](db-active-record.md) に数多くの変更を導入しました。
Yii 2.0 は [アクティブレコード](db-active-record.md) に数多くの変更を導入しました。
最も顕著な違いは、クエリの構築方法とリレーショナルクエリの処理の二つです。
1.1 の `CDbCriteria` クラスは Yii 2 では [[yii\db\ActiveQuery]] に置き換えられました。

2
docs/guide-ja/intro-yii.md

@ -19,7 +19,7 @@ Yii を他のフレームワークと比べるとどうか?
あなたが既に他のフレームワークに親しんでいる場合は、Yii を比較するとどうなるのかを知りたいと思うでしょう:
- ほとんどの PHP フレームワーク同様、Yii は MVC (Model-View-Controller) デザインパターンを実装し、このパターンに基いたコードの組織化を促進しています。
- ほとんどの PHP フレームワーク同様、Yii は MVC (Model-View-Controller) デザインパターンを実装し、このパターンに基いたコードの組織化を促進しています。
- Yii は、コードはシンプルかつエレガントに書かれるべきである、という哲学を採用しています。
Yii は、何らかのデザインパターンを厳密に守ることを主たる目的として大袈裟な設計をすることは、決してしようとしません。
- Yii は、検証済みで直ちに使える多数の機能を提供するフル装備のフレームワークです:

11
docs/guide-ja/start-databases.md

@ -127,7 +127,7 @@ $country->save();
```
> Info|情報: アクティブレコードは、オブジェクト指向の流儀でデータベースのデータにアクセスし、操作する強力な方法です。
[Active Record](db-active-record.md) の節で、更に詳細な情報を得ることが出来ます。
[アクティブレコード](db-active-record.md) の節で、更に詳細な情報を得ることが出来ます。
もう一つの方法として、[データアクセスオブジェクト(DAO)](db-dao.md) と呼ばれる、より低レベルなデータアクセス方法を使って
データベースを操作することも出来ます。
@ -184,7 +184,7 @@ class CountryController extends Controller
* クエリによって表現される SQL 文に `offset` 句と `limit` 句をセットして、一度に一ページ分のデータだけ (1ページ最大5行)を返すようにします。
* 次の項で説明されるように、一連のページボタンからなるページャをビューに表示するために使われます。
コードの最後で、`index` アクションは `index` と言う名前のビューを表示していますが、このとき、国データはもちろん、そのページ付け情報もビューに渡されます。
コードの最後で、`index` アクションは `index` と言う名前のビューをレンダリングしていますが、このとき、国データはもちろん、そのページ付け情報もビューに渡されます。
ビューを作成する<a name="creating-view"></a>
@ -213,8 +213,9 @@ use yii\widgets\LinkPager;
```
ビューは国データの表示に関連して二つの部分に分けられます。
最初の部分では、提供された国データが HTML の順序無しリストとして表示されます。
第二の部分では、アクションから渡されたページ付け情報を使って、[[yii\widgets\LinkPager]] ウィジェットが表示されます。
最初の部分では、提供された国データがたどられて、HTML の順序無しリストとしてレンダリングされます。
第二の部分では、アクションから渡されたページ付け情報を使って、[[yii\widgets\LinkPager]]
ウィジェットがレンダリングされます。
`LinkPager` ウィジェットはページボタンのリストを表示します。ボタンのどれかをクリックすると、対応するページの国データが更新表示されます。
@ -243,7 +244,7 @@ http://hostname/index.php?r=country/index&page=2
* 最初、[[yii\data\Pagination|Pagination]] は、1ページ目を表しています。
これは、国の SELECT クエリが `LIMIT 5 OFFSET 0` という句を伴うことを示しています。
その結果、最初の5つの国が取得されて表示されます。
* [[yii\widgets\LinkPager|LinkPager]] ウィジェットは、[[yii\data\Pagination::createUrl()|Pagination]] によって作成された URL を使ってページボタンを表示します。
* [[yii\widgets\LinkPager|LinkPager]] ウィジェットは、[[yii\data\Pagination::createUrl()|Pagination]] によって作成された URL を使ってページボタンをレンダリングします。
URL は、別々のページ番号を表現する `page` というクエリパラメータを含んだものになります。
* ページボタン "2" をクリックすると、`country/index` のルートに対する新しいリクエストが発行され、処理されます。
[[yii\data\Pagination|Pagination]] が URL から `page` クエリパラメータを読み取って、カレントページ番号を 2 にセットします。

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

@ -172,7 +172,7 @@ use yii\widgets\ActiveForm;
```
このビューは HTML フォームを構築するのに、[[yii\widgets\ActiveForm|ActiveForm]] と呼ばれる強力な [ウィジェット](structure-widgets.md) を使います。
ウィジェットの `begin()` メソッドと `end()` メソッドが、それぞれ、フォームの開始タグと終了タグを表示します。
ウィジェットの `begin()` メソッドと `end()` メソッドが、それぞれ、フォームの開始タグと終了タグをレンダリングします。
この二つのメソッドの呼び出しの間に、[[yii\widgets\ActiveForm::field()|field()]] メソッドによって入力フィールドが作成されます。
最初の入力フィールドは "name" のデータ、第二の入力フィールドは "email" のデータのためのものです。
入力フィールドの後に、[[yii\helpers\Html::submitButton()]] メソッドが呼ばれて、送信ボタンを生成しています。

2
docs/guide-ja/start-gii.md

@ -46,7 +46,7 @@ defined('YII_ENV') or define('YII_ENV', 'dev');
http://hostname/index.php?r=gii
```
> Note|注意: ローカルホスト以外のマシンから GII にアクセスしようとすると、既定ではセキュリティ上の
> Note|注意: ローカルホスト以外のマシンから Gii にアクセスしようとすると、既定ではセキュリティ上の
> 目的からアクセスが拒否されます。下記のように Gii を構成して、許可される IP アドレスを追加することが出来ます。
>
```php

20
docs/guide-ja/start-hello.md

@ -4,14 +4,14 @@
この節では、アプリケーションに新しい「こんにちは」というページを作成する方法を説明します。
この目的を達するために、[アクション](structure-controllers.md#creating-actions) と [ビュー](structure-views.md) を作成することになります:
* アプリケーションがこのページへのリクエストをそのアクションに送致(dispatch)し、
* アプリケーションがこのページへのリクエストをそのアクションに送し、
* 次にそのアクションが "Hello" という言葉をエンドユーザに示すビューを表示します。
このチュートリアルを通じて、次の三つのことを学びます:
1. リクエストに応える [アクション](structure-controllers.md) をどのようにして作るか、
2. レスポンスの内容を構成する [ビュー](structure-views.md) をどのようにして作るか、そして、
3. アプリケーションはどのようにしてリクエストを [アクション](structure-controllers.md#creating-actions) に送するか。
3. アプリケーションはどのようにしてリクエストを [アクション](structure-controllers.md#creating-actions) に送するか。
アクションを作成する<a name="creating-action"></a>
@ -48,31 +48,31 @@ class SiteController extends Controller
```
上記のコードで、`say` アクションは `SiteController` クラスの中で `actionSay` という名前のメソッドとして定義されています。
Yii はコントローラクラスの中でアクションのメソッドとアクションでないメソッドを区別するために、`action` という接頭を使います。
`action` という接頭の後の名前がアクション ID にマップされます。
Yii はコントローラクラスの中でアクションのメソッドとアクションでないメソッドを区別するために、`action` という接頭を使います。
`action` という接頭の後の名前がアクション ID にマップされます。
アクションを命名するについては、Yii がアクション ID をどのように取り扱うかを知っているべきです。
アクション ID は常に小文字で参照されます。
アクション ID が複数の単語を必要とするときは、単語がダッシュ(-)で連結されます (例えば、`create-comment`)。
アクションメソッドの名前は、アクション ID からダッシュを全て削除し、各単語の先頭の文字を大文字にした結果に `action` という接頭を付けたものとします。
アクションメソッドの名前は、アクション ID からダッシュを全て削除し、各単語の先頭の文字を大文字にした結果に `action` という接頭を付けたものとします。
例えば、アクション ID `create-comment` に対応するアクションメソッド名は `actionCreateComment` となります。
私たちの例では、このアクションメソッドは `$message` というパラメータを取ります。
そして、このパラメータは `"Hello"` という既定値を取ります
(PHP で関数やメソッドの引数について既定値をセットするのと全く同じ方法を使います)。
アプリケーションは、リクエストを受け取って、当該リクエストの処理を `say` アクションに任せると決定した場合、リクエストの中に同じ名前の付いたパラメータがあれば、それをこのパラメータに代入します。
言い換えれば、もしリクエストに `"GoodBye"` という値の `message` パラメータが入っていれば、アクションの `$message` 変数にその値が割り当てられます。
言い換えれば、もしリクエストに `"GoodBye"` という値の `message` パラメータが入っていれば、アクションの `$message` 変数にその値が割り当てられます。
このアクションメソッドの中では、[[yii\web\Controller::render()|render()]] が呼ばれて `say` と言う名前の [ビュー](structure-views.md) ファイルが表示されます。
このアクションメソッドの中では、[[yii\web\Controller::render()|render()]] が呼ばれて `say` と言う名前の [ビュー](structure-views.md) ファイルがレンダリングされます。
`message` パラメータも同時にビューに渡され、そこで使用されます。
表示結果はアクションメソッドによって返されます。
レンダリング結果はアクションメソッドによって返されます。
返された結果はアプリケーションによって受け取られ、ブラウザ上でエンドユーザに(完全な HTML ページの一部として)表示されます。
ビューを作成する<a name="creating-view"></a>
----------------
[ビュー](structure-views.md) は、レスポンスのコンテンツを生成するために書くスクリプトです。
[ビュー](structure-views.md) は、レスポンスのコンテンツを生成するためにあなたが書くスクリプトです。
「こんにちは」のタスクのためには、アクションメソッドから受け取った `message` パラメータを印字する `say` ビューを作成します:
```php
@ -126,7 +126,7 @@ URL から `message` パラメータを省略すると、"Hello" だけを表示
> Info|情報: アクションと同じく、コントローラもまたアプリケーションの中で一意に定義される ID を持ちます。
コントローラ ID も、アクション ID と同じ命名規則を使います。
コントローラクラスの名前は、コントローラ ID からダッシュを削除し、各単語の最初の文字を大文字にし、結果として出来る文字列に `Controller` という接尾を追加したものとします。
コントローラクラスの名前は、コントローラ ID からダッシュを削除し、各単語の最初の文字を大文字にし、結果として出来る文字列に `Controller` という接尾を追加したものとします。
例えば、`post-comment` というコントローラ ID に対応するコントローラクラスの名前は `PostCommentController` です。

7
docs/guide-ja/start-installation.md

@ -35,9 +35,9 @@ Composer がインストールされたら、ウェブからアクセスでき
必要なら別のディレクトリ名を選ぶことも出来ます。
> Note|注意: インストール実行中に Composer が あなたの Github アカウントの認証情報を尋ねてくることがあるかも知れません。
> これは、Comoser が Github API の帯域制限にひっかかったためです。
> これは、Comoser が Github API の転送レート制限にひっかかったためです。
> Composer は全てのパッケージのための大量の情報を Github から読み出さなければならないので、こうなるのは普通のことです。
> Github にログインすると API の帯域制限が緩和され、Composer が仕事を続けることが出来るようになります。
> Github にログインすると API の転送レート制限が緩和され、Composer が仕事を続けることが出来るようになります。
> 更なる詳細については、[Composer documentation](https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens) を参照してください。
> Tip|ヒント: Yii の最新の開発バージョンをインストールしたい場合は、[stability option](https://getcomposer.org/doc/04-schema.md#minimum-stability) を追加した次のコマンドを代りに使うことが出来ます:
@ -157,7 +157,8 @@ DocumentRoot "path/to/basic/web"
### 推奨される Nginx の構成<a name="recommended-nginx-configuration"></a>
[Nginx](http://wiki.nginx.org/) を使うためには、PHP を [FPM SAPI](http://jp1.php.net/install.fpm) としてインストールしていなければなりません。
下記の設定を使い、`path/to/basic/web` の部分を `basic/web` の実際のパスに置き換え、`mysite.local` を実際のサーバのホスト名に置き換えてください。
下記の設定を使うことができます (`path/to/basic/web` の部分を `basic/web` の実際のパスに置き換え、
`mysite.local` を実際のサーバのホスト名に置き換えてください)。
```
server {

8
docs/guide-ja/start-looking-ahead.md

@ -10,20 +10,20 @@ Gii をコード生成に使うと、ウェブ開発のプロセスの大部分
この節では、Yii フレームワークを使うときの生産性を更に高めるために利用できるリソースについてまとめます。
* ドキュメンテーション
- 公式ガイド:
- [公式ガイド](http://www.yiiframework.com/doc-2.0/guide-README.html):
Definitive(最も確実な) という名前が示すように、このガイドは Yii がどのように動作すべきものかを正確に記述し、
Yii を使用するについての全般的な手引きを提供するものです。
これは唯一最重要な Yii のチュートリアルであり、Yii のコードを少しでも書く前に読むべきものです。
- クラスリファレンス:
- [クラスリファレンス](http://www.yiiframework.com/doc-2.0/index.html):
これは Yii によって提供される全てのクラスの使用法を記述しています。
主として、コードを書いている時に、特定のクラス、メソッド、プロパティについて理解したい場合に読まれるべきものです。
クラスリファレンスの使用は、フレームワーク全体の文脈的な理解が出来てからにするのが最善です。
- Wiki の記事:
- [Wiki の記事]((http://www.yiiframework.com/wiki/?tag=yii2)):
Wiki の記事は、Yii のユーザが自身の経験に基づいて書いたものです。
ほとんどの記事は、料理本のレシピのように書かれており、特定の問題を Yii を使って解決する方法を示しています。
これらの記事の品質は公式ガイドほどには良くないかもしれませんが、
より広範なトピックをカバーしていることと、たいていは即座に使えるソリューションを提供してくれることにおいて有用なものです。
-
- [書籍](http://www.yiiframework.com/doc/)
* [エクステンション](http://www.yiiframework.com/extensions/):
Yii は、ユーザによって作られた数千におよぶエクステンションのライブラリを誇りとしています。
エクステンションはあなたのアプリケーションに簡単に組み込むことが出来、そうすることでアプリケーションの開発作業をより一層速くて簡単なものにします。

10
docs/guide-ja/start-workflow.md

@ -69,7 +69,7 @@ Yii は [モデル・ビュー・コントローラ (MVC)](http://wikipedia.org/
各アプリケーションは一つのエントリスクリプト `web/index.php` を持ちます。これはアプリケーション中で唯一ウェブからアクセス可能な PHP スクリプトです。
エントリスクリプトは入力されたリクエストを受け取って、[アプリケーション](structure-applications.md) のインスタンスを作成します。
[アプリケーション](structure-applications.md) は [コンポーネント](concept-components.md) の助力を得てリクエストを解決し、リクエストを MVC 要素に対して送出します。
[アプリケーション](structure-applications.md) は [コンポーネント](concept-components.md) の助力を得てリクエストを解決し、リクエストを MVC に送付します。
[ウィジェット](structure-widgets.md) は、複雑で動的なユーザインタフェイス要素を構築するために、[ビュー](structure-views.md) の中で使われます。
@ -78,7 +78,7 @@ Yii は [モデル・ビュー・コントローラ (MVC)](http://wikipedia.org/
次の図は、アプリケーションがどのようにリクエストを処理するかを示すものです。
![リクエストのライフサイクル](images/application-lifecycle.png)
![リクエストのライフサイクル](images/request-lifecycle.png)
1. ユーザが [エントリスクリプト](structure-entry-scripts.md) `web/index.php` に対してリクエストを出します。
2. エントリスクリプトはアプリケーションの [コンフィギュレーション](concept-configurations.md) を読み出して、
@ -90,7 +90,7 @@ Yii は [モデル・ビュー・コントローラ (MVC)](http://wikipedia.org/
6. 一つでもフィルタが失敗したときは、アクションはキャンセルされます。
7. すべてのフィルタを通ったとき、アクションが実行されます。
8. アクションはデータモデルを、おそらくはデータベースから、読み出します。
9. アクションはデータモデルをビューに提供して、ビューを表示します。
10. 表示された結果が [レスポンス](runtime-responses.md) アプリケーションコンポーネントに返されます。
11. レスポンスコンポーネントが表示された結果をユーザのブラウザに送信します。
9. アクションはデータモデルをビューに提供して、ビューをレンダリングします。
10. レンダリング結果が [レスポンス](runtime-responses.md) アプリケーションコンポーネントに返されます。
11. レスポンスコンポーネントがレンダリング結果をユーザのブラウザに送信します。

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

@ -0,0 +1,119 @@
アプリケーションコンポーネント
==============================
アプリケーションは [サービスロケータ](concept-service-locator.md) です。
アプリケーションは、リクエストを処理するためのいろいろなサービスを提供する一連のオブジェクト、いわゆる *アプリケーションコンポーネント* をホストします。
例えば、`urlManager` がウェブリクエストを適切なコントローラにルーティングする役割を負い、
`db` コンポーネントが DB 関連のサービスを提供する、等々です。
全てのアプリケーションコンポーネントは、それぞれ、同一のアプリケーション内で他のアプリケーションコンポーネントから区別できるように、ユニークな ID を持ちます。
アプリケーションコンポーネントには、次の式によってアクセス出来ます:
```php
\Yii::$app->componentID
```
例えば、`\Yii::$app->db` を使って、アプリケーションに登録された [[yii\db\Connection|DB 接続]] を取得することが出来ます。
また、`\Yii::$app->cache` を使って、[[yii\caching\Cache|プライマリキャッシュ]] を取得できます。
アプリケーションコンポーネントは、上記の式を使ってアクセスされた最初の時に作成されます。
二度目以降のアクセスでは、同じコンポーネントのインスタンスが返されます。
どのようなオブジェクトでも、アプリケーションコンポーネントとすることが可能です。
[アプリケーションのコンフィギュレーション](structure-applications.md#application-configurations) の中で [[yii\base\Application::components]] プロパティを構成することによって、アプリケーションコンポーネントを登録することが出来ます。
例えば、
```php
[
'components' => [
// クラス名を使って "cache" コンポーネントを登録
'cache' => 'yii\caching\ApcCache',
// コンフィギュレーション配列を使って "db" コンポーネントを登録
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=demo',
'username' => 'root',
'password' => '',
],
// 無名関数を使って "search" コンポーネントを登録
'search' => function () {
return new app\components\SolrService;
},
],
]
```
> Info|情報: 必要なだけ多くのアプリケーションコンポーネントを登録することが出来ますが、慎重にしなければなりません。
アプリケーションコンポーネントはグローバル変数のようなものです。あまり多くのアプリケーションコンポーネントを使うと
コードのテストと保守が困難になるおそれがあります。
多くの場合、必要なときにローカルなコンポーネントを作成して使用するだけで十分です。
## コンポーネントをブートストラップに含める<a name="bootstrapping-components"></a>
上述のように、アプリケーションコンポーネントは最初にアクセスされた時に初めてインスタンスが作成されます。
リクエストの間に全くアクセスされなかった時は、インスタンスは作成されません。けれども、場合によっては、
明示的にアクセスされないときでも、リクエストごとにアプリケーションコンポーネントのインスタンスを作成する必要がある
ことがあります。そうするためには、アプリケーションの [[yii\base\Application::bootstrap|bootstrap]] プロパティのリストに
そういうコンポーネントの ID を挙げることが出来ます。
例えば、次のアプリケーションコンフィギュレーションは、`log` コンポーネントが常にロードされることを保証するものです:
```php
[
'bootstrap' => [
'log',
],
'components' => [
'log' => [
// "log" コンポーネントのコンフィギュレーション
],
],
]
```
## コアアプリケーションコンポーネント<a name="core-application-components"></a>
Yii は固定の ID とデフォルトのコンフィギュレーションを持つ一連の *コア* アプリケーションコンポーネントを定義しています。
例えば、[[yii\web\Application::request|request]] コンポーネントは、ユーザリクエストに関する情報を収集し、
それを [ルート](runtime-routing.md) として解決します。
[[yii\base\Application::db|db]] コンポーネントは、それを通じてデータベースクエリを実行できるデータベース接続を表現します。
Yii のアプリケーションがユーザリクエストを処理することが出来るのは、まさにこれらのコアアプリケーションコンポーネントの助力によります。
下記が事前に定義されたコアアプリケーションコンポーネントです。
通常のアプリケーションコンポーネントに対するのと同様に、これらを構成し、カスタマイズすることが出来ます。
コアアプリケーションコンポーネントを構成するときは、クラスを指定しなければ、デフォルトのクラスが使用されます。
* [[yii\web\AssetManager|assetManager]]: アセットバンドルとアセットの発行を管理します。
更なる詳細は [アセットを管理する](structure-assets.md) の節を参照してください。
* [[yii\db\Connection|db]]: データベース接続を表します。これを通じて、DB クエリを実行することが出来ます。
このコンポーネントを構成するときは、コンポーネントのクラスはもちろん、
[[yii\db\Connection::dsn]] のような必須のコンポーネントプロパティを指定しなければならないことに注意してください。
更なる詳細は [データアクセスオブジェクト (DAO)](db-dao.md) の節を参照してください。
* [[yii\base\Application::errorHandler|errorHandler]]: PHP のエラーと例外を処理します。
更なる詳細は [エラー処理](runtime-handling-errors.md) の節を参照してください。
* [[yii\i18n\Formatter|formatter]]: エンドユーザに表示されるデータに書式を設定します。
例えば、数字が3桁ごとの区切りを使って表示されたり、日付が長い書式で表示されたりします。
更なる詳細は [データの書式設定](output-formatter.md) の節を参照してください。
* [[yii\i18n\I18N|i18n]]: メッセージの翻訳と書式設定をサポートします。
更なる詳細は [国際化](tutorial-i18n.md) の節を参照してください。
* [[yii\log\Dispatcher|log]]: ログの対象を管理します。
更なる詳細は [ログ](runtime-logging.md) の節を参照してください。
* [[yii\swiftmailer\Mailer|mail]]: メールの作成と送信をサポートします。
更なる詳細は [メール](tutorial-mailing.md) の節を参照してください。
* [[yii\base\Application::response|response]]: エンドユーザに送信されるレスポンスを表現します。
更なる詳細は [レスポンス](runtime-responses.md) の節を参照してください。
* [[yii\base\Application::request|request]]: エンドユーザから受信したリクエストを表現します。
更なる詳細は [リクエスト](runtime-requests.md) の節を参照してください。
* [[yii\web\Session|session]]: セッション情報を表現します。
このコンポーネントは、[[yii\web\Application|ウェブアプリケーション]] においてのみ利用できます。.
更なる詳細は [セッションとクッキー](runtime-sessions-cookies.md) の節を参照してください。
* [[yii\web\UrlManager|urlManager]]: URL の解析と生成をサポートします。
更なる詳細は [URL の解析と生成](runtime-url-handling.md) の節を参照してください。
* [[yii\web\User|user]]: ユーザの認証情報を表現します。
このコンポーネントは、[[yii\web\Application|ウェブアプリケーション]] においてのみ利用できます。.
更なる詳細は [認証](security-authentication.md) の節を参照してください。
* [[yii\web\View|view]]: ビューのレンダリングをサポートします。
更なる詳細は [ビュー](structure-views.md) の節を参照してください。

52
docs/guide-ja/structure-applications.md

@ -215,7 +215,7 @@ if (YII_ENV_DEV) {
#### [[yii\base\Application::controllerMap|controllerMap]] <a name="controllerMap"></a>
このプロパティは、コントローラ ID を任意のコントローラクラスに割り付けることを可能にするものです。
既定では、Yii は [規約](#controllerNamespace) に基いてコントローラ ID をコントローラクラスに割り付けます
既定では、Yii は [規約](#controllerNamespace) に基いてコントローラ ID をコントローラクラスに割り付けます
(例えば、`post` という ID は `app\controllers\PostController` に割り付けられます)。
このプロパティを構成することによって、特定のコントローラに対する規約を破ることが出来ます。
下記の例では、`account` は `app\controllers\UserController` に割り付けられ、
@ -426,7 +426,7 @@ $width = \Yii::$app->params['thumbnail.size'][0];
#### [[yii\base\Application::layout|layout]] <a name="layout"></a>
このプロパティは、[ビュー](structure-views.md) を描画するときに使われるべきデフォルトのレイアウトを規定します。
このプロパティは、[ビュー](structure-views.md) をレンダリングするときに使われるべきデフォルトのレイアウトを規定します。
デフォルト値は `'main'` であり、[レイアウトパス](#layoutPath) の下にある `main.php` というファイルが使われるべき事を意味します。
[レイアウトパス](#layoutPath) と [ビューパス](#viewPath) の両方がデフォルト値を取る場合、
デフォルトのレイアウトファイルは `@app/views/layouts/main.php` というパスエイリアスとして表すことが出来ます。
@ -470,8 +470,6 @@ Yii フレームワークを含めて、あなたのアプリケーションに
このプロパティはディレクトリまたはパス [エイリアス](concept-aliases.md) として構成することが出来ます。
このプロパティを修正するときは、必ず、Composer の構成もそれに合せて調整してください。
You may configure this property as a directory or a path [alias](concept-aliases.md). When you modify
this property, make sure you also adjust the Composer configuration accordingly.
このパスに簡単にアクセスできるように、Yii は `@vendor` というパスエイリアスを事前に定義しています。
@ -484,10 +482,8 @@ Yii リリースに含まれているコアコマンドを有効にすべきか
## アプリケーションのイベント<a name="application-events"></a>
アプリケーションはリクエストを処理するライフサイクルの中でいくつかのイベントを発生させます。
これらのイベントに対して、下記のようにして、アプリケーションのコンフィギュレーションの中でイベントハンドラを付けることが出来ます。
An application triggers several events during the lifecycle of handling an request. You may attach event
handlers to these events in application configurations like the following,
アプリケーションはリクエストを処理するライフサイクルの中でいくつかのイベントをトリガします。
これらのイベントに対して、下記のようにして、アプリケーションのコンフィギュレーションの中でイベントハンドラを取り付けることが出来ます。
```php
[
@ -499,7 +495,7 @@ handlers to these events in application configurations like the following,
`on eventName` という構文の使い方については、[コンフィギュレーション](concept-configurations.md#configuration-format) の節で説明されています。
別の方法として、アプリケーションのインスタンスが生成された後、[ブートストラップの過程](runtime-bootstrapping.md) の中でイベントハンドラを付けることも出来ます。
別の方法として、アプリケーションのインスタンスが生成された後、[ブートストラップの過程](runtime-bootstrapping.md) の中でイベントハンドラを取り付けることも出来ます。
例えば、
```php
@ -510,28 +506,28 @@ handlers to these events in application configurations like the following,
### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] <a name="beforeRequest"></a>
このイベントは、アプリケーションがリクエストを処理する *前*発生します。
このイベントは、アプリケーションがリクエストを処理する *前*トリガされます。
実際のイベント名は `beforeRequest` です。
このイベントが発生するときには、アプリケーションのインスタンスは既に構成されて初期化されています。
ですから、イベントメカニズムを使って、リクエスト処理のプロセスに横槍を入れるカスタムコードを挿入するのには、ちょうど良い場所です。
例えば、このイベントハンドラの中で、何らかのパラメータに基いて [[yii\base\Application::language]] プロパティを動的にセットすることが出来ます。
このイベントがトリガされるときには、アプリケーションのインスタンスは既に構成されて初期化されています。
ですから、イベントメカニズムを使って、リクエスト処理のプロセスに干渉するカスタムコードを挿入するのには、ちょうど良い場所です。
例えば、このイベントハンドラの中で、何らかのパラメータに基いて [[yii\base\Application::language]] プロパティを動的にセットすることが出来ます。
### [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]] <a name="afterRequest"></a>
このイベントは、アプリケーションがリクエストの処理を完了した *後*、レスポンスを送信する *前*発生します。
このイベントは、アプリケーションがリクエストの処理を完了した *後*、レスポンスを送信する *前*トリガされます。
実際のイベント名は `afterRequest` です。
このイベントが発生するときにはリクエストの処理は完了していますので、この機をとらえて、リクエストに対する何らかの後処理をしたり、レスポンスをカスタマイズしたりすることが出来ます。
このイベントがトリガされるときにはリクエストの処理は完了していますので、この機をとらえて、リクエストに対する何らかの後処理をしたり、レスポンスをカスタマイズしたりすることが出来ます。
[[yii\web\Response|response]] コンポーネントも、エンドユーザにレスポンスのコンテンツを送出する間にいくつかのイベントを発生させることに注意してください。
それらのイベントは、このイベントの *後*発生します。
[[yii\web\Response|response]] コンポーネントも、エンドユーザにレスポンスのコンテンツを送出する間にいくつかのイベントをトリガすることに注意してください。
それらのイベントは、このイベントの *後*トリガされます。
### [[yii\base\Application::EVENT_BEFORE_ACTION|EVENT_BEFORE_ACTION]] <a name="beforeAction"></a>
このイベントは、[コントローラアクション](structure-controllers.md) を走らせる *前* に毎回発生します。
このイベントは、[コントローラアクション](structure-controllers.md) を走らせる *前* に毎回トリガされます。
実際のイベント名は `beforeAction` です。
イベントのパラメータは [[yii\base\ActionEvent]] のインスタンスです。
@ -550,14 +546,14 @@ handlers to these events in application configurations like the following,
```
同じ `beforeAction` イベントが、[モジュール](structure-modules.md) と [コントローラ](structure-controllers.md)
からも発生することに注意してください。
アプリケーションオブジェクトが最初にこのイベントを発生させ、次に (もし有れば) モジュールが、そして最後にコントローラがこのイベントを発生させます。
イベントハンドラが [[yii\base\ActionEvent::isValid]] を `false` にセットすると、後続のイベントは発生しません。
からもトリガされることに注意してください。
アプリケーションオブジェクトが最初にこのイベントをトリガし、次に (もし有れば) モジュールが、そして最後にコントローラがこのイベントをトリガします。
イベントハンドラが [[yii\base\ActionEvent::isValid]] を `false` にセットすると、後続のイベントはトリガされません。
### [[yii\base\Application::EVENT_AFTER_ACTION|EVENT_AFTER_ACTION]] <a name="afterAction"></a>
このイベントは、[コントローラアクション](structure-controllers.md) が走った *後* に毎回発生します。
このイベントは、[コントローラアクション](structure-controllers.md) が走った *後* に毎回トリガされます。
実際のイベント名は `afterAction` です。
イベントのパラメータは [[yii\base\ActionEvent]] のインスタンスです。
@ -576,13 +572,15 @@ handlers to these events in application configurations like the following,
```
同じ `afterAction` イベントが、[モジュール](structure-modules.md) と [コントローラ](structure-controllers.md)
からも発生することに注意してください。
これらのオブジェクトは、`beforeAction` の場合とは逆の順でイベントを発生させます。
すなわち、コントローラオブジェクトが最初にこのイベントを発生させ、次に (もし有れば) モジュールが、そして最後にアプリケーションがこのイベントを発生させます。
からもトリガされることに注意してください。
これらのオブジェクトは、`beforeAction` の場合とは逆の順でイベントをトリガします。
すなわち、コントローラオブジェクトが最初にこのイベントをトリガし、次に (もし有れば) モジュールが、そして最後にアプリケーションがこのイベントをトリガします。
## アプリケーションのライフサイクル<a name="application-lifecycle"></a>
![アプリケーションのライフサイクル](images/application-lifecycle.png)
[エントリスクリプト](structure-entry-scripts.md) が実行されて、リクエストが処理されるとき、
アプリケーションは次のようなライフサイクルを経ます:
@ -595,9 +593,9 @@ handlers to these events in application configurations like the following,
* [[yii\base\Application::init()|init()]] が呼ばれ、そこから更に、ブートストラップコンポーネントを
走らせるために、[[yii\base\Application::bootstrap()|bootstrap()]] が呼ばれる。
3. エントリスクリプトが [[yii\base\Application::run()]] を呼んで、アプリケーションを走らせる:
* [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] イベントを発生させる。
* [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] イベントをトリガする。
* リクエストを処理する: リクエストを [ルート](runtime-routing.md) とそれに結び付くパラメータとして解決する;
ルートによって指定されたモジュール、コントローラ、および、アクションを作成する; そしてアクションを走らせる。
* [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]] イベントを発生させる。
* [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]] イベントをトリガする。
* エンドユーザにレスポンスを送信する。
4. エントリスクリプトがアプリケーションから終了ステータスを受け取り、リクエストの処理を完了する。

453
docs/guide-ja/structure-controllers.md

@ -0,0 +1,453 @@
コントローラ
============
コントローラは [MVC](http://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャの一部を成すものです。
これは [[yii\base\Controller]] を拡張したクラスのオブジェクトであり、リクエストの処理とレスポンスの生成について責任を負うものです。
具体的には、[アプリケーション](structure-applications.md) から制御を引き継いだ後、コントローラは入ってきたリクエストのデータを分析し、
それを [モデル](structure-models.md) に引き渡して、モデルが生成した結果を [ビュー](structure-views.md) に投入し、
最終的に外に出て行くレスポンスを生成します。
## アクション<a name="actions"></a>
コントローラは *アクション* から構成されます。
アクションは、エンドユーザがアドレスを指定して実行をリクエストできる最も基本的な構成単位です。
コントローラは一つまたは複数のアクションを持ち得ます。
次の例は、`view` と `create` という二つのアクションを持つ `post` コントローラを示すものです:
```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,
]);
}
}
}
```
`view` アクション (`actionView()` メソッドで定義されます) において、
コードは最初に、リクエストされたモデルの ID に従って [モデル](structure-models.md) を読み出します。
モデルの読み出しが成功したときは、`view` という名前の [ビュー](structure-views.md) を使ってモデルを表示します。
失敗したときは例外を投げます。
`create` アクション (`actionCreate()` メソッドで定義されます) においても、コードは似たようなものです。
最初にリクエストデータを使って [モデル](structure-models.md) にデータを投入して、モデルを保存することを試みます。
両方が成功したときは、新しく作成されたモデルの ID を使って `view` アクションにブラウザをリダイレクトします。
どちらかが失敗したときは、ユーザが必要なデータを入力できるようにするための `create` ビューを表示します。
## ルート<a name="routes"></a>
エンドユーザは、いわゆる *ルート* によって、アクションのアドレスを指定します。
ルートは、次の部分からなる文字列です。
* モジュール ID: この部分は、コントローラがアプリケーションではなく [モジュール](structure-modules.md) に属する場合にのみ存在します;
* コントローラ ID: 同じアプリケーション (または、コントローラがモジュールに属する場合は、同じモジュール)
に属する全てのコントローラの中から、特定のコントローラを指定するユニークな文字列;
* アクション ID: 同じコントローラに属する全てのアクションの中から、特定のアクションを指定するユニークな文字列。
ルートは次の形式を取ります:
```
ControllerID/ActionID
```
または、コントローラがモジュールに属する場合は、次の形式を取ります:
```php
ModuleID/ControllerID/ActionID
```
ですから、ユーザが `http://hostname/index.php?r=site/index` という URL でリクエストをした場合は、`site` コントローラの中の `index` アクションが実行されます。
どのようにしてルートがアクションとして解決されるかについて、更なる詳細は [ルーティングと URL 生成](runtime-routing.md) の節を参照してください。
## コントローラを作成する<a name="creating-controllers"></a>
[[yii\web\Application|ウェブアプリケーション]] では、コントローラは [[yii\web\Controller]] またはその子クラスから派生させるべきです。
同様に、[[yii\console\Application|コンソールアプリケーション]] では、コントローラは [[yii\console\Controller]] またはその子クラスから派生させるべきです。
次のコードは `site` コントローラを定義するものです:
```php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
}
```
### コントローラの ID<a name="controller-ids"></a>
通常、コントローラは特定の型のリソースに関するリクエストを処理するように設計されます。
この理由により、たいていはコントローラが処理するリソースの型を示す名詞をコントローラの ID として使います。
例えば、記事データを処理するコントローラの ID としては、`article` を使うことが出来ます。
既定では、コントローラの ID は、以下の文字のみを含むべきものです: すなわち、小文字の英字、数字、アンダースコア、ダッシュ、
および、フォワードスラッシュ。
例えば、`article` と `post-comment` はともに有効なコントローラの ID ですが、`article?`、`PostComment`、`admin\post` は有効ではありません。
コントローラの ID は、サブディレクトリの接頭辞を含んでも構いません。例えば、`admin/article` は、
[[yii\base\Application::controllerNamespace|コントローラ名前空間]] の下の `admin` サブディレクトリにある `article` コントローラを表します。
サブディレクトリの接頭辞として有効な文字は以下を含みます: 小文字または大文字の英字、数字、アンダースコア、そして、
フォワードスラッシュ。フォワードスラッシュは、複数レベルのサブディレクトリの区切り文字として使われます (例えば、`panels/admin`)。
### コントローラクラスの命名規則<a name="controller-class-naming"></a>
コントローラクラスの名前は下記の規則に従ってコントローラの ID から導出することが出来ます:
* ダッシュで区切られた各単語の最初の文字を大文字に変える。コントローラ ID がスラッシュを含む場合、
この規則は ID の最後のスラッシュの後ろの部分にのみ適用されることに注意。
* ダッシュを削除し、フォワードスラッシュを全てバックワードスラッシュに置き換える。
* 接尾辞 `Controller` を追加する。
* そして、[[yii\base\Application::controllerNamespace|コントローラ名前空間]] を頭に付ける。
以下は、[[yii\base\Application::controllerNamespace|コントローラ名前空間]] がデフォルト値 `app\controllers` を取っていると
仮定したときの、いくつかの例です:
* `article` から `app\controllers\ArticleController` が導出される;
* `post-comment` から `app\controllers\PostCommentController` が導出される;
* `admin/post-comment` から `app\controllers\admin\PostCommentController` が導出される;
* `adminPanels/post-comment` から `app\controllers\adminPanels\PostCommentController` が導出される。
コントローラクラスは [オートロード可能](concept-autoloading.md) でなければなりません。この理由により、
上記の例の `aritcle` コントローラクラスは [エイリアス](concept-aliases.md) が `@app/controllers/ArticleController.php` である
ファイルに保存されるべきものとなります。一方、`admin/post2-comment` コントローラは `@app/controllers/admin/Post2CommentController.php`
というエイリアスのファイルに保存されるべきものとなります。
> Info|情報: 最後の例である `admin/post2-comment` は、どうすれば [[yii\base\Application::controllerNamespace|コントローラ名前空間]] の
サブディレクトリにコントローラを置くことが出来るかを示しています。
この方法は、コントローラをいくつかのカテゴリに分けて組織したい、けれども [モジュール](structure-modules.md) は使いたくない、
という場合に役立ちます。
### コントローラマップ<a name="controller-map"></a>
[[yii\base\Application::controllerMap|コントローラマップ]] を構成すると、上で述べたコントローラの ID とクラス名の制約を乗り越えることが出来ます。
これは、主として、クラス名に対する制御が及ばないサードパーティのコントローラを使おうとする場合に有用です。
[[yii\base\Application::controllerMap|コントローラマップ]] は [アプリケーションのコンフィギュレーション](structure-applications.md#application-configurations) の中で、次のように構成することが出来ます:
```php
[
'controllerMap' => [
// クラス名を使って "account" コントローラを宣言する
'account' => 'app\controllers\UserController',
// コンフィギュレーション配列を使って "article" コントローラを宣言する
'article' => [
'class' => 'app\controllers\PostController',
'enableCsrfValidation' => false,
],
],
]
```
### デフォルトコントローラ<a name="default-controller"></a>
全てのアプリケーションは、それぞれ、[[yii\base\Application::defaultRoute]] プロパティを通じて規定されるデフォルトコントローラを持ちます。
リクエストが [ルート](#ids-routes) を指定しない場合、このプロパティによって指定されたルートが使われます。
[[yii\web\Application|ウェブアプリケーション]] では、この値は `'site'` であり、一方、[[yii\console\Application|コンソールアプリケーション]] では、`help` です。
従って、URL が `http://hostname/index.php` である場合は、`site` コントローラがリクエストを処理することになります。
次のように [アプリケーションのコンフィギュレーション](structure-applications.md#application-configurations) を構成して、デフォルトコントローラを変更することが出来ます:
```php
[
'defaultRoute' => 'main',
]
```
## アクションを作成する<a name="creating-actions"></a>
アクションの作成は、コントローラクラスの中にいわゆる *アクションメソッド* を定義するだけの簡単なことです。
アクションメソッドとは、`action` という語で始まる名前を持つ *public* メソッドのことです。
アクションメソッドの返り値がエンドユーザに送信されるレスポンスデータを表します。
次のコードは、`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';
}
}
```
### アクション ID<a name="action-ids"></a>
アクションは、たいてい、あるリソースについて特定の操作を実行するように設計されます。この理由により、
アクション ID は、通常、`view`、`update` などのような動詞になります。
既定では、アクション ID は次の文字のみを含むべきものです: すなわち、小文字の英字、数字、アンダースコア、そして、ダッシュ。
アクション ID の中のダッシュは単語を分けるために使われます。例えば、
`view`、`update2`、`comment-post` は全て有効なアクション ID ですが、`view?`、`Update` は有効ではありません。
アクションは二つの方法で作成することが出来ます: すなわち、インラインアクションとスタンドアロンアクションです。
インラインアクションはコントローラクラスのメソッドとして定義されるものであり、一方、スタンドアロンアクションは
[[yii\base\Action]] またはその子クラスから派生させたクラスです。
インラインアクションは作成するのにより少ない労力を要し、アクションを再利用する意図がない場合によく推奨されます。
もう一方で、スタンドアロンアクションは、主として、さまざまなコントローラの中で使われることや、
[エクステンション](structure-extensions.md) として再配布されることを意図して作成されます。
### インラインアクション<a name="inline-actions"></a>
インラインアクションは、たった今説明したように、アクションメソッドとして定義されるアクションを指します。
アクションメソッドの名前は、次の基準に従って、アクション ID から導出されます:
* アクション ID に含まれる各単語の最初の文字を大文字に変換する;
* ダッシュを削除する;
* 前置辞 `action` を前に付ける。
例えば、`index` は `actionIndex` となり、`hello-world` は `actionHelloWorld` となります。
> Note|注意: アクションメソッドの名前は、*大文字と小文字を区別* します。`ActionIndex` という名前のメソッドがあっても、
それはアクションメソッドとは見なされず、結果として、`index` アクションに対するリクエストは例外に帰結します。
アクションメソッドが public でなければならない事にも注意してください。private や protected なメソッドが
インラインアクションを定義することはありません。
アクションは、作成するのにほとんど労力を要さないため、たいていの場合、インラインアクションとして定義されます。
しかしながら、同じアクションを別の場所で再利用する計画があったり、また、アクションを再配布したいと思ったりする場合は、
*スタンドアロンアクション* として定義することを考慮すべきです。
### スタンドアロンアクション<a name="standalone-actions"></a>
スタンドアロンアクションは、[[yii\base\Action]] またはその子クラスを拡張したクラスとして定義されるものです。
例えば、Yii のリリースに [[yii\web\ViewAction]] と [[yii\web\ErrorAction]] が含まれていますが、これらは両方とも
スタンドアロンアクションです。
スタンドアロンアクションを使用するためには、下記のように、コントローラの [[yii\base\Controller::actions()]] メソッドを
オーバーライドして、スタンドアロンアクションを *アクションマップ* の中で宣言します:
```php
public function actions()
{
return [
// クラス名を使って "error" アクションを宣言する
'error' => 'yii\web\ErrorAction',
// コンフィギュレーション配列を使って "view" アクションを宣言する
'view' => [
'class' => 'yii\web\ViewAction',
'viewPrefix' => '',
],
];
}
```
見ると分かるように、`actions()` メソッドは、キーがアクション ID であり、値が対応するアクションのクラス名または
[コンフィギュレーション](concept-configurations.md) である配列を返すべきものです。
インラインアクションと違って、スタンドアロンアクションのアクション ID は、`actions()` メソッドにおいて宣言される
限りにおいて、任意の文字を含むことが出来ます。
スタンドアロンアクションクラスを作成するためには、[[yii\base\Action]] またはその子クラスを拡張して、
`run()` という名前の public メソッドを実装しなければなりません。
`run()` メソッドの役割はアクションメソッドのそれと似たようなものです。例えば、
```php
<?php
namespace app\components;
use yii\base\Action;
class HelloWorldAction extends Action
{
public function run()
{
return "Hello World";
}
}
```
### アクションの結果<a name="action-results"></a>
アクションメソッド、または、スタンドアロンアクションの `run()` メソッドの返り値は、重要な意味を持ちます。
それは、対応するアクションの結果を表すものです。
返り値は、エンドユーザにレスポンスとして送信される [レスポンス](runtime-responses.md) オブジェクトとすることが出来ます。
* [[yii\web\Application|ウェブアプリケーション]] では、返り値を、[[yii\web\Response::data]] に割り当てられ、
さらにレスポンスの本文を表す文字列へと変換される任意のデータとすることも出来ます。
* [[yii\console\Application|コンソールアプリケーション]] では、返り値をコマンド実行の [[yii\console\Response::exitStatus|終了ステータス]]
を示す整数とすることも出来ます。
これまでに示した例においては、アクションの結果はすべて文字列であり、エンドユーザに送信されるレスポンスの本文として扱われるものでした。
次の例では、アクションがレスポンスオブジェクトを返すことによって、ユーザのブラウザを新しい URL にリダイレクトすることが出来る様子が示されています
([[yii\web\Controller::redirect()|redirect()]] メソッドの返り値はレスポンスオブジェクトです):
```php
public function actionForward()
{
// ユーザのブラウザを http://example.com にリダイレクトする
return $this->redirect('http://example.com');
}
```
### アクションパラメータ<a name="action-parameters"></a>
インラインアクションのアクションメソッドと、スタンドアロンアクションの `run()` メソッドは、
*アクションパラメータ* と呼ばれる引数を取ることが出来ます。
パラメータの値はリクエストから取得されます。
[[yii\web\Application|ウェブアプリケーション]] では、各アクションパラメータの値は `$_GET` からパラメータ名をキーとして読み出されます。
[[yii\console\Application|コンソールアプリケーション]] では、アクションパラメータはコマンドライン引数に対応します。
次の例では、`view` アクション (インラインアクションです) は、二つのパラメータを宣言しています: すなわち、`$id` と `$version` です。
```php
namespace app\controllers;
use yii\web\Controller;
class PostController extends Controller
{
public function actionView($id, $version = null)
{
// ...
}
}
```
アクションパラメータは、次のように、さまざまなリクエストに応じて値を投入されます:
* `http://hostname/index.php?r=post/view&id=123`: `$id` パラメータには `'123'` という値が入れられますが、
`version` というクエリパラメータが無いので、`$version` は null のままになります。
* `http://hostname/index.php?r=post/view&id=123&version=2`: `$id` および `$version` パラメータに、それぞれ、
`'123'``'2'` が入ります。
* `http://hostname/index.php?r=post/view`: 必須の `$id` パラメータがリクエストで提供されていないため、
[[yii\web\BadRequestHttpException]] 例外が投げられます。
* `http://hostname/index.php?r=post/view&id[]=123`: `$id` パラメータが予期しない配列値 `['123']` を受け取ろうとするため、
[[yii\web\BadRequestHttpException]] 例外が投げられます。
アクションパラメータに配列値を受け取らせたい場合は、以下のように、パラメータに `array` の型ヒントを付けなければなりません:
```php
public function actionView(array $id, $version = null)
{
// ...
}
```
このようにすると、リクエストが `http://hostname/index.php?r=post/view&id[]=123` である場合、`$id` パラメータは
`['123']` という値を受け取るようになります。
リクエストが `http://hostname/index.php?r=post/view&id=123` である場合も、スカラ値 `'123'` が自動的に配列に変換されるため、
`$id` パラメータは引き続き同じ配列値を受け取ります。
上記の例は主としてウェブアプリケーションでのアクションパラメータの動作を示すものです。
コンソールアプリケーションについては、[コンソールコマンド](tutorial-console.md) の節で更なる詳細を参照してください。
### デフォルトアクション<a name="default-action"></a>
すべてのコントローラは、それぞれ、[[yii\base\Controller::defaultAction]] によって規定されるデフォルトアクションを持ちます。
[ルート](#ids-routes) がコントローラ ID のみを含む場合は、指定されたコントローラのデフォルトアクションがリクエストされたことを意味します。
既定では、デフォルトアクションは `index` と設定されます。
このデフォルト値を変更したい場合は、以下のように、コントローラクラスでこのプロパティをオーバーライドするだけです:
```php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public $defaultAction = 'home';
public function actionHome()
{
return $this->render('home');
}
}
```
## コントローラのライフサイクル<a name="controller-lifecycle"></a>
リクエストを処理するときに、[アプリケーション](structure-applications.md) はリクエストされた [ルート](#routes)に基いてコントローラを作成します。
そして、次に、コントローラはリクエストに応じるために以下のライフサイクルを経過します:
1. コントローラが作成され構成された後、[[yii\base\Controller::init()]] メソッドが呼ばれる。
2. コントローラは、リクエストされたアクション ID に基いて、アクションオブジェクトを作成する:
* アクション ID が指定されていないときは、[[yii\base\Controller::defaultAction|デフォルトアクション ID]] が使われる。
* アクション ID が [[yii\base\Controller::actions()|アクションマップ]] の中に見つかった場合は、
スタンドアロンアクションが作成される。
* アクション ID に合致するアクションメソッドが見つかった場合は、インラインアクションが作成される。
* アクションが見つからないと、[[yii\base\InvalidRouteException]] 例外が投げられる。
3. コントローラは、アプリケーション、(コントローラがモジュールに属する場合は) モジュール、そしてコントローラの
`beforeAction()` メソッドをこの順で呼び出す:
* どれか一つの呼び出しが false を返した場合は、残りのまだ呼ばれていない `beforeAction()` はスキップされ、
アクションの実行はキャンセルされる。
* 既定では、それぞれの `beforeAction()` メソッドは、ハンドラを取り付けることが出来る `beforeAction` イベントをトリガする。
4. コントローラがアクションを走らせる:
* リクエストデータが解析されて、アクションパラメータにデータが投入される。
5. コントローラは、コントローラ、(コントローラがモジュールに属する場合は) モジュール、そしてアプリケーションの
`afterAction()` メソッドをこの順で呼び出す。
* 既定では、それぞれの `afterAction()` メソッドは、ハンドラを取り付けることが出来る `afterAction` イベントをトリガする。
6. アプリケーションはアクションの結果を受け取り、それを [レスポンス](runtime-responses.md) に割り当てる。
## 最善の慣行<a name="best-practices"></a>
良く設計されたアプリケーションでは、コントローラはたいてい非常に軽いものになり、
それぞれのアクションは数行のコードしか含まないものになります。
あなたのコントローラが少々複雑になっている場合、そのことは、通常、コントローラをリファクタして、
コードの一部を他のクラスに移動すべきことを示すものです。
要約すると、コントローラは、
* [リクエスト](runtime-requests.md) データにアクセスすることが出来ます;
* リクエストデータを使って [モデル](structure-models.md) や他のサービスコンポーネントのメソッドを呼ぶことが出来ます;
* [ビュー](structure-views.md) を使ってレスポンスを構成することが出来ます;
* リクエストされたデータの処理をするべきではありません - データは [モデル](structure-models.md) において処理されるべきです;
* HTML を埋め込むなどの表示に関わるコードは避けるべきです - 表示は [ビュー](structure-views.md) で行う方が良いです。

401
docs/guide-ja/structure-filters.md

@ -0,0 +1,401 @@
フィルタ
========
フィルタは、[コントローラアクション](structure-controllers.md#actions) の前 および/または 後に走るオブジェクトです。
例えば、アクセスコントロールフィルタはアクションの前に走って、アクションが特定のエンドユーザだけにアクセスを許可するものであることを保証します。
また、コンテンツ圧縮フィルタはアクションの後に走って、レスポンスのコンテンツをエンドユーザに送出する前に圧縮します。
フィルタは、前フィルタ (アクションの *前* に適用されるフィルタのロジック) および/または 後フィルタ (アクションの *後*
に適用されるフィルタ) から構成されます。
## フィルタを使用する <a name="using-filters"></a>
フィルタは、本質的には特別な種類の [ビヘイビア](concept-behaviors.md) です。したがって、フィルタを使うことは
[ビヘイビアを使う](concept-behaviors.md#attaching-behaviors) ことと同じです。下記のように、
[[yii\base\Controller::behaviors()|behaviors()]] メソッドをオーバーライドすることによって、コントローラの中で
フィルタを宣言することが出来ます:
```php
public function behaviors()
{
return [
[
'class' => 'yii\filters\HttpCache',
'only' => ['index', 'view'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('user')->max('updated_at');
},
],
];
}
```
既定では、コントローラクラスの中で宣言されたフィルタは、そのコントローラの *全て* のアクションに適用されます。
しかし、[[yii\base\ActionFilter::only|only]] プロパティを構成することによって、フィルタがどのアクションに適用されるべきかを
明示的に指定することも出来ます。上記の例では、 `HttpCache` フィルタは、`index` と `view` のアクションに対してのみ適用されています。
また、[[yii\base\ActionFilter::except|except]] プロパティを構成して、いくつかのアクションをフィルタされないように除外することも可能です。
コントローラのほかに、[モジュール](structure-modules.md) または [アプリケーション](structure-applications.md)
でもフィルタを宣言することが出来ます。
そのようにした場合、[[yii\base\ActionFilter::only|only]] と [[yii\base\ActionFilter::except|except]] のプロパティを
上で説明したように構成しない限り、そのフィルタは、モジュールまたはアプリケーションに属する *全て* のコントローラアクションに適用されます。
> Note|注意: モジュールやアプリケーションでフィルタを宣言する場合、[[yii\base\ActionFilter::only|only]] と
[[yii\base\ActionFilter::except|except]] のプロパティでは、アクション ID ではなく、[ルート](structure-controllers.md#routes)
を使うべきです。なぜなら、モジュールやアプリケーションのスコープでは、アクション ID だけでは完全にアクションを指定することが
出来ないからです。
一つのアクションに複数のフィルタが構成されている場合、フィルタは下記で説明されている規則に従って適用されます。
* 前フィルタ
- アプリケーションで宣言されたフィルタを `behaviors()` にリストされた順に適用する。
- モジュールで宣言されたフィルタを `behaviors()` にリストされた順に適用する。
- コントローラで宣言されたフィルタを `behaviors()` にリストされた順に適用する。
- フィルタのどれかがアクションをキャンセルすると、そのフィルタの後のフィルタ (前フィルタと後フィルタの両方) は適用されない。
* 前フィルタを通過したら、アクションを走らせる。
* 後フィルタ
- コントローラで宣言されたフィルタを `behaviors()` にリストされた逆順で適用する。
- モジュールで宣言されたフィルタを `behaviors()` にリストされた逆順で適用する。
- アプリケーションで宣言されたフィルタを `behaviors()` にリストされた逆順で適用する。
## フィルタを作成する <a name="creating-filters"></a>
新しいアクションフィルタを作成するためには、[[yii\base\ActionFilter]] を拡張して、
[[yii\base\ActionFilter::beforeAction()|beforeAction()]] および/または [[yii\base\ActionFilter::afterAction()|afterAction()]]
メソッドをオーバーライドします。前者はアクションが走る前に実行され、後者は走った後に実行されます。
[[yii\base\ActionFilter::beforeAction()|beforeAction()]] の返り値が、アクションが実行されるべきか否かを決定します。
返り値が false である場合、このフィルタの後に続くフィルタはスキップされ、アクションは実行を中止されます。
次の例は、アクションの実行時間をログに記録するフィルタを示すものです:
```php
namespace app\components;
use Yii;
use yii\base\ActionFilter;
class ActionTimeFilter extends ActionFilter
{
private $_startTime;
public function beforeAction($action)
{
$this->_startTime = microtime(true);
return parent::beforeAction($action);
}
public function afterAction($action, $result)
{
$time = microtime(true) - $this->_startTime;
Yii::trace("アクション '{$action->uniqueId}' は $time 秒を消費。");
return parent::afterAction($action, $result);
}
}
```
## コアのフィルタ <a name="core-filters"></a>
Yii はよく使われる一連のフィルタを提供しており、それらは、主として `yii\filters` 名前空間の下にあります。以下では、
それらのフィルタを簡単に紹介します。
### [[yii\filters\AccessControl|AccessControl]] <a name="access-control"></a>
AccessControl は、一組の [[yii\filters\AccessControl::rules|規則]] に基づいて、シンプルなアクセスコントロールを提供するものです。
具体的に言うと、アクションが実行される前に、AccessControl はリストされた規則を調べて、現在のコンテキスト変数 (例えば、ユーザの IP アドレスや、ユーザのログイン状態など) に最初に合致するものを見つけます。
そして、合致した規則によって、リクエストされたアクションの実行を許可するか拒否するかを決定します。
合致する規則がなかった場合は、アクセスは拒否されます。
次の例は、認証されたユーザに対しては `create``update` のアクションへのアクセスを許可し、
その他のすべてのユーザにはこれら二つのアクションに対するアクセスを拒否する仕方を示すものです。
```php
use yii\filters\AccessControl;
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['create', 'update'],
'rules' => [
// 認証されたユーザに許可する
[
'allow' => true,
'roles' => ['@'],
],
// その他は、既定により拒否される
],
],
];
}
```
アクセスコントロール一般について、更なる詳細は [権限](security-authorization.md) の節を参照してください。
### 認証メソッドフィルタ <a name="auth-method-filters"></a>
認証メソッドフィルタは、[HTTP Basic 認証](http://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC)、
[OAuth 2](http://oauth.net/2/) など、様々なメソッドを使ってユーザを認証するために使われるものです。
これらのフィルタクラスはすべて `yii\filters\auth` 名前空間の下にあります。
次の例は、[[yii\filters\auth\HttpBasicAuth]] の使い方を示すもので、HTTP Basic 認証に基づくアクセストークンを使ってユーザを認証しています。
これを動作させるためには、あなたの [[yii\web\User::identityClass|ユーザアイデンティティクラス]] が
[[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]
メソッドを実装していなければならないことに注意してください。
```php
use yii\filters\auth\HttpBasicAuth;
public function behaviors()
{
return [
'basicAuth' => [
'class' => HttpBasicAuth::className(),
],
];
}
```
認証メソッドフィルタは RESTful API を実装するときに使われるのが通例です。詳細については、
RESTful の [認証](rest-authentication.md) の節を参照してください。
### [[yii\filters\ContentNegotiator|ContentNegotiator]] <a name="content-negotiator"></a>
ContentNegotiator は、レスポンス形式のネゴシエーションとアプリケーション言語のネゴシエーションをサポートします。
このフィルタは `GET` パラメータと `Accept` HTTP ヘッダを調べることによって、レスポンス形式 および/または
言語を決定しようとします。
次の例では、ContentNegotiator はレスポンス形式として JSON と XML をサポートし、(合衆国の)英語とドイツ語を
言語としてサポートするように構成されています。
```php
use yii\filters\ContentNegotiator;
use yii\web\Response;
public function behaviors()
{
return [
[
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
],
'languages' => [
'en-US',
'de',
],
],
];
}
```
レスポンス形式と言語は [アプリケーションのライフサイクル](structure-applications.md#application-lifecycle)
のもっと早い段階で決定される必要があることがよくあります。このため、ContentNegotiator はフィルタの他に、
[ブートストラップコンポーネント](structure-applications.md#bootstrap) としても使うことができるように設計されています。
例えば、次のように、ContentNegotiator を [アプリケーションのコンフィギュレーション](structure-applications.md#application-configurations) の中で構成することが出来ます。
```php
use yii\filters\ContentNegotiator;
use yii\web\Response;
[
'bootstrap' => [
[
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
],
'languages' => [
'en-US',
'de',
],
],
],
];
```
> Info|情報: 望ましいコンテントタイプと言語がリクエストからは決定できない場合は、[[formats]] および [[languages]]
に挙げられている最初の形式と言語が使用されます。
### [[yii\filters\HttpCache|HttpCache]] <a name="http-cache"></a>
HttpCache は `Last-Modified` および `Etag` の HTTP ヘッダを利用して、クライアントサイドのキャッシュを実装するものです。
```php
use yii\filters\HttpCache;
public function behaviors()
{
return [
[
'class' => HttpCache::className(),
'only' => ['index'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('user')->max('updated_at');
},
],
];
}
```
HttpCache に関する更なる詳細は [HTTP キャッシュ](caching-http.md) の節を参照してください。
### [[yii\filters\PageCache|PageCache]] <a name="page-cache"></a>
PageCache はサーバサイドにおけるページ全体のキャッシュを実装するものです。次の例では、PageCache が
`index` アクションに適用されて、最大 60 秒間、または、`post` テーブルのエントリ数が変化するまでの間、
ページ全体をキャッシュしています。さらに、このページキャッシュは、選択されたアプリケーションの言語に従って、
違うバージョンのページを保存するようにしています。
```php
use yii\filters\PageCache;
use yii\caching\DbDependency;
public function behaviors()
{
return [
'pageCache' => [
'class' => PageCache::className(),
'only' => ['index'],
'duration' => 60,
'dependency' => [
'class' => DbDependency::className(),
'sql' => 'SELECT COUNT(*) FROM post',
],
'variations' => [
\Yii::$app->language,
]
],
];
}
```
PageCache の使用に関する更なる詳細は [ページキャッシュ](caching-page.md) の節を参照してください。
### [[yii\filters\RateLimiter|RateLimiter]] <a name="rate-limiter"></a>
RateLimiter は [リーキーバケットアルゴリズム](http://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%BC%E3%82%AD%E3%83%BC%E3%83%90%E3%82%B1%E3%83%83%E3%83%88)
に基づいて転送レート制限のアルゴリズムを実装するものです。主として RESTful API を実装するときに使用されます。
このフィルタの使用に関する詳細は [転送レート制限](rest-rate-limiting.md) の節を参照してください。
### [[yii\filters\VerbFilter|VerbFilter]] <a name="verb-filter"></a>
VerbFilter は、HTTP リクエストメソッドがリクエストされたアクションによって許可されているかどうかをチェックするものです。
許可されていない場合は、HTTP 405 例外を投げます。次の例では、VerbFilter が宣言されて、
CRUD アクションに対して許可されるメソッドの典型的なセットを規定しています。
```php
use yii\filters\VerbFilter;
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index' => ['get'],
'view' => ['get'],
'create' => ['get', 'post'],
'update' => ['get', 'put', 'post'],
'delete' => ['post', 'delete'],
],
],
];
}
```
### [[yii\filters\Cors|Cors]] <a name="cors"></a>
クロスオリジンリソース共有 [CORS](https://developer.mozilla.org/ja/docs/HTTP_access_control) とは、
ウェブページにおいて、さまざまなリソース (例えば、フォントや JavaScript など) を、
それを生成するドメイン以外のドメインからリクエストすることを可能にするメカニズムです。
特に言えば、JavaScript の AJAX 呼出しが使用することが出来る XMLHttpRequest メカニズムです。
このような「クロスドメイン」のリクエストは、このメカニズムに拠らなければ、
同一生成元のセキュリティポリシーによって、ウェブブラウザから禁止されるはずのものです。
CORS は、ブラウザとサーバが交信して、クロスドメインのリクエストを許可するか否かを決定する方法を定義するものです。
[[yii\filters\Cors|Cors フィルタ]] は、CORS ヘッダが常に送信されることを保証するために、Authentication / Authorization のフィルタよりも前に定義されなければなりません。
```php
use yii\filters\Cors;
use yii\helpers\ArrayHelper;
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => Cors::className(),
],
], parent::behaviors());
}
```
Cors のフィルタリングは `cors` プロパティを使ってチューニングすることが出来ます。
* `cors['Origin']`: 許可される生成元を定義するのに使われる配列。`['*']` (すべて) または `['http://www.myserver.net'、'http://www.myotherserver.com']` などが設定可能。デフォルトは `['*']`
* `cors['Access-Control-Request-Method']`: 許可されるメソッドの配列。たとえば、`['GET', 'OPTIONS', 'HEAD']`。デフォルトは `['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']`
* `cors['Access-Control-Request-Headers']`: 許可されるヘッダの配列。全てのヘッダを意味する `['*']` または特定のヘッダを示す `['X-Request-With']` が設定可能。デフォルトは `['*']`
* `cors['Access-Control-Allow-Credentials']`: 現在のリクエストをクレデンシャルを使ってすることが出来るかどうかを定義。
`true`、`false` または `null` (設定なし) が設定可能。デフォルトは `null`
* `cors['Access-Control-Max-Age']`: プリフライトリクエストの寿命を定義。デフォルトは `86400`
次の例は、生成元 `http://www.myserver.net` に対する `GET`、`HEAD` および `OPTIONS` のメソッドによる CORS を許可するものです:
```php
use yii\filters\Cors;
use yii\helpers\ArrayHelper;
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => Cors::className(),
'cors' => [
'Origin' => ['http://www.myserver.net'],
'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
],
],
], parent::behaviors());
}
```
デフォルトのパラメータをアクション単位でオーバーライドして CORS ヘッダをチューニングすることも可能です。
例えば、`login` アクションに `Access-Control-Allow-Credentials` を追加することは、次のようにすれば出来ます:
```php
use yii\filters\Cors;
use yii\helpers\ArrayHelper;
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => Cors::className(),
'cors' => [
'Origin' => ['http://www.myserver.net'],
'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
],
'actions' => [
'login' => [
'Access-Control-Allow-Credentials' => true,
]
]
],
], parent::behaviors());
}
```

504
docs/guide-ja/structure-models.md

@ -0,0 +1,504 @@
モデル
======
モデルは [MVC](http://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャの一部を成すものです。
これは、業務のデータ、規則、ロジックを表現するオブジェクトです。
モデルクラスは、[[yii\base\Model]] またはその子クラスを拡張することによって作成することが出来ます。
基底クラス [[yii\base\Model]] は数多くの有用な機能をサポートしています。
* [属性](#attributes): 業務のデータを表現し、通常のオブジェクトプロパティや配列要素のようにアクセス出来る。
* [属性のラベル](#attribute-labels): 属性の表示ラベルを規定する。
* [一括代入](#massive-assignment): 一回のステップで複数の属性にデータを投入することをサポートしている。
* [検証規則](#validation-rules): 宣言された検証規則に基いて入力されたデータを確認する。
* [データのエクスポート](#data-exporting): カスタマイズ可能な書式を使ってモデルのデータを配列の形式にエクスポートすることが出来る。
`Model` クラスは、[アクティブレコード](db-active-record.md) のような、更に高度なモデルの基底クラスでもあります。
そういう高度なモデルについての詳細は、関連するドキュメントを参照してください。
> Info|情報: あなたのモデルクラスの基底クラスとして [[yii\base\Model]] を使うことは必須の条件ではありません。
しかしながら、Yii のコンポーネントの多くが [[yii\base\Model]] をサポートするように作られていますので、
通常は [[yii\base\Model]] がモデルの基底クラスとして推奨されます。
## 属性<a name="attributes"></a>
モデルは業務のデータを *属性* の形式で表現します。
全ての属性はそれぞれパブリックにアクセス可能なモデルのプロパティと同様なものです。
メソッド [[yii\base\Model::attributes()]] が、モデルがどのような属性を持つかを規定します。
属性に対しては、通常のオブジェクトプロパティにアクセスするのと同じようにして、アクセスすることが出来ます。
```php
$model = new \app\models\ContactForm;
// "name" は ContactForm の属性
$model->name = 'example';
echo $model->name;
```
また、配列の要素にアクセスするようして、属性にアクセスすることも出来ます。
これは、[[yii\base\Model]] が [ArrayAccess インターフェイス](http://php.net/manual/ja/class.arrayaccess.php) と [ArrayIterator クラス](http://jp2.php.net/manual/ja/class.arrayiterator.php) をサポートしているおかげです。
```php
$model = new \app\models\ContactForm;
// 配列要素のように属性にアクセスする
$model['name'] = 'example';
echo $model['name'];
// 属性に反復アクセスする
foreach ($model as $name => $value) {
echo "$name: $value\n";
}
```
### 属性を定義する<a name="defining-attributes"></a>
あなたのモデルが [[yii\base\Model]] を直接に拡張するものである場合、既定によって、全ての *static でない public な* メンバ変数は属性となります。
例えば、次に示す `ContactForm` モデルは4つの属性を持ちます: すなわち、`name`、`email`、`subject`、そして、`body` です。
この `ContactForm` モデルは、HTML フォームから受け取る入力データを表現するために使われます。
```php
namespace app\models;
use yii\base\Model;
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $body;
}
```
[[yii\base\Model::attributes()]] をオーバーライドして、属性を異なる方法で定義することが出来ます。
このメソッドはモデルの中の属性の名前を返さなくてはなりません。
例えば、[[yii\db\ActiveRecord]] はそのようにして、関連付けられたデータベーステーブルのコラム名を属性の名前として返しています。
これと同時に `__get()``__set()` などのマジックメソッドをオーバーライドして、
属性が通常のオブジェクトプロパティと同じようにアクセス出来るようにする必要があるかもしれないことに注意してください。
### 属性のラベル <a name="attribute-labels"></a>
属性の値を表示したり、入力してもらったりするときに、属性と関連付けられたラベルを表示する必要があることがよくあります。
例えば、`firstName` という名前の属性を考えたとき、入力フォームやエラーメッセージのような箇所でエンドユーザに表示するときは、もっとユーザフレンドリーな `First Name` というラベルを表示したいと思うでしょう。
[[yii\base\Model::getAttributeLabel()]] を呼ぶことによって属性のラベルを得ることが出来ます。例えば、
```php
$model = new \app\models\ContactForm;
// "Name" を表示する
echo $model->getAttributeLabel('name');
```
既定では、属性のラベルは属性の名前から自動的に生成されます。
ラベルの生成は [[yii\base\Model::generateAttributeLabel()]] というメソッドによって行われます。
このメソッドは、キャメルケースの変数名を複数の単語に分割し、各単語の最初の文字を大文字にします。
例えば、`username` は `Username` となり、`firstName` は `First Name` となります。
自動的に生成されるラベルを使用したくない場合は、[[yii\base\Model::attributeLabels()]] をオーバーライドして、
属性のラベルを明示的に宣言することが出来ます。例えば、
```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',
];
}
}
```
複数の言語をサポートするアプリケーションでは、属性のラベルを翻訳したいと思うでしょう。
これも、以下のように、[[yii\base\Model::attributeLabels()|attributeLabels()]] の中で行うことが出来ます:
```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'),
];
}
```
さらに進んで、条件に従って属性のラベルを定義しても構いません。例えば、モデルが使用される
[シナリオ](#scenarios) に基づいて、同じ属性に対して違うラベルを返すことことが出来ます。
> Info|情報: 厳密に言えば、属性のラベルは [ビュー](structure-views.md) の一部を成すものです。
しかし、たいていの場合、モデルの中でラベルを宣言する方が便利が良く、
結果としてクリーンで再利用可能なコードになります。
## シナリオ<a name="scenarios"></a>
モデルはさまざまに異なる *シナリオ* で使用されます。
例えば、`User` モデルはユーザログインの入力を収集するために使われますが、同時に、ユーザ登録の目的でも使われます。
異なるシナリオの下では、モデルが使用する業務のルールとロジックも異なるでしょう。
例えば、`email` 属性はユーザ登録の際には必須とされるかも知れませんが、ログインの際にはそうではないでしょう。
モデルは [[yii\base\Model::scenario]] プロパティを使って、自身が使われているシナリオを追跡します。
既定では、モデルは `default` という単一のシナリオのみをサポートします。
次のコードは、モデルのシナリオを設定する二つの方法を示すものです:
```php
// プロパティとしてシナリオをセットする
$model = new User;
$model->scenario = 'login';
// シナリオはコンフィギュレーションでセットされる
$model = new User(['scenario' => 'login']);
```
既定では、モデルによってサポートされるシナリオは、モデルで宣言されている [検証規則](#validation-rules) によって決定されます。
しかし、次のように、[[yii\base\Model::scenarios()]] メソッドをオーバーライドして、この動作をカスタマイズすることが出来ます:
```php
namespace app\models;
use yii\db\ActiveRecord;
class User extends ActiveRecord
{
public function scenarios()
{
return [
'login' => ['username', 'password'],
'register' => ['username', 'email', 'password'],
];
}
}
```
> Info|情報: 上記の例と後続の例では、モデルクラスは [[yii\db\ActiveRecord]] を拡張するものとなっています。
というのは、複数のシナリオの使用は、通常、[アクティブレコード](db-active-record.md) クラスで発生するからです。
`seanarios()` メソッドは、キーがシナリオの名前であり、値が対応する *アクティブな属性* である配列を返します。
アクティブな属性とは、[一括代入](#massive-assignment) することが出来て、[検証](#validation-rules) の対象になる属性です。
上記の例では、`login` シナリオにおいては `username``password` の属性がアクティブであり、一方、
`register` シナリオにおいては、`username` と `password` に加えて `email` もアクティブです。
`scenarios()` の既定の実装は、検証規則の宣言メソッドである [[yii\base\Model::rules()]] に現れる全てのシナリオを返すものです。
`scenarios()` をオーバーライドするときに、デフォルトのシナリオに加えて新しいシナリオを導入したい場合は、
次のようなコードを書きます:
```php
namespace app\models;
use yii\db\ActiveRecord;
class User extends ActiveRecord
{
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios['login'] = ['username', 'password'];
$scenarios['register'] = ['username', 'email', 'password'];
return $scenarios;
}
}
```
シナリオの機能は、主として、[検証](#validation-rules) と [属性の一括代入](#massive-assignment) によって使用されます。
しかし、他の目的に使うことも可能です。例えば、現在のシナリオに基づいて異なる [属性のラベル](#attribute-labels) を宣言することも出来ます。
## 検証規則<a name="validation-rules"></a>
モデルのデータをエンドユーザから受け取ったときは、データを検証して、それが一定の規則 (*検証規則*、あるいは、いわゆる *ビジネスルール*) を満たしていることを確認しなければなりません。
`ContactForm` モデルを例に挙げるなら、全ての属性が空っぽではなく、`email` 属性が有効なメールアドレスを含んでいることを確認したいでしょう。
いずれかの属性の値が対応するビジネスルールを満たしていないときは、ユーザがエラーを訂正するのを助ける適切なエラーメッセージが表示されるべきです。
受信したデータを検証するために、[[yii\base\Model::validate()]] を呼ぶことが出来ます。
このメソッドは、[[yii\base\Model::rules()]] で宣言された検証規則を使って、該当するすべての属性を検証します。
エラーが見つからなければ、メソッドは true を返します。そうでなければ、[[yii\base\Model::errors]]
にエラーを保存して、false を返します。例えば、
```php
$model = new \app\models\ContactForm;
// モデルの属性にユーザの入力を代入する
$model->attributes = \Yii::$app->request->post('ContactForm');
if ($model->validate()) {
// すべての入力値は有効である
} else {
// 検証が失敗: $errors はエラーメッセージを含む配列
$errors = $model->errors;
}
```
モデルに関連付けられた検証規則を宣言するためには、[[yii\base\Model::rules()]] メソッドをオーバーライドして、
モデルの属性が満たすべき規則を返すようにします。
次の例は、`ContactForm` モデルのために宣言された検証規則を示します:
```php
public function rules()
{
return [
// name、email、subject、body の属性が必須
[['name', 'email', 'subject', 'body'], 'required'],
// email 属性は、有効なメールアドレスでなければならない
['email', 'email'],
];
}
```
一個の規則は、一個または複数の属性を検証するために使うことが出来ます。
また、一個の属性は、一個または複数の規則によって検証することが出来ます。
検証規則をどのように宣言するかについて、更なる詳細は [入力を検証する](input-validation.md) の節を参照してください。
時として、特定の [シナリオ](#scenarios) にのみ適用される規則が必要になるでしょう。そのためには、下記のように、
規則に `on` プロパティを指定することが出来ます:
```php
public function rules()
{
return [
// "register" シナリオでは、username、email、password のすべてが必須
[['username', 'email', 'password'], 'required', 'on' => 'register'],
// "login" シナリオでは、username と password が必須
[['username', 'password'], 'required', 'on' => 'login'],
];
}
```
`on` プロパティを指定しない場合は、その規則は全てのシナリオに適用されることになります。
現在の [[yii\base\Model::scenario|シナリオ]] に適用可能な規則は *アクティブな規則* と呼ばれます。
属性が検証されるのは、それが `scenarios()` の中でアクティブな属性であると宣言されており、
かつ、`rules()` の中で宣言されている一つまたは複数のアクティブな規則と関連付けられている場合であり、また、そのような場合だけです。
## 一括代入<a name="massive-assignment"></a>
一括代入は、一行のコードを書くだけで、ユーザの入力したデータをモデルに投入できる便利な方法です。
一括代入は、入力されたデータを [[yii\base\Model::$attributes]] に直接に代入することによって、モデルの属性にデータを投入します。
次の二つのコード断片は等価であり、どちらもエンドユーザから送信されたフォームのデータを `ContactForm` モデルの属性に割り当てようとするものです。
明らかに、一括代入を使う前者の方が、後者よりも明瞭で間違いも起こりにくいでしょう:
```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;
```
### 安全な属性<a name="safe-attributes"></a>
一括代入は、いわゆる *安全な属性*、すなわち、モデルの現在の [[yii\base\Model::scenario|シナリオ]]
用に [[yii\base\Model::scenarios()]] にリストされている属性に対してのみ適用されます。
例えば、`User` モデルが次のようなシナリオ宣言を持っている場合において、現在のシナリオが `login` であるときは、`username` と `password` のみが一括代入が可能です。その他の属性はいっさい触れられません。
```php
public function scenarios()
{
return [
'login' => ['username', 'password'],
'register' => ['username', 'email', 'password'],
];
}
```
> Info|情報: 一括代入が安全な属性に対してのみ適用されるのは、どの属性がエンドユーザのデータによって
修正されうるかを制御する必要があるからです。
例えば、`User` モデルに、ユーザに割り当てられる権限を決定する `permission` という属性がある場合、
この属性が修正できるのは、管理者がバックエンドのインターフェイスを通じてする時だけに制限したいでしょう。
[[yii\base\Model::scenarios()]] の既定の実装は [[yii\base\Model::rules()]] に現われる全てのシナリオと属性を返すものです。
従って、このメソッドをオーバーライドしない場合は、アクティブな検証規則のどれかに出現する限り、その属性は安全である、ということになります。
このため、実際に検証することなく属性を安全であると宣言できるように、`safe` というエイリアスを与えられた特別なバリデータが提供されています。例えば、次の規則は `title``description` の両方が安全な属性であると宣言しています。
```php
public function rules()
{
return [
[['title', 'description'], 'safe'],
];
}
```
### 安全でない属性<a name="unsafe-attributes"></a>
上記で説明したように、[[yii\base\Model::scenarios()]] メソッドは二つの目的を持っています:
すなわち、どの属性が検証されるべきかを決めることと、どの属性が安全であるかを決めることです。
めったにない場合として、属性を検証する必要はあるが、安全であるという印は付けたくない、ということがあります。
そういう時は、下の例の `secret` 属性のように、`scenarios()` の中で宣言するときに属性の名前の前に感嘆符
`!` を前置することが出来ます:
```php
public function scenarios()
{
return [
'login' => ['username', 'password', '!secret'],
];
}
```
このモデルが `login` シナリオにある場合、三つの属性は全て検証されます。しかし、`username` と
`password` の属性だけが一括代入が可能です。`secret` 属性に入力値を割り当てるためには、
下記のように明示的に実行する必要があります。
```php
$model->secret = $secret;
```
## データのエクスポート <a name="data-exporting"></a>
モデルを他の形式にエクスポートする必要が生じることはよくあります。例えば、一群のモデルを JSON や
Excel 形式に変換したい場合があるでしょう。
エクスポートのプロセスは二つの独立したステップに分割することが出来ます。
最初のステップで、モデルは配列に変換されます。そして第二のステップで、配列が目的の形式に変換されます。
あなたは最初のステップだけに注力しても構いません。と言うのは、第二のステップは汎用的なデータフォーマッタ、
例えば [[yii\web\JsonResponseFormatter]] によって達成できるからです。
モデルを配列に変換する最も簡単な方法は、[[yii\base\Model::$attributes]] プロパティを使うことです。
例えば、
```php
$post = \app\models\Post::findOne(100);
$array = $post->attributes;
```
既定によって、[[yii\base\Model::$attributes]] プロパティは [[yii\base\Model::attributes()]] で宣言されている *全て* の属性の値を返します。
モデルを配列に変換するためのもっと柔軟で強力な方法は、[[yii\base\Model::toArray()]] メソッドを使うことです。
このメソッドの既定の動作は [[yii\base\Model::$attributes]] のそれと同じものです。
しかしながら、このメソッドを使うと、どのデータ項目 (*フィールド* と呼ばれます) を結果の配列に入れるか、
そして、その項目にどのような書式を適用するかを選ぶことが出来ます。
実際、[レスポンスの書式設定](rest-response-formatting.md) で説明されているように、
RESTful ウェブサービスの開発においては、これがモデルをエクスポートする既定の方法となっています。
### フィールド<a name="fields"></a>
フィールドとは、単に、モデルの [[yii\base\Model::toArray()]] メソッドを呼ぶことによって取得される配列の中の、
名前付きの要素のことです。
既定では、フィールドの名前は属性の名前と等しいものになります。しかし、この既定の動作は、
[[yii\base\Model::fields()|fields()]] および/または [[yii\base\Model::extraFields()|extraFields()]] メソッドをオーバーライドして、変更することが出来ます。
どちらも、フィールド定義のリストを返すべきメソッドです。
`fields()` によって定義されたフィールドは、デフォルトフィールドです。
すなわち、`toArray()` が、既定ではこれらのフィールドを返すということを意味します。
`extraFields()` メソッドは、`$expand` パラメータによって指定する限りにおいて `toArray()` によって返され得る、追加のフィールドを定義します。
例として、次のコードは、`fields()` で定義された全てのフィールドと、
(`extraFields()` で定義されていれば) `prettyName``fullAddress` フィールドを返すものです。
```php
$array = $model->toArray([], ['prettyName', 'fullAddress']);
```
`fields()` をオーバーライドして、フィールドを追加、削除、リネーム、再定義することが出来ます。
`fields()` の返り値は配列でなければなりません。配列のキーはフィールド名であり、
配列の値は対応するフィールド定義です。フィールド定義には、プロパティ/属性の名前か、または、対応するフィールドの値を返す無名関数を使うことが出来ます。
フィールド名がそれを定義する属性名と同一であるという特殊な場合においては、配列のキーを省略することが出来ます。
例えば、
```php
// 明示的に全てのフィールドをリストする方法。(API の後方互換性を保つために) DB テーブルやモデル属性の
// 変更がフィールドの変更を引き起こさないことを保証したい場合に適している。
public function fields()
{
return [
// フィールド名が属性名と同じ
'id',
// フィールド名は "email"、対応する属性名は "email_address"
'email' => 'email_address',
// フィールド名は "name"、その値は PHP コールバックで定義
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
];
}
// いくつかのフィールドを除去する方法。親の実装を継承しつつ、慎重に扱うべきフィールドは
// 除外したいときに適している。
public function fields()
{
$fields = parent::fields();
// 慎重に扱うべき情報を含むフィールドを削除する
unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);
return $fields;
}
```
> Warning|警告: 既定ではモデルの全ての属性がエクスポートされる配列に含まれるため、データを精査して、
> 慎重に扱うべき情報が含まれていないことを確認すべきです。そういう情報がある場合は、
> `fields()` をオーバーライドして、除去すべきです。上記の例では、`auth_key`、`password_hash`
> および `password_reset_token` を選んで除去しています。
## 最善の慣行<a name="best-practices"></a>
モデルは、業務のデータ、規則、ロジックを表わす中心的なオブジェクトです。
モデルは、さまざまな場所で再利用される必要がよくあります。
良く設計されたアプリケーションでは、通常、モデルは [コントローラ](structure-controllers.md) よりもはるかに重いものになります。
要約すると、モデルは、
* ビジネスデータを表現する属性を含むことが出来ます;
* データの有効性と整合性を保証する検証規則を含むことが出来ます;
* ビジネスロジックを実装するメソッドを含むことが出来ます;
* リクエスト、セッション、または他の環境データに直接アクセスするべきではありません。
これらのデータは、[コントローラ](structure-controllers.md) によってモデルに注入されるべきです;
* HTML を埋め込むなどの表示用のコードは避けるべきです - 表示は [ビュー](structure-views.md) で行う方が良いです;
* あまりに多くの [シナリオ](#scenarios) を単一のモデルで持つことは避けましょう。
大規模で複雑なシステムを開発するときには、たいてい、上記の最後にあげた推奨事項を考慮するのが良いでしょう。
そういうシステムでは、モデルは数多くの場所で使用され、それに従って、数多くの規則セットやビジネスロジックを含むため、非常に大きくて重いものになり得ます。
コードの一ヶ所に触れるだけで数ヶ所の違った場所に影響が及ぶため、ついには、モデルのコードの保守が悪夢になってしまうこともよくあります。
モデルのコードの保守性を高めるために、以下の戦略をとることが出来ます:
* 異なる [アプリケーション](structure-applications.md) や [モジュール](structure-modules.md)
によって共有される一連の基底モデルクラスを定義します。
これらのモデルクラスは、すべてで共通に使用される最小限の規則セットとロジックのみを含むべきです。
* モデルを使用するそれぞれの [アプリケーション](structure-applications.md) または [モジュール](structure-modules.md) において、
対応する基底モデルクラスから拡張した具体的なモデルクラスを定義します。
この具体的なモデルクラスが、そのアプリケーションやモジュールに固有の規則やロジックを含むべきです。
例えば、[アドバンストアプリケーションテンプレート](tutorial-advanced-app.md) の中で、
基底モデルクラス `common\models\Post` を定義することが出来ます。
次に、フロントエンドアプリケーションにおいては、`common\models\Post` から拡張した具体的なモデルクラス
`frontend\models\Post` を定義して使います。
また、バックエンドアプリケーションにおいても、同様に、`backend\models\Post` を定義します。
この戦略を取ると、`frontend\models\Post` の中のコードはフロントエンドアプリケーション固有のものであると保証することが出来ます。
そして、フロントエンドのコードにどのような変更を加えても、バックエンドアプリケーションを壊すかもしれないと心配する必要がなくなります。

262
docs/guide-ja/structure-modules.md

@ -0,0 +1,262 @@
モジュール
==========
モジュールは、[モデル](structure-models.md)、[ビュー](structure-views.md)、[コントローラ](structure-controllers.md)、
およびその他の支援コンポーネントから構成される自己充足的なソフトウェアのユニットです。
モジュールが [アプリケーション](structure-applications.md) にインストールされている場合、
エンドユーザはモジュールのコントローラにアクセスする事が出来ます。これらのことを理由として、
モジュールは小さなアプリケーションと見なされることがよくあります。しかし、モジュールは単独では配置できず、
アプリケーションの中に存在しなければならないという点で [アプリケーション](structure-applications.md) とは異なります。
## モジュールを作成する <a name="creating-modules"></a>
モジュールは、モジュールの [[yii\base\Module::basePath|ベースパス]] と呼ばれるディレクトリとして組織されます。
このディレクトリの中に、ちょうどアプリケーションの場合と同じように、`controllers`、`models`、`views`
のようなサブディレクトリが存在して、コントローラ、モデル、ビュー、その他のコードを収納しています。
次の例は、モジュール内の中身を示すものです:
```
forum/
Module.php モジュールクラスファイル
controllers/ コントローラクラスファイルを含む
DefaultController.php デフォルトのコントローラクラスファイル
models/ モデルクラスファイルを含む
views/ コントローラのビューとレイアウトのファイルを含む
layouts/ レイアウトのビューファイルを含む
default/ DefaultController のためのビューファイルを含む
index.php index ビューファイル
```
### モジュールクラス <a name="module-classes"></a>
全てのモジュールは [[yii\base\Module]] から拡張したユニークなモジュールクラスを持たなければなりません。
モジュールクラスは、モジュールの [[yii\base\Module::basePath|ベースパス]] 直下に配置されて
[オートロード可能](concept-autoloading.md) になっていなければなりません。
モジュールがアクセスされたとき、対応するモジュールクラスの単一のインスタンスが作成されます。
[アプリケーションのインスタンス](structure-applications.md) と同じように、モジュールのインスタンスは
モジュール内のコードがデータとコンポーネントを共有するために使用されます。
次のコードは、モジュールクラスがどのように見えるかを示す例です:
```php
namespace app\modules\forum;
class Module extends \yii\base\Module
{
public function init()
{
parent::init();
$this->params['foo'] = 'bar';
// ... 他の初期化コード ...
}
}
```
`init` メソッドがモジュールのプロパティを初期化するためのコードをたくさん含む場合は、それを
[コンフィギュレーション](concept-configurations.md) の形で保存し、`init()` の中で次のコードを使って
読み出すことも可能です:
```php
public function init()
{
parent::init();
// config.php からロードしたコンフィギュレーションでモジュールを初期化する
\Yii::configure($this, require(__DIR__ . '/config.php'));
}
```
ここで、コンフィギュレーションファイル `config.php` は、
[アプリケーションのコンフィギュレーション](structure-applications.md#application-configurations) の場合と同じように、
次のような内容を含むことが出来ます。
```php
<?php
return [
'components' => [
// コンポーネントのコンフィギュレーションのリスト
],
'params' => [
// パラメータのリスト
],
];
```
### モジュール内のコントローラ <a name="controllers-in-modules"></a>
モジュールの中でコントローラを作成するときは、コントローラクラスをモジュールクラスの名前空間の `controllers`
サブ名前空間に置くことが規約です。このことは、同時に、コントローラのクラスファイルをモジュールの
[[yii\base\Module::basePath|ベースパス]] 内の `controllers` ディレクトリに置くべきことをも意味します。
例えば、前の項で示された `forum` モジュールの中で `post` コントローラを作成するためには、次のようにして
コントローラを宣言しなければなりません:
```php
namespace app\modules\forum\controllers;
use yii\web\Controller;
class PostController extends Controller
{
// ...
}
```
コントローラクラスの名前空間は、[[yii\base\Module::controllerNamespace]] プロパティを構成してカスタマイズすることが出来ます。
いくつかのコントローラがこの名前空間の外にある場合でも、[[yii\base\Module::controllerMap]] プロパティを構成することによって、
それらをアクセス可能にすることが出来ます。これは、[アプリケーションでのコントローラマップ](structure-applications.md#controller-map)
の場合と同様です。
### モジュール内のビュー <a name="views-in-modules"></a>
モジュール内のビューは、モジュールの [[yii\base\Module::basePath|ベースパス]] 内の `views` ディレクトリに置かれなくてはなりません。
モジュール内のコントローラによってレンダリングされるビューは、ディレクトリ `views/ControllerID` の下に置きます。ここで、
`ControllerID` は [コントローラ ID](structure-controllers.md#routes) を指します。例えば、コントローラクラスが `PostController`
である場合、ディレクトリはモジュールの [[yii\base\Module::basePath|ベースパス]] の中の `views/post` となります。
モジュールは、そのモジュールのコントローラによってレンダリングされるビューに適用される [レイアウト](structure-views.md#layouts)
を指定することが出来ます。レイアウトは、既定では `views/layouts` ディレクトリに置かれなければならず、また、
[[yii\base\Module::layout]] プロパティがレイアウトの名前を指すように構成しなければなりません。
`layout` プロパティを構成しない場合は、アプリケーションのレイアウトが代りに使用されます。
## モジュールを使う <a name="using-modules"></a>
アプリケーションの中でモジュールを使うためには、アプリケーションの [[yii\base\Application::modules|modules]] プロパティのリストに
そのモジュールを載せてアプリケーションを構成するだけで大丈夫です。次のコードは、
[アプリケーションのコンフィギュレーション](structure-applications.md#application-configurations) の中で
`forum` モジュールを使うようにするものです:
```php
[
'modules' => [
'forum' => [
'class' => 'app\modules\forum\Module',
// ... モジュールのその他のコンフィギュレーション ...
],
],
]
```
[[yii\base\Application::modules|modules]] プロパティは、モジュールのコンフィギュレーションの配列を取ります。各配列のキーは、
アプリケーションの全てのモジュールの中でそのモジュールを特定するためのユニークな *モジュール ID* を表します。そして、
対応する配列の値は、そのモジュールを作成するための [コンフィギュレーション](concept-configurations.md) です。
### ルート <a name="routes"></a>
アプリケーションの中のコントローラをアクセスするのと同じように、[ルート](structure-controllers.md#routes)
がモジュールの中のコントローラを指し示すために使われます。モジュール内のコントローラのルートは、モジュール ID で始まり、
コントローラ ID、アクション ID と続くものでなければなりません。例えば、アプリケーションが `forum` という名前のモジュールを
使用している場合、`forum/post/index` というルートは、`forum` モジュール内の `post` コントローラの `index` アクションを表します。
ルートがモジュール ID だけを含む場合は、[[yii\base\Module::defaultRoute]] プロパティ (その既定値は `default` です) が、
どのコントローラ/アクションが使用されるべきかを決定します。これは、`forum` というルートは `forum` モジュール内の
`default` コントローラを表すという意味です。
### モジュールにアクセスする <a name="accessing-modules"></a>
モジュール内において、モジュール ID や、モジュールのパラメータ、モジュールのコンポーネントなどにアクセスするために、
[モジュールクラス](#module-classes) のインスタンスを取得する必要があることがよくあります。次の文を使ってそうすることが出来ます:
```php
$module = MyModuleClass::getInstance();
```
ここで `MyModuleClass` は、関心を持っているモジュールクラスの名前を指します。`getInstance()` メソッドは、
現在リクエストされているモジュールクラスのインスタンスを返します。モジュールがリクエストされていない場合は、
このメソッドは null を返します。モジュールクラスの新しいインスタンスを手動で作成しようとしてはいけないことに注意してください。
そのインスタンスは、リクエストに対するレスポンスとして Yii によって作成されたインスタンスとは別のものになります。
> Info|情報: モジュールを開発するとき、モジュールが固定の ID を使うと仮定してはいけません。なぜなら、モジュールは、
アプリケーションや他のモジュールの中で使うときに、任意の ID と結び付けることが出来るからです。
モジュール ID を取得するためには、上記の方法を使って最初にモジュールのインスタンスを取得し、そして `$module->id`
によって ID を取得しなければなりません。
モジュールのインスタンスにアクセスするためには、次の二つの方法を使うことも出来ます:
```php
// ID が "forum" である子モジュールを取得する
$module = \Yii::$app->getModule('forum');
// 現在リクエストされているコントローラが属するモジュールを取得する
$module = \Yii::$app->controller->module;
```
最初の方法は、モジュール ID を知っている時しか役に立ちません。一方、第二の方法は、
リクエストされているコントローラについて知っている場合に使うのに最適な方法です。
いったんモジュールのインスタンスをとらえれば、モジュールに登録されたパラメータやコンポーネントにアクセスすることが可能になります。
例えば、
```php
$maxPostCount = $module->params['maxPostCount'];
```
### モジュールをブートストラップする <a name="bootstrapping-modules"></a>
いくつかのモジュールは、全てのリクエストで毎回走らせる必要があります。[[yii\debug\Module|デバッグ]] モジュールがその一例です。
そうするためには、そのようなモジュールをアプリケーションの [[yii\base\Application::bootstrap|bootstrap]] プロパティのリストに挙げます。
例えば、次のアプリケーションのコンフィギュレーションは、`debug` モジュールが常にロードされることを保証するものです:
```php
[
'bootstrap' => [
'debug',
],
'modules' => [
'debug' => 'yii\debug\Module',
],
]
```
## 入れ子のモジュール <a name="nested-modules"></a>
モジュールはレベルの制限無く入れ子にすることが出来ます。つまり、モジュールは別のモジュールを含むことが出来、
その含まれたモジュールもさらに別のモジュールを含むことが出来ます。含む側を *親モジュール*、含まれる側を *子モジュール*
と呼びます。子モジュールは、親モジュールの [[yii\base\Module::modules|modules]] プロパティの中で宣言されなければなりません。
例えば、
```php
namespace app\modules\forum;
class Module extends \yii\base\Module
{
public function init()
{
parent::init();
$this->modules = [
'admin' => [
// ここはもっと短い名前空間の使用を考慮すべきだ!
'class' => 'app\modules\forum\modules\admin\Module',
],
];
}
}
```
入れ子にされたモジュールの中にあるコントローラのルートは、全ての祖先のモジュールの ID を含まなければなりません。
例えば、`forum/admin/dashboard/index` というルートは、`forum` モジュールの子モジュールである `admin` モジュールの
`dashboard` コントローラの `index` アクションを表します。
> Info|情報: [[yii\base\Module::getModule()|getModule()]] メソッドは、親モジュールに直接属する子モジュールだけを返します。
[[yii\base\Application::loadedModules]] プロパティがロードされた全てのモジュールのリストを保持しています。
このリストには、直接の子と孫以下の両方のモジュールが含まれ、クラス名によってインデックスされています。
## 最善の慣行 <a name="best-practices"></a>
モジュールは、それぞれ密接に関係する一連の機能を含む数個のグループに分割できるような、規模の大きなアプリケーションに
最も適しています。そのような機能グループをそれぞれモジュールとして、特定の個人やチームによって開発することが出来ます。
モジュールは、また、機能グループレベルでコードを再利用するための良い方法でもあります。ある種のよく使われる機能、
例えばユーザ管理やコメント管理などは、全て、将来のプロジェクトで容易に再利用できるように、モジュールの形式で
開発することが出来ます。

763
docs/guide-ja/structure-views.md

@ -0,0 +1,763 @@
ビュー
======
ビューは [MVC](http://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャの一部を成すものです。
ビューはエンドユーザにデータを表示することに責任を持つコードです。
ウェブアプリケーションにおいては、ビューは、通常、主として HTML コードと表示目的の PHP コードを含む PHP スクリプトファイルである、
*ビューテンプレート* の形式で作成されます。
そして、ビューテンプレートを管理する [[yii\web\View|ビュー]] [アプリケーションコンポーネント](structure-application-components.md) は、
ビューの構築とレンダリングを助けるためによく使われるメソッドを提供します。
なお、簡潔さを重視して、ビューテンプレートまたはビューテンプレートファイルを単にビューと呼ぶことがよくあります。
## ビューを作成する <a name="creating-views"></a>
前述のように、ビューは HTML と PHP コードが混ざった単なる PHP スクリプトです。
次に示すのは、ログインフォームを表示するビューです。
見ると分るように、PHP コードがタイトルやフォームなど動的なコンテンツを生成するのに使われ、HTML コードがそれらを編成して表示可能な HTML ページを作っています。
```php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $form yii\widgets\ActiveForm */
/* @var $model app\models\LoginForm */
$this->title = 'ログイン';
?>
<h1><?= Html::encode($this->title) ?></h1>
<p>次の項目を入力してログインしてください:</p>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= Html::submitButton('ログイン') ?>
<?php ActiveForm::end(); ?>
```
ビューの中でアクセスできる `$this` は、このビューテンプレートを管理しレンダリングしている
[[yii\web\View|ビューコンポーネント]] を参照します。
`$this` 以外に、上記の例の `$model` のように、前もって定義された変数がビューの中にあることがあります。
このような変数は、[コントローラ](structure-controllers.md) または [ビューのレンダリング](#rendering-views) をトリガするオブジェクトによってビューに *プッシュ* されたデータを表します。
> Tip|ヒント: 上の例では、事前に定義された変数は、IDE に認識されるように、
ビューの先頭のコメントブロックの中にリストされています。これは、ビューに
ドキュメントを付けるのにも良い方法です。
### セキュリティ <a name="security"></a>
HTML ページを生成するビューを作成するときは、エンドユーザから受け取るデータを
表示する前に エンコード および/または フィルター することが重要です。
そうしなければ、あなたのアプリケーションは [クロスサイトスクリプティング](http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0) 攻撃をこうむるおそれがあります。
平文テキストを表示するためには、まず [[yii\helpers\Html::encode()]] を呼んでエンコードします。
例えば、次のコードはユーザの名前を表示する前にエンコードしています:
```php
<?php
use yii\helpers\Html;
?>
<div class="username">
<?= Html::encode($user->name) ?>
</div>
```
HTML コンテンツを表示するためには、[[yii\helpers\HtmlPurifier]] を使って、最初にコンテンツをフィルターします。
例えば、次のコードは、投稿のコンテンツを表示する前にフィルターしています:
```php
<?php
use yii\helpers\HtmlPurifier;
?>
<div class="post">
<?= HtmlPurifier::process($post->text) ?>
</div>
```
> Tip|ヒント: HTMLPurifier は、出力を安全なものにすることにおいては素晴らしい仕事をしますが、
速くはありません。アプリケーションが高いパフォーマンスを要求する場合は、
フィルター結果を [キャッシュ](caching-overview.md) することを考慮すべきです。
### ビューを整理する <a name="organizing-views"></a>
[コントローラ](structure-controllers.md) や [モデル](structure-models.md) と同じように、
ビューを整理するための規約があります。.
* コントローラによって表示されるビューは、既定では、ディレクトリ
`@app/views/ControllerID` の下に置かれるべきものです。
ここで、`ControllerID` は [コントローラ ID](structure-controllers.md#routes) を指します。
例えば、コントローラクラスが `PostController` である場合、ディレクトリは `@app/views/post`
となります。`PostCommentController` の場合は、ディレクトリは `@app/views/post-comment` です。
また、コントローラがモジュールに属する場合は、ディレクトリは [[yii\base\Module::basePath|モジュールディレクトリ]]
の下の `views/ControllerID` です。
* [ウィジェット](structure-widgets.md) で表示されるビューは、既定では、`WidgetPath/views`
ディレクトリの下に置かれるべきものです。ここで、`WidgetPath` は、ウィジェットのクラスファイル
を含んでいるディレクトリを指します。
* 他のオブジェクトによって表示されるビューについても、ウィジェットの場合と同じ規約に従うことが
推奨されます。
これらの既定のビューディレクトリは、コントローラやウィジェットの [[yii\base\ViewContextInterface::getViewPath()]]
メソッドをオーバーライドすることでカスタマイズすることが可能です。
## ビューをレンダリングする <a name="rendering-views"></a>
[コントローラ](structure-controllers.md) の中でも、[ウィジェット](structure-widgets.md) の中でも、
または、その他のどんな場所でも、ビューをレンダリングするメソッドを呼ぶことによって
ビューをレンダリングすることが出来ます。
これらのメソッドは、下記に示されるような類似のシグニチャを共有します。
```
/**
* @param string $view ビュー名またはファイルパス、実際のレンダリングメソッドに依存する
* @param array $params ビューに引き渡されるデータ
* @return string レンダリングの結果
*/
methodName($view, $params = [])
```
### コントローラでのレンダリング <a name="rendering-in-controllers"></a>
[コントローラ](structure-controllers.md) の中では、ビューをレンダリングするために
次のコントローラメソッドを呼ぶことが出来ます:
* [[yii\base\Controller::render()|render()]]: [名前付きビュー](#named-views) をレンダリングし、
その結果に [レイアウト](#layouts) を適用する。
* [[yii\base\Controller::renderPartial()|renderPartial()]]: [名前付きビュー](#named-views) を
レイアウトなしでレンダリングする。
* [[yii\web\Controller::renderAjax()|renderAjax()]]: [名前付きビュー](#named-views) を
レイアウトなしでレンダリングし、登録されている全ての JS/CSS スクリプトおよびファイルを注入する。
通常、AJAX ウェブリクエストに対するレスポンスにおいて使用される。
* [[yii\base\Controller::renderFile()|renderFile()]]: ビューファイルのパスまたは [エイリアス](concept-aliases.md)
の形式で指定されたビューをレンダリングする。
例えば、
```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;
}
// "view" という名前のビューをレンダリングし、レイアウトを適用する
return $this->render('view', [
'model' => $model,
]);
}
}
```
### ウィジェットでのレンダリング <a name="rendering-in-widgets"></a>
[ウィジェット](structure-widgets.md) の中では、ビューをレンダリングするために、
次のウィジェットメソッドを使用することが出来ます。
* [[yii\base\Widget::render()|render()]]: [名前付きのビュー](#named-views) をレンダリングする。
* [[yii\base\Widget::renderFile()|renderFile()]]: ビューファイルのパスまたは [エイリアス](concept-aliases.md)
の形式で指定されたビューをレンダリングする。
例えば、
```php
namespace app\components;
use yii\base\Widget;
use yii\helpers\Html;
class ListWidget extends Widget
{
public $items = [];
public function run()
{
// "list" という名前のビューをレンダリングする
return $this->render('list', [
'items' => $this->items,
]);
}
}
```
### ビューでのレンダリング <a name="rendering-in-views"></a>
[[yii\base\View|ビューコンポーネント]] によって提供される下記のメソッドのどれかを使うと、
ビューの中で、別のビューをレンダリングすることが出来ます:
* [[yii\base\View::render()|render()]]: [名前付きのビュー](#named-views) をレンダリングする。
* [[yii\web\View::renderAjax()|renderAjax()]]: [名前付きビュー](#named-views) をレンダリングし、
登録されている全ての JS/CSS スクリプトおよびファイルを注入する。
通常、AJAX ウェブリクエストに対するレスポンスにおいて使用される。
* [[yii\base\View::renderFile()|renderFile()]]: ビューファイルのパスまたは [エイリアス](concept-aliases.md)
の形式で指定されたビューをレンダリングする。
例えば、ビューの中の次のコードは、現在レンダリングされているビューと同じディレクトリにある
`_overview.php` というビューファイルをレンダリングします。
ビューでは `$this` が [[yii\base\View|ビュー]] コンポーネントを参照することを思い出してください:
```php
<?= $this->render('_overview') ?>
```
### 他の場所でのレンダリング <a name="rendering-in-other-places"></a>
場所がどこであれ、`Yii::$app->view` という式によって [[yii\base\View|ビュー]] アプリケーションコンポーネントにアクセスすることが出来ますから、
前述の [[yii\base\View|ビュー]] コンポーネントメソッドを使ってビューをレンダリングすることが出来ます。
例えば、
```php
// ビューファイル "@app/views/site/license.php" を表示
echo \Yii::$app->view->renderFile('@app/views/site/license.php');
```
### 名前付きビュー <a name="named-views"></a>
ビューをレンダリングするとき、ビューを指定するのには、ビューの名前か、
ビューファイルのパス/エイリアスか、どちらかを使うことが出来ます。
たいていの場合は、より簡潔で柔軟な前者を使います。
名前を使って指定されるビューを *名前付きビュー* と呼びます。
ビューの名前は、以下の規則に従って、対応するビューファイルのパスに解決されます。
* ビュー名はファイル拡張子を省略することが出来ます。その場合、`.php` が拡張子として使われます。
例えば、`about` というビュー名は `about.php` というファイル名に対応します。
* ビュー名が二つのスラッシュ (`//`) で始まる場合は、対応するビューファイルのパスは `@app/views/ViewName`
となります。つまり、ビューファイルは [[yii\base\Application::viewPath|アプリケーションのビューパス]]
の下で探されます。例えば、`//site/about` は `@app/views/site/about.php` へと解決されます。
* ビュー名が一つのスラッシュ (`/`) で始まる場合は、ビューファイルのパスは、ビュー名の前に、現在
アクティブな [モジュール](structure-modules.md) の [[yii\base\Module::viewPath|ビューパス]]
を置くことによって形成されます。アクティブなモジュールが無い場合は、`@app/views/ViewName`
が使用されます。例えば、`/user/create` は、現在アクティブなモジュールが `user` である場合は、
`@app/modules/user/views/user/create.php` へと解決されます。アクティブなモジュールが無い場合は、
ビューファイルのパスは `@app/views/user/create.php` となります。
* ビューが [[yii\base\View::context|コンテキスト]] を伴ってレンダリングされ、そのコンテキストが
[[yii\base\ViewContextInterface]] を実装している場合は、ビューファイルのパスは、コンテキストの
[[yii\base\ViewContextInterface::getViewPath()|ビューパス]] をビュー名の前に置くことによって
形成されます。これは、主として、コントローラとウィジェットの中でレンダリングされるビューに当てはまります。
例えば、コンテキストが `SiteController` コントローラである場合、`site/about` は `@app/views/site/about.php`
へと解決されます。
* あるビューが別のビューの中でレンダリングされる場合は、後者のビューファイルを含んでいるディレクトリが
前者のビュー名の前に置かれて、実際のビューファイルのパスが形成されます。例えば、`item` は、
`@app/views/post/index.php` というビューの中でレンダリングされる場合、`@app/views/post/item`
へと解決されます。
上記の規則によると、コントローラ `app\controllers\PostController` の中で `$this->render('view')` を呼ぶと、
実際には、ビューファイル `@app/views/post/view.php` がレンダリングされ、一方、そのビューの中で
`$this->render('_overview')` を呼ぶと、ビューファイル `@app/views/post/_overview.php`
がレンダリングされることになります。
### ビューの中でデータにアクセスする <a name="accessing-data-in-views"></a>
ビューの中でデータにアクセスするためのアプローチが二つあります: 「プッシュ」と「プル」です。
ビューをレンダリングするメソッドに二番目のパラメータとしてデータを渡すのが「プッシュ」のアプローチです。
データは、「名前-値」のペアの配列として表されなければなりません。
ビューがレンダリングされるときに、PHP の `extract()` 関数がこの配列に対して呼び出され、
ビューの中でこの配列から変数が抽出されます。
例えば、次のコードはコントローラの中でビューをレンダリングしていますが、`report` ビューに
二つの変数、すなわち、`$foo = 1` と `$bar = 2` をプッシュしています。
```php
echo $this->render('report', [
'foo' => 1,
'bar' => 2,
]);
```
「プル」のアプローチは、[[yii\base\View|ビューコンポーネント]] またはビューからアクセス出来るその他のオブジェクト (例えば `Yii::$app`) から
積極的にデータを読み出すものです。
下記のコードを例として使って、ビューの中で `$this->context` という式でコントローラオブジェクト
を取得することが出来ます。その結果、`report` ビューの中でコントローラの全てのプロパティや
メソッドにアクセスすることが出来ます。次の例ではコントローラ ID にアクセスしています:
```php
The controller ID is: <?= $this->context->id ?>
?>
```
通常は「プッシュ」アプローチが、ビューでデータにアクセスする方法として推奨されます。
なぜなら、ビューのコンテキストオブジェクトに対する依存がより少ないからです。
その短所は、常にデータ配列を手作業で作成する必要がある、ということです。
ビューが共有されてさまざまな場所でレンダリングされる場合、その作業が面倒くさくなり、また、
間違いも生じやすくなります。
### ビューの間でデータを共有する <a name="sharing-data-among-views"></a>
[[yii\base\View|ビューコンポーネント]] が提供する [[yii\base\View::params|params]] プロパティを使うと
ビューの間でデータを共有することが出来ます。
例えば、`about` というビューで、次のようなコードを使って、
パン屑リストの現在の区分を指定することが出来ます。
```php
$this->params['breadcrumbs'][] = 'About Us';
```
そして、[レイアウト](#layouts) ファイル (これも一つのビューです) の中で、[[yii\base\View::params|params]]
によって渡されたデータを使って、パン屑リストを表示することが出来ます:
```php
<?= yii\widgets\Breadcrumbs::widget([
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>
```
## レイアウト <a name="layouts"></a>
レイアウトは、複数のビューの共通部分をあらわす特殊なタイプのビューです。
例えば、たいていのウェブアプリケーションでは、ページは共通のヘッダとフッタを持っています。
すべてのビューで同じヘッダとフッタを繰り返すことも出来ますが、もっと良い方法は、
そういうことはレイアウトの中で一度だけして、コンテンツビューのレンダリング結果を
レイアウトの中の適切な場所に埋め込むことです。
### レイアウトを作成する <a name="creating-layouts"></a>
レイアウトもまたビューですので、通常のビューと同様な方法で作成することが出来ます。既定では、
レイアウトは `@app/views/layouts` ディレクトリに保存されます。[モジュール](structure-modules.md)
の中で使用されるレイアウトについては、[[yii\base\Module::basePath|モジュールディレクトリ]] の下の
`views/layouts` ディレクトリに保存されるべきものとなります。既定のレイアウトディレクトリは、
アプリケーションまたはモジュールの [[yii\base\Module::layoutPath]] プロパティを構成することで
カスタマイズすることが出来ます。
次の例は、レイアウトがどのようなものであるかを示すものです。説明のために、レイアウトの中のコードを
大幅に単純化していることに注意してください。実際には、ヘッドのタグやメインメニューなど、もっと
多くのコンテンツを追加する必要があるでしょう。
```php
<?php
use yii\helpers\Html;
/* @var $this yii\web\View */
/* @var $content string */
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
<header>My Company</header>
<?= $content ?>
<footer>&copy; 2014 by My Company</footer>
<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>
```
見ると分かるように、レイアウトはすべてのページに共通な HTML タグを生成しています。`<body>`
セクションの中でレイアウトが `$content` という変数をエコーしていますが、これは、
コンテンツビューのレンダリング結果を表すものであり、[[yii\base\Controller::render()]] が呼ばれるときに、レイアウトにプッシュされるものです。
上記のコードに示されているように、たいていのレイアウトは次に挙げるメソッドを呼び出すべきです。
これらのメソッドは主としてレンダリングの過程に関するイベントをトリガして、他の場所で登録された
スクリプトやタグが、メソッドが呼ばれた場所に正しく注入されるようにするためのものです。
- [[yii\base\View::beginPage()|beginPage()]]: このメソッドがレイアウトの一番初めに呼ばれるべきです。
これは、ページの開始を示す [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]] イベントをトリガします。
- [[yii\base\View::endPage()|endPage()]]: このメソッドがレイアウトの最後で呼ばれるべきです。
これは、ページの終了を示す [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]] イベントをトリガします。
- [[yii\web\View::head()|head()]]: このメソッドが HTML ページの `<head>` セクションの中で呼ばれるべきです。
このメソッドは、ページのレンダリングが完了したときに、登録された head の HTML コード (リンクタグ、メタタグなど) に置き換えられるプレースホルダを生成します。
- [[yii\web\View::beginBody()|beginBody()]]: このメソッドが `<body>` セクションの最初で呼ばれるべきです。
このメソッドは [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]] イベントをトリガし、
body の開始位置を目的とする登録された HTML コード (JavaScript など) によって置き換えられる
プレースホルダを生成します。
- [[yii\web\View::endBody()|endBody()]]: このメソッドが `<body`> セクションの最後で呼ばれるべきです。
このメソッドは [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]] イベントをトリガし、
body の終了位置を目的とする登録された HTML コード (JavaScript など) によって置き換えられる
プレースホルダを生成します。
### レイアウトでデータにアクセスする <a name="accessing-data-in-layouts"></a>
レイアウトの中では、事前定義された二つの変数にアクセス出来ます: `$this``$content` です。前者は、
通常のビューにおいてと同じく、[[yii\base\View|ビュー]] コンポーネントを参照します。一方、後者は、
コントローラの中で [[yii\base\Controller::render()|render()]] メソッドを呼ぶことによってレンダリングされる、
コンテンツビューのレンダリング結果を含むものです。
レイアウトの中で他のデータにアクセスする必要があるときは、[ビューの中でデータにアクセスする](#accessing-data-in-views)
の項で説明されている「プル」の方法を使う必要があります。コンテンツビューからレイアウトにデータを渡す必要があるときは、
[ビューの間でデータを共有する](#sharing-data-among-views) の項で説明されている方法を使うことが出来ます。
### レイアウトを使う <a name="using-layouts"></a>
[コントローラでのレンダリング](#rendering-in-controllers) の項で説明されているように、コントローラの中で
[[yii\base\Controller::render()|render()]] メソッドを呼んでビューをレンダリングすると、レンダリング結果に
レイアウトが適用されます。既定では、`@app/views/layouts/main.php` というレイアウトが使用されます。
[[yii\base\Application::layout]] または [[yii\base\Controller::layout]] のどちらかを構成することによって、異なるレイアウトを
使うことが出来ます。前者は全てのコントローラによって使用されるレイアウトを決定するものですが、後者は個々のコントローラについて
前者をオーバーライドするものです。例えば、次のコードは、`post` コントローラがビューをレンダリングするときに
`@app/views/layouts/post.php` をレイアウトとして使うようにするものです。その他のコントローラは、`layout` プロパティに
触れられていないと仮定すると、引き続き既定の `@app/views/layouts/main.php` をレイアウトとして使います。
```php
namespace app\controllers;
use yii\web\Controller;
class PostController extends Controller
{
public $layout = 'post';
// ...
}
```
モジュールに属するコントローラについては、モジュールの [[yii\base\Module::layout|layout]] プロパティを構成して、モジュール内の
コントローラに特定のレイアウトを使用することも出来ます。
`layout` プロパティは異なるレベル (コントローラ、モジュール、アプリケーション) で構成されうるものですので、
Yii は舞台裏で二つのステップを践んで、特定のコントローラで実際に使われるレイアウトファイルが何であるかを決定します。
最初のステップで、Yii はレイアウトの値とコンテキストモジュールを決定します:
- コントローラの [[yii\base\Controller::layout]] プロパティが null でないときは、それをレイアウトの値として使い、
コントローラの [[yii\base\Controller::module|モジュール]] をコンテキストモジュールとして使う。
- [[yii\base\Controller::layout|layout]] が null のときは、コントローラの祖先となっている全てのモジュール
(アプリケーション自体も含む) を探して、[[yii\base\Module::layout|layout]] プロパティが null でない最初のモジュールを見つける。
見つかったモジュールとその [[yii\base\Module::layout|layout]] の値をコンテキストモジュールと選ばれたレイアウトの値とする。
そのようなモジュールが見つからなかったときは、レイアウトは適用されないということを意味する。
第二のステップでは、最初のステップで決定されたレイアウトの値とコンテキストモジュールに従って、実際のレイアウトファイルを決定します。
レイアウトの値は下記のいずれかであり得ます:
- パスエイリアス (例えば、`@app/views/layouts/main`)。
- 絶対パス (例えば、`/main`): すなわち、スラッシュで始まるレイアウトの値の場合。
実際のレイアウトファイルはアプリケーションの [[yii\base\Application::layoutPath|レイアウトパス]]
(デフォルトでは `@app/views/layouts`) の下で探される。
- 相対パス (例えば、`main`): 実際のレイアウトファイルはコンテキストモジュールの [[yii\base\Module::layoutPath|レイアウトパス]]
(デフォルトでは [[yii\base\Module::basePath|モジュールディレクトリ]] の下の `views/layouts` ディレクトリ) の下で探される。
- 真偽値 `false`: レイアウトは適用されない。
レイアウトの値がファイル拡張子を含んでいない場合は、デフォルト値である `.php` を使います。
### 入れ子のレイアウト <a name="nested-layouts"></a>
ときとして、あるレイアウトの中に別のレイアウトを入れたい場合があるでしょう。例えば、
ウェブサイトの別々のセクションにおいて、違うレイアウトを使いたいけれども、
それらのレイアウトは全て、全体としての HTML5 ページ構造を生成する同一の基本レイアウトを
共有している、という場合です。この目的を達することは、次のように、子レイアウトの中で
[[yii\base\View::beginContent()|beginContent()]] と [[yii\base\View::endContent()|endContent()]]
を呼ぶことで可能になります:
```php
<?php $this->beginContent('@app/views/layouts/base.php'); ?>
... 子レイアウトのコンテンツをここに ...
<?php $this->endContent(); ?>
```
上のコードが示すように、子レイアウトのコンテンツは [[yii\base\View::beginContent()|beginContent()]] と
[[yii\base\View::endContent()|endContent()]] によって囲まれなければなりません。
[[yii\base\View::beginContent()|beginContent()]] に渡されるパラメータは、
親レイアウトで何であるかを指定するものです。レイアウトのファイルまたはエイリアスのどちらかを使うことが出来ます。
上記のアプローチを使って、2レベル以上のレイアウトを入れ子にすることも出来ます。
### ブロックを使う <a name="using-blocks"></a>
ブロックを使うと、ある場所でビューコンテンツを規定して、別の場所でそれを表示することが可能になります。
ブロックはたいていはレイアウトと一緒に使われます。例えば、ブロックをコンテンツビューで定義して、
それをレイアウトで表示する、ということが出来ます。
[[yii\base\View::beginBlock()|beginBlock()]] と [[yii\base\View::endBlock()|endBlock()]]
を呼んでブロックを定義します。
すると、そのブロックを `$view->blocks[$blockID]` によってアクセス出来るようになります。
ここで `$blockID` は、定義したときにブロックに割り当てたユニークな ID を指します。
次の例は、どのようにブロックを使えば、レイアウトの特定の部分をコンテンツビューで
カスタマイズすることが出来るかを示すものです。
最初に、コンテンツビューで、一つまたは複数のブロックを定義します。
```php
...
<?php $this->beginBlock('block1'); ?>
... block1 のコンテンツ ...
<?php $this->endBlock(); ?>
...
<?php $this->beginBlock('block3'); ?>
... block3 のコンテンツ ...
<?php $this->endBlock(); ?>
```
次に、レイアウトビューで、得ることが出来ればブロックをレンダリングし、ブロックが定義されていないときは
何らかの既定のコンテンツを表示します。
```php
...
<?php if (isset($this->blocks['block1'])): ?>
<?= $this->blocks['block1'] ?>
<?php else: ?>
... block1 の既定のコンテンツ ...
<?php endif; ?>
...
<?php if (isset($this->blocks['block2'])): ?>
<?= $this->blocks['block2'] ?>
<?php else: ?>
... block2 の既定のコンテンツ ...
<?php endif; ?>
...
<?php if (isset($this->blocks['block3'])): ?>
<?= $this->blocks['block3'] ?>
<?php else: ?>
... block3 の既定のコンテンツ ...
<?php endif; ?>
...
```
## ビューコンポーネントを使う <a name="using-view-components"></a>
[[yii\base\View|ビューコンポーネント]] はビューに関連する多くの機能を提供します。
ビューコンポーネントは、[[yii\base\View]] またはその子クラスの個別のインスタンスを作成することによっても取得できますが、
たいていの場合は、`view` アプリケーションコンポーネントを主として使うことになるでしょう。
このコンポーネントは [アプリケーションのコンフィギュレーション](structure-applications.md#application-configurations) の中で、次のようにして構成することが出来ます:
```php
[
// ...
'components' => [
'view' => [
'class' => 'app\components\View',
],
// ...
],
]
```
ビューコンポーネントは、次に挙げるビュー関連の有用な機能を提供します。それぞれについては、
独立の節で更に詳細に説明されます。
* [テーマ](output-theming.md): ウェブサイトのテーマを開発し変更することを可能にします。
* [フラグメントキャッシュ](caching-fragment.md): ウェブページの中の断片をキャッシュすることを可能にします。
* [クライアントスクリプトの取り扱い](output-client-scripts.md): CSS と JavaScript の登録とレンダリングをサポートします。
* [アセットバンドルの取り扱い](structure-assets.md): [アセットバンドル](structure-assets.md) の登録とレンダリングをサポートします。
* [代替のテンプレートエンジン](tutorial-template-engines.md): [Twig](http://twig.sensiolabs.org/)、[Smarty](http://www.smarty.net/) など、他のテンプレートエンジンを使用することを可能にします。
次に挙げるマイナーではあっても有用な諸機能は、ウェブページを開発するときに頻繁に使用するでしょう:
### ページタイトルを設定する <a name="setting-page-titles"></a>
どんなウェブページにもタイトルが無ければなりません。通常、タイトルタグは [layout](#layouts) の中で表示されます。しかし、
実際においては、多くの場合、タイトルはレイアウトではなくコンテンツビューで決められます。この問題を解決するために、
[[yii\web\View]] は、タイトル情報をコンテンツビューからレイアウトに渡すための [[yii\web\View::title|title]] プロパティを
提供しています。
この機能を利用するためには、全てのコンテンツビューにおいて、次のようにタイトルを設定します:
```php
<?php
$this->title = 'My page title';
?>
```
そして、レイアウトビューで、`<head>` セクションに次のコードを忘れずに書くようにします:
```php
<title><?= Html::encode($this->title) ?></title>
```
### メタタグを登録する <a name="registering-meta-tags"></a>
ウェブページは、通常、いろいろな関係者によって必要とされるさまざまなメタタグを生成する必要があります。ページタイトルと同じように、
メタタグは `<head>` セクションに出現して、通常はレイアウトの中で生成されます。
どのようなメタタグを生成するかをコンテンツビューの中で指定したい場合は、下記のように、
[[yii\web\View::registerMetaTag()]] をコンテンツビューの呼ぶことが出来ます:
```php
<?php
$this->registerMetaTag(['name' => 'keywords', 'content' => 'yii, framework, php']);
?>
```
上記のコードは、ビューコンポーネントによって "keywords" メタタグを登録するものです。登録されたメタタグは、
レイアウトがレンダリングを完了した後でレンダリングされます。すなわち、レイアウトの中で [[yii\web\View::head()]]
を呼び出した場所に、次の HTML コードが生成されて挿入されます:
```php
<meta name="keywords" content="yii, framework, php">
```
[[yii\web\View::registerMetaTag()]] を複数回呼び出した場合は、メタタグが同じものか否かに関係なく、
複数のメタタグが登録されることに注意してください。
ある型のメタタグのインスタンスが一つだけになることを保証したい場合は、このメソッドを呼ぶときに第二のパラメータとして
キーを指定することが出来ます。例えば、次のコードでは、二つの "description" メタタグを登録していますが、
二番目のものだけがレンダリングされることになります。
```html
$this->registerMetaTag(['name' => 'description', 'content' => '俺が Yii で作ったクールなウェブサイトだぜぃ!!'], 'description');
$this->registerMetaTag(['name' => 'description', 'content' => '面白いアライグマに関するウェブサイトです。'], 'description');
```
### リンクタグを登録する <a name="registering-link-tags"></a>
[メタタグ](#registering-meta-tags) と同じように、リンクタグも多くの場合において有用なものです。例えば、favicon をカスタマイズしたり、
RSS フィードを指し示したり、OpenID を別のサーバに委任したり、等々。リンクタグも、[[yii\web\View::registerLinkTag()]] を使って、
メタタグと同じような方法で取り扱うことが出来ます。例えば、コンテンツビューにおいて、次のようにしてリンクタグを登録することが出来ます。
```php
$this->registerLinkTag([
'title' => 'Yii ライブニューズ',
'rel' => 'alternate',
'type' => 'application/rss+xml',
'href' => 'http://www.yiiframework.com/rss.xml/',
]);
```
上記のコードは、次の結果になります。
```html
<link title="Yii ライブニューズ" rel="alternate" type="application/rss+xml" href="http://www.yiiframework.com/rss.xml/">
```
[[yii\web\View::registerMetaTag()|registerMetaTags()]] と同じように、[[yii\web\View::registerLinkTag()|registerLinkTag()]]
を呼ぶときにキーを指定すると、同じリンクタグを繰り返して生成するのを避けることが出来ます。
## ビューのイベント <a name="view-events"></a>
[[yii\base\View|ビューコンポーネント]] はビューをレンダリングする過程においていくつかのイベントをトリガします。
これらのイベントに反応することによって、ビューにコンテンツを注入したり、
エンドユーザに送信される前にレンダリング結果を加工したりすることが出来ます。
- [[yii\base\View::EVENT_BEFORE_RENDER|EVENT_BEFORE_RENDER]]: コントローラでファイルをレンダリングする前にトリガされます。
このイベントのハンドラは、[[yii\base\ViewEvent::isValid]] を false にセットして、レンダリングのプロセスをキャンセルすることが出来ます。
- [[yii\base\View::EVENT_AFTER_RENDER|EVENT_AFTER_RENDER]]: ファイルのレンダリングの後、[[yii\base\View::afterRender()]] を呼ぶことによってトリガされます。
このイベントのハンドラは、レンダリング結果を [[yii\base\ViewEvent::output]] によって取得することが出来、
このプロパティを修正してレンダリング結果を変更することが出来ます。
- [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]]: レイアウトの中で [[yii\base\View::beginPage()]] を呼ぶことによってトリガされます。
- [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]]: レイアウトの中で [[yii\base\View::endPage()]] を呼ぶことによってトリガされます。
- [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]]: レイアウトの中で [[yii\web\View::beginBody()]] を呼ぶことによってトリガされます。
- [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]]: レイアウトの中で [[yii\web\View::endBody()]] を呼ぶことによってトリガされます。
例えば、次のコードはページの body の最後に現在の日付を注入するものです:
```php
\Yii::$app->view->on(View::EVENT_END_BODY, function () {
echo date('Y-m-d');
});
```
## 静的なページをレンダリングする <a name="rendering-static-pages"></a>
静的なページというのは、主たるコンテンツのほとんどが静的なもので、コントローラからプッシュされる動的なデータに
アクセスする必要がないページを指します。
静的なページは、そのコードをビューに置き、そして、コントローラで次のようなコードを使うと表示することが出来ます:
```php
public function actionAbout()
{
return $this->render('about');
}
```
ウェブサイトが多くの静的なページを含んでいる場合、同じようなコードを何度も繰り返すのは非常に面倒くさいでしょう。
この問題を解決するために、[[yii\web\ViewAction]] という [スタンドアロンアクション](structure-controllers.md#standalone-actions)
をコントローラに導入することが出来ます。例えば、
```php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public function actions()
{
return [
'page' => [
'class' => 'yii\web\ViewAction',
],
];
}
}
```
このようにすると、ディレクトリ `@app/views/site/pages` の下に `about` という名前のビューを作成したときに、
次の URL によってこのビューを表示することが出来るようになります:
```
http://localhost/index.php?r=site/page&view=about
```
`view` という `GET` パラメータが、どのビューがリクエストされているかを [[yii\web\ViewAction]] に教えます。
そこで、アクションはこのビューをディレクトリ `@app/views/site/pages` の下で探します。
[[yii\web\ViewAction::viewPrefix]] を構成して、ビューを探すディレクトリを変更することが出来ます。
## 最善の慣行 <a name="best-practices"></a>
ビューはエンドユーザが望む形式でモデルを表現することに対して責任を持ちます。一般的に、ビューは
* 主として表示目的のコードを含むべきです。例えば、HTML、そしてデータをたどり、書式化してレンダリングする簡単な PHP コードなど。
* DB クエリを実行するコードは含むべきではありません。そのようなコードはモデルの中で実行されるべきです。
* `$_GET``$_POST` のようなリクエストデータに直接アクセスするべきではありません。それはコントローラの仕事です。
リクエストデータが必要な場合は、コントローラからビューにプッシュされるべきです。
* モデルのプロパティを読み出すことが出来ます。しかし、それを修正するべきではありません。
ビューを管理しやすいものにするために、複雑すぎるビューや、冗長なコードをあまりに多く含むビューを作ることは避けましょう。
この目的を達するために、次のテクニックを使うことが出来ます:
* 共通の表示セクション (ページのヘッダやフッタなど) を表すために [レイアウト](#layouts) を使う。
* 複雑なビューはいくつかの小さなビューに分割する。既に説明したレンダリングのメソッドを使えば、
小さなビューをレンダリングして大きなビューを組み上げることが出来る。
* ビューの構成要素として [ウィジェット](structure-widgets.md) を使う。
* ビューでデータを変換し書式化するためのヘルパークラスを作成して使う。

0
docs/guide-pt-BR/images/application-lifecycle.graphml → docs/guide-pt-BR/images/request-lifecycle.graphml

0
docs/guide-pt-BR/images/application-lifecycle.png → docs/guide-pt-BR/images/request-lifecycle.png

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

2
docs/guide-pt-BR/start-workflow.md

@ -89,7 +89,7 @@ Ciclo de Vida da Requisição <a name="request-lifecycle"></a>
O diagrama a seguir demonstra como uma aplicação gerencia uma requisição.
![Ciclo de Vida da Requisição](images/application-lifecycle.png)
![Ciclo de Vida da Requisição](images/request-lifecycle.png)
1. Um usuário faz uma requisiçao ao [script de entrada](structure-entry-scripts.md) `web/index.php`.
2. O script de entrada carrega a [configuração](concept-configurations.md) da

6
docs/guide-ru/caching-fragment.md

@ -29,7 +29,7 @@ if ($this->beginCache($id)) {
### Срок хранения <a name="duration"></a>
Наверное, наиболее часто используемым параметром является [[yii\widgets\FragmentCache::duration|duration]].
Он определяет какое количество секунд содержимое будет оставаться действительным (корректным). Следующий код помещает фрагмент в кэш не более, чем на час::
Он определяет какое количество секунд содержимое будет оставаться действительным (корректным). Следующий код помещает фрагмент в кэш не более, чем на час:
```php
if ($this->beginCache($id, ['duration' => 3600])) {
@ -83,7 +83,7 @@ if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {
### Переключение кэширования <a name="toggling-caching"></a>
Иногда может потребоваться включать кеширование фрагментов только для определённых условий. Например, страницу с формой мы хотим кэшировать только тогда, когда обращение к ней произошло впервые (посредством GET запроса). Любое последующее отображение формы (посредством POST запроса) не должно быть кэшировано, потому что может содержать данные, введённые пользователем. Для этого мы задаём параметр [[yii\widgets\FragmentCache::enabled|enabled]]:
Иногда может потребоваться включать кэширование фрагментов только для определённых условий. Например, страницу с формой мы хотим кэшировать только тогда, когда обращение к ней произошло впервые (посредством GET запроса). Любое последующее отображение формы (посредством POST запроса) не должно быть кэшировано, потому что может содержать данные, введённые пользователем. Для этого мы задаём параметр [[yii\widgets\FragmentCache::enabled|enabled]]:
```php
if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {
@ -117,7 +117,7 @@ if ($this->beginCache($id1)) {
}
```
Параметры кэширования могут быть различными для вложенных кэшей. Например, внутренний и внешний кэши в вышеприведённом примере могут иметь разные сроки хранения. Даже когда данные внешнего кэша уже не являются актуальными, внутренний кеш может содержать актуальный фрагмент. Тем не менее, обратное не верно. Если внешний кэш актуален, данные будут отдаваться из него даже если внутренний кэш содержит устаревшие данные. Следует проявлять осторожность при выставлении срока хранения и задания зависимостей для вложенных кэшей. В противном случае вы можете получить устаревшие данные.
Параметры кэширования могут быть различными для вложенных кэшей. Например, внутренний и внешний кэши в вышеприведённом примере могут иметь разные сроки хранения. Даже когда данные внешнего кэша уже не являются актуальными, внутренний кэш может содержать актуальный фрагмент. Тем не менее, обратное не верно. Если внешний кэш актуален, данные будут отдаваться из него даже если внутренний кэш содержит устаревшие данные. Следует проявлять осторожность при выставлении срока хранения и задания зависимостей для вложенных кэшей. В противном случае вы можете получить устаревшие данные.
## Динамическое содержимое <a name="dynamic-content"></a>

2
docs/guide-ru/caching-http.md

@ -104,7 +104,7 @@ Cache-Control: public, max-age=3600
## Ограничитель кэша сессий <a name="session-cache-limiter"></a>
Когда на странице используются сессии, PHP автоматически отправляет некоторые связанные с кэшем HTTP заголовки, определённые в настройке `session.cache_limiter` в php.ini. Эти заголовки могут вмешиваться или отключать кэширование, которое вы ожидаете от `HttpCache`. Чтобы предотвратить эту проблему, по-умолчанию `HttpCache` будет автоматически отключать отправку этих заголовков. Если вы хотите изменить это поведение, вы должны настроить свойство [[yii\filters\HttpCache::sessionCacheLimiter]]. Это свойство может принимать строковое значение, включая `public`, `private`, `private_no_expire` и `nocache`. Пожалуйста, обратитесь к руководству PHP о [session_cache_limiter()](http://www.php.net/manual/en/function.session-cache-limiter.php)
Когда на странице используются сессии, PHP автоматически отправляет некоторые связанные с кэшем HTTP заголовки, определённые в настройке `session.cache_limiter` в php.ini. Эти заголовки могут вмешиваться или отключать кэширование, которое вы ожидаете от `HttpCache`. Чтобы предотвратить эту проблему, по умолчанию `HttpCache` будет автоматически отключать отправку этих заголовков. Если вы хотите изменить это поведение, вы должны настроить свойство [[yii\filters\HttpCache::sessionCacheLimiter]]. Это свойство может принимать строковое значение, включая `public`, `private`, `private_no_expire` и `nocache`. Пожалуйста, обратитесь к руководству PHP о [session_cache_limiter()](http://www.php.net/manual/en/function.session-cache-limiter.php)
для объяснения этих значений.

4
docs/guide-ru/caching-page.md

@ -2,7 +2,7 @@
=================
Кэширование страниц — это кэширование всего содержимого страницы на стороне сервера. Позже, когда эта страница
будет снова запрошена, сервер вернет её из кэша вместо того что бы генерировать её заново.
будет снова запрошена, сервер вернет её из кэша вместо того чтобы генерировать её заново.
Кэширование страниц осуществляется при помощи [фильтра действия](structure-filters.md) [[yii\filters\PageCache]] и
может быть использовано в классе контроллера следующим образом:
@ -27,7 +27,7 @@ public function behaviors()
}
```
Приведённый код задействует кэширование только для действия `index`. Содержимое страницы кешируется максимум на 60 секунд
Приведённый код задействует кэширование только для действия `index`. Содержимое страницы кэшируется максимум на 60 секунд
и варьируется в зависимости от текущего языка приложения. Кэшированная страница должна быть признана просроченной, если
общее количество постов изменилось.

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

@ -1,12 +1,12 @@
Настройки
========
Конфигурации
============
Настройки широко используются в Yii при создании новых объектов или при инициализации уже существующих объектов.
Обычно настройки включают в себя названия классов создаваемых объектов и список первоначальных значений
которые должны быть присвоены [свойствам](concept-properties.md) объекта. Также в настройках можно указать список
Конфигурации широко используются в Yii при создании новых объектов или при инициализации уже существующих объектов.
Обычно конфигурации включают в себя названия классов создаваемых объектов и список первоначальных значений,
которые должны быть присвоены [свойствам](concept-properties.md) объекта. Также в конфигурациях можно указать список
[обработчиков событий](concept-events.md) объекта, и/или список [поведений](concept-behaviors.md) объекта.
Пример настроек подключения к базе данных и дальнейшей инициализации подключения:
Пример конфигурации подключения к базе данных и дальнейшей инициализации подключения:
```php
$config = [
@ -20,22 +20,22 @@ $config = [
$db = Yii::createObject($config);
```
Метод [[Yii::createObject()]] принимает в качестве аргумента массив настроек и создаёт объект указанного в них класса.
Метод [[Yii::createObject()]] принимает в качестве аргумента массив с конфигурацией и создаёт объект указанного в них класса.
При этом оставшаяся часть конфигурации используется для инициализации свойств, обработчиков событий и поведений объекта.
Если объект уже создан, вы можете использовать [[Yii::configure()]] для того, чтобы инициализировать свойства объекта
массивом настроек:
массивом с конфигурацией:
```php
Yii::configure($object, $config);
```
Обратите внимание, что в этом случае массив с настройками не должен содержать ключ `class`.
Обратите внимание, что в этом случае массив с конфигурацией не должен содержать ключ `class`.
## Формат настроек <a name="configuration-format"></a>
## Формат конфигурации <a name="configuration-format"></a>
Формат настроек выглядит следующим образом:
Формат конфигурации выглядит следующим образом:
```php
[
@ -53,14 +53,14 @@ Yii::configure($object, $config);
создаваемого объекта, а значения — начальными значениями свойств создаваемого объекта.
Таким способом могут быть установлены только публичные переменные объекта и его [свойства](concept-properties.md),
созданные через геттеры и сеттеры.
* Элементы `on eventName` указывают какие обработчики должны быть установлены для [событий](concept-events.md) объекта.
* Элементы `on eventName` указывают на то, какие обработчики должны быть прикреплены к [событиям](concept-events.md) объекта.
Обратите внимание, что ключи массива начинаются с `on `. Чтобы узнать весь список поддерживаемых видов
обработчиков событий обратитесь в раздел [события](concept-events.md)
* Элементы `as behaviorName` указывают какие [поведения](concept-behaviors.md) должны быть установлены для объекта.
Обратите внимание, что ключи массива начинаются с `as `. `$behaviorConfig` это массив для настройки
поведения, этот массив такой же как тот, о котором идет речь.
* Элементы `as behaviorName` указывают на то, какие [поведения](concept-behaviors.md) должны быть внедрены в объект.
Обратите внимание, что ключи массива начинаются с `as `; а `$behaviorConfig` представляет собой конфигурацию для
создания [поведения](concept-behaviors.md), похожую на все остальные конфигурации.
Пример настроек с установкой первоначальных значений свойств объекта, обработчика событий и поведения:
Пример конфигурации с установкой первоначальных значений свойств объекта, обработчика событий и поведения:
```php
[
@ -77,21 +77,21 @@ Yii::configure($object, $config);
```
## Использование настроек <a name="using-configurations"></a>
## Использование конфигурации <a name="using-configurations"></a>
Возможность настройки широко используется в Yii. В самом начале данной главы мы узнали как
Конфигурации повсеместно используются в Yii. В самом начале данной главы мы узнали как
создать объект с необходимыми параметрами используя метод [[Yii::createObject()]].
В данном разделе речь пойдет о настройках приложения и настройках виджетов — двух основных способов
использования настроек.
В данном разделе речь пойдет о конфигурации приложения и конфигурациях виджетов — двух основных способов
использования конфигурации.
### Настройки приложения <a name="application-configurations"></a>
### Конфигурация приложения <a name="application-configurations"></a>
Настройки [приложения](structure-applications.md) пожалуй самые сложные из используемых в фреймворке.
Причина в том, что класс [[yii\web\Application|application]] содержит большое количество настраиваемых
Конфигурация [приложения](structure-applications.md), пожалуй, самая сложная из используемых в фреймворке.
Причина в том, что класс [[yii\web\Application|application]] содержит большое количество конфигурируемых
свойств и событий. Более того, свойство приложения [[yii\web\Application::components|components]]
может принимать массив настроек для создания компонентов, регистрируемых на уровне приложения.
Пример настроек приложения для [шаблона приложения basic](start-basic.md).
может принимать массив с конфигурацией для создания компонентов, регистрируемых на уровне приложения.
Пример конфигурации приложения для [шаблона приложения basic](start-basic.md).
```php
$config = [
@ -125,22 +125,22 @@ $config = [
];
```
Ключ `class` в данных настройках не указывается. Причина в том, что класс вызывается по полному имени во
Ключ `class` в данной конфигурации не указывается. Причина в том, что класс вызывается по полному имени во
[входном скрипте](structure-entry-scripts.md):
```php
(new yii\web\Application($config))->run();
```
Для более подробной документации о настройке свойства приложения `components` обратитесь к главам
За более подробной документацией о настройках свойства `components` в конфигурации приложения обратитесь к главам
[приложения](structure-applications.md) и [Service Locator](concept-service-locator.md).
### Настройки виджетов <a name="widget-configurations"></a>
### Конфигурации виджетов <a name="widget-configurations"></a>
При использовании [виджетов](structure-widgets.md) часто возникает необходимость изменить параметры виджета с помощью
настроек. Для создания виджета можно использовать два метода: [[yii\base\Widget::widget()]] и
[[yii\base\Widget::beginWidget()]]. Оба метода принимают настройки в виде массива:
конфигурации. Для создания виджета можно использовать два метода: [[yii\base\Widget::widget()]] и
[[yii\base\Widget::beginWidget()]]. Оба метода принимают конфигурацию в виде PHP массива:
```php
use yii\widgets\Menu;
@ -161,11 +161,11 @@ echo Menu::widget([
Обратите внимание что параметр `class` НЕ передается, так как полное имя уже указано.
## Файлы Настроек <a name="configuration-files"></a>
## Конфигурационные файлы <a name="configuration-files"></a>
Если настройки сложные, то их, как правило, разделяют по нескольким PHP файлам. Такие файлы называют
*файлами настроек* или *конфигурационными файлами*. Файл настроек возвращает массив PHP с настройками.
Например, настройки приложения можно хранить в отдельном файле `web.php`, как показано ниже:
Если конфигурация очень сложная, то её, как правило, разделяют по нескольким PHP файлам. Такие файлы называют
*Конфигурационными файлами*. Конфигурационный файл возвращает массив PHP являющийся конфигурацией.
Например, конфигурацию приложения можно хранить в отдельном файле `web.php`, как показано ниже:
```php
return [
@ -207,7 +207,7 @@ return [
];
```
Чтобы получить настройки, хранимые в файле, достаточно подключить файл с помощью `require`:
Чтобы получить конфигурацию, хранящуюся в файле, достаточно подключить файл с помощью `require`:
```php
$config = require('path/to/web.php');
@ -215,12 +215,10 @@ $config = require('path/to/web.php');
```
## Настройки по умолчанию <a name="default-configurations"></a>
## Значения конфигурации по умолчанию <a name="default-configurations"></a>
Метод [[Yii::createObject()]] реализован с использованием [dependency injection container](concept-di-container.md).
Это позволяет указывать так называемые *настройки по умолчанию*, которые будут применены ко ВСЕМ экземплярам классов
во время их инициализации методом [[Yii::createObject()]]. Настройки по умолчанию указываются с помощью метода
`Yii::$container->set()` на этапе [предварительной загрузки](runtime-bootstrapping.md).
Это позволяет задавать так называемые *значения конфигурации по умолчанию*, которые будут применены ко ВСЕМ экземплярам классов во время их инициализации методом [[Yii::createObject()]]. Значения конфигурации по умолчанию указываются с помощью метода `Yii::$container->set()` на этапе [предварительной загрузки](runtime-bootstrapping.md).
Например, если мы хотим изменить виджет [[yii\widgets\LinkPager]] так, чтобы все виджеты данного вида показывали максимум
5 кнопок на странице вместо 10 (как это установлено изначально), можно использовать следующий код:
@ -231,15 +229,15 @@ $config = require('path/to/web.php');
]);
```
Если бы мы не установили настройки по умолчанию, то тогда нам нужно было бы каждый раз при использовании LinkPager
указывать настройки `maxButtonCount`.
Без использования значений конфигурации по умолчанию, при использовании LinkPager, вам пришлось бы каждый раз
задавать значение `maxButtonCount`.
## Константы окружения <a name="environment-constants"></a>
Настройки могут различаться в зависимости от окружения, в котором происходит запуск приложения. Например,
в окружении разработчика вы используете базу данных `mydb_dev`, а на продакшн сервере базу данных
`mydb_prod`. Для упрощения смены окружений в Yii существует константа `YII_ENV`. Вы можете указать её во
Конфигурации могут различаться в зависимости от режима, в котором происходит запуск приложения. Например,
в окружении разработчика (development) вы используете базу данных `mydb_dev`, а в эксплуатационном (production) окружении
базу данных `mydb_prod`. Для упрощения смены окружений в Yii существует константа `YII_ENV`. Вы можете указать её во
[входном скрипте](structure-entry-scripts.md) своего приложения:
```php
@ -248,20 +246,20 @@ defined('YII_ENV') or define('YII_ENV', 'dev');
`YII_ENV` может принимать следующие значения:
- `prod`: production окружение, т.е. окружение для конечного сервера. Константа `YII_ENV_PROD` установлена в true.
- `prod`: окружение production, т.е. эксплуатационный режим сервера. Константа `YII_ENV_PROD` установлена в true.
Значение по умолчанию.
- `dev`: development окружение, т.е. окружение для разработки. Константа `YII_ENV_DEV` установлена в true.
- `test`: testing окружение, т.е. окружения для тестирования. Константа `YII_ENV_TEST` установлена в true.
- `dev`: окружение development, т.е. режим для разработки. Константа `YII_ENV_DEV` установлена в true.
- `test`: окружение testing, т.е. режим для тестирования. Константа `YII_ENV_TEST` установлена в true.
Используя эти константы вы можете изменить настройки в соответствии с вашим окружением.
Например, чтобы включить [отладочную панель и отладчик](tool-debugger.md) в development окружении вы можете использовать
следующие настройки приложения:
Используя эти константы, вы можете задать в конфигурации значения параметров зависящие от текущего окружения.
Например, чтобы включить [отладочную панель и отладчик](tool-debugger.md) в режиме разработки, вы можете использовать
следующий код в конфигурации приложения:
```php
$config = [...];
if (YII_ENV_DEV) {
// настройки для 'dev' окружения
// значения параметров конфигурации для окружения разработки 'dev'
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
}

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

@ -98,7 +98,7 @@ $container = new \yii\di\Container;
// регистрация имени класса, как есть. это может быть пропущено.
$container->set('yii\db\Connection');
// регистраци интерфейса
// регистрация интерфейса
// Когда класс зависит от интерфейса, соответствующий класс
// будет использован в качестве зависимости объекта
$container->set('yii\mail\MailInterface', 'yii\swiftmailer\Mailer');
@ -172,7 +172,7 @@ $engine = $container->get('app\components\SearchEngine', [$apiKey], ['type' => 1
```
За кулисами, контейнер внедрения зависимостей делает гораздо больше работы, чем просто создание нового объекта.
Прежде всего, контейнер, осмотрит конструктор класса, что бы узнать имя зависимого класса или интерфейса, а затем автоматически разрешит эти зависимости рекурсивно.
Прежде всего, контейнер, осмотрит конструктор класса, чтобы узнать имя зависимого класса или интерфейса, а затем автоматически разрешит эти зависимости рекурсивно.
Следующий код демонстрирует более сложный пример. Класс `UserLister` зависит от объекта, реализующего интерфейс `UserFinderInterface`; класс `UserFinder` реализует этот интерфейс и зависит от
объекта `Connection`. Все эти зависимости были объявлены через тип подсказки параметров конструктора класса.
@ -240,7 +240,7 @@ $lister = new UserLister($finder);
Yii создаёт контейнер внедрения зависимостей когда вы подключаете файл `Yii.php` во [входном скрипте](structure-entry-scripts.md)
вашего приложения. Контейнер внедрения зависимостей доступен через [[Yii::$container]]. При вызове [[Yii::createObject()]],
метод на самом деле вызовет метод контейнера [[yii\di\Container::get()|get()]], что бы создать новый объект.
метод на самом деле вызовет метод контейнера [[yii\di\Container::get()|get()]], чтобы создать новый объект.
Как упомянуто выше, контейнер внедрения зависимостей автоматически разрешит зависимости (если таковые имеются) и внедрит их в только что созданный объект.
Поскольку Yii использует [[Yii::createObject()]] в большей части кода своего ядра для создания новых объектов, это означает,
что вы можете настроить глобальные объекты, имея дело с [[Yii::$container]].
@ -307,7 +307,7 @@ class HotelController extends Controller
Итог <a name="summary"></a>
-------
Как dependency injection, так и [service locator](concept-service-locator.md) являются популярными паттернами проектирования, которые позволяют
создавать программное обеспечение в слабосвязаной и более тестируемой манере.
создавать программное обеспечение в слабосвязанной и более тестируемой манере.
Мы настоятельно рекомендуем к прочтению
[статью Мартина Фаулера](http://martinfowler.com/articles/injection.html), для более глубокого понимания dependency injection и service locator.

0
docs/guide-ru/images/application-lifecycle.graphml → docs/guide-ru/images/request-lifecycle.graphml

0
docs/guide-ru/images/application-lifecycle.png → docs/guide-ru/images/request-lifecycle.png

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

2
docs/guide-ru/intro-upgrade-from-v1.md

@ -445,7 +445,7 @@ Yii 2.0 осуществляет жадную загрузку связи не
$customers = Customer::find()->asArray()->all();
```
Ещё одно изменение связано с тем, что вы больше не можете определять значения по-умолчанию через public свойства.
Ещё одно изменение связано с тем, что вы больше не можете определять значения по умолчанию через public свойства.
Вы должны установить их в методе `init` вашего класса, если это требуется.
```php

4
docs/guide-ru/intro-yii.md

@ -10,7 +10,7 @@ Yii – это высокопроизводительный компонентн
------------------------------------------
Yii – это универсальный фреймворк и может быть задействован во всех типах веб приложений. Благодаря его компонентной
структуре и отличной поддержке кеширования, фреймворк особенно подходит для разработки таких крупных проектов как
структуре и отличной поддержке кэширования, фреймворк особенно подходит для разработки таких крупных проектов как
порталы, форумы, CMS, магазины или RESTful-приложения.
@ -23,7 +23,7 @@ Yii – это универсальный фреймворк и может бы
- Yii придерживается философии простого и элегантного кода не пытаясь усложнять дизайн только ради следования каким-либо
шаблонам проектирования.
- Yii является full-stack фреймворком и включает в себя проверенные и хорошо зарекомендовавшие себя возможности, такие как
ActiveRecord для реляционных и NoSQL баз данных, поддержку REST API, многоуровневое кеширование и другие.
ActiveRecord для реляционных и NoSQL баз данных, поддержку REST API, многоуровневое кэширование и другие.
- Yii отлично расширяем. Вы можете настроить или заменить практически любую часть основного кода. Используя архитектуру расширений легко делиться кодом или использовать код сообщества.
- Одна из главных целей Yii – производительность.

2
docs/guide-ru/rest-quick-start.md

@ -5,7 +5,7 @@ Yii включает полноценный набор средств для у
В частности это следующие возможности:
* Быстрое создание прототипов с поддержкой распространенных API к [Active Record](db-active-record.md);
* Настройка формата ответа (JSON и XML реализованы по-умолчанию);
* Настройка формата ответа (JSON и XML реализованы по умолчанию);
* Получение сериализованных объектов с нужной вам выборкой полей;
* Надлежащее форматирование данных и ошибок при их валидации;
* Поддержка [HATEOAS](http://en.wikipedia.org/wiki/HATEOAS);

2
docs/guide-ru/rest-rate-limiting.md

@ -18,7 +18,7 @@
Вы можете использовать два столбца в таблице user для хранения количества разрешённых запросов и времени последней проверки.
В методах `loadAllowance()` и `saveAllowance()` можно реализовать чтение и сохранение значений этих столбцов в соответствии
с данными текущего аутентифицированного пользователя. Для улучшения производительности можно попробовать хранить эту
информацию в кеше или NoSQL хранилище.
информацию в кэше или NoSQL хранилище.
Как только соответствующий интерфейс будет реализован в классе identity, Yii начнёт автоматически проверять ограничения
частоты запросов при помощи [[yii\filters\RateLimiter]], фильтра действий для [[yii\rest\Controller]]. При превышении

4
docs/guide-ru/rest-resources.md

@ -26,7 +26,7 @@ RESTful API строятся вокруг доступа к *ресурсам*
Вы можете указать какие данные включать в представление ресурса в виде массива путём переопределения методов
[[yii\base\Model::fields()|fields()]] и/или [[yii\base\Model::extraFields()|extraFields()]]. Разница между ними в том,
что первый определяет набор полей которые всегда будут включены в массив, а второй определяет дополнительные поля, которые
что первый определяет набор полей, которые всегда будут включены в массив, а второй определяет дополнительные поля, которые
пользователь может запросить через параметр `expand`:
```
@ -36,7 +36,7 @@ http://localhost/users
// вернёт только поля id и email, если они объявлены в методе fields()
http://localhost/users?fields=id,email
// вернёт все поля обявленные в fields() и поле profile если оно указано в extraFields()
// вернёт все поля объявленные в fields() и поле profile если оно указано в extraFields()
http://localhost/users?expand=profile
// вернёт только id, email и profile, если они объявлены в fields() и extraFields()

126
docs/guide-ru/runtime-requests.md

@ -0,0 +1,126 @@
Запросы
========
Запросы, сделанные к приложению, представлены в терминах [[yii\web\Request]] объектов, которые предоставляют информацию о параметрах запроса, HTTP заголовках, cookies и т.д. Для получения доступа к текущему запросу вы должны обратиться к объекту `request` [application component](structure-application-components.md), который по умолчанию является экземпляром [[yii\web\Request]].
## Параметры запроса <a name="request-parameters"></a>
Чтобы получить параметры запроса, вы должны вызвать методы [[yii\web\Request::get()|get()]] и [[yii\web\Request::post()|post()]] компонента `request`. Они возвращают значения переменных `$_GET` и `$_POST` соответственно. Например,
```php
$request = Yii::$app->request;
$get = $request->get();
// эквивалентно: $get = $_GET;
$id = $request->get('id');
// эквивалентно: $id = isset($_GET['id']) ? $_GET['id'] : null;
$id = $request->get('id', 1);
// эквивалентно: $id = isset($_GET['id']) ? $_GET['id'] : 1;
$post = $request->post();
// эквивалентно: $post = $_POST;
$name = $request->post('name');
// эквивалентно: $name = isset($_POST['name']) ? $_POST['name'] : null;
$name = $request->post('name', '');
// эквивалентно: $name = isset($_POST['name']) ? $_POST['name'] : '';
```
> Информация: Вместо того, чтобы обращаться напрямую к переменным `$_GET` и `$_POST` для получения параметров запроса, рекомендуется
чтобы вы обращались к ним через компонент `request` как было показано выше. Это упростит написание тестов, поскольку вы можете создать mock компонент запроса с не настоящими данными запроса.
При реализации [RESTful API](rest-quick-start.md), зачастую вам требуется получить параметры, которые были отправлены через PUT, PATCH или другие [методы запроса](#request-methods). Вы можете получить эти параметры, вызвав метод [[yii\web\Request::getBodyParam()]]. Например,
```php
$request = Yii::$app->request;
// возвращает все параметры
$params = $request->bodyParams;
// возвращает параметр "id"
$param = $request->getBodyParam('id');
```
> Информация: В отличии от `GET` параметров, параметры, которые были переданы через `POST`, `PUT`, `PATCH` и д.р. отправляются в теле запроса.
Компонент `request` будет обрабатывать эти параметры, когда вы попробуете к ним обратиться через методы, описанные выше.
Вы можете настроить способ обработки этих параметров через настройку свойства [[yii\web\Request::parsers]].
## Методы запроса <a name="request-methods"></a>
Вы можете получить названия HTTP метода, используемого в текущем запросе, обратившись к выражению `Yii::$app->request->method`.
Также имеется целый набор логических свойств для проверки соответствует ли текущий метод определённому типу запроса.
Например,
```php
$request = Yii::$app->request;
if ($request->isAjax) { // является ли текущий запрос AJAX запросом }
if ($request->isGet) { // является ли текущий запрос GET запросом }
if ($request->isPost) { // является ли текущий запрос POST запросом }
if ($request->isPut) { // является ли текущий запрос PUT запросом }
```
## URL запроса <a name="request-urls"></a>
Компонент `request` предоставляет множество способов изучения текущего запрашиваемого URL.
Если предположить, что URL запроса будет `http://example.com/admin/index.php/product?id=100`, то вы можете получить различные части этого адреса так как это показано ниже:
* [[yii\web\Request::url|url]]: вернёт адрес `/admin/index.php/product?id=100`, который содержит URL без информации об имени хоста.
* [[yii\web\Request::absoluteUrl|absoluteUrl]]: вернёт адрес `http://example.com/admin/index.php/product?id=100`,
который содержит полный URL, включая имя хоста.
* [[yii\web\Request::hostInfo|hostInfo]]: вернёт адрес `http://example.com`, который содержит только имя хоста.
* [[yii\web\Request::pathInfo|pathInfo]]: вернёт адрес `/product`, который содержит часть между адресом начального скрипта и параметрами запроса, которые идут после знака вопроса.
* [[yii\web\Request::queryString|queryString]]: вернёт адрес `id=100`, который содержит часть URL после знака вопроса.
* [[yii\web\Request::baseUrl|baseUrl]]: вернёт адрес `/admin`, который является частью URL после информации о хосте и перед именем входного скрипта.
* [[yii\web\Request::scriptUrl|scriptUrl]]: вернёт адрес `/admin/index.php`, который содержит URL без информации о хосте и параметрах запроса.
* [[yii\web\Request::serverName|serverName]]: вернёт адрес `example.com`, который содержит имя хоста в URL.
* [[yii\web\Request::serverPort|serverPort]]: вернёт 80, что является адресом порта, который использует веб-сервер.
## HTTP заголовки <a name="http-headers"></a>
Вы можете получить информацию о HTTP заголовках через [[yii\web\HeaderCollection|header collection]], возвращаемыми свойством [[yii\web\Request::headers]]. Например,
```php
// переменная $headers является объектом yii\web\HeaderCollection
$headers = Yii::$app->request->headers;
// возвращает значения заголовка Accept
$accept = $headers->get('Accept');
if ($headers->has('User-Agent')) { // есть ли в запросе заголовок User-Agent }
```
Компонент `request` также предоставляет доступ к некоторым часто используемым заголовкам, включая
* [[yii\web\Request::userAgent|userAgent]]: возвращает значение заголовка `User-Agent`.
* [[yii\web\Request::contentType|contentType]]: возвращает значение заголовка `Content-Type`, который указывает на MIME тип данных в теле запроса.
* [[yii\web\Request::acceptableContentTypes|acceptableContentTypes]]: возвращает список MIME типов данных, которые принимаются пользователем.
Возвращаемый список типов будет отсортирован по показателю качества. Типы с более высокими показателями будут первыми в списке.
* [[yii\web\Request::acceptableLanguages|acceptableLanguages]]: возвращает языки, которые поддерживает пользователь.
Список языков будет отсортирован по уровню предпочтения. Наиболее предпочитаемый язык будет первым в списке.
Если ваше приложение поддерживает множество языков и вы хотите показать страницу на языке, который предпочитает пользователь,
то вы можете воспользоваться языковым методом согласования (negotiation) [[yii\web\Request::getPreferredLanguage()]].
Этот метод принимает список поддерживаемых языков в вашем приложении, сравнивает их с [[yii\web\Request::acceptableLanguages|acceptableLanguages]]
и возвращает наиболее подходящий язык.
> Подсказка: Вы также можете использовать фильтр [[yii\filters\ContentNegotiator|ContentNegotiator]] для динамического определения
какой тип содержимого и язык должен использоваться в ответе. Фильтр реализует согласование содержимого на основе свойств и методов, описанных выше.
## Информация о клиенте <a name="client-information"></a>
Вы можете получить имя хоста и IP адрес пользователя через свойства [[yii\web\Request::userHost|userHost]]
и [[yii\web\Request::userIP|userIP]] соответственно. Например,
```php
$userHost = Yii::$app->request->userHost;
$userIP = Yii::$app->request->userIP;
```

2
docs/guide-ru/runtime-url-handling.md

@ -85,7 +85,7 @@ Url::previous(); // получить ранее сохраненный URL
>**Совет**: чтобы сгенерировать URL с хэштэгом, например `/index.php?r=site/page&id=100#title`, укажите параметр `#` в хелпере таким образом:
`Url::to(['post/read', 'id' => 100, '#' => 'title'])`.
Также существует метод `Url::canonical()` , который позволяет создать [канонический URL](https://en.wikipedia.org/wiki/Canonical_link_element) (статья на англ., перевода пока нет) для текущего действия. Этот метод при создании игнорирует все параметры действия кроме тех, которые были переданы как аргументы.
Также существует метод `Url::canonical()`, который позволяет создать [канонический URL](https://en.wikipedia.org/wiki/Canonical_link_element) (статья на англ., перевода пока нет) для текущего действия. Этот метод при создании игнорирует все параметры действия кроме тех, которые были переданы как аргументы.
Пример:
```php

75
docs/guide-ru/start-installation.md

@ -5,47 +5,67 @@
Первый способ предпочтительнее так как позволяет установить новые [расширения](structure-extensions.md)
или обновить Yii одной командой.
> Примечание: В отличие от Yii 1, после стандартной установки Yii 2 мы получаем как фреймворк, так и шаблон приложения.
Установка при помощи Composer <a name="installing-via-composer"></a>
-----------------------
Если Composer еще не установлен это можно сделать по инструкции на
[getcomposer.org](https://getcomposer.org/download/), или одним из нижеперечисленных способов:
* на Linux или Mac, используйте следующую команду:
[getcomposer.org](https://getcomposer.org/download/), или одним из нижеперечисленных способов. На Linux или Mac
используйте следующую команду:
```
curl -s http://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
```
* на Windows, скачайте и запустите [Composer-Setup.exe](https://getcomposer.org/Composer-Setup.exe).
На Windows, скачайте и запустите [Composer-Setup.exe](https://getcomposer.org/Composer-Setup.exe).
В случае возникновения проблем или если вам необходима дополнительная информация, обращайтесь
к [документации Composer](https://getcomposer.org/doc/) .
к [документации Composer](https://getcomposer.org/doc/).
Если у вас уже установлен Composer, обновите его при помощи `composer self-update`.
После установки Composer устанавливать Yii можно запустив следующую команду в папке доступной через веб:
```
composer create-project --prefer-dist yiisoft/yii2-app-basic basic
```
composer global require "fxp/composer-asset-plugin:1.0.0-beta3"
composer create-project --prefer-dist yiisoft/yii2-app-basic basic
Первая команда устанавливает [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/),
который позводяет управлять зависимостями пакетов bower и npm через Composer. Эту команду достаточно выполнить один раз.
Вторая команда устанавливает Yii в директорию `basic`. Если хотите, можете выбрать другое имя директории.
Composer установит Yii (шаблонное приложение basic) в папку `basic`.
> **Подсказка**: Если хотите установить последнюю нестабильную версию Yii, вы можете добавить ключ `stability`:
```
composer create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic
```
Стоит отметить, что нестабилную версию Yii нельзя использовать на рабочем сервере.
> Примечание: В процессе установки Composer может запросить логин и пароль от Github потому как у API Github имеется
> ограничение на количество запросов. Это нормально потому как Composer в процессе работы запрашивает у Github большое
> количество информации для каждого пакета. Вход на Github повышает ограничение по запросам API и Composer может
> продолжить свою работу. Подробнее об этом можно прочитать в
> [документации Composer](https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens).
> Подсказка: Если вы хотите установить последнюю нестабильную ревизию Yii, можете использовать следующую команду,
> в которой присутствует [опция stability](https://getcomposer.org/doc/04-schema.md#minimum-stability):
>
> composer create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic
>
> Старайтесь не использовать нестабильную версию Yii на рабочих серверах потому как она может внезапно поломать код.
Установка из архива <a name="installing-from-archive-file"></a>
-------------------------------
Установка Yii из архива состоит из двух шагов:
Установка Yii из архива состоит из трёх шагов:
1. Скачайте архив по адресу [yiiframework.com](http://www.yiiframework.com/download/yii2-basic);
1. Скачайте архив с [yiiframework.com](http://www.yiiframework.com/download/);
2. Распакуйте скачанный архив в папку, доступную из Web.
3. В файле `config/web.php` добавьте сектетный ключ в значение `cookieValidationKey` (при установке через Composer
это происходит автоматически):
```php
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'enter your secret key here',
```
Другие опции установки <a name="other-installation-options"></a>
--------------------------
@ -64,18 +84,20 @@ composer create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic bas
Проверка установки <a name="verifying-installation"></a>
----------------------
Если вы установили приложение в директорию `basic` в корневой директории вашего веб сервера и имя сервера `hostname`,
запустить приложение можно открыв следующий URL через браузер:
После установки приложение будет доступно по следующему URL:
```
http://hostname/basic/web/index.php
http://localhost/basic/web/index.php
```
Здесь подразумевается, что вы установили приложение в директорию `basic` в корневой директории вашего веб сервера
сервер работает локально (`localhost`). Вам может потребоваться предварительно его настроить.
![Успешно установленный Yii](images/start-app-installed.png)
Вы должны увидеть страницу приветствия «Congratulations!». Если нет — проверьте требования Yii одним из способов:
* Браузером перейдите по адресу `http://hostname/basic/requirements.php`
* Браузером перейдите по адресу `http://localhost/basic/requirements.php`
* Или выполните команду в консоли:
```
@ -96,12 +118,14 @@ http://hostname/basic/web/index.php
его на рабочем сервере.
Приложение, установленное по инструкциям, приведённым выше, будет работать сразу как с [Apache](http://httpd.apache.org/),
так и с [Nginx](http://nginx.org/) под Windows и Linux.
так и с [Nginx](http://nginx.org/) под Windows и Linux с установленным PHP 5.4 и выше. Yii 2.0 также совместим с
[HHVM](http://hhvm.com/). Тем не менее, в некоторых случаях поведение при работе с HHVM отличается от обычного PHP.
Будьте внимательны.
На рабочем сервере вам наверняка захочется изменить URL приложения с `http://hostname/basic/web/index.php`
на `http://hostname/index.php`. Для этого необходимо изменить корневую директорию в настройках веб сервера так, чтобы та
указывала на `basic/web`. Дополнительно можно спрятать `index.php` следуя описанию в разделе «[Разбор и генерация URL](runtime-url-handling.md)».
Далее будет показано как настроить Apache и Nginx.
На рабочем сервере вам наверняка захочется изменить URL приложения с `http://www.example.com/basic/web/index.php`
на `http://www.example.com/index.php`. Для этого необходимо изменить корневую директорию в настройках веб сервера так,
чтобы та указывала на `basic/web`. Дополнительно можно спрятать `index.php` следуя описанию в разделе
«[Разбор и генерация URL](runtime-url-handling.md)». Далее будет показано как настроить Apache и Nginx.
> Информация: Устанавливая `basic/web` корневой директорией веб сервера вы защищаете от нежелательного доступа код и данные,
находящиеся на одном уровне с `basic/web`. Это делает приложение более защищенным.
@ -136,7 +160,8 @@ DocumentRoot "path/to/basic/web"
### Рекомендуемые настройки Nginx <a name="recommended-nginx-configuration"></a>
PHP должен быть установлен как [FPM SAPI](http://php.net/manual/ru/install.fpm.php) для [Nginx](http://wiki.nginx.org/).
Используйте следующие параметры Nginx и не забудьте заменить `path/to/basic/web` на корректный путь к `basic/web`.
Используйте следующие параметры Nginx и не забудьте заменить `path/to/basic/web` на корректный путь к `basic/web` и
`mysite.local` на ваше имя хоста.
```
server {

4
docs/guide-ru/start-workflow.md

@ -34,7 +34,7 @@ basic/ корневой каталог приложения
commands/ содержит классы консольных команд
controllers/ контроллеры
models/ модели
runtime/ файлы, которые генерирует Yii во время выполнения приложения (логи, кеш и т.п.)
runtime/ файлы, которые генерирует Yii во время выполнения приложения (логи, кэш и т.п.)
vendor/ содержит пакеты Composer'а и, собственно, сам фреймворк Yii
views/ виды приложения
web/ корневая директория Web приложения. Содержит файлы, доступные через Web
@ -62,7 +62,7 @@ basic/ корневой каталог приложения
На диаграмме показано как приложение обрабатывает запрос.
![Жизненный цикл запроса](images/application-lifecycle.png)
![Жизненный цикл запроса](images/request-lifecycle.png)
1. Пользователь обращается к [точке входа](structure-entry-scripts.md) `web/index.php`.
2. Скрипт загружает конфигурацию [configuration](concept-configurations.md) и создает экземпляр [приложения](structure-applications.md) для дальнейшей обработки запроса.

4
docs/guide-ru/structure-application-components.md

@ -50,14 +50,14 @@
## Встроенные компоненты приложения <a name="core-application-components"></a>
В Yii есть несколько *встроенных* компонентов приложения, с фиксированными ID и конфигурациями по-умолчанию. Например,
В Yii есть несколько *встроенных* компонентов приложения, с фиксированными ID и конфигурациями по умолчанию. Например,
компонент [[yii\web\Application::request|request]] используется для сбора информации о запросе пользователя и разбора его в
определенный [маршрут](runtime-routing.md); компонент [[yii\base\Application::db|db]] представляет собой соединение с базой данных,
через которое вы можете выполнять запросы. Именно с помощью этих встроенных компонентов Yii приложения могут обработать
запрос пользователя.
Ниже представлен список встроенных компонентов приложения. Вы можете конфигурировать их также как и другие компоненты приложения.
Когда вы конфигурируете встроенный компонент приложения и не указываете класс этого компонента, то значение по-умолчанию будет использовано.
Когда вы конфигурируете встроенный компонент приложения и не указываете класс этого компонента, то значение по умолчанию будет использовано.
* [[yii\web\AssetManager|assetManager]]: используется для управления и опубликования ресурсов приложения.
Более детальная информация представлена в разделе [Ресурсы](output-assets.md);

170
docs/guide-ru/structure-applications.md

@ -2,11 +2,11 @@
==========
Приложения это объекты, которые управляют всей структурой и жизненным циклом прикладной системы Yii.
Каждая Yii прикладная система включает в себя один объект приложения, который создается в [входном скрипте](structure-entry-scripts.md)
Каждая прикладная система Yii включает в себя один объект приложения, который создается во [входном скрипте](structure-entry-scripts.md)
и глобально доступен через `\Yii::$app`.
> Информация: В зависимости от контекста, когда мы говорим "приложение", это может означать как объект приложения так и
прикладную систему приложения в целом.
приложение как прикладную систему в целом.
Существует два вида приложений: [[yii\web\Application|веб приложения]] и [[yii\console\Application|консольные приложения]].
Как можно догадаться по названию, первый тип в основном занимается обработкой веб запросов, в то время как последний - консольных команд.
@ -14,8 +14,8 @@
## Конфигурации приложения <a name="application-configurations"></a>
Когда [входной скрипт](structure-entry-scripts.md создает приложение, он загрузит [конфигурацию](concept-configurations.md)
и применит ее к приложению, например:
Когда [входной скрипт](structure-entry-scripts.md) создаёт приложение, он загрузит [конфигурацию](concept-configurations.md)
и применит её к приложению, например:
```php
require(__DIR__ . '/../vendor/autoload.php');
@ -29,8 +29,8 @@ $config = require(__DIR__ . '/../config/web.php');
```
Также как и обычные [конфигурации](concept-configurations.md), конфигурации приложения указывают как следует инициализировать
свойства объектов приложения. Из-за того, что конфигурации приложений часто являются сложными, они разбиваются на несколько
[конфигурационных файлов](concept-configurations.md#configuration-files), например, `web.php` файл в приведенном выше примере.
свойства объектов приложения. Из-за того, что конфигурация приложения часто является очень сложной, она разбивается на несколько
[конфигурационных файлов](concept-configurations.md#configuration-files), например, `web.php` - файл в приведённом выше примере.
## Свойства приложений <a name="application-properties"></a>
@ -55,29 +55,29 @@ $config = require(__DIR__ . '/../config/web.php');
#### [[yii\base\Application::basePath|basePath]] <a name="basePath"></a>
Свойство [[yii\base\Application::basePath|basePath]] указывает на корневую папку приложения. Это папка, которая содержит
весь код прикладной системы приложения. В данной папке обычно могут находится подпапки `models`, `views`, `controllers`, которые
содержат код, отвечающий шаблону проектирования MVC.
Свойство [[yii\base\Application::basePath|basePath]] указывает на корневую директорию приложения. Эта директория содержит
весь защищенный исходный код приложения. В данной директории обычно могут находится поддиректории `models`, `views`,
`controllers`, содержащие код, соответствующий шаблону проектирования MVC.
Вы можете настроить свойство [[yii\base\Application::basePath|basePath]] указав напрямую путь к каталогу через
[псевдонимы пути](concept-aliases.md). В обоих случаях, указанная папка должна существовать, иначе будет брошено исключение.
Путь будет нормализован с помощью вызова функции `realpath()`.
Вы можете задать свойство [[yii\base\Application::basePath|basePath]] используя путь к директории или используя
[псевдоним пути](concept-aliases.md). В обоих случаях, указанная директория должна существовать, иначе будет выброшено
исключение. Путь будет нормализован функцией `realpath()`.
Свойство [[yii\base\Application::basePath|basePath]] часто используется для получения других важных путей, например, путь к
runtime папке, которая используется в процессе работы приложения. Именно по этой причине, псевдоним пути `@app` является
предопределенным и указывает на данную папку. Другие пути могут быть получены с помощью использования псевдонима пути, например,
`@app/runtime`.
Свойство [[yii\base\Application::basePath|basePath]] часто используется для указания других важных путей (например, путь к
директории runtime, используемой приложением). По этой причине, псевдоним пути `@app` предустановлен и содержит данный путь.
Производные пути могут быть получены с использованием этого псевдонима пути (например, `@app/runtime` указывает на
времененную дирректорию runtime).
### Важные свойства <a name="important-properties"></a>
Свойства, указанные в этом подразделе, часто должны быть настроены т. к. они могут отличаться от приложения к приложению.
Свойства, указанные в этом подразделе, часто нуждаются в преднастройке т.к. они разнятся от приложения к приложению.
#### [[yii\base\Application::aliases|aliases]] <a name="aliases"></a>
Это свойство позволяет настроить вам множество [псевдонимов](concept-aliases.md) в рамках массива.
Ключами массива являются имена псевдонимов, а ключами - соответствующие значение пути. Например,
Ключами массива являются имена псевдонимов, а значениями массива - соответствующие значения пути. Например,
```php
[
@ -88,7 +88,7 @@ runtime папке, которая используется в процессе
]
```
Это свойство доступно таким образом, чтобы вы могли указывать псевдонимы в рамках конфигураций приложения,
Это свойство доступно таким образом, чтобы вы могли указывать псевдонимы в рамках конфигурации приложения,
а не вызовов метода [[Yii::setAlias()]].
@ -105,7 +105,8 @@ ID в качестве элемента данного свойства.
- ID, указанный в [компонентах](#components);
- ID модуля, указанный в [модулях](#modules);
- название класса;
- массив конфигурации.
- массив конфигурации;
- анонимная функция, которая создаёт и возвращает компонент.
Например,
@ -116,19 +117,34 @@ ID в качестве элемента данного свойства.
'demo',
// название класса
'app\components\TrafficMonitor',
'app\components\Profiler',
// массив конфигурации
[
'class' => 'app\components\Profiler',
'level' => 3,
]
],
// анонимная функция
function () {
return new app\components\Profiler();
}
],
]
```
> Info: Если ID модуля такой же, как идентификатор компонента приложения, то в процессе [начальной загрузки](runtime-bootstrapping.md)
> будет использован компонент приложения. Если Вы вместо этого хотите использовать модуль, то можете указать его при
> помощи анонимной функции похожей на эту:
>```php
[
function () {
return Yii::$app->getModule('user');
},
]
```
В процессе начальной загрузки, каждый компонент будет создан. Если класс компонента имеет интерфейс [[yii\base\BootstrapInterface]], то
также будет вызван метод [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]].
В процессе [начальной загрузки](runtime-bootstrapping.md), каждый компонент будет создан. Если класс компонента имеет
интерфейс [[yii\base\BootstrapInterface]], то также будет вызван метод [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]].
Еще одним практическим примером является конфигурация [базового шаблона приложения](start-installation.md), в котором
модули `debug` и `gii` указаны как `bootstrap` компоненты, когда приложение находится в отладочном режиме.
@ -144,19 +160,21 @@ if (YII_ENV_DEV) {
}
```
> Примечание: Указывание слишком большого количества компонентов в `bootstrap` приведет к снижению производительности приложения,
потому что для каждого запроса одно и то же количество компонентов должно быть загружено. Таким образом вы должны использовать
начальную загрузку разумно.
> Примечание: Указывание слишком большого количества компонентов в [`bootstrap`](runtime-bootstrapping.md) приведет
к снижению производительности приложения, потому что для каждого запроса одно и то же количество компонентов должно
быть загружено. Таким образом вы должны использовать начальную загрузку разумно.
#### [[yii\web\Application::catchAll|catchAll]] <a name="catchAll"></a>
Данное свойство поддерживается только [[yii\web\Application|веб приложениями]].Оно указывает [действие контроллера](structure-controllers.md),
которое должно обрабатывать все входящие запросы от пользователя. В основном это используется, когда приложения находится в
режиме обслуживания и должно обрабатывать все запросы через одно действие.
Данное свойство поддерживается только [[yii\web\Application|веб приложениями]]. Оно указывает
[действие контроллера](structure-controllers.md), которое должно обрабатывать все входящие запросы от пользователя.
В основном это используется, когда приложения находится в режиме обслуживания и должно обрабатывать все запросы через
одно действие.
Конфигурация это массив, первый элемент которого, указывает маршрут действия. Остальные элементы в формате ключ-значение
указывают дополнительные параметры, которые должны быть переданы действию. Например,
Конфигурация это массив, первый элемент которого, определяет маршрут действия. Остальные элементы в формате пара
ключ-значение задают дополнительные параметры, которые должны быть переданы действию (методу контроллера actionXXX).
Например,
```php
[
@ -171,8 +189,9 @@ if (YII_ENV_DEV) {
#### [[yii\base\Application::components|components]] <a name="components"></a>
Данное свойство является наиболее важным. Оно позволяет вам указать список компонентов, которые называются [компоненты приложения](#structure-application-components.md),
которые вы можете использовать в других местах. Например,
Данное свойство является наиболее важным. Оно позволяет вам зарегистрировать список именованных компонентов, называемых
[компоненты приложения](#structure-application-components.md), которые Вы можете использовать в других местах.
Например,
```php
[
@ -188,22 +207,23 @@ if (YII_ENV_DEV) {
]
```
Каждый компонент приложения указан массивом в формате ключ-значение. Ключ представляет собой ID компонента приложения, в то время
как значение представляет собой название класса или [конфигурацию](concept-configurations.md).
Каждый компонент приложения указан массивом в формате ключ-значение. Ключ представляет собой ID компонента приложения,
в то время как значение представляет собой название класса или [конфигурацию](concept-configurations.md).
Вы можете зарегистрировать любой компонент в приложении, позже этот компонент будет глобально доступен
через выражение `\Yii::$app->ComponentID`.
Вы можете зарегистрировать любой компонент в приложении, позже этот компонент будет глобально доступен через
выражение `\Yii::$app->ComponentID`.
Более детальная информация приведена в разделе [Компоненты приложения](structure-application-components.md).
Более подробная информация приведена в разделе [Компоненты приложения](structure-application-components.md).
#### [[yii\base\Application::controllerMap|controllerMap]] <a name="controllerMap"></a>
Данное свойство позволяет вам устанавливать соответствия между ID контроллера и его классом. По-умолчанию, Yii устанавливает
соответствие между ID контроллера и его классом согласно данному [соглашению](#controllerNamespace) (таким образом,
ID `post` будет соответствовать `app\controllers\PostController` ). С помощью настройки этого свойства вы можете изменить
соглашение для нужных контроллеров. В приведенном ниже примере, `account` будет соответствовать `app\controllers\UserController`,
в то время как `article` будет соответствовать `app\controllers\PostController`.
Данное свойство позволяет вам задавать соответствия(mapping) между ID контроллера и произвольным классом контроллера.
По-умолчанию, Yii задает соответствие между ID контроллера и его классом согласно данному [соглашению](#controllerNamespace)
(таким образом, ID `post` будет соответствовать `app\controllers\PostController` ). Задавая эти свойства вы можете
переопределить соответствия для необходимых контроллеров. В приведенном ниже примере, `account` будет соответствовать
контроллеру `app\controllers\UserController`, в то время как `article` будет соответствовать контроллеру
`app\controllers\PostController`.
```php
[
@ -219,35 +239,35 @@ ID `post` будет соответствовать `app\controllers\PostControl
]
```
Ключами данного свойства являются ID контроллеров, а значениями являются название
класса контроллера или [конфигурация](concept-configurations.md).
Ключами данного свойства являются ID контроллеров, а значениями являются соответствующие названия
классов(полное название класса с пространством имен) контроллера или [конфигурация](concept-configurations.md).
#### [[yii\base\Application::controllerNamespace|controllerNamespace]] <a name="controllerNamespace"></a>
Данное свойство указывает пространство имен, в котором по-умолчанию должны находится названия классов контроллеров.
Данное свойство указывает пространство имен, в котором по умолчанию должны находится названия классов контроллеров.
По-умолчанию значение равно `app\controllers`. Если ID контроллера `post`, то согласно соглашению, соответствующий класс
контроллера (без пространства имен) будет равен `PostController`, а полное название класса будет равно `app\controllers\PostController`.
Класс контроллера может также находиться в подпапке папки, которая соответствует этому пространству имен.
Например, дан ID контроллера `admin/post`, соответствующие полное имя класса контроллера будет `app\controllers\admin\PostController`.
Класс контроллера может также находиться в поддиректории директории, соответствующей этому пространству имен.
Например, ID контроллера `admin/post`, будет соответветствовать полное имя класса контроллера `app\controllers\admin\PostController`.
Очень важно, чтобы полное имя класса контроллера могло быть использовано [автозагрузкой](concept-autoloading.md) и соответствующее
пространство имен вашего контроллера соответствовало данному свойству. Иначе, вы получите ошибку "Страница не найдена", когда
попытаетесь получить доступ к приложению.
Очень важно, чтобы полное имя класса контроллера могло быть использовано [автозагрузкой](concept-autoloading.md) и
соответствующее пространство имен вашего контроллера соответствовало данному свойству. Иначе, Вы получите ошибку
"Страница не найдена", при доступе к приложению.
В случае, если вы хотите изменить соглашение как описано выше, вы можете использовать свойство [controllerMap](#controllerMap).
В случае, если вы хотите переопределить соответствия как описано выше, вы можете настроить свойство [controllerMap](#controllerMap).
#### [[yii\base\Application::language|language]] <a name="language"></a>
Данное свойство указывает язык приложения, на котором содержимое страницы должно быть отображено конечному пользователю.
По-умолчанию значение данного свойства равно `en`, что означает "Английский". Если ваше приложение должно поддерживать несколько
языков, вы должны настроить данное свойство.
По-умолчанию значение данного свойства равно `en`, что означает "Английский". Если ваше приложение должно поддерживать
несколько языков, вы должны настроить данное свойство.
Значение данного свойства определяется различными аспектами [интернационализации](tutorial-i18n.md), в том числе
переводом сообщений, форматированием дат, форматированием чисел, и т. д. Например, виджет [[yii\jui\DatePicker]]
использует данное свойство для определения по-умолчанию языка, на котором должен быть отображен календарь и формат данных
использует данное свойство для определения по умолчанию языка, на котором должен быть отображен календарь и формат данных
для календаря.
Рекомендуется что вы будете указывать язык в рамках стандарта [IETF](http://en.wikipedia.org/wiki/IETF_language_tag).
@ -348,7 +368,7 @@ $width = \Yii::$app->params['thumbnail.size'][0];
### Полезные свойства <a name="useful-properties"></a>
Свойства, указанные в данном подразделе, не являются часто конфигурируемыми, т. к. их значения по-умолчанию
Свойства, указанные в данном подразделе, не являются часто конфигурируемыми, т. к. их значения по умолчанию
соответствуют общепринятым соглашениям. Однако, вы можете их настроить, если вам нужно использовать другие
соглашения.
@ -364,14 +384,14 @@ $width = \Yii::$app->params['thumbnail.size'][0];
Свойство указывает [маршрут](runtime-routing.md), который должно использовать приложение, когда он не указан
во входящем запросе. Маршрут может состоять из ID модуля, ID контроллера и/или ID действия. Например, `help`,
`post/create`, `admin/post/create`. Если действие не указано, то будет использовано значение по-умолчанию
`post/create`, `admin/post/create`. Если действие не указано, то будет использовано значение по умолчанию
указанное в [[yii\base\Controller::defaultAction]].
Для [yii\web\Application|веб приложений], значение по-умолчанию для данного свойства равно `'site'`, что означает
контроллер `SiteController` и его действие по-умолчанию должно быть использовано. Таким образом, если вы попытаетесь
Для [yii\web\Application|веб приложений], значение по умолчанию для данного свойства равно `'site'`, что означает
контроллер `SiteController` и его действие по умолчанию должно быть использовано. Таким образом, если вы попытаетесь
получить доступ к приложению не указав маршрут, оно покажет вам результат действия `app\controllers\SiteController::actionIndex()`.
Для [yii\console\Application|консольных приложений], значение по-умолчанию равно `'help'`, означающее, что встроенная
Для [yii\console\Application|консольных приложений], значение по умолчанию равно `'help'`, означающее, что встроенная
команда [[yii\console\controllers\HelpController::actionIndex()]] должна быть использована. Таким образом, если вы
выполните команду `yii` без аргументов, вам будет отображена справочная информация.
@ -412,19 +432,19 @@ $width = \Yii::$app->params['thumbnail.size'][0];
#### [[yii\base\Application::layout|layout]] <a name="layout"></a>
Данное свойство указывает имя шаблона по-умолчанию, который должен быть использовать при формировании [представлений](structure-views.md).
Значение по-умолчанию равно `'main'`, означающее, что должен быть использован шаблон `main.php` в [папке шаблонов](#layoutPath).
Если оба свойства [папка шаблонов](#layoutPath) и [папка представлений](#viewPath) имеют значение по-умолчаниею,
то файл шаблона по-умолчанию может быть представлен псевдонимом пути как `@app/views/layouts/main.php`.
Данное свойство указывает имя шаблона по умолчанию, который должен быть использовать при формировании [представлений](structure-views.md).
Значение по умолчанию равно `'main'`, означающее, что должен быть использован шаблон `main.php` в [папке шаблонов](#layoutPath).
Если оба свойства [папка шаблонов](#layoutPath) и [папка представлений](#viewPath) имеют значение по умолчанию,
то файл шаблона по умолчанию может быть представлен псевдонимом пути как `@app/views/layouts/main.php`.
Для отключения использования шаблона, вы можете указать данное свойство как `false`, хотя это используется очень редко.
#### [[yii\base\Application::layoutPath|layoutPath]] <a name="layoutPath"></a>
Свойство указывает путь, по которому следует искать шаблоны. Значение по-умолчанию равно `layouts`, означающее подпапку
в [папке представлений](#viewPath). Если значение [папки представлений](#viewPath) является значением по-умолчанию, то
папка шаблонов по-умолчанию может быть представлена псевдонимом пути как `@app/views/layouts`.
Свойство указывает путь, по которому следует искать шаблоны. Значение по умолчанию равно `layouts`, означающее подпапку
в [папке представлений](#viewPath). Если значение [папки представлений](#viewPath) является значением по умолчанию, то
папка шаблонов по умолчанию может быть представлена псевдонимом пути как `@app/views/layouts`.
Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md).
@ -443,14 +463,14 @@ $width = \Yii::$app->params['thumbnail.size'][0];
#### [[yii\base\Application::viewPath|viewPath]] <a name="viewPath"></a>
Данное свойство указывает базовую папку,где содержаться все файлы представлений. Значение по-умолчанию представляет
Данное свойство указывает базовую папку,где содержаться все файлы представлений. Значение по умолчанию представляет
собой псевдоним `@app/views`. Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md).
#### [[yii\base\Application::vendorPath|vendorPath]] <a name="vendorPath"></a>
Свойство указывает папку сторонних библиотек, которые используются и управляются [Composer](http://getcomposer.org).
Она содержит все сторонние библиотеки используемые приложением, включая Yii фреймворк. Значение по-умолчанию
Она содержит все сторонние библиотеки используемые приложением, включая Yii фреймворк. Значение по умолчанию
представляет собой псевдоним `@app/vendor`.
Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md). При изменении данного свойства,
@ -462,7 +482,7 @@ $width = \Yii::$app->params['thumbnail.size'][0];
#### [[yii\console\Application::enableCoreCommands|enableCoreCommands]] <a name="enableCoreCommands"></a>
Данное свойство поддерживается только [[yii\console\Application|консольными приложениями]]. Оно указывает
нужно ли использовать встроенные в Yii консольные команды. Значение по-умолчанию равно `true`.
нужно ли использовать встроенные в Yii консольные команды. Значение по умолчанию равно `true`.
## События приложения <a name="application-events"></a>
@ -500,7 +520,7 @@ $width = \Yii::$app->params['thumbnail.size'][0];
от некоторых параметров.
### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_REQUEST]] <a name="afterRequest"></a>
### [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]] <a name="afterRequest"></a>
Данное событие возникает *после* того как приложение заканчивает обработку запроса, но *до* того как произойдет
отправка ответа. Настоящее имя события - `afterRequest`.
@ -512,7 +532,7 @@ $width = \Yii::$app->params['thumbnail.size'][0];
конечному пользователю. Эти события возникают *после* текущего события.
### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_ACTION]] <a name="beforeAction"></a>
### [[yii\base\Application::EVENT_BEFORE_ACTION|EVENT_BEFORE_ACTION]] <a name="beforeAction"></a>
Событие возникает *до* того как будет выполнено [действие контроллера](structure-controllers.md).
Настоящее имя события - `beforeAction`.
@ -539,7 +559,7 @@ $width = \Yii::$app->params['thumbnail.size'][0];
свойство [[yii\base\ActionEvent::isValid]] равным `false`, все последующие события не возникнут.
### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_ACTION]] <a name="afterAction"></a>
### [[yii\base\Application::EVENT_AFTER_ACTION|EVENT_AFTER_ACTION]] <a name="afterAction"></a>
Событие возникает *после* выполнения [действия контроллера](structure-controllers.md).
Настоящее имя события - `afterAction`.
@ -572,7 +592,7 @@ $width = \Yii::$app->params['thumbnail.size'][0];
будет развиваться согласно следующему жизненному циклу:
1. Входной скрипт загружает конфигурацию приложения в качества массива;
2. Входной скрипт создает новый объект приложения:
2. Входной скрипт создаёт новый объект приложения:
* Вызывается метод [[yii\base\Application::preInit()|preInit()]], который настраивает некоторые
жизненно важные свойства приложения, такие как [[yii\base\Application::basePath|basePath]];
* Регистрируется [[yii\base\Application::errorHandler|обработчик ошибок]];

14
docs/guide-ru/structure-controllers.md

@ -130,7 +130,7 @@ ID контроллеров также могут содержать префи
* Добавить в начало [[yii\base\Application::controllerNamespace|пространство имен контроллеров]].
Ниже приведены несколько примеров, с учетом того, что [[yii\base\Application::controllerNamespace|пространство имен контроллеров]]
имеет значение по-умолчанию равное `app\controllers`:
имеет значение по умолчанию равное `app\controllers`:
* `article` соответствует `app\controllers\ArticleController`;
* `post-comment` соответствует `app\controllers\PostCommentController`;
@ -172,14 +172,14 @@ ID контроллеров также могут содержать префи
]
```
### Контроллер по-умолчанию <a name="default-controller"></a>
### Контроллер по умолчанию <a name="default-controller"></a>
Каждое приложение имеет контроллер по-умолчанию, указанный через свойство [[yii\base\Application::defaultRoute]].
Каждое приложение имеет контроллер по умолчанию, указанный через свойство [[yii\base\Application::defaultRoute]].
Когда в запросе не указан [маршрут](#ids-routes), тогда будет использован маршрут указанный в данном свойстве.
Для [[yii\web\Application|Веб приложений]], это значение `'site'`, в то время как для [[yii\console\Application|консольных приложений]],
это `'help'`. Таким образом, если задан URL `http://hostname/index.php`, это означает, что контроллер `site` выполнит обработку запроса.
Вы можете изменить контроллер по-умолчанию следующим образом в [настройках приложения](structure-applications.md#application-configurations):
Вы можете изменить контроллер по умолчанию следующим образом в [настройках приложения](structure-applications.md#application-configurations):
```php
[
@ -375,10 +375,10 @@ public function actionView(array $id, $version = null)
о параметрах консольных приложений представлено в секции [Консольные команды](tutorial-console.md).
### Действие по-умолчанию <a name="default-action"></a>
### Действие по умолчанию <a name="default-action"></a>
Каждый контроллер имеет действие, указанное через свойство [[yii\base\Controller::defaultAction]].
Когда [маршрут](#ids-routes) содержит только ID контроллера, то подразумевается, что действие контроллера по-умолчанию
Когда [маршрут](#ids-routes) содержит только ID контроллера, то подразумевается, что действие контроллера по умолчанию
было запрошено.
По-умолчанию, это действие имеет значение `index`. Если вы хотите изменить это значение, просто переопределите данное
@ -409,7 +409,7 @@ class SiteController extends Controller
1. Метод [[yii\base\Controller::init()]] будет вызван после того как контроллер будет создан и сконфигурирован;
2. Контроллер создает объект действия, основываясь на запрошенном ID действия:
* Если ID действия не указан, то будет использовано [[yii\base\Controller::defaultAction|ID действия по-умолчанию]];
* Если ID действия не указан, то будет использовано [[yii\base\Controller::defaultAction|ID действия по умолчанию]];
* Если ID действия найдено в [[yii\base\Controller::actions()|карте действий]], то отдельное действие будет создано;
* Если ID действия соответствует методу действия, то встроенное действие будет создано;
* В противном случае, будет выброшено исключение [[yii\base\InvalidRouteException]].

8
docs/guide-ru/structure-views.md

@ -239,7 +239,7 @@ ID контроллера: <?= $this->context->id ?>
### Передача данных между видами <a name="sharing-data-among-views"></a>
[[yii\base\View|Компонент вида]] имеет свойство [[yii\base\View::params|params]] , которое вы можете использовать для обмена данными между видами.
[[yii\base\View|Компонент вида]] имеет свойство [[yii\base\View::params|params]], которое вы можете использовать для обмена данными между видами.
Например, в виде `about` вы можете указать текущий сегмент хлебных крошек с помощью следующего кода.
@ -298,7 +298,7 @@ use yii\helpers\Html;
Большинство шаблонов вызывают методы, аналогично тому, как это сделано в примере выше, чтобы скрипты и тэги, зарегистированные в других местах приложения могли быть правильно отображены в местах вызова (например, в шаблоне).
- [[yii\base\View::beginPage()|beginPage()]]: Этот метод нужно вызывать в самом начале шаблона.
Он вызывает событие [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]] , которое происходит при начале обработки страницы.
Он вызывает событие [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]], которое происходит при начале обработки страницы.
- [[yii\base\View::endPage()|endPage()]]: Этот метод нужно вызывать в конце страницы.
Он вызывает событие [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]] . Оно указывает на обработку конца страницы.
- [[yii\web\View::head()|head()]]: Этот метод нужно вызывать в `<head>` секции страницы html.
@ -320,7 +320,7 @@ use yii\helpers\Html;
### Использование шаблонов <a name="using-layouts"></a>
Как было описано в секции [Рендеринг в контроллерах](#rendering-in-controllers) , когда вы рендерите вид, вызывая метод [[yii\base\Controller::render()|render()]] из контроллера, к результату рендеринга будет применен шаблон. По умолчанию будет использован шаблон `@app/views/layouts/main.php` .
Как было описано в секции [Рендеринг в контроллерах](#rendering-in-controllers), когда вы рендерите вид, вызывая метод [[yii\base\Controller::render()|render()]] из контроллера, к результату рендеринга будет применен шаблон. По умолчанию будет использован шаблон `@app/views/layouts/main.php` .
Вы можете использовать разные шаблоны, конфигурируя [[yii\base\Application::layout]] или [[yii\base\Controller::layout]].
Первый переопределяет шаблон, который используется по умолчанию всеми контроллерами, а второй переопределяет шаблон в отдельном контроллере.
@ -391,7 +391,7 @@ Yii определяет какой шаблон использовать для
Например, вы определяете (записываете) блок в виде и отображаете его в шаблоне.
Для определения блока вызываются методы [[yii\base\View::beginBlock()|beginBlock()]] и [[yii\base\View::endBlock()|endBlock()]].
После определения, блок доступен через `$view->blocks[$blockID]` , где `$blockID` - это уникальный ID, который вы присваиваете блоку
После определения, блок доступен через `$view->blocks[$blockID]`, где `$blockID` - это уникальный ID, который вы присваиваете блоку
в начале определения.
В примере ниже показано, как можно использовать блоки, определенные в виде, чтобы динамически изменять фрагменты шаблона.

4
docs/guide-ru/structure-widgets.md

@ -108,7 +108,7 @@ class HelloWidget extends Widget
}
```
Для того, что бы использовать этот виджет, достаточно добавить в представление следующий код:
Для того, чтобы использовать этот виджет, достаточно добавить в представление следующий код:
```php
<?php
@ -177,7 +177,7 @@ public function run()
По умолчанию, файлы представлений виджетов должны находиться в директории `WidgetPath/views`, где `WidgetPath` -
директория, содержащая файл класса виджета. Таким образом, в приведенном выше примере, для виджета будет
использован файл представления `@app/components/views/hello.php`, при этом файл с классом виджета расположен в
`@app/components`. Для того, что бы изменить директорию, в которой содержатся файлы-представления для виджета,
`@app/components`. Для того, чтобы изменить директорию, в которой содержатся файлы-представления для виджета,
следует переопределить метод [[yii\base\Widget::getViewPath()]].

240
docs/guide-ru/tutorial-advanced-app.md

@ -0,0 +1,240 @@
Шаблон приложения advanced
==========================
> Примечание: Данная глава находится в разработке.
This application template also goes a bit further regarding features and provides essential database, signup and password restore out of the box.-->
Этот шаблон предназначен для крупных проектов разрабатываемых в командах где администраторская часть (backend) отделена
от приложения пользователя (frontend), прилжения располагаются на нескольких серверах и т.д. Этот шаблон приложения включает
значительное количество возможностей, таких как начальная схема базы данных, регистрация пользователя и воостановление его
пароля.
Установка
---------
### Установка при помощи Composer
Если у вас ещё не установлен [Composer](http://getcomposer.org/), следуйте инструкциям в разделе
[установка Yii](start-installation.md#installing-via-composer).
Если Composer установлен, вы можете установить приложение используя следующие команды:
composer global require "fxp/composer-asset-plugin:1.0.0-beta3"
composer create-project --prefer-dist yiisoft/yii2-app-advanced yii-application
Первая команда установит плагин [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/),
который позволит работать с пакетами bower и npm через Composer. Эту команду необходимо выполнить едножды. Вторая команда
установит приожение advanced в директорию `yii-application`. Вы можете выбрать другое имя директория если пожелаете.
Начало работы
-------------
После установки приложения, вам необходимо один раз выполнить приведённые ниже действия для того, чтобы инициализировать
установленное приложение.
1. Выполните команду `init` и выберите окружение `dev`.
```
php /path/to/yii-application/init
```
Для производственных сервером удобно выполнять данную команду в неинтерактивном режиме.
```
php /path/to/yii-application/init --env=Production overwrite=All
```
2. Создайте новую базу данных и внесите соответствующие изменения в секцию `components.db` файла `common/config/main-local.php`.
3. Примените миграции при помощи консольной команды `yii migrate`.
4. Настройте на вебсервере URL и корневые директории:
- для приложения frontend директория `/path/to/yii-application/frontend/web/` и URL `http://yourdomain/frontend/`
- для приложения backend директория `/path/to/yii-application/frontend/web/` и URL `http://yourdomain/backend/`
Структура директорий
-------------------
Корневая директория содержит следующие поддиректории:
- `backend` - веб приложение администраторской части.
- `common` - общие файлы для всех приложений.
- `console` - приложение для консоли.
- `environments` - настройки для различных окружений.
- `frontend` - веб приложение пользователя.
Корневая директория содержит следующие файлы:
- `.gitignore` содержит список директорий игнорируемых системой контроля версий git. Если вам необходимо предотвратить
их попадание в репозиторий, перечислите их в данном файле.
- `composer.json` - Конфигурация Composer, подробно описанная в разделе «Настройка Composer» ниже.
- `init` - скрипт инициализации. Подробно описан ниже в разделе «Конфигурации и окружения».
- `init.bat` - он же для Windows.
- `LICENSE.md` - информация о лицензии. Разместите в нём лицензию вашего проекта. Особенно в случае OpenSource.
- `README.md` - основная информация об установки шаблона. Можете разместить в нём информацию о вашем проекте и его установке.
- `requirements.php` - проверка соответствия требованиям Yii.
- `yii` - входной скрипт консольного приложения.
- `yii.bat` - он же для Windows.
Встроенные псевдонимы путей
---------------------------
- `@yii` - директория фрэймворка.
- `@app` - корневая директория выполняемого в данный момент приложения.
- `@common` - директория common.
- `@frontend` - директория веб-приложения frontend.
- `@backend` - директория веб-приложения backend.
- `@console` - директория console.
- `@runtime` - директория runtime исполняемого приложения.
- `@vendor` - директория vendor, содержащая пакеты загруженые Composer'ом.
- `@bower` - директория vendor, содержащая [пакеты bower](http://bower.io/).
- `@npm` - директория vendor, содержащая [пакеты npm](https://www.npmjs.org/).
- `@web` - базовый URL исполняемого веб-приложения.
- `@webroot` - корневая веб-директория исполняемого веб-приложения.
Псевдонимы, характерные для структуры директорий приложения advanced (`@common`, `@frontend`, `@backend` и `@console`)
задаются в `common/config/bootstrap.php`.
Приложения
----------
В шаблоне advanced три приложения: frontend, backend и console. Frontend это та часть приложения, которае обеспечивает
взаимодействие системы с конечным пользователем проекта. Backend это административная панель, аналитика и прочая подобная
функциональность. Console обычно используется для выполнения заданий по расписанию через cron, низкоуровневого
управления сервером, при развёртывании приложения, работы с миграциями и ресурсами.
Также есть директория `common`, которая содержит файлы используемые более чем одним приложением. Например, модель `User`.
Оба веб приложения frontend и backend содержат директорию `web`. Это корневая директория, которую вы должны настроить
в вебсервере.
У каждого приложения есть собственное пространство имён и соответствующий его названию псевдоним. Это же справедливо и для
общей директории `common`.
Конфигурации и окружения
------------------------
Существует множество проблем при типичном подходе к настройке конфигурации:
- Каждый член команды имеет свою собственную конфигурацию. Изменение конфигурации в общем репозитории повлияет на всех
остальных.
- Пароль от эксплуатационной БД и API ключи не должны оказаться в репозитории.
- Существует много окружений: development (разработка), testing (тестирование), production (эксплуатация). Каждое окружение
должно иметь свою собственную конфигурацию.
- Настройка всех параметров конфигурации для каждого случая однотипна и отнимает слишком много времени.
Для решения этих проблем Yii вводит простую концепцию окружений. Каждое окружение представлено набором файлов в
директории `environments`. Для переключения между окружениями используется команда `init`. Она довольно проста. Всё,
что она на самом деле делает - это копирование всех файлов из директории окружения в корневую директорию, где находятся
все приложения.
Обычно окружение содержит входные скрипты приложения, такие как `index.php`, и файлы конфигурации, имена которых
дополнены суфиксами `-local.php`. Эти файлы добавлены в `.gitignore` и никогда не попадут в репозиторий.
Чтобы избежать дублирования, конфигурации перекрывают друг друга. Например, приложение frontend считывает конфигурацию
в следующем порядке:
- `common/config/main.php`
- `common/config/main-local.php`
- `frontend/config/main.php`
- `frontend/config/main-local.php`
Парамтры считываются в следующем порядке:
- `common/config/params.php`
- `common/config/params-local.php`
- `frontend/config/params.php`
- `frontend/config/params-local.php`
Значения из следующего конфигурационного файла перекрывают аналогичные значения из предыдущих конфигурационных файлов.
Полная схема:
![Конфигурации приложения advanced](images/advanced-app-configs.png)
Настройка Composer
------------------
После того как шаблон приложения установлен, хорошо бы изменить `composer.json` который находится в корневой директории
проекта:
```json
{
"name": "yiisoft/yii2-app-advanced",
"description": "Yii 2 Advanced Application Template",
"keywords": ["yii", "framework", "advanced", "application template"],
"homepage": "http://www.yiiframework.com/",
"type": "project",
"license": "BSD-3-Clause",
"support": {
"issues": "https://github.com/yiisoft/yii2/issues?state=open",
"forum": "http://www.yiiframework.com/forum/",
"wiki": "http://www.yiiframework.com/wiki/",
"irc": "irc://irc.freenode.net/yii",
"source": "https://github.com/yiisoft/yii2"
},
"minimum-stability": "dev",
"require": {
"php": ">=5.4.0",
"yiisoft/yii2": "*",
"yiisoft/yii2-swiftmailer": "*",
"yiisoft/yii2-bootstrap": "*",
"yiisoft/yii2-debug": "*",
"yiisoft/yii2-gii": "*"
},
"scripts": {
"post-create-project-cmd": [
"yii\\composer\\Installer::setPermission"
]
},
"extra": {
"writable": [
"backend/runtime",
"backend/web/assets",
"console/runtime",
"console/migrations",
"frontend/runtime",
"frontend/web/assets"
]
}
}
```
Во-первых, мы обновляем основную информацию. Меняем значения `name`, `description`, `keywords`, `homepage` и `support`
на соответствующие вашему проекту.
А сейчас интересная часть. вы можете добавить больше пакетов, необходимых для вашего приложения, в раздел `require`.
Все они с [packagist.org](https://packagist.org/). Стоит его изучить так как там множество пакетов с полезным кодом.
После того как ваш `composer.json` настроен, вы можете выполнить в консоли команду `composer update --prefer-dist`,
подождать пока требуемые пакеты загрузятся и установятся, и начать их использовать. Автозагрузка классов этих пакетов
будет осуществляться автоматически.
Создание ссылок на frontend из backend
--------------------------------------
Часто приходится создавать ссылки из приложения backend на приложение frontend. Так как frontend может использовать
собственную конфигурация менеджера URL, вам придётся продублировать её в конфигурации backend под новым именем:
```php
return [
'components' => [
'urlManager' => [
// конфигурация основного менеджера URL в конфигурации backend
],
'urlManagerFrontend' => [
// конфигурация менеджера URL из frontend
],
],
];
```
После того, как это будет сделано, вы сможете получить URL, указывающий на frontend, следующим способом:
```php
echo Yii::$app->urlManagerFrontend->createUrl(...);
```

2
docs/guide-ru/tutorial-core-validators.md

@ -238,7 +238,7 @@ function foo($model, $attribute) {
строка, содержащая имена файловых расширений, разделенных пробелом или запятой (пр.: "gif, jpg").
Имя расширения не чувствительно к регистру. По умолчанию - null, что значит, что все имена файловых расширений
допустимы.
- `mimeTypes`: список MIME-типов которые допустимы для загрузки. Это может быть или массив, или строка,
- `mimeTypes`: список MIME-типов, которые допустимы для загрузки. Это может быть или массив, или строка,
содержащая MIME-типы файлов, разделенные пробелом или запятой (пример: "image/jpeg, image/png").
Имена mime-типов не чувствительны к регистру. По умолчанию - null, что значит, что допустимы все MIME-типы.
- `minSize`: минимальный размер файла в байтах, разрешенный для загрузки. По умолчанию - null, что значит, что нет

147
docs/guide-uk/caching-fragment.md

@ -0,0 +1,147 @@
Кешування фрагментів
================
Кешування фрагментів відноситься до кешуванню фрагментів сторінки. Наприклад, якщо сторінка відображає в таблиці сумарні річні продажі, ми можемо зберегти цю таблицю в кеші з метою економії часу, необхідного для створення таблиці при кожному запиті. Кешування фрагментів засноване на [кешуванні даних](caching-data.md).
Для кешування фрагментів використовуйте наступний код в [виді](structure-views.md):
```php
if ($this->beginCache($id)) {
// ... тут створюємо вміст ...
$this->endCache();
}
```
Таким чином укладіть те, що ви хочете закешовану між викликом [[yii\base\View::beginCache()|beginCache()]] та
[[yii\base\View::endCache()|endCache()]]. Якщо вміст буде знайдено в кеші, [[yii\base\View::beginCache()|beginCache()]]
відобразить закешований вміст і поверне false, минаючи генерацію вмісту.
В іншому випадку, буде виконаний код генерації контента і коли буде викликаний [[yii\base\View::endCache()|endCache()]], то сгенерированное вміст буде записано і збережено в кеші.
Также как и [кэширование данных](caching-data.md), для кэширования фрагментов требуется уникальный идентификатор для определения кэшируемого фрагмента.
## Параметры кэширования <a name="caching-options"></a>
Вызывая метод [[yii\base\View::beginCache()|beginCache()]], мы можем передать в качестве второго аргумента массив, содержащий параметры кэширования для управления кэшированием фрагмента. Заглядывая за кулисы, можно увидеть, что этот массив будет использоваться для настройки виджета [[yii\widgets\FragmentCache]], который реализует фактическое кэширование фрагментов.
### Срок хранения <a name="duration"></a>
Наверное, наиболее часто используемым параметром является [[yii\widgets\FragmentCache::duration|duration]].
Он определяет какое количество секунд содержимое будет оставаться действительным (корректным). Следующий код помещает фрагмент в кэш не более, чем на час::
```php
if ($this->beginCache($id, ['duration' => 3600])) {
// ... здесь создаём содержимое ...
$this->endCache();
}
```
Если мы не установим длительность (срок хранения), она будет равна значению по умолчанию (60 секунд). Это значит, что кэшированное содержимое станет недействительным через 60 секунд.
### Зависимости <a name="dependencies"></a>
Также как и [кэширование данных](caching-data.md#cache-dependencies), кэшируемое содержимое фрагмента тоже может иметь зависимости. Например, отображение содержимого сообщения зависит от того, изменено или нет это сообщение.
Для определения зависимости мы устанавливаем параметр [[yii\widgets\FragmentCache::dependency|dependency]], который может быть либо объектом [[yii\caching\Dependency]], либо массивом настроек, который может быть использован для создания объекта [[yii\caching\Dependency]]. Следующий код определяет содержимое фрагмента, зависящее от изменения значения столбца `updated_at`:
```php
$dependency = [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT MAX(updated_at) FROM post',
];
if ($this->beginCache($id, ['dependency' => $dependency])) {
// ... здесь создаём содержимое ...
$this->endCache();
}
```
### Вариации <a name="variations"></a>
Кэшируемое содержимое может быть изменено в соответствии с некоторыми параметрами. Например, для веб-приложений, поддерживающих несколько языков, одна и та же часть кода может создавать содержимое на нескольких языках. Поэтому у вас может возникнуть желание кэшировать содержимое в зависимости от текущего языка приложения.
Чтобы задать вариации кэша, установите параметр [[yii\widgets\FragmentCache::variations|variations]], который должен быть массивом, содержащим скалярные значения, каждое из которых представляет определенный коэффициент вариации. Например,
чтобы кэшировать содержимое в зависимости от языка приложения, вы можете использовать следующий код:
```php
if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {
// ... здесь создаём содержимое ...
$this->endCache();
}
```
### Переключение кэширования <a name="toggling-caching"></a>
Иногда может потребоваться включать кеширование фрагментов только для определённых условий. Например, страницу с формой мы хотим кэшировать только тогда, когда обращение к ней произошло впервые (посредством GET запроса). Любое последующее отображение формы (посредством POST запроса) не должно быть кэшировано, потому что может содержать данные, введённые пользователем. Для этого мы задаём параметр [[yii\widgets\FragmentCache::enabled|enabled]]:
```php
if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {
// ... здесь создаём содержимое ...
$this->endCache();
}
```
## Вложенное кэширование <a name="nested-caching"></a>
Кэширование фрагментов может быть вложенным. Это значит, что кэшируемый фрагмент окружён более крупным фрагментом (содержится в нём), который также кэшируется. Например, комментарии кэшируются во внутреннем фрагменте кэша, и они же кэшируются вместе с содержимым сообщения во внешнем фрагменте кэша. Следующий код демонстрирует как два фрагмента кэша могут быть вложенными:
```php
if ($this->beginCache($id1)) {
// ...логика создания контента...
if ($this->beginCache($id2, $options2)) {
// ...логика создания контента...
$this->endCache();
}
// ...логика создания контента...
$this->endCache();
}
```
Параметры кэширования могут быть различными для вложенных кэшей. Например, внутренний и внешний кэши в вышеприведённом примере могут иметь разные сроки хранения. Даже когда данные внешнего кэша уже не являются актуальными, внутренний кеш может содержать актуальный фрагмент. Тем не менее, обратное не верно. Если внешний кэш актуален, данные будут отдаваться из него даже если внутренний кэш содержит устаревшие данные. Следует проявлять осторожность при выставлении срока хранения и задания зависимостей для вложенных кэшей. В противном случае вы можете получить устаревшие данные.
## Динамическое содержимое <a name="dynamic-content"></a>
Когда используется кэширование фрагментов, вы можете столкнуться с ситуацией когда большой фрагмент содержимого статичен за исключением одного или нескольких мест. Например, заголовок страницы может отображаться в главном меню вместе с
именем текущего пользователя. Еще одна проблема в том, что содержимое, которое было закэшировано, может содержать PHP код, который должен выполняться для каждого запроса (например код для регистрации в asset bundle). Обе проблемы могут быть решены с помощью, так называемой функции *динамического содержимого*.
Динамическое содержимое значит, что часть вывода не будет закэширована даже если она заключена в кэширование фрагментов. Чтобы сделать содержимое динамическим постоянно, оно должно быть создано, используя специальный PHP код.
Вы можете вызвать [[yii\base\View::renderDynamic()]] в пределах кэширования фрагмента для вставки динамического содержимого
в нужное место, как в примере ниже:
```php
if ($this->beginCache($id1)) {
// ...логика создания контента...
echo $this->renderDynamic('return Yii::$app->user->identity->name;');
// ...логика создания контента...
$this->endCache();
}
```
Метод [[yii\base\View::renderDynamic()|renderDynamic()]] принимает некоторую часть PHP кода как параметр.
Возвращаемое значение этого кода будет вставлено в динамическое содержимое. Этот PHP код будет выполняться для каждого запроса, независимо от того находится ли он внутри кэширования фрагмента или нет.

118
docs/guide-uk/concept-aliases.md

@ -0,0 +1,118 @@
Псевдоніми
=========
Псевдоніми використовуються для позначення шляхів до файлів або URL адрес і допомагають уникнути використання абсолютних шляхів
або URL в коді. Для того, щоб не переплутати псевдонім із звичайним шляхом до файлу або URL, він повинен починатися з `@`. В Yii
є безліч заздалегідь визначених псевдонімів. Наприклад, `@yii` вказує на директорію, в яку був встановлений
Yii framework, а `@web` можна використовувати для отримання базового URL поточного додатку.
Створення псевдонімів <a name="defining-aliases"></a>
----------------------------------------------
Для створення псевдоніма шляху до файлу або URL використовується метод [[Yii::setAlias()]]:
```php
// псевдонім шляху до файлу
Yii::setAlias('@foo', '/path/to/foo');
// псевдонім URL
Yii::setAlias('@bar', 'http://www.example.com');
```
> Примітка: псевдонім шляху до файлу або URL *не* обов'язково вказує на існуючий файл або ресурс.
Використовуючи вже заданий псевдонім, ви можете отримати на основі нього новий без виклику [[Yii :: setAlias ()]]. Зробити це можна, додавши в його кінець `/`, за яким слід один або більше сегментів шляху. Псевдоніми, визначені за допомогою
[[Yii::setAlias()]], є *кореневими псевдонімами*, в той час як отримані з них називаються похідними псевдонімами. На приклад, `@foo` є кореневим псевдонімом, а `@foo/bar/file.php` — похідним.
Ви можете задати новий псевдонім, використовуючи раніше створений псевдонім (не важливо, кореневої він чи похідний):
```php
Yii::setAlias('@foobar', '@foo/bar');
```
Кореневі псевдоніми, як правило, створюються на етапі [попереднього завантаження (bootstrapping)](runtime-bootstrapping.md).
Наприклад, ви можете викликати [[Yii::setAlias()]] у [вхідному скрипті](structure-entry-scripts.md). Для зручності, в
[додатку (Application)](structure-applications.md) передбачено властивість `aliases`, яке можна задати через
[конфігурацію додатку](concept-configurations.md):
```php
return [
// ...
'aliases' => [
'@foo' => '/path/to/foo',
'@bar' => 'http://www.example.com',
],
];
```
Перетворення псевдонімів <a name="resolving-aliases"></a>
----------------------------------------------------
Метод [[Yii :: getAlias ()]] перетворює кореневої псевдонім в шлях до файлу або URL, який цей псевдонім представляє. Цей же метод може працювати і з похідними псевдонімами:
```php
echo Yii::getAlias('@foo'); // виведе: /path/to/foo
echo Yii::getAlias('@bar'); // виведе: http://www.example.com
echo Yii::getAlias('@foo/bar/file.php'); // виведе: /path/to/foo/bar/file.php
```
Шлях або URL, представлений похідним псевдонімом, визначається шляхом заміни в ньому частині, що відповідає кореневого псевдоніму, на відповідний йому шлях або URL.
> Примітка: Метод [[Yii :: getAlias ()]] не перевіряє фактичного існування одержуваного шляху або URL.
Кореневої псевдонім може містити знаки '/'. При цьому метод [[Yii::getAlias()]] коректно визначить, яка частина псевдоніма є кореневої і вірно сформує шлях або URL:
```php
Yii::setAlias('@foo', '/path/to/foo');
Yii::setAlias('@foo/bar', '/path2/bar');
Yii::getAlias('@foo/test/file.php'); // виведе: /path/to/foo/test/file.php
Yii::getAlias('@foo/bar/file.php'); // виведе: /path2/bar/file.php
```
Якби `@foo/bar` не був оголошений кореневим псевдонімом, остання строка вивела б `/path/to/foo/bar/file.php`.
Використання псевдонімів. <a name="using-aliases"></a>
------------------------------------------------
Псевдоніми розпізнаються в багатьох частинах Yii без необхідності попередньо викликати [[Yii::getAlias()]] для отримання шляху або URL. Наприклад, [[yii\caching\FileCache::cachePath]] приймає як звичайний шлях до файлу, так і псевдонім шляху завдяки префіксу `@`, який дозволяє їх розрізняти.
```php
use yii\caching\FileCache;
$cache = new FileCache([
'cachePath' => '@runtime/cache',
]);
```
Для того, щоб дізнатися чи підтримує метод або властивість псевдоніми, зверніться до документації API.
Заздалегідь визначені псевдоніми <a name="predefined-aliases"></a>
----------------------------------------------------------
В Yii заздалегідь визначені псевдоніми для часто використовуваних шляхів до файлів і URL:
- `@yii`: директорія, в якій знаходиться файл `BaseYii.php` (директорія фреймворка).
- `@app`: [[yii\base\Application::basePath|базовий шлях]] поточного додатку.
- `@runtime`: [[yii\base\Application::runtimePath|директорія runtime]] поточного додатку.
- `@vendor`: [[yii\base\Application::vendorPath|директорія vendor Composer].
- `@webroot`: вебрут поточного веб додатка (там де `index.php`).
- `@web`: базовий URL поточного додатку.
Псевдонім `@yii` задається в момент підключення файлу `Yii.php` у [вхідному скрипті](structure-entry-scripts.md).
Решта псевдоніми задаються в конструкторі додатки в момент застосування [конфигурації](concept-configurations.md).
Псевдоніми розширень <a name="extension-aliases"></a>
------------------------------------------------
Для кожного [розширення](structure-extensions.md), встановлюваного через Composer, автоматично задається псевдонім.
Його ім'я відповідає кореневого простору імен розширення відповідно до його `composer.json`. Псевдонім представляє
шлях до кореневої директорії пакета. Наприклад, якщо ви встановите розширення `yiisoft/yii2-jui`, то вам автоматично стане доступний псевдонім `@yii/jui`. Він створюється на етапі [первинного завантаження (bootstrapping)](runtime-bootstrapping.md)
приблизно так:
```php
Yii::setAlias('@yii/jui', 'VendorPath/yiisoft/yii2-jui');
```

8
docs/guide-uk/concept-autoloading.md

@ -4,12 +4,12 @@
[автозавантаження класів](http://www.php.net/manual/ru/language.oop5.autoload.php). Фреймворк надає свій швидкий сумісний з [PSR-4](https://github.com/php-fig/fig-standards/blob/master/proposed/psr-4-autoloader/psr-4-autoloader.md)
автозавантажувач, який встановлюється в момент підключення `Yii.php`.
> Примітка: Для простоти оповіді, в цьому розділі ми будемо говорити тільки про автозавантаження класів. Тим не менш, все описане застосовно до інтерфейсів і трейтам.
> Примітка: Для простоти оповіді, в цьому розділі ми будемо говорити тільки про автозавантаження класів. Тим не менш, все описане може бути застосовно до інтерфейсів і трейтів.
Як використовувати автозавантажувач Yii <a name="using-yii-autoloader"></a>
--------------------------------------------------------------
При використанні автозавантажувач класів Yii слід дотримуватися два простих правила створення і іменування класів:
При використанні автозавантажувача класів Yii слід дотримуватися два простих правила створення і іменування класів:
* Кожен клас повинен належати простору імен (тобто `foo\bar\MyClass`).
* Кожен клас повинен знаходитися в окремому файлі, шлях до якого визначаться наступним правилом:
@ -65,13 +65,13 @@ require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
```
Ви можете використовувати автозавантажувач Composer без автозавантажувач Yii. Однак, швидкість автозавантаження в цьому випадку може зменшиться. Також вам буде необхідно слідувати правилам автозавантажувача Composer.
Ви можете використовувати автозавантажувач Composer без автозавантажувачa Yii. Однак, швидкість автозавантаження в цьому випадку може зменшиться. Також вам буде необхідно слідувати правилам автозавантажувача Composer.
> Інформація: Якщо ви не хочете використовувати автозавантажувач Yii, створіть свою версію файлу `Yii.php`
і підключіть його в [вхідному скрипті](structure-entry-scripts.md).
Автозагрузка класів розширень <a name="autoloading-extension-classes"></a>
Автозавантаження класів розширень <a name="autoloading-extension-classes"></a>
-------------------------------------------------------------------
Автозавантажувач Yii може автоматично завантажувати класи [розширень](structure-extensions.md) в тому випадку, якщо дотримується єдине правило. Розширення повинно правильно описати розділ 'autoload' у файлі 'composer.json'. Більш докладно про це можна дізнатися з [офіційній документації Composer](https://getcomposer.org/doc/04-schema.md#autoload).

2
docs/guide-uk/start-workflow.md

@ -62,7 +62,7 @@ basic/ кореневий каталог додатка
На діаграмі показано як додаток опрацьовує запит.
![Життєвий цикл запиту](../guide/images/application-lifecycle.png)
![Життєвий цикл запиту](../guide/images/request-lifecycle.png)
1. Користувач звертається до [місця входження](structure-entry-scripts.md) `web/index.php`.
2. Скрипт завантажує конфігурацію [configuration](concept-configurations.md) і створює екземпляр [додатку](structure-applications.md) для наступного опрацювання запиту.

87
docs/guide-uk/structure-application-components.md

@ -0,0 +1,87 @@
Компоненти додатка
=====================
Додатки є [сервіс локаторами](concept-service-locators.md). Вони зберігають багато так званих
*компонентів додатку*, які надають різноманітні інструменти для опрацювання запитів. Наприклад,
компоненти `urlManager` відповідає за маршрутизацію веб запитів до потрібного контролера; компонент `db` надає інструменти для работи з базою даних; і т. д.
Кожний компонент додатка має свій унікальний ID, який дозволяє ідентифікувати його серед інших різноманітних компонентів
в одному і тому ж додатку. Ви можете отримати доступ до компонента наступним чином:
```php
\Yii::$app->ComponentID
```
Наприклад, ви можете використовувати `\Yii::$app->db` для отримання [[yii\db\Connection|з’єднання з БД]],
і `\Yii::$app->cache` для отримання доступу до основного компонента [[yii\caching\Cache|кеша]], зареєстрованого в додатку.
Компонентами додатку можуть бути любі об’єкти. Ви можете зареєструвати їх з допомогою властивості [[yii\base\Application::components]] в [конфігурації](structure-applications.md#application-configurations) додатка.
Наприклад,
```php
[
'components' => [
// реєстрація "cache" компонента з допомогою назви класу
'cache' => 'yii\caching\ApcCache',
// реєстрація "db" компонента з допомогою масива конфігурації
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=demo',
'username' => 'root',
'password' => '',
],
// реєстрація "search" компонента з допомогою анонімної функції
'search' => function () {
return new app\components\SolrService;
},
],
]
```
> Інформація: Хоча ви можете зареєструвати стільки компонентів в додатку скільки вам потрібно,
все ж таки варто робити це осмислено. Компоненти додатку схожі на глобальні змінні. Використання дуже великої кількості компонетів додатку може потенційно зробити ваш код складним для розробки і тестування.
В більшості випадків ви можете просто створити локальний компонент і використовувати його при необхідності.
## Вбудовані компоненти додатку <a name="core-application-components"></a>
В Yii є декілька *вбудованих* компонентів додатку, з фіксованими ID і конфігураціями за замовчуванням. Наприклад,
компонент [[yii\web\Application::request|request]] використовується для отримання інформації про запит користувача і розбору його в
певний [маршрут](runtime-routing.md); компонент [[yii\base\Application::db|db]] являє собою з’єднання з базою даних,
через яке ви можете виконувати запити. Саме з допомогою цих вбудованих компонентів Yii додатки можуть обрабляти
запит користувача.
Нижче наведений перелік вбудованих компонентів додатку. Ви можете конфігурувати їх так само як і інші компоненти додатку.
Коли ви конфігуруєте вбудований компонент додатку і не вказуєте клас цього компонента, то буде використовуватись значення за замовчуванням.
* [[yii\web\AssetManager|assetManager]]: використовується для керування і відображенням ресурсів додатку.
Більш детальна інформація представлена в розділі [Ресурси](output-assets.md);
* [[yii\db\Connection|db]]: являє собою з’єднання з базою даних, через яке ви можете виконувати запити.
Зверніть увагу, що коли конфігуруєте даний компонент, ви маєте вказати клас компонента так як і решту необхідних параметрів, а саме такі як [[yii\db\Connection::dsn]].
Більш детальна інформація представлена в розділі [Об’єкти доступу до даних (DAO)](db-dao.md);
* [[yii\base\Application::errorHandler|errorHandler]]: здійснює опрацювання PHP помилок і виключень.
Більш детальна інформація представлена в розділі [Обробка помилок](runtime-handling-errors.md);
* [[yii\base\Formatter|formatter]]: форматує дані для відображення їх кінцевому користувачу. Наприклад, число може
бути зображене з різноманітними розділителями, дата може бути зображена в форматі `long`.
Більш детальна інформація представлена в розділі [Форматування даних](output-formatting.md);
* [[yii\i18n\I18N|i18n]]: використовується для перекладу повідомлень і форматування.
Більш детальна інформація представлена в розділі [Інтернаціоналізація](tutorial-i18n.md);
* [[yii\log\Dispatcher|log]]: обробка і маршрутизація логів.
Більш детальна інформація представлена в розділі [Логування](runtime-logging.md);
* [[yii\swiftmailer\Mailer|mail]]: надає можливості для побудови і розсилки поштових повідомлень.
Більш детальна інформація представлена в розділі [Відправлення пошти](tutorial-mailing.md);
* [[yii\base\Application::response|response]]: являє собою дані від серверу, які будуть направлені користувачу.
Більш детальна інформація представлена в розділі [Відповіді](runtime-responses.md);
* [[yii\base\Application::request|request]]: являє собою запит, отриманий від кінцевого користувача.
Більш детальна інформація представлена в розділі [Запити](runtime-requests.md);
* [[yii\web\Session|session]]: інформація про сесії. Даний компонент доступний тільки в [[yii\web\Application|веб додатках]].
Більш детальна інформація представлена в розділі [Сесії і куки](runtime-sessions-cookies.md);
* [[yii\web\UrlManager|urlManager]]: використовується для розбору і побудови URL.
Більш детальна інформація представлена в розділі [Розбір і генерація URL](runtime-url-handling.md);
* [[yii\web\User|user]]: являє собою інформацію авторизованого користувача.
Даний компонент доступний тільки в [[yii\web\Application|веб додатках]].
Більш детальна інформація представлена в розділі [Аутентифікація](security-authentication.md);
* [[yii\web\View|view]]: використовується для відображення представлень.
Більш детальна інформація представлена в розділі [Представлення](structure-views.md).

414
docs/guide-uk/structure-controllers.md

@ -0,0 +1,414 @@
Контролери
===========
Контролери є частиною [MVC](https://ru.wikipedia.org/wiki/Model-View-Controller) архітектури. Це об’єкти класів, успадкованих
від [[yii\base\Controller]] і відповідають за опрацювання запиту і генерації відповіді. По суті, після опрацювання запиту [додатками](structure-applications.md),
контролери проаналізують вхідні дані, передадуть їх в [моделі](structure-models.md), додадуть результати моделі в [представлення](structure-views.md),
і в кінцевому підсумку згенерують вихідні відповіді.
## Події <a name="actions"></a>
Контролери складаються з *подій*, які є основними блоками, до яких може звертатись кінцевий користувач і запитувати виконання того або іншого функціоналу. В контролері може бути одна або декілька подій.
Наступний приклад показує `post` контролер з двома подіями: `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,
]);
}
}
}
```
В події `view` (визначено методом `actionView()`), код спочатку завантажує [модель](structure-models.md)
згідно запитуваної ID моделі; Якщо модель успішно завантажена, то код відобразить її за допомогою [представлення](structure-views.md)
під назвою `view`. В іншому випадку буде визване виключення.
В події `create` (визначено методом `actionCreate()`), код аналогічний. Він спочатку намагається завантажити [модель](structure-models.md) за допомогою даних із запиту і зберегти модель. Якщо все пройшло успішно, то код перенаправить браузер на подію `view` з ID щойно створеної моделі. В іншому випадку він відобразить предаставлення `create`, через яке користувач зможе вказати необхідні дані.
## Маршрути <a name="routes"></a>
Кінцеві користувачі звертаються до подій з допомогою так названих *маршрутів*. Маршрут це рядок, який складається з наступних частин:
* ID модуля: він існує, тільки якщо контролер належить не додатку, а [модулю](structure-modules.md);
* ID контролера: рядок, який унікально ідентифікує контролер серед всіх інших контролерів одного і того ж додатка
(або одного й того ж модуля, якщо контролер належить модулю);
* ID події: рядок, який унікально идентифікує подію серед всіх інших подій одного й того ж конторолера.
Маршрути можуть мати наступний формат:
```
ControllerID/ActionID
```
або наступний формат, якщо контролер належить модулю:
```php
ModuleID/ControllerID/ActionID
```
Таким чином, якщо користувач звертається до URL `http://hostname/index.php?r=site/index`, то `index` подія в `site` контролері яку буде викликано.
Секція [Маршрутизація](runtime-routing.md) містить більш детальну інформацію про те як маршрути співставляються з подіями.
## Створення контролерів <a name="creating-controllers"></a>
В [[yii\web\Application|Веб додатках]], контролери мусять бути успадковані від [[yii\web\Controller]] або його потомків.
Аналогічно для [[yii\console\Application|консольних додатків]], контролери мусять бути успадковані від [[yii\console\Controller]] або його потомків. Наступний код визначає `site` контролер:
```php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
}
```
### ID контролерів <a name="controller-ids"></a>
За звичай контролер зроблений таким чином, що він мусить опрацьовувати запити, які пов’язані з певним ресурсом.
Саме через дані причини, ID контролерів за завичай є іменниками, які посилаються на ресурс, який вони опрацьовують.
Наприклад, ви можете використовувати `article` в якості ID контролера, який відповідає за опрацювання даних публікацій.
За замовчуванням, ID контролерів мають містити тільки наступні символи: Англійські букви в нижньому регістрі, цифри, підкреслення,
тире и слеш. Наприклад, обидва `article` і `post-comment` є прийнятними ID контролерів, в той час як `article?`, `PostComment`,
`admin\post` не являються такими.
ID контролерів також можуть містити префікс субдиректорії. Наприклад, в `admin/article` частина `article` є контролером в
субдиректорії `admin` в [[yii\base\Application::controllerNamespace|порсторі імен]].
Допустимими символами для префіксів субдиректорій є: Англійські букви в нижньому і верхньому регістрі, символи підкреслення і слеш, де слеш використовується в якості розділителя для багатовкладених субдиректорій (наприклад `panels/admin`).
### Правила найменування класів контролерів <a name="controller-class-naming"></a>
Назви класів контролерів можуть бути отримані з ID контролерів наступними способами:
* Привести в верхній регістр перший символ в кожному слові, розділеному дефісами. Зверніть увагу що, якщо ID контролера
містить слеш, то дане правило поширюється тільки на частину після останнього слеша в ID контролера;
* Прибрати дефіси і замінити будь-який прямий слеш на зворотний;
* Додати суфікс `Controller`;
* Додати в початок [[yii\base\Application::controllerNamespace|простір імен контролерів]].
Нижче наведено декілька прикладів, з урахуванням того, що [[yii\base\Application::controllerNamespace|простір імен контролерів]] має значення за замовчуванням `app\controllers`:
* `article` відповідає `app\controllers\ArticleController`;
* `post-comment` відповідає `app\controllers\PostCommentController`;
* `admin/post-comment` відповідає `app\controllers\admin\PostCommentController`;
* `adminPanels/post-comment` відповідає `app\controllers\adminPanels\PostCommentController`.
Класи контролерів мають бути [автозавантаженими](concept-autoloading.md). Саме по цій причині, у вищенаведених прикладах,
контролер `article` має бути збереженим у файл, [псевдонім](concept-aliases.md) якого `@app/controllers/ArticleController.php`;
в той час як контролер `admin/post2-comment` має знаходитись у файлі `@app/controllers/admin/Post2CommentController.php`.
> Інформація: Останній приклад `admin/post2-comment` показує яким чином ви можете розташувати контролер в директорії
[[yii\base\Application::controllerNamespace|простору імен контролерів]]. Це дуже зручно, коли ви хочете організувати свої контролери в декілька категорій і не хочете використовувати [модулі](structure-modules.md).
### Мапа контролерів <a name="controller-map"></a>
Ви можете налаштувати [[yii\base\Application::controllerMap|Мапу контролерів]] для того, щоб подолати
описані вище обмеження іменування ID контролерів і назв класів. В основному це дуже зручно, коли ви використовуєте
сторонні контролери, іменування яких ви не можете контролювати.
Ви можете налаштувати [[yii\base\Application::controllerMap|мапу контролерів]] в [налаштуваннях додатка](structure-applications.md#application-configurations)
наступним чином:
```php
[
'controllerMap' => [
[
// оголошує "account" контролер, використовуючи назву класу
'account' => 'app\controllers\UserController',
// оголошує "article" контролер, використовуючи масив конфігурації
'article' => [
'class' => 'app\controllers\PostController',
'enableCsrfValidation' => false,
],
],
],
]
```
### Контролер за замовчуванням <a name="default-controller"></a>
Кожний додаток має контролер за замовчуванням, вказаний через властивість [[yii\base\Application::defaultRoute]].
Коли в запиті не вказаний [маршрут](#ids-routes), тоді буде використаний маршрут вказаний в даній властивості.
Для [[yii\web\Application|Веб додатків]], це значення `'site'`, в той час як для [[yii\console\Application|консольних додатків]],
це `'help'`. Таким чином, якщо вказаний URL `http://hostname/index.php`, це значить, що контролер `site` виконає обробку запиту.
Ви можете змінити контролер за замовчуванням наступним чином в [налаштуваннях додатку](structure-applications.md#application-configurations):
```php
[
'defaultRoute' => 'main',
]
```
## Створення подій <a name="creating-actions"></a>
Створення подій не містить складнощів також як і оголошення так званих *методов подій* в класі контролера. Метод події це *public* метод, ім’я якого починається за слова `action`. Значення, що повертаються методу події являють собою відповідні дані, які будуть вислані кінцевому користувачу. Наведений нижче код визначає дві події `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';
}
}
```
### ID подій <a name="action-ids"></a>
В основному події розробляються для певної конкретної обробки ресурса. По цій причині, ID подій в основному
є дієсловами, такими як `view`, `update`, і т. д.
За замовчуванням, ID події повинен містити тільки такі символи: Англійські букви в нижньому регістрі, цифри,
підкреслення і дефіси. Дефіси в ID подій використовуються для поділу слів. Наприклад, `view`, `update2`, `comment-post` є допустимими ID подій, в той час як `view?`, `Update` не являються такими.
Ви можете створювати події двома способами: вбудовані події і окремі події. Вбудована подія є методом, визначеним
в класі контролера, тоді як окрема подія є екземпляром класу, успадкованого від [[yii\base\Action]] або його потомків.
Вбудовані події вимагають менше зусиль для створення і в основному використовуються якщо у вас немає потреби в повторному використанні подій.
Окремі події, з іншого боку, в основному створюються для використання в різних контролерах або при використанні в [розширеннях](structure-extensions.md).
### Вбудовані події <a name="inline-actions"></a>
Вбудовані події це ті події, які визначені в рамках методів контролера, як ми це вже обговорили.
Назви методів подій можуть бути отримані з ID подій наступним чином:
* Привести перший символ кожного слова в ID події у верхній регістр;
* Прибрати дефіси;
* Додати префікс `action`.
Наприклад, `index` відповідає `actionIndex`, а `hello-world` відповідає `actionHelloWorld`.
> Примітка: Назви імен подій є *регістрозалежними*. Якщо у вас є метод `ActionIndex`, він не буде врахований як метод події, таким чином, запит до події `index` призведе до зображення виключення. Також слід врахувати, що методи подій повинні мати область видимості public. Методи, що мають область видимості private або protected НЕ визначають методи вбудованих подій.
Вбудовані події в основному використовуються, тому що для їх створення не потрібного багато зусиль. Тим не менше, якщо ви плануєте повторно використовувати деякі події в різних місцях, або якщо ви хочете перерозподілити події, ви повинні визначити їх як *окремі події*.
### Окремі події <a name="standalone-actions"></a>
Окремі події визначаються в якості класів, успадкованих від [[yii\base\Action]] або його потомків.
Наприклад, в Yii релізах, присутні [[yii\web\ViewAction]] і [[yii\web\ErrorAction]], обидва з яких є окремими подіями.
Для використання окремої події, ви маєте вказати її в *мапі подій*, з допомогою перевизначення метода
[[yii\base\Controller::actions()]] у вашому класі контролера, наступним чином:
```php
public function actions()
{
return [
// оголошує "error" подію з допомогою назви класу
'error' => 'yii\web\ErrorAction',
// оголошує "view" подію з допомогою конфігураційного масиву
'view' => [
'class' => 'yii\web\ViewAction',
'viewPrefix' => '',
],
];
}
```
Як ви можете бачити, метод `actions()` мусить повернути масив, ключами якого є ID подій, а значенями - відповідні назви класу події або [конфігурація](concept-configurations.md). На відміну від вбудованих подій, ID окремих подій можуть містити довільні символи, до тих пір поки вони визначені в методі `actions()`.
Для створення окремої події, ви мусите успадкуватись від класу [[yii\base\Action]] або його потомків, і реалізувати
метод `run()` з областю видимості public. Роль метода `run()` аналогічна іншим методам подій. Наприклад,
```php
<?php
namespace app\components;
use yii\base\Action;
class HelloWorldAction extends Action
{
public function run()
{
return "Hello World";
}
}
```
### Результати подій <a name="action-results"></a>
Значення, що повертається методами подій або методом `run()` окремої події дуже важливе. Воно є результатом
виконання відповідної події.
Значення, що повертається може бути об’єктом [response](runtime-responses.md), який буде направлений кінцевому користувачу в якості відповіді.
* Для [[yii\web\Application|Веб додатків]], значення, що повертається також може бути довільними даними, яким будуть
назначені [[yii\web\Response::data]], а потім конвертовані в рядок, що представляє тіло відповіді.
* Для [[yii\console\Application|Консольних додатків]], значення, що повертається також може бути числом, що представляє
[[yii\console\Response::exitStatus|статус виходу]] виконання команди.
В вищенаведених прикладах, всі результати подій є рядками, які будуть використані в якості тіла відповіді,
висланого користувачеві. Наступний приклад, показує подію, що може перенаправити браузер користувача на новий URL, за допомогою
повернення response об'єкта ([[yii\web\Controller::redirect()|redirect()]] метод повертає response об’єкт):
```php
public function actionForward()
{
// перенаправляємо браузер користувача на http://example.com
return $this->redirect('http://example.com');
}
```
### Параметри подій <a name="action-parameters"></a>
Методи подій для вбудованих подій і методи `run()` для окремих подій можуть приймати параметри, які називають *параметри подій*. Їх значення беруться із запитів. Для [[yii\web\Application|Веб додатків]], значення кожного з параметрів події береться з `$_GET`, використовуючи назву параметра в якості ключа;
для [[yii\console\Application|консольних додатків]], вони відповідають аргументам командної строки.
В наведеному нижче прикладі, подія `view` (вбудовона подія) визначає два параметра: `$id` і `$version`.
```php
namespace app\controllers;
use yii\web\Controller;
class PostController extends Controller
{
public function actionView($id, $version = null)
{
// ...
}
}
```
Для різних запитів параметри події будуть визначені наступним чином:
* `http://hostname/index.php?r=post/view&id=123`: параметр `$id` буде присвоєне значення `'123'`, в той час як `$version` буде мати значення null, так як рядок запиту не містить параметра `version`;
* `http://hostname/index.php?r=post/view&id=123&version=2`: параметрам `$id` і `$version` будуть присвоєні
значення `'123'` і `'2'` відповідно;
* `http://hostname/index.php?r=post/view`: буде вкинуте виключення [[yii\web\BadRequestHttpException]], так як
обов’язковий параметр `$id` не був вказаний в запиті;
* `http://hostname/index.php?r=post/view&id[]=123`: буде вкинуте виключення [[yii\web\BadRequestHttpException]], так як
параметр `$id` отримав невірне значення `['123']`.
Якщо ви хочите, щою параметр події приймав масив значеннь, ви мусите використовувати type-hint значення `array`, як зображено нажче:
```php
public function actionView(array $id, $version = null)
{
// ...
}
```
Тепер, якщо запит буде містити URL `http://hostname/index.php?r=post/view&id[]=123`, то параметр `$id` отримає значення
`['123']`. Якщо запит буде містити URL `http://hostname/index.php?r=post/view&id=123`, то параметр `$id` все рівно буде містити масив, так як скалярне значення `'123'` буде автоматично сконвертовано в масив.
Вищенаведені приклади в основному показують як параметри подій працюють для Веб додатків. Більше інформації
про параметри консольних додатків наведено в секції [Консольні команди](tutorial-console.md).
### Події за замовчуванням <a name="default-action"></a>
Кожний контролер містить події, визначені через властивість [[yii\base\Controller::defaultAction]].
Коли [маршрут](#ids-routes) містить тільки ID контролера, то розуміється, що було запрошено подію контролера за замовчуванням.
За замовчуванням, ця подія має значення `index`. Якщо ви хочите змінити це значення, просто перевизначте дану властивість в класі контролера наступним чином:
```php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public $defaultAction = 'home';
public function actionHome()
{
return $this->render('home');
}
}
```
## Життєвий цикл контролера <a name="controller-lifecycle"></a>
При опрацюванні запиту, [додаток](structure-applications.md) створить контролер, базуючись на
запрошеному [маршруті](#routes). Для виконання запиту, контролер пройде через наступні етапи життєвого циклу:
1. Метод [[yii\base\Controller::init()]] буде викликаний після того як контролер буде створений і сконфігурований;
2. Контролер створить об’єкт події, базуючись на запрошеному ID події:
* Якщо ID події не вказано, то буде використано [[yii\base\Controller::defaultAction|ID події за замовчуванням]];
* Якщо ID події знайдено в [[yii\base\Controller::actions()|мапі подій]], то буде створено окрему подію;
* Якщо ID події відповідає методу події, то буде створено вбудовану подію;
* В іншому випадку, буде вкинуте виключення [[yii\base\InvalidRouteException]].
3. Контролер послідовно викликає метод `beforeAction()` додатка, модуля (якщо контролер належить модулю) і
самого контролера.
* Якщо один із методів повернув `false`, то решта, невикликані методи `beforeAction` будуть пропущені, а виконання події буде відмінено;
* За замовчуванням, кожний виклик метода `beforeAction()` викликає подію `beforeAction`, на яку ви можете призначити обробників.
4. Контролер запускає подію:
* Параметри події будуть проаналізовані і заповнені з даних запиту.
5. Контролер послідовно викликає методи `afterAction` контролера, модуля (якщо контролер належить модулю) і додатка.
* За замовчуванням, кожний виклик метода `afterAction()` викликає подію `afterAction`, на яку ви можете призначити обробників.
6. Додаток, отримавши результат виконання події, присвоює його об’єкту [response](runtime-responses.md).
## Кращі практики <a name="best-practices"></a>
В добре організованих додатках, контролери за звичай дуже тонкі, і містять лише декілька рядків коду.
Якщо ваш контролер дуже складний, це за звичай означає, що вам потрібно провести рефакторинг його і перенести будь-який код в інші місце.
В цілому, контролери
* можуть мати доступ до даних [запиту](runtime-requests.md);
* можуть викликати методи [моделей](structure-models.md) і інших компонентів системи з даними запиту;
* можуть використовувати [представлення](structure-views.md) для формування відповіді;
* не повинні займатись опрацюванням даних, це має відбуватись в [моделях](structure-models.md);
* мають уникати використання HTML або іншої розмітки, краще це робити в [представленнях](structure-views.md).

2
docs/guide-zh-CN/README.md

@ -62,7 +62,7 @@ Yii 2.0 权威指南
* **已定稿** [行为(Behavior)](concept-behaviors.md)
* **已定稿** [配置(Configurations)](concept-configurations.md)
* **已定稿** [类自动加载(Autoloading)](concept-autoloading.md)
* **已定稿** [别名(Alias)](concept-alias.md)
* **已定稿** [别名(Alias)](concept-aliases.md)
* **已定稿** [服务定位器(Service Locator)](concept-service-locator.md)
* **已定稿** [依赖注入容器(DI Container)](concept-di-container.md)

0
docs/guide-zh-CN/images/application-lifecycle.graphml → docs/guide-zh-CN/images/request-lifecycle.graphml

0
docs/guide-zh-CN/images/application-lifecycle.png → docs/guide-zh-CN/images/request-lifecycle.png

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save