Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
@ -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]]. |
@ -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`. |
@ -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. |
@ -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). |
@ -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 |
||||
} |
||||
} |
||||
``` |
@ -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]]. |
@ -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. |
@ -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. |
||||
|
@ -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' |
||||
``` |
@ -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' => [], |
||||
] |
||||
] |
||||
] |
||||
``` |
@ -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]] |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
@ -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 が上限値です。そのためクエリ結果のサイズがこの制約を越える場合、キャッシュは失敗します。 |
@ -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 コードはすべてのリクエストに対して実行されますが、囲まれている断片がキャッシュから提供されているか否かは問いません。 |
@ -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> |
||||
|
||||
検索エンジンのボットはキャッシュヘッダを尊重する傾向があります。 クローラの中には、一定期間内に処理するドメインごとのページ数に制限を持っているものもあるため、キャッシュヘッダを導入して、処理の必要があるページ数を減らしてやると、サイトのインデックスの作成を促進できるかも知れません。 |
@ -0,0 +1,13 @@
|
||||
キャッシュ |
||||
======= |
||||
|
||||
ウェブアプリケーションのパフォーマンスを向上させるための簡単で効果的な方法としてキャッシュというものがあります。比較的静的なデータをキャッシュに格納し、必要に応じてキャッシュからそれらを取得することによって、アプリケーションは一からデータを生成するのに必要な時間を節約することができます。 |
||||
|
||||
キャッシュはさまざまなレベルのものを、アプリケーション内のさまざまな場所で使用することができます。例えばサーバサイドでの低いレベルでは、データベースから取得した最新の記事情報リストのような基本的なデータを格納するために使用したり、高いレベルでは、レンダリング結果の一部分、最新の記事であったり、またウェブページ全体を格納するためなどにも使用できます。クライアントサイドでは、ブラウザのキャッシュに最近訪れたことのあるページの内容を格納するために HTTP キャッシュを使用することもできます。 |
||||
|
||||
Yii では以下のリストに挙げられているキャッシュ機構をサポートしています: |
||||
|
||||
* [データキャッシュ](caching-data.md) |
||||
* [フラグメントキャッシュ](caching-fragment.md) |
||||
* [ページキャッシュ](caching-page.md) |
||||
* [HTTP キャッシュ](caching-http.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) も使用することができます。 |
@ -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> |
After Width: | Height: | Size: 13 KiB |
@ -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> |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 38 KiB |
@ -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> |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 41 KiB |
@ -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"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
<y:Resource id="2"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#49AD33"/> |
||||
<stop offset="1" style="stop-color:#C2DA92"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
</y:Resources> |
||||
</data> |
||||
</graphml> |
After Width: | Height: | Size: 19 KiB |
@ -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"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
<y:Resource id="2"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#49AD33"/> |
||||
<stop offset="1" style="stop-color:#C2DA92"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
</y:Resources> |
||||
</data> |
||||
</graphml> |
After Width: | Height: | Size: 19 KiB |
@ -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"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
<y:Resource id="2"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#49AD33"/> |
||||
<stop offset="1" style="stop-color:#C2DA92"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
</y:Resources> |
||||
</data> |
||||
</graphml> |
After Width: | Height: | Size: 19 KiB |
@ -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"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
<y:Resource id="2"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#49AD33"/> |
||||
<stop offset="1" style="stop-color:#C2DA92"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
</y:Resources> |
||||
</data> |
||||
</graphml> |
After Width: | Height: | Size: 16 KiB |
@ -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"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FCB57A"/> |
||||
<stop offset="1" style="stop-color:#FF8C36"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
<y:Resource id="2"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#49AD33"/> |
||||
<stop offset="1" style="stop-color:#C2DA92"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
</y:Resources> |
||||
</data> |
||||
</graphml> |
After Width: | Height: | Size: 18 KiB |
@ -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"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<g> |
||||
|
||||
<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)"> |
||||
<stop offset="0.2711" style="stop-color:#FFAB4F"/> |
||||
<stop offset="1" style="stop-color:#FFD28F"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#74AEEE"/> |
||||
<stop offset="1" style="stop-color:#2068A3"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
<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"/> |
||||
<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"/> |
||||
<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"/> |
||||
<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"/> |
||||
|
||||
<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"> |
||||
<stop offset="0" style="stop-color:#FFD28F"/> |
||||
<stop offset="1" style="stop-color:#FFAB4F"/> |
||||
</radialGradient> |
||||
<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"/> |
||||
|
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.24"/> |
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.16"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
<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"/> |
||||
<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"/> |
||||
</g> |
||||
</svg> |
||||
</y:Resource> |
||||
<y:Resource id="2"><?xml version="1.0" encoding="utf-8"?> |
||||
<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"> |
||||
<defs> |
||||
</defs> |
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#3C89C9"/> |
||||
<stop offset="0.1482" style="stop-color:#60A6DD"/> |
||||
<stop offset="0.3113" style="stop-color:#81C1F0"/> |
||||
<stop offset="0.4476" style="stop-color:#95D1FB"/> |
||||
<stop offset="0.5394" style="stop-color:#9CD7FF"/> |
||||
<stop offset="0.636" style="stop-color:#98D4FD"/> |
||||
<stop offset="0.7293" style="stop-color:#8DCAF6"/> |
||||
<stop offset="0.8214" style="stop-color:#79BBEB"/> |
||||
<stop offset="0.912" style="stop-color:#5EA5DC"/> |
||||
<stop offset="1" style="stop-color:#3C89C9"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#9CD7FF"/> |
||||
<stop offset="0.0039" style="stop-color:#9DD7FF"/> |
||||
<stop offset="0.2273" style="stop-color:#BDE5FF"/> |
||||
<stop offset="0.4138" style="stop-color:#D1EEFF"/> |
||||
<stop offset="0.5394" style="stop-color:#D9F1FF"/> |
||||
<stop offset="0.6155" style="stop-color:#D5EFFE"/> |
||||
<stop offset="0.6891" style="stop-color:#C9E7FA"/> |
||||
<stop offset="0.7617" style="stop-color:#B6DAF3"/> |
||||
<stop offset="0.8337" style="stop-color:#9AC8EA"/> |
||||
<stop offset="0.9052" style="stop-color:#77B0DD"/> |
||||
<stop offset="0.9754" style="stop-color:#4D94CF"/> |
||||
<stop offset="1" style="stop-color:#3C89C9"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#3C89C9"/> |
||||
<stop offset="0.1482" style="stop-color:#60A6DD"/> |
||||
<stop offset="0.3113" style="stop-color:#81C1F0"/> |
||||
<stop offset="0.4476" style="stop-color:#95D1FB"/> |
||||
<stop offset="0.5394" style="stop-color:#9CD7FF"/> |
||||
<stop offset="0.636" style="stop-color:#98D4FD"/> |
||||
<stop offset="0.7293" style="stop-color:#8DCAF6"/> |
||||
<stop offset="0.8214" style="stop-color:#79BBEB"/> |
||||
<stop offset="0.912" style="stop-color:#5EA5DC"/> |
||||
<stop offset="1" style="stop-color:#3C89C9"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#9CD7FF"/> |
||||
<stop offset="0.0039" style="stop-color:#9DD7FF"/> |
||||
<stop offset="0.2273" style="stop-color:#BDE5FF"/> |
||||
<stop offset="0.4138" style="stop-color:#D1EEFF"/> |
||||
<stop offset="0.5394" style="stop-color:#D9F1FF"/> |
||||
<stop offset="0.6155" style="stop-color:#D5EFFE"/> |
||||
<stop offset="0.6891" style="stop-color:#C9E7FA"/> |
||||
<stop offset="0.7617" style="stop-color:#B6DAF3"/> |
||||
<stop offset="0.8337" style="stop-color:#9AC8EA"/> |
||||
<stop offset="0.9052" style="stop-color:#77B0DD"/> |
||||
<stop offset="0.9754" style="stop-color:#4D94CF"/> |
||||
<stop offset="1" style="stop-color:#3C89C9"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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"/> |
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#3C89C9"/> |
||||
<stop offset="0.1482" style="stop-color:#60A6DD"/> |
||||
<stop offset="0.3113" style="stop-color:#81C1F0"/> |
||||
<stop offset="0.4476" style="stop-color:#95D1FB"/> |
||||
<stop offset="0.5394" style="stop-color:#9CD7FF"/> |
||||
<stop offset="0.636" style="stop-color:#98D4FD"/> |
||||
<stop offset="0.7293" style="stop-color:#8DCAF6"/> |
||||
<stop offset="0.8214" style="stop-color:#79BBEB"/> |
||||
<stop offset="0.912" style="stop-color:#5EA5DC"/> |
||||
<stop offset="1" style="stop-color:#3C89C9"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#9CD7FF"/> |
||||
<stop offset="0.0039" style="stop-color:#9DD7FF"/> |
||||
<stop offset="0.2273" style="stop-color:#BDE5FF"/> |
||||
<stop offset="0.4138" style="stop-color:#D1EEFF"/> |
||||
<stop offset="0.5394" style="stop-color:#D9F1FF"/> |
||||
<stop offset="0.6155" style="stop-color:#D5EFFE"/> |
||||
<stop offset="0.6891" style="stop-color:#C9E7FA"/> |
||||
<stop offset="0.7617" style="stop-color:#B6DAF3"/> |
||||
<stop offset="0.8337" style="stop-color:#9AC8EA"/> |
||||
<stop offset="0.9052" style="stop-color:#77B0DD"/> |
||||
<stop offset="0.9754" style="stop-color:#4D94CF"/> |
||||
<stop offset="1" style="stop-color:#3C89C9"/> |
||||
</linearGradient> |
||||
<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"/> |
||||
<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)"> |
||||
<stop offset="0" style="stop-color:#9CD7FF"/> |
||||
<stop offset="1" style="stop-color:#3C89C9"/> |
||||
</linearGradient> |
||||
<ellipse fill="url(#SVGID_7_)" cx="19.625" cy="3.926" rx="18.396" ry="3.926"/> |
||||
<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"/> |
||||
</svg> |
||||
</y:Resource> |
||||
</y:Resources> |
||||
</data> |
||||
</graphml> |
After Width: | Height: | Size: 41 KiB |
@ -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) の節を参照してください。 |
@ -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) で行う方が良いです。 |
@ -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()); |
||||
} |
||||
``` |
@ -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` の中のコードはフロントエンドアプリケーション固有のものであると保証することが出来ます。 |
||||
そして、フロントエンドのコードにどのような変更を加えても、バックエンドアプリケーションを壊すかもしれないと心配する必要がなくなります。 |
@ -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> |
||||
|
||||
モジュールは、それぞれ密接に関係する一連の機能を含む数個のグループに分割できるような、規模の大きなアプリケーションに |
||||
最も適しています。そのような機能グループをそれぞれモジュールとして、特定の個人やチームによって開発することが出来ます。 |
||||
|
||||
モジュールは、また、機能グループレベルでコードを再利用するための良い方法でもあります。ある種のよく使われる機能、 |
||||
例えばユーザ管理やコメント管理などは、全て、将来のプロジェクトで容易に再利用できるように、モジュールの形式で |
||||
開発することが出来ます。 |
@ -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>© 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) を使う。 |
||||
* ビューでデータを変換し書式化するためのヘルパークラスを作成して使う。 |
||||
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
@ -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; |
||||
``` |
@ -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(...); |
||||
``` |
@ -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 код будет выполняться для каждого запроса, независимо от того находится ли он внутри кэширования фрагмента или нет. |
@ -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). |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |