From b5c396bd41ce578c01998a0eb45f842628edde4c Mon Sep 17 00:00:00 2001 From: Luciano Baraglia Date: Tue, 11 Nov 2014 13:12:20 -0300 Subject: [PATCH 01/13] Spanish Guide minor changes [skip ci] --- docs/guide-es/rest-authentication.md | 64 ++++++++++++++++++---------- docs/guide/rest-authentication.md | 2 +- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/docs/guide-es/rest-authentication.md b/docs/guide-es/rest-authentication.md index 4bb4579bb3..ce046ff270 100644 --- a/docs/guide-es/rest-authentication.md +++ b/docs/guide-es/rest-authentication.md @@ -1,28 +1,41 @@ 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. +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) **. -Hay muchas maneras de enviar una pieza (token) de acceso: +Hay muchas maneras de enviar una token (pieza) 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. +* [Autorización Básica HTTP](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). + `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 [tokens HTTP del portador] (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]]. +1. Configura el componente `user` de la aplicación: + - Define la propiedad [[yii\web\User::enableSession|enableSession]] como `false`. + - Define la propiedad [[yii\web\User::loginUrl|loginUrl]] como `null` para mostrar un error HTTP 403 en vez de redireccionar a la pantalla de login. +2. Especifica cuál método de autenticación planeas usar configurando el comportamiento (behavior) `authenticator` en tus + clases de controladores REST. +3. Implementa [[yii\web\IdentityInterface::findIdentityByAccessToken()]] en tu [[yii\web\User::identityClass|clase de identidad de usuarios]]. -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. +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 persistir entre peticiones usando sesiones. +Si embargo, la autenticación será realizada para cada petición, lo que se consigue en 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: +> Tip: Puedes 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() { @@ -31,7 +44,7 @@ public function init() } ``` -Por ejemplo, para usar HTTP Basic Auth, puedes configurar `authenticator` como sigue, +Por ejemplo, para usar HTTP Basic Auth, puedes configurar el comportamiento `authenticator` como sigue, ```php use yii\filters\auth\HttpBasicAuth; @@ -46,7 +59,7 @@ public function behaviors() } ``` -Si quires implementar las tres autenticaciones explicadas antes, puedes usar `CompositeAuth` de la siguiente manera, +Si quieres implementar los tres métodos de autenticación explicados antes, puedes usar `CompositeAuth` de la siguiente manera, ```php use yii\filters\auth\CompositeAuth; @@ -69,10 +82,12 @@ public function 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. +Cada elemento en `authMethods` debe de ser el nombre de una clase de método de autenticación 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, +La implementación de `findIdentityByAccessToken()` es específico de la aplicación. Por ejemplo, en escenarios simples +cuando cada usuario sólo puede tener un token de acceso, puedes almacenar este token 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; @@ -87,15 +102,20 @@ class User extends ActiveRecord implements IdentityInterface } ``` -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()`. +Después que la autenticación es activada, tal y como se describe arriba, para cada petición de la API, el controlador solicitado +puede intentar autenticar al usuario en su evento `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 tiene éxito, el controlador realizará otras comprobaciones (como son límite del ratio, autorización) +y entonces ejecutar la acción. La identidad del usuario autenticado puede ser recuperada 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` ). +Si la autenticación falla, una respuesta con estado HTTP 401 será devuelta junto con otras cabeceras apropiadas (tal como la cabecera para autenticación básica HTTP `WWW-Authenticate`). ## Autorización -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). +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 solicitada. 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]]. +Si tus controladores extienden de [[yii\rest\ActiveController]], puedes sobreescribir +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]]. diff --git a/docs/guide/rest-authentication.md b/docs/guide/rest-authentication.md index b91214bd11..11541180c9 100644 --- a/docs/guide/rest-authentication.md +++ b/docs/guide/rest-authentication.md @@ -11,7 +11,7 @@ via HTTPS to prevent man-in-the-middle (MitM) attacks**. There are different ways to send an access token: * [HTTP Basic Auth](http://en.wikipedia.org/wiki/Basic_access_authentication): the access token - is sent as the username. This is should only be used when an access token can be safely stored + is sent as the username. This should only be used when an access token can be safely stored on the API consumer side. For example, the API consumer is a program running on a server. * Query parameter: the access token is sent as a query parameter in the API URL, e.g., `https://example.com/users?access-token=xxxxxxxx`. Because most Web servers will keep query From bb216655c4a26a8f842de8721f4138fa04f02243 Mon Sep 17 00:00:00 2001 From: Luciano Baraglia Date: Tue, 11 Nov 2014 13:28:37 -0300 Subject: [PATCH 02/13] More Spanish guide small changes [skip ci] --- docs/guide-es/rest-error-handling.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/guide-es/rest-error-handling.md b/docs/guide-es/rest-error-handling.md index 409c7b5081..a8b1dda1ff 100644 --- a/docs/guide-es/rest-error-handling.md +++ b/docs/guide-es/rest-error-handling.md @@ -1,8 +1,12 @@ 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: +Cuando se maneja una petición de 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 solicitado no existe), debes considerar lanzar una excepción +con el código HTTP de estado apropiado (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 @@ -22,7 +26,7 @@ Content-Type: application/json; charset=UTF-8 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. +* `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. @@ -33,12 +37,14 @@ La siguiente lista sumariza los códigos de estado HTTP que son usados por el fr * `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. +* `500`: Error interno del servidor. Esto puede estar causado por errores internos del programa. ## Personalizando la Respuesta al Error -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, +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 encapsular el código de estado HTTP real como parte de una estructura JSON en la respuesta, como se muestra a continuación, ``` HTTP/1.1 200 OK @@ -58,7 +64,7 @@ Content-Type: application/json; charset=UTF-8 } ``` -Para lograr este objetivo, puedes responder al evento `beforeSend` de el componente `response` en la configuración de la aplicación: +Para lograr este objetivo, puedes responder al evento `beforeSend` del componente `response` en la configuración de la aplicación: ```php return [ @@ -81,5 +87,5 @@ return [ ]; ``` -El anterior código puede reformatear la respuesta (para ambas respuestas, exitosa o fallida) de forma aclaratoria cuando +El anterior código reformateará la respuesta (sea exitosa o fallida) como se explicó cuando `suppress_response_code` es pasado como un parámetro `GET`. From a24c2a6a092f07d2ff31bf00aedb4cbd8941942f Mon Sep 17 00:00:00 2001 From: munawer Date: Wed, 12 Nov 2014 12:52:11 +0530 Subject: [PATCH 03/13] Fixes in guide [ci skip] --- docs/guide/tutorial-i18n.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/guide/tutorial-i18n.md b/docs/guide/tutorial-i18n.md index 2e4cf8f119..e2c79a757d 100644 --- a/docs/guide/tutorial-i18n.md +++ b/docs/guide/tutorial-i18n.md @@ -57,13 +57,13 @@ The format for the language/locale is `ll-CC` where `ll` is a two- or three-lett Message translation ------------------- -Message translation is used to translate messages that are ouput by an applicaiton to different languages +Message translation is used to translate messages that are output by an application to different languages so that users from different countries can use the application in their native language. The message translation feature in Yii works simply as finding a translation of the message from a source language into a target language. To use the message translation feature you wrap your original message strings with a call to the [[Yii::t()]] method. -The first parameter of this method takes a category which helps to distingish the source of messages in differnet parts +The first parameter of this method takes a category which helps to distinguish the source of messages in different parts of the application and the second parameter is the message itself. ```php @@ -501,7 +501,7 @@ Yii uses the [PHP intl extension](http://php.net/manual/en/book.intl.php) to pro such as the number and date formatting of the [[yii\i18n\Formatter]] class and the message formatting using [[yii\i18n\MessageFormatter]]. Both classes provides a fallback implementation that provides basic functionality in case intl is not installed. This fallback implementation however only works well for sites in english language and even there can not provide the -rich set of features that is avialable with the PHP intl extension, so its installation is highly recommended. +rich set of features that is available with the PHP intl extension, so its installation is highly recommended. The [PHP intl extension](http://php.net/manual/en/book.intl.php) is based on the [ICU library](http://site.icu-project.org/) which provides the knowledge and formatting rules for all the different locales. According to this fact the formatting of dates and numbers From 80849ab935fdf677dcdcc39785a4d3cdf36526fe Mon Sep 17 00:00:00 2001 From: ilgiz-badamshin Date: Wed, 12 Nov 2014 12:56:35 +0300 Subject: [PATCH 04/13] Typo fix in guide-ru --- docs/guide-ru/start-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide-ru/start-installation.md b/docs/guide-ru/start-installation.md index 4a2563da11..091c250ce1 100644 --- a/docs/guide-ru/start-installation.md +++ b/docs/guide-ru/start-installation.md @@ -59,7 +59,7 @@ Composer установит Yii (шаблонное приложение basic) 1. Скачайте архив с [yiiframework.com](http://www.yiiframework.com/download/); 2. Распакуйте скачанный архив в папку, доступную из Web. -3. В файле `config/web.php` добавьте сектетный ключ в значение `cookieValidationKey` (при установке через Composer +3. В файле `config/web.php` добавьте секретный ключ в значение `cookieValidationKey` (при установке через Composer это происходит автоматически): ```php From 42ca4bb9912b724a0c84ebaf3b9d1f9b6676534d Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Wed, 12 Nov 2014 14:06:26 +0300 Subject: [PATCH 05/13] Fixed `yii\log\DbTarget` migration and SQLs to use float column for log_time --- framework/log/migrations/m141106_185632_log_init.php | 2 +- framework/log/migrations/schema-mssql.sql | 2 +- framework/log/migrations/schema-mysql.sql | 2 +- framework/log/migrations/schema-oci.sql | 2 +- framework/log/migrations/schema-pgsql.sql | 2 +- framework/log/migrations/schema-sqlite.sql | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/framework/log/migrations/m141106_185632_log_init.php b/framework/log/migrations/m141106_185632_log_init.php index 62fbe82601..95ece81e1c 100644 --- a/framework/log/migrations/m141106_185632_log_init.php +++ b/framework/log/migrations/m141106_185632_log_init.php @@ -65,7 +65,7 @@ class m141106_185632_log_init extends Migration 'id' => Schema::TYPE_BIGPK, 'level' => Schema::TYPE_INTEGER, 'category' => Schema::TYPE_STRING, - 'log_time' => Schema::TYPE_INTEGER, + 'log_time' => Schema::TYPE_FLOAT, 'prefix' => Schema::TYPE_TEXT, 'message' => Schema::TYPE_TEXT, ], $tableOptions); diff --git a/framework/log/migrations/schema-mssql.sql b/framework/log/migrations/schema-mssql.sql index 503635f7bf..1a2456cc0b 100644 --- a/framework/log/migrations/schema-mssql.sql +++ b/framework/log/migrations/schema-mssql.sql @@ -19,7 +19,7 @@ create table [log] [id] bigint IDENTITY PRIMARY KEY, [level] integer, [category] varchar(255), - [log_time] integer, + [log_time] float, [prefix] text, [message] text ); diff --git a/framework/log/migrations/schema-mysql.sql b/framework/log/migrations/schema-mysql.sql index 8c1f2a56cd..371af44376 100644 --- a/framework/log/migrations/schema-mysql.sql +++ b/framework/log/migrations/schema-mysql.sql @@ -19,7 +19,7 @@ create table `log` `id` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, `level` integer, `category` varchar(255), - `log_time` integer, + `log_time` float, `prefix` text, `message` text, key `idx_log_level` (`level`), diff --git a/framework/log/migrations/schema-oci.sql b/framework/log/migrations/schema-oci.sql index 35bde707c8..6452881e9b 100644 --- a/framework/log/migrations/schema-oci.sql +++ b/framework/log/migrations/schema-oci.sql @@ -19,7 +19,7 @@ create table "log" "id" number(20) NOT NULL PRIMARY KEY, "level" integer, "category" varchar(255), - "log_time" integer, + "log_time" float, "prefix" text, "message" text, key "idx_log_level" ("level"), diff --git a/framework/log/migrations/schema-pgsql.sql b/framework/log/migrations/schema-pgsql.sql index 5b343b065f..c21df2f5f2 100644 --- a/framework/log/migrations/schema-pgsql.sql +++ b/framework/log/migrations/schema-pgsql.sql @@ -19,7 +19,7 @@ create table "log" "id" bigserial NOT NULL PRIMARY KEY, "level" integer, "category" varchar(255), - "log_time" integer, + "log_time" real, "prefix" text, "message" text ); diff --git a/framework/log/migrations/schema-sqlite.sql b/framework/log/migrations/schema-sqlite.sql index 1da8e64e8e..96cd832937 100644 --- a/framework/log/migrations/schema-sqlite.sql +++ b/framework/log/migrations/schema-sqlite.sql @@ -19,7 +19,7 @@ create table "log" "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "level" integer, "category" varchar(255), - "log_time" integer, + "log_time" float, "prefix" text, "message" text ); From 4fb47a23d44db7fafe060d95ca0ea02a69e07a57 Mon Sep 17 00:00:00 2001 From: Luciano Baraglia Date: Wed, 12 Nov 2014 10:22:40 -0300 Subject: [PATCH 06/13] Spanish guide minor fix [skip ci] --- docs/guide-es/rest-rate-limiting.md | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/docs/guide-es/rest-rate-limiting.md b/docs/guide-es/rest-rate-limiting.md index 803e39f778..8545eba55d 100644 --- a/docs/guide-es/rest-rate-limiting.md +++ b/docs/guide-es/rest-rate-limiting.md @@ -1,20 +1,28 @@ 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 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 a un máximo de 100 llamadas al API dentro de un periodo de 10 minutos. +Si se reciben demasiadas peticiones de un usuario dentro del periodo de tiempo declarado, deveríá devolverse una respuesta con código de estado 429 (que significa "Demasiadas peticiones"). 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 . +* `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 restante de peticiones permitidas y el tiempo actual (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. +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 utilizados 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. +Una vez que la clase de identidad implementa la interfaz requerida, Yii utilizará automáticamente [[yii\filters\RateLimiter]] +configurado como un filtro de acción para que [[yii\rest\Controller]] compruebe el límite de ratio. El limitador de ratio +lanzará una excepeción [[yii\web\TooManyRequestsHttpException]] cuando el límite del ratio sea excedido. -Puedes configurar el limitador de ratio en tu clase REST de la controladora como sigue: +Puedes configurar el limitador de ratio +en tu clase controlador REST como sigue: ```php public function behaviors() @@ -25,10 +33,12 @@ public function 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: +Cuando se activa el límite de ratio, por defecto todas las respuestas serán enviadas con la siguiente cabecera HTTP conteniendo +información sobre el límite actual 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. +Puedes desactivar estas cabeceras configurando [[yii\filters\RateLimiter::enableRateLimitHeaders]] a false, +tal y como en el anterior ejemplo. From beae91979cb8f6b96cf0cbf3bf1ba94c0f02046d Mon Sep 17 00:00:00 2001 From: Luciano Baraglia Date: Wed, 12 Nov 2014 10:58:17 -0300 Subject: [PATCH 07/13] Spanish guide updates and fixes [skip ci] --- docs/guide-es/rest-controllers.md | 70 +++++++++++++++++++---------- docs/guide-es/rest-rate-limiting.md | 18 ++++---- docs/guide/rest-controllers.md | 2 +- 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/docs/guide-es/rest-controllers.md b/docs/guide-es/rest-controllers.md index abc4e36923..b16c9f8018 100644 --- a/docs/guide-es/rest-controllers.md +++ b/docs/guide-es/rest-controllers.md @@ -1,13 +1,20 @@ Controladores ============= -Después de crear las clases de recursos y especificar cómo debe ser el formato de datos de recursos, el siguiente paso es crear acciones del controlador para exponer los recursos a los usuarios a través de las APIs RESTful finales. +Después de crear las clases de recursos y especificar cómo debe ser el formato de datos de recursos, el siguiente paso +es crear acciones del controlador para exponer los recursos a los usuarios finales a través de las APIs RESTful. -Yii ofrece dos clases de controlador base para simplificar su trabajo de crear acciones REST: [[yii\rest\Controller]] y [[yii\rest\ActiveController]]. La diferencia entre estos dos controladores es que este último proporciona un conjunto predeterminado de acciones que están específicamente diseñadas para hacer frente a los recursos representados con [Active Record](db-active-record.md). Así que si usted está utilizando [Active Record](db-active-record.md) y se siente cómodo con las acciones integradas que proporciona, es posible considerar la prolongación de sus clases de controlador de [[yii\rest\ActiveController]], que le permitirá crear potentes APIs RESTful con un mínimo de código. +Yii ofrece dos clases controlador base para simplificar tu trabajo de crear acciones REST: +[[yii\rest\Controller]] y [[yii\rest\ActiveController]]. La diferencia entre estos dos controladores +es que este último proporciona un conjunto predeterminado de acciones que están específicamente diseñado para trabajar con +los recursos representados como [Active Record](db-active-record.md). Así que si estás utilizando [Active Record](db-active-record.md) +y te sientes cómodo con las acciones integradas provistas, podrías considerar extender tus controladores +de [[yii\rest\ActiveController]], lo que te permitirá crear potentes APIs RESTful con un mínimo de código. -Ambos [[yii\rest\Controller]] y [[yii\rest\ActiveController]] proporcionan las siguientes características, algunas de las cuales se describen en detalle en las siguientes secciones: +Ambos [[yii\rest\Controller]] y [[yii\rest\ActiveController]] proporcionan las siguientes características, +algunas de las cuales se describen en detalle en las siguientes secciones: -* Métodos de Validación HTTP; +* Método de Validación HTTP; * [Negociación de contenido y formato de datos](rest-response-formatting.md); * [Autenticación](rest-authentication.md); * [Límite de Rango](rest-rate-limiting.md). @@ -15,14 +22,20 @@ Ambos [[yii\rest\Controller]] y [[yii\rest\ActiveController]] proporcionan las s [[yii\rest\ActiveController]] además provee de las siguientes características: * Un conjunto de acciones comunes necesarias: `index`, `view`, `create`, `update`, `delete`, `options`; -* La autorización del usuario en cuanto a la acción solicitada y recursos. +* La autorización del usuario de acuerdo a la acción y recurso solicitado. -## Creando Clases Controladoras +## Creando Clases de Controlador -Al crear una nueva clase de controlador, una convención para nombrar la clase del controlador es utilizar el nombre del tipo de recurso y el uso en singular. Por ejemplo, para servir información de usuario, el controlador puede ser nombrado como `UserController`. +Al crear una nueva clase de controlador, una convención para nombrar la clase del controlador es utilizar +el nombre del tipo de recurso en singular. Por ejemplo, para servir información de usuario, +el controlador puede ser nombrado como `UserController`. -Creación de una nueva acción es similar a crear una acción para una aplicación Web. La única diferencia es que en lugar de hacer que el resultado utilicé una vista llamando al método `render()`, para las acciones REST regresá directamente los datos. El [[yii\rest\Controller::serializer|serializer]] y el [[yii\web\Response|response object]] se encargará de la conversión de los datos originales al formato solicitado. Por ejemplo, +Crear una nueva acción es similar a crear una acción para una aplicación Web. La única diferencia +es que en lugar de renderizar el resultado utilizando una vista llamando al método `render()`, para las acciones REST +regresas directamente los datos. El [[yii\rest\Controller::serializer|serializer]] y el +[[yii\web\Response|response object]] se encargarán de la conversión de los datos originales +al formato solicitado. Por ejemplo, ```php public function actionView($id) @@ -34,15 +47,20 @@ public function actionView($id) ## Filtros -La mayoría de las características API REST son proporcionadas por [[yii\rest\Controller]] que son implementadas por los terminos de los [filtros](structure-filters.md). +La mayoría de las características API REST son proporcionadas por [[yii\rest\Controller]] son implementadas en los términos de [filtros](structure-filters.md). En particular, los siguientes filtros se ejecutarán en el orden en que aparecen: -* [[yii\filters\ContentNegotiator|contentNegotiator]]: apoya la negociación de contenido, que se explica en la sección el [Formateo de respuestas](rest-response-formatting.md); -* [[yii\filters\VerbFilter|verbFilter]]: apoya métodos de validación HTTP; -* [[yii\filters\AuthMethod|authenticator]]: apoya autenticación de usuarios, que se explica en la sección [Autenticación](rest-authentication.md); -* [[yii\filters\RateLimiter|rateLimiter]]: apoya la limitación de rango, que se explica en la sección [Límite de Rango](rest-rate-limiting.md). +* [[yii\filters\ContentNegotiator|contentNegotiator]]: soporta la negociación de contenido, que se explica en + la sección [Formateo de respuestas](rest-response-formatting.md); +* [[yii\filters\VerbFilter|verbFilter]]: soporta métodos de validación HTTP; +* [[yii\filters\AuthMethod|authenticator]]: soporta la autenticación de usuarios, que se explica en + la sección [Autenticación](rest-authentication.md); +* [[yii\filters\RateLimiter|rateLimiter]]: soporta la limitación de rango, que se explica en + la sección [Límite de Rango](rest-rate-limiting.md). -Estos filtros se declaran nombrándolos en el método [[yii\rest\Controller::behaviors()|behaviors()]]. Puede reemplazar este método para configurar los filtros individuales, desactivar algunos de ellos o añadir sus propios filtros. Por ejemplo, si sólo desea utilizar la autenticación básica HTTP, puede escribir el siguiente código: +Estos filtros se declaran nombrándolos en el método [[yii\rest\Controller::behaviors()|behaviors()]]. +Puede sobrescribir este método para configurar filtros individuales, desactivar algunos de ellos, o añadir los tuyos. +Por ejemplo, si sólo deseas utilizar la autenticación básica HTTP, puede escribir el siguiente código: ```php use yii\filters\auth\HttpBasicAuth; @@ -60,21 +78,24 @@ public function behaviors() ## Extendiendo `ActiveController` -Si su clase controlador extiende de [[yii\rest\ActiveController]], debe establecer su propiedad [[yii\rest\ActiveController::modelClass||modelClass]] a ser el nombre del recurso de la clase que va a servir a través de este controlador. La clase debe extender de [[yii\db\ActiveRecord]]. +Si tu clase controlador extiende de [[yii\rest\ActiveController]], debe establecer +su propiedad [[yii\rest\ActiveController::modelClass||modelClass]] con el nombre de la clase del recurso +que planeas servir a través de este controlador. La clase debe extender de [[yii\db\ActiveRecord]]. ### Personalizando Acciones Por defecto, [[yii\rest\ActiveController]] provee de las siguientes acciones: -* [[yii\rest\IndexAction|index]]: lista de recursos pagina por pagina; -* [[yii\rest\ViewAction|view]]: retorna el detalle de un recurso específico; +* [[yii\rest\IndexAction|index]]: listar recursos página por página; +* [[yii\rest\ViewAction|view]]: devolver el detalle de un recurso específico; * [[yii\rest\CreateAction|create]]: crear un nuevo recurso; * [[yii\rest\UpdateAction|update]]: actualizar un recurso existente; * [[yii\rest\DeleteAction|delete]]: eliminar un recurso específico; -* [[yii\rest\OptionsAction|options]]: retorna los métodos HTTP soportados. +* [[yii\rest\OptionsAction|options]]: devolver los métodos HTTP soportados. -Todas esta acciones se declaran a través del métodos [[yii\rest\ActiveController::actions()|actions()]]. Usted puede configurar todas estas acciones o desactivar alguna de ellas reescribiendo el método `actions()`, como se muestra a continuación, +Todas esta acciones se declaran a través de método [[yii\rest\ActiveController::actions()|actions()]]. +Puedes configurar estas acciones o desactivar alguna de ellas sobrescribiendo el método `actions()`, como se muestra a continuación, ```php public function actions() @@ -96,12 +117,14 @@ public function prepareDataProvider() } ``` -Por favor, consulte las referencias de clases para la clase de acción individuales para aprender las opciones de configuración que se dispone. +Por favor, consulta las referencias de clases de acciones individuales para aprender las opciones de configuración disponibles para cada una. ### Realizando Comprobación de Acceso -Al exponer los recursos a través de RESTful APIs, a menudo es necesario comprobar si el usuario actual tiene permiso para acceder y manipular el recurso solicitado. Con [[yii\rest\ActiveController]], puede hacerse reemplazando el método [[yii\rest\ActiveController::checkAccess()|checkAccess()]] con lo siguiente, +Al exponer los recursos a través de RESTful APIs, a menudo es necesario comprobar si el usuario actual tiene permiso +para acceder y manipular el/los recurso solicitado/s. Con [[yii\rest\ActiveController]], esto puede lograrse +sobrescribiendo el método [[yii\rest\ActiveController::checkAccess()|checkAccess()]] como a continuación, ```php /** @@ -123,6 +146,7 @@ public function checkAccess($action, $model = null, $params = []) } ``` -El método `checkAccess()` será llamado por defecto en las acciones predeterminadas de [[yii\rest\ActiveController]]. Si crea nuevas acciones y también desea llevar a cabo la comprobación de acceso, debe llamar a este método de forma explícita en las nuevas acciones. +El método `checkAccess()` será llamado por defecto en las acciones predeterminadas de [[yii\rest\ActiveController]]. Si creas +nuevas acciones y también deseas llevar a cabo la comprobación de acceso, debe llamar a este método de forma explícita en las nuevas acciones. -> Consejo: Usted puede implementar `checkAccess()` mediante el uso del [Componente Role-Based Access Control (RBAC)](security-authorization.md). +> Consejo: Puedes implementar `checkAccess()` mediante el uso del [Componente Role-Based Access Control (RBAC)](security-authorization.md). diff --git a/docs/guide-es/rest-rate-limiting.md b/docs/guide-es/rest-rate-limiting.md index 8545eba55d..23ca26b8b1 100644 --- a/docs/guide-es/rest-rate-limiting.md +++ b/docs/guide-es/rest-rate-limiting.md @@ -1,16 +1,16 @@ -Limitando el ratio (rate) +Limitando el rango (rate) ========================= -Para prevenir el abuso, puedes considerar añadir un *límitación del ratio (rate limiting)* para tus APIs. Por ejemplo, +Para prevenir el abuso, puedes considerar añadir un *límitación del rango (rate limiting)* para tus APIs. Por ejemplo, puedes querer limitar el uso del API de cada usuario a un máximo de 100 llamadas al API dentro de un periodo de 10 minutos. Si se reciben demasiadas peticiones de un usuario dentro del periodo de tiempo declarado, deveríá devolverse una respuesta con código de estado 429 (que significa "Demasiadas peticiones"). -Para activar la limitación de ratio, la clase [[yii\web\User::identityClass|user identity class]] debe implementar [[yii\filters\RateLimitInterface]]. +Para activar la limitación de rango, 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. + con el último límite del rango que ha sido comprobado. * `saveAllowance()`: guarda ambos, el número restante de peticiones permitidas y el tiempo actual (fecha/hora) UNIX . 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, @@ -18,10 +18,10 @@ entonces `loadAllowance()` y `saveAllowance()` pueden ser utilizados para leer y 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 la interfaz requerida, Yii utilizará automáticamente [[yii\filters\RateLimiter]] -configurado como un filtro de acción para que [[yii\rest\Controller]] compruebe el límite de ratio. El limitador de ratio -lanzará una excepeción [[yii\web\TooManyRequestsHttpException]] cuando el límite del ratio sea excedido. +configurado como un filtro de acción para que [[yii\rest\Controller]] compruebe el límite de rango. El limitador de rango +lanzará una excepeción [[yii\web\TooManyRequestsHttpException]] cuando el límite del rango sea excedido. -Puedes configurar el limitador de ratio +Puedes configurar el limitador de rango en tu clase controlador REST como sigue: ```php @@ -33,8 +33,8 @@ public function behaviors() } ``` -Cuando se activa el límite de ratio, por defecto todas las respuestas serán enviadas con la siguiente cabecera HTTP conteniendo -información sobre el límite actual de ratio: +Cuando se activa el límite de rango, por defecto todas las respuestas serán enviadas con la siguiente cabecera HTTP conteniendo +información sobre el límite actual de rango: * `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 diff --git a/docs/guide/rest-controllers.md b/docs/guide/rest-controllers.md index ce0289a6fe..f84751a08f 100644 --- a/docs/guide/rest-controllers.md +++ b/docs/guide/rest-controllers.md @@ -59,7 +59,7 @@ In particular, the following filters will be executed in the order they are list the [Rate Limiting](rest-rate-limiting.md) section. These named filters are declared in the [[yii\rest\Controller::behaviors()|behaviors()]] method. -You may override this method to configure individual filters, disable some of them, or add your own filters. +You may override this method to configure individual filters, disable some of them, or add your own filters. For example, if you only want to use HTTP basic authentication, you may write the following code: ```php From a8020d22536bbdc2af1818a3d312b8bea9c902f4 Mon Sep 17 00:00:00 2001 From: Luciano Baraglia Date: Wed, 12 Nov 2014 11:41:09 -0300 Subject: [PATCH 08/13] Rest response formatting spanish guide changes [skip ci] --- docs/guide-es/rest-response-formatting.md | 52 ++++++++++++++--------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/docs/guide-es/rest-response-formatting.md b/docs/guide-es/rest-response-formatting.md index d632334444..f60db3616f 100644 --- a/docs/guide-es/rest-response-formatting.md +++ b/docs/guide-es/rest-response-formatting.md @@ -1,26 +1,30 @@ -Dando Formato a la Respuesta -=================== +Formato de 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: +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]]. + 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 recurso en arrays, como está descrito en la sección [Recursos (Resources)](rest-resources.md). + Esto es realizado por la clase [[yii\rest\Serializer]]. +3. La conversión de arrays en cadenas con el formato determinado por el paso de negociación de contenido. Esto es + realizado por los [[yii\web\ResponseFormatterInterface|response formatters]] registrados con el + componente de la aplicación [[yii\web\Response::formatters|response]]. ## Negociación de contenido (Content Negotiation) -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, +Yii soporta la negociación de contenido a través del filtro [[yii\filters\ContentNegotiator]]. La clase de controlador 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: +puede obtener una respuesta en formato JSON, como a continuación: ``` $ curl -i -H "Accept: application/json; q=1.0, */*; q=0.1" "http://localhost/users" @@ -52,11 +56,15 @@ Content-Type: application/json; charset=UTF-8 ] ``` -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: +Detrás de escena, antes de que sea ejecutada una acción del controlador del API RESTful, el filtro [[yii\filters\ContentNegotiator]] +comprobará la cabecera HTTP `Accept` de la petición y definirá el [[yii\web\Response::format|response format]] +como `'json'`. Después de que la acción sea ejecutada y devuelva el objeto recurso o la 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 del controlador del API: ```php use yii\web\Response; @@ -69,15 +77,21 @@ public function 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]]. +Las claves de la propiedad `formats` son los tipos MIME soportados, mientras que los valores son los nombres de formato de respuesta correspondientes, +los cuales deben ser soportados en [[yii\web\Response::formatters]]. ## Serialización de Datos -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. +Como hemos descrito antes, [[yii\rest\Serializer]] es la pieza central responsable de convertir +objetos recurso o colecciones en arrays. Reconoce objetos tanto implementando [[yii\base\ArrayableInterface]] +como [[yii\data\DataProviderInterface]]. El primer formateador es implementado principalmente para objetos recursos, +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: +Puedes configurar el serializador definiendo la propiedad [[yii\rest\Controller::serializer]] con un array de configuración. +Por ejemplo, a veces puedes querer ayudar a simplificar el 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; From dcb68bb464286790ac917262f61a9e8a12cc9793 Mon Sep 17 00:00:00 2001 From: Luciano Baraglia Date: Wed, 12 Nov 2014 12:05:57 -0300 Subject: [PATCH 09/13] rest routing spanish guide fixes and changes [skip ci] --- docs/guide-es/rest-routing.md | 60 +++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/docs/guide-es/rest-routing.md b/docs/guide-es/rest-routing.md index a371100454..74d9dc9c9b 100644 --- a/docs/guide-es/rest-routing.md +++ b/docs/guide-es/rest-routing.md @@ -1,11 +1,13 @@ -Enrutado -======= +Enrutamiento +============ -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. +Con las clases de controlador y recurso 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: +En la práctica, querrás usualmente usar URLs limpias y obtener ventajas de los verbos HTTP. +Por ejemplo, una petición `POST /users` significaría acceder a la acción `user/create`. +Esto puede realizarse fácilmente configurando el componente de la aplicación `urlManager` +como sigue: ```php 'urlManager' => [ @@ -18,8 +20,10 @@ Esto puede realizarse fácilmente configurando el componente de la aplicación ` ] ``` -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: +En comparación con la gestión de URL en las aplicaciones Web, lo principalmente nuevo de lo anterior es el uso de +[[yii\rest\UrlRule]] para el enrutamiento de las peticiones con el API RESTful. Esta clase especial de regla URL creará +un conjunto completo de reglas URL hijas para soportar el enrutamiento y creación de URL para el/los controlador/es especificados. +Por ejemplo, el código anterior es equivalente a las siguientes reglas: ```php [ @@ -33,19 +37,20 @@ Por ejemplo, el código anterior es aproximadamente equivalente a las siguientes ] ``` -Y los siguientes puntos finales del API son mantenidos por la siguiente regla: +Y los siguientes puntos finales del API son mantenidos por esta 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; +* `GET /users`: lista de todos los usuarios página a página; +* `HEAD /users`: muestra ĺ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; +* `HEAD /users/123`: muestra 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`. +* `OPTIONS /users`: muestra los verbos soportados de acuerdo al punto final `/users`; +* `OPTIONS /users/123`: muestra los verbos soportados de acuerdo al punto final `/users/123`. -Puedes configurar las opciones `only` y `except` para explícitamente listar las acciones a soportar y cuales desabilitar, respectivamente. Por ejemplo, +Puedes configurar las opciones `only` y `except` para explícitamente listar cuáles acciones a soportar o cuáles +deshabilitar, respectivamente. Por ejemplo, ```php [ @@ -55,8 +60,8 @@ Puedes configurar las opciones `only` y `except` para explícitamente listar la ], ``` -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, +También puedes configurar las propiedades `patterns` o `extraPatterns` para redifinir patrones existentes o añadir nuevos soportados por esta regla. +Por ejemplo, para soportar una nueva acción `search` por el punto final `GET /users/search`, configura la opción `extraPatterns` como sigue, ```php [ @@ -65,8 +70,23 @@ Por ejemplo, para soportar la nueva acción `search` por `GET /users/search`, co '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]]. +Puedes haber notado que el ID del controlador `user` aparece en formato plural `users` en los puntos finales de las URLs. +Esto se debe a que [[yii\rest\UrlRule]] automáticamente pluraliza los IDs de los controladores al crear reglas URL hijas. +Puedes desactivar este comportamiento definiendo la propiedad [[yii\rest\UrlRule::pluralize]] como false. + +> Info: La pluralización de los IDs de los controladores es realizada por [[yii\helpers\Inflector::pluralize()]]. Este método respeta + reglas especiales de pluralización. Por ejemplo, la palabra `box` (caja) será pluralizada como `boxes` en vez de `boxs`. + +En caso de que la pluralización automática no encaje en tus requerimientos, puedes además configurar la propiedad +[[yii\rest\UrlRule::controller]] para especificar exlpícitamente cómo mapear un nombre utilizado en un punto final URL +a un ID de controlador. Por ejemplo, el siguiente código mapea el nombre `u` al ID del controlador `user`. + +```php +[ + 'class' => 'yii\rest\UrlRule', + 'controller' => ['u' => 'user'], +] +``` From c53a5100c23a0c5e9f225bc565b63111d11c812d Mon Sep 17 00:00:00 2001 From: Luciano Baraglia Date: Wed, 12 Nov 2014 12:41:18 -0300 Subject: [PATCH 10/13] Rest versioning spanish guide changes and fixes [skip ci] --- docs/guide-es/rest-versioning.md | 54 +++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/docs/guide-es/rest-versioning.md b/docs/guide-es/rest-versioning.md index 04aa7efbf7..9e7aa03fb7 100644 --- a/docs/guide-es/rest-versioning.md +++ b/docs/guide-es/rest-versioning.md @@ -1,29 +1,38 @@ 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. +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, compatibilidad 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. +> 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`. +Una manera común de implementar el versionado de la API es embeber el número de versión en las URLs de la API. +For example, `http://example.com/v1/users` se refiere al punto final `/users` de la versión 1 de la API. -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` : +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 +// vía de el tipo de contenido del proveedor 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: +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. +* Pon cada versión superior de la implementación de la API en un módulo separado cuyo ID es el número de la versión mayor (p.e. `v1`, `v2`). + Naturalmente, las URLs de la API contendrán números de versión mayores. +* Dentro de cada versión mayor (y por lo tanto, dentro del correspondiente módulo), usa la cabecera de HTTP `Accept` + para determinar el número de la versión menor y escribe código condicional para responder a la menor versión como corresponde. -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()`. +Para cada módulo sirviendo una versión mayor, el módulo debe incluir las clases de recursos y y controladores +que especifican la versión. Para separar mejor la responsabilidad del código, puedes conservar un conjunto común de +clases base de recursos y controladores, y hacer subclases de ellas en cada versión individual del módulo. Dentro de las subclases, +impementa el código concreto como por ejemplo `Model::fields()`. Tu código puede estar organizado como lo que sigue: @@ -53,7 +62,7 @@ api/ Post.php ``` -La configuración de su aplicación puede tener este aspecto: +La configuración de tu aplicación puede tener este aspecto: ```php return [ @@ -81,15 +90,22 @@ return [ ]; ``` -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. +Como consecuencia del código anterior, `http://example.com/v1/users` devolverá la lista de usuarios en la versión 1, mientras +`http://example.com/v2/users` 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. +Gracias a los módulos, el código de las diferentes principales versiones puede ser aislado. Pero los módulos hacen posible +reutilizar 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. +Para tratar con versiones menores, puedes tomar ventaja de la característica de negociación de contenido +provista por el comportamiento (behavior) [[yii\filters\ContentNegotiator|contentNegotiator]]. El comportamiento `contentNegotiator` +definirá la propiedad [[yii\web\Response::acceptParams]] cuando determina qué tipo +de contenido 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']`. +Por ejemplo, si una petición es enviada con la cabecera HTTP `Accept: application/json; version=v1`, +después de la negociación de contenido, [[yii\web\Response::acceptParams]] contendrá 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. +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. +Dado que por definición las versiones menores requireren mantener la compatibilidad hacia atrás, con suerte no tendrás demasiadas +comprobaciones de versión en tu código. De otra manera, probablemente puede ocurrir que necesites crear una versión mayor. From d36bf9e8a861efea761d7fa4f364be619d477c43 Mon Sep 17 00:00:00 2001 From: fly Date: Wed, 29 Oct 2014 14:03:40 +0300 Subject: [PATCH 11/13] Pass all the button's config array to Button::widget() instead of creating new one item by item. Now allowed to pass in ButtonGroup button's configs any possible attributes(like tagName, encodeLabel, etc). --- extensions/bootstrap/ButtonGroup.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/extensions/bootstrap/ButtonGroup.php b/extensions/bootstrap/ButtonGroup.php index 7066b9630f..ebbe0a56a9 100644 --- a/extensions/bootstrap/ButtonGroup.php +++ b/extensions/bootstrap/ButtonGroup.php @@ -7,7 +7,6 @@ namespace yii\bootstrap; -use yii\helpers\ArrayHelper; use yii\helpers\Html; /** @@ -81,14 +80,10 @@ class ButtonGroup extends Widget $buttons = []; foreach ($this->buttons as $button) { if (is_array($button)) { - $label = ArrayHelper::getValue($button, 'label'); - $options = ArrayHelper::getValue($button, 'options'); - $buttons[] = Button::widget([ - 'label' => $label, - 'options' => $options, - 'encodeLabel' => $this->encodeLabels, - 'view' => $this->getView() - ]); + $button['view'] = $this->getView(); + if (!isset($button['encodeLabel'])) + $button['encodeLabel'] = $this->encodeLabels; + $buttons[] = Button::widget($button); } else { $buttons[] = $button; } From b7012ca9350f22e53c0720fd3c681da0b7c86a14 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 12 Nov 2014 14:54:03 -0500 Subject: [PATCH 12/13] Fixes #5799: `yii\bootstrap\ButtonGroup::buttons` can take all options that are supported by `yii\bootstrap\Button` --- extensions/bootstrap/ButtonGroup.php | 3 ++- extensions/bootstrap/CHANGELOG.md | 1 + framework/CHANGELOG.md | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/extensions/bootstrap/ButtonGroup.php b/extensions/bootstrap/ButtonGroup.php index ebbe0a56a9..91bed411b2 100644 --- a/extensions/bootstrap/ButtonGroup.php +++ b/extensions/bootstrap/ButtonGroup.php @@ -81,8 +81,9 @@ class ButtonGroup extends Widget foreach ($this->buttons as $button) { if (is_array($button)) { $button['view'] = $this->getView(); - if (!isset($button['encodeLabel'])) + if (!isset($button['encodeLabel'])) { $button['encodeLabel'] = $this->encodeLabels; + } $buttons[] = Button::widget($button); } else { $buttons[] = $button; diff --git a/extensions/bootstrap/CHANGELOG.md b/extensions/bootstrap/CHANGELOG.md index b35eff76d0..298810e69a 100644 --- a/extensions/bootstrap/CHANGELOG.md +++ b/extensions/bootstrap/CHANGELOG.md @@ -7,6 +7,7 @@ Yii Framework 2 bootstrap extension Change Log - Bug #5570: `yii\bootstrap\Tabs` would throw an exception if `content` is not set for one of its `items` (RomeroMsk) - Enh #4181: Added `yii\bootstrap\Modal::$headerOptions` and `yii\bootstrap\Modal::$footerOptions` (tuxoff, samdark) - Enh #5735: Added `yii\bootstrap\Tabs::renderTabContent` to support manually rendering tab contents (RomeroMsk) +- Enh #5799: `yii\bootstrap\ButtonGroup::buttons` can take all options that are supported by `yii\bootstrap\Button` (aleksanderd) - Chg #5874: Upgraded Twitter Bootstrap to 3.3.x (samdark) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 9a64de2938..36a1cd3334 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -40,6 +40,7 @@ Yii Framework 2 Change Log - Enh #5688: Added optional `$formName` to `Model::loadMultiple()` to support customizing form name directly (qiangxue) - Enh #5735: Added `yii\bootstrap\Tabs::renderTabContent` to support manually rendering tab contents (RomeroMsk) - Enh #5770: Added more PHP error names for `ErrorException` (mongosoft) +- Enh #5799: `yii\bootstrap\ButtonGroup::buttons` can take all options that are supported by `yii\bootstrap\Button` (aleksanderd) - Enh #5806: Allow `Html::encode()` to be used when the application is not started (qiangxue) - Enh #5954: `yii message` command now shows user friendly error if it's not able to parse source file (samdark) - Enh #5983: Added `Inflector::sentence()` (pana1990, qiangxue) From 8d0cac8cbad845f63d29db6a5fb0db044b5e2bae Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 12 Nov 2014 15:37:09 -0500 Subject: [PATCH 13/13] Fixes #5220 --- docs/guide/structure-assets.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/docs/guide/structure-assets.md b/docs/guide/structure-assets.md index a9b36b5470..e02b9fe646 100644 --- a/docs/guide/structure-assets.md +++ b/docs/guide/structure-assets.md @@ -160,7 +160,7 @@ This will cause a CSS file in the bundle to be included using the following HTML ``` -To wrap link tag with `