Commit 2e105d2a by Qiang Xue

Merge branch 'master' of git://github.com/yiisoft/yii2

Conflicts: framework/CHANGELOG.md
parents 046b56ce cc740413
Guía Definitiva de Yii 2.0
Guía Definitiva de Yii 2.0
==========================
Este tutorial se publica con arreglo a los [Términos de Documentación Yii](http://www.yiiframework.com/doc/terms/).
......@@ -40,7 +40,7 @@ Estructura de una aplicación
* [Filtros](structure-filters.md)
* [Widgets](structure-widgets.md)
* [Módulos](structure-modules.md)
* **TBD** [Recursos](structure-assets.md)
* **TBD** [Assets](structure-assets.md)
* **TBD** [Extensiones](structure-extensions.md)
......@@ -48,9 +48,9 @@ Gestión de las peticiones
-------------------------
* [Información general](runtime-overview.md)
* **TBD** [Bootstrapping](runtime-bootstrapping.md)
* **TBD** [Rutas](runtime-routing.md)
* **TBD** [Peticiones](runtime-requests.md)
* [Bootstrapping](runtime-bootstrapping.md)
* [Routing](runtime-routing.md)
* [Requests](runtime-requests.md)
* **TBD** [Respuestas](runtime-responses.md)
* **TBD** [Sesiones y Cookies](runtime-sessions-cookies.md)
* **TBD** [Procesamiento y generación de las URL](runtime-url-handling.md)
......@@ -68,7 +68,7 @@ Conceptos clave
* [Configuraciones](concept-configurations.md)
* [Alias](concept-aliases.md)
* [Autocarga de clases](concept-autoloading.md)
* **TBD** [Localizador de servicios (Service Locator)](concept-service-locator.md)
* [Localizador de servicios (Service Locator)](concept-service-locator.md)
* **TBD** [Contenedor de inyección de dependencia](concept-di-container.md)
......
Componentes
Componentes
===========
Los componentes son los principales bloques de construcción de las aplicaciones Yii. Los componentes son instancias de
[[yii\base\Component]] o de una clase extendida. Las tres características principales que los componentes proporcionan
Los componentes son los principales bloques de construcción de las aplicaciones Yii. Los componentes son instancias de [[yii\base\Component]] o de una clase extendida. Las tres características principales que los componentes proporcionan
a las otras clases son:
* [Propiedades](concept-properties.md)
* [Eventos](concept-events.md)
* [Comportamientos](concept-behaviors.md)
Por separado y combinadas, estas características hacen que las clases Yii sean mucho mas personalizables y sean mucho
más fáciles de usar. Por ejemplo, el incluido [[yii\jui\DatePicker|widget de selección de fecha]], un componente de la
interfaz de usuario, puede ser utilizado en una [vista](structure-view.md) para generar un selector de fechas interactivo:
Por separado y combinadas, estas características hacen que las clases Yii sean mucho mas personalizables y sean mucho más fáciles de usar. Por ejemplo, el incluido [[yii\jui\DatePicker|widget de selección de fecha]], un componente de la interfaz de usuario, puede ser utilizado en una [vista](structure-view.md) para generar un DatePicker interactivo:
```php
use yii\jui\DatePicker;
......@@ -25,22 +22,16 @@ echo DatePicker::widget([
]);
```
Las propiedades del widget son facilmente modificables porque la clase se extiende de [[yii\base\Component]].
Las propiedades del widget son fácilmente modificables porque la clase se extiende de [[yii\base\Component]].
Mientras que los componentes son muy potentes, son un poco más pesados que los objetos normales, debido al hecho de que
necesitan más memoria y tiempo de CPU para poder soportar [eventos](concept-events.md) y [comportamientos](concept-behaviors.md) en particular.
Si tus componentes no necesitan estas dos características, deberías considerar extender tu componente directamente de
[[yii\base\Object]] en vez de [[yii\base\Component]]. De esta manera harás que tus componentes sean mucho más eficientes que
que objetos PHP normales, pero con el añadido soporte para [propiedades](concept-properties.md).
Mientras que los componentes son muy potentes, son un poco más pesados que los objetos normales, debido al hecho de que necesitan más memoria y tiempo de CPU para poder soportar [eventos](concept-events.md) y [comportamientos](concept-behaviors.md) en particular.
Si tus componentes no necesitan estas dos características, deberías considerar extender tu componente directamente de [[yii\base\Object]] en vez de [[yii\base\Component]]. De esta manera harás que tus componentes sean mucho más eficientes que objetos PHP normales, pero con el añadido soporte para [propiedades](concept-properties.md).
Cuando extiendes tu clase de [[yii\base\Component]] o [[yii\base\Object]], se recomienda que sigas las siguientes
convenciones:
Cuando extiendes tu clase de [[yii\base\Component]] o [[yii\base\Object]], se recomienda que sigas las siguientes convenciones:
- Si sobrescribes el constructor, especifica un parámetro `$config` como el *último* parámetro del constructor, y después
pasa este parámetro al constructor de la clase "padre".
- Si sobrescribes el constructor, especifica un parámetro `$config` como el *último* parámetro del constructor, y después pasa este parámetro al constructor de la clase "padre".
- Siempre llama al constructor del "padre" al *final* de su propio constructor.
- Si sobrescribes el método [[yii\base\Object::init()]], asegúrate de que llamas a la implementación de la clase "padre"
*al principio* de tu método `init`.
- Si sobrescribes el método [[yii\base\Object::init()]], asegúrate de que llamas a la implementación de la clase "padre" *al principio* de tu método `init`.
Por ejemplo:
......@@ -65,7 +56,7 @@ class MyClass extends Object
{
parent::init();
// ... inicialización despues de la configuración esta siendo aplicada
// ... inicialización después de la configuración esta siendo aplicada
}
}
```
......@@ -82,19 +73,14 @@ $component = \Yii::createObject([
], [1, 2]);
```
> Información: Mientras que el enfoque de llamar [[Yii::createObject()]] parece mucho más complicado, es mucho más potente
debido al hecho de que se implementa en la parte superior de un [contenedor de inyección de dependencia](concept-di-container.md).
> Información: Mientras que el enfoque de llamar [[Yii::createObject()]] parece mucho más complicado, es mucho más potente debido al hecho de que se implementa en la parte superior de un [contenedor de inyección de dependencia](concept-di-container.md).
La clase [[yii\base\Object]] hace cumplir el siguiente ciclo de vida del objeto:
1. Pre-inicialización en el constructor. Puedes establecer los valores predeterminados de propiedades aquí.
2. Configuración del objeto a través de `$config`. La configuración puede sobrescribir los valores prdeterminados dentro
del constructor.
3. Post-inicialización dentro de [[yii\base\Object::init()|init()]]. Puedes sobrescribir este método para realizar
comprobaciones de validez y normalización de las propiedades.
4. LLamadas a métodos del objeto.
2. Configuración del objeto a través de `$config`. La configuración puede sobrescribir los valores prdeterminados dentro del constructor.
3. Post-inicialización dentro de [[yii\base\Object::init()|init()]]. Puedes sobrescribir este método para realizar comprobaciones de validez y normalización de las propiedades.
4. Llamadas a métodos del objeto.
Los tres primeros pasos ocurren dentro del constructor del objeto. Esto significa que una vez obtengas la instancia de
un objeto, ésta ha sido inicializada para que puedas utilizarla adecuadamente.
Los tres primeros pasos ocurren dentro del constructor del objeto. Esto significa que una vez obtengas la instancia de un objeto, ésta ha sido inicializada para que puedas utilizarla adecuadamente.
Localizador de Servicios
========================
Un localizador de servicios es un objeto que sabe cómo proporcionar todo tipo de servicios (o componentes) que puede necesitar una aplicación. Dentro de un localizador de servicios, existe en cada componente como una única instancia, únicamente identificado por un ID. Se utiliza el ID para recuperar un componente desde el localizador de servicios.
En Yii, un localizador de servicio es simplemente una instancia de [[yii\di\ServiceLocator]], o de una clase hija.
El localizador de servicio más utilizado en Yii es el objeto *aplicación*, que se puede acceder a través de `\Yii::$app`. Los servicios que prestá son llamadas *componentes de la aplicación*, como los componentes `request`, `response`, and `urlManager`. Usted puede configurar estos componentes, o incluso cambiarlos por sus propias implementaciones fácilmente a través de la funcionalidad proporcionada por el localizador de servicios.
Además del objeto de aplicación, cada objeto módulo es también un localizador de servicios.
Para utilizar un localizador de servicios, el primer paso es registrar los componentes de la misma. Un componente se puede registrar a través de [[yii\di\ServiceLocator::set()]]. El código siguiente muestra diferentes maneras de registrarse componentes:
```php
use yii\di\ServiceLocator;
use yii\caching\FileCache;
$locator = new ServiceLocator;
// register "cache" using a class name that can be used to create a component
$locator->set('cache', 'yii\caching\ApcCache');
// register "db" using a configuration array that can be used to create a component
$locator->set('db', [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=demo',
'username' => 'root',
'password' => '',
]);
// register "search" using an anonymous function that builds a component
$locator->set('search', function () {
return new app\components\SolrService;
});
// register "pageCache" using a component
$locator->set('pageCache', new FileCache);
```
Una vez que el componente se ha registrado, usted puede acceder a él utilizando su ID, en una de las dos formas siguientes:
```php
$cache = $locator->get('cache');
// or alternatively
$cache = $locator->cache;
```
Como puede observarse, [[yii\di\ServiceLocator]] le permite acceder a un componente como una propiedad utilizando el ID de componente. Cuando acceda a un componente, por primera vez, [[yii\di\ServiceLocator]] utilizará la información de registro de componente para crear una nueva instancia del componente y devolverlo. Más tarde, si se accede de nuevo al componente, el localizador de servicio devolverá la misma instancia.
Usted puede utilizar [[yii\di\ServiceLocator::has()]] para comprobar si un ID de componente ya ha sido registrada.
Si llama [[yii\di\ServiceLocator::get()]] con una identificación válida, se produce una excepción.
Debido a que los localizadores de servicios a menudo se crean con [configuraciones](concept-configurations.md), se proporciona una propiedad que puede escribir el nombre [[yii\di\ServiceLocator::setComponents()|components]]. Esto le permite configurar y registrar varios componentes a la vez. El siguiente código muestra un arreglo de configuración que se puede utilizar para configurar una aplicación, al mismo tiempo que el registro de la "db", "cache" y "buscar" componentes:
```php
return [
// ...
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=demo',
'username' => 'root',
'password' => '',
],
'cache' => 'yii\caching\ApcCache',
'search' => function () {
return new app\components\SolrService;
},
],
];
```
......@@ -219,7 +219,7 @@
<y:Geometry height="30.0" width="150.55899810791016" x="637.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="17.96875" modelName="custom" textColor="#000000" visible="true" width="101.447265625" x="24.555866241455078" y="6.015625">interpretar vista<y:LabelModel>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="98.3359375" x="26.111530303955078" y="6.015625">renderizar vista<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
......
docs/guide-es/images/application-lifecycle.png

36.1 KB | W: 0px | H: 0px

docs/guide-es/images/application-lifecycle.png

39.2 KB | W: 0px | H: 0px

  • 2-up
  • Swipe
  • Onion skin
docs/guide-es/images/application-structure.png

15.5 KB | W: 0px | H: 0px

docs/guide-es/images/application-structure.png

15 KB | W: 0px | H: 0px

  • 2-up
  • Swipe
  • Onion skin
Bootstrapping
=============
El Bootstrapping hace referencia al proceso de preparar el entorno antes de que una aplicación se inicie para resolver y procesar una petición entrante. El se ejecuta en dos lugares: el [script de entrada](structure-entry-scripts.md) y la [aplicación](structure-applications.md).
En el [script de entrada](structure-entry-scripts.md), se registran los cargadores automáticos de clase para diferentes librerías. Esto incluye el cargador automático de Composer a través de su fichero ‘autoload.php’ y del cargador automático de Yii a través del fichero de clase ‘Yii’. El script de entrada después carga la [configuración](concept-configurations.md) de la aplicación y crea una instancia de la [aplicación](structure-applications.md).
El constructor de la aplicación, ejecuta el siguiente trabajo de bootstrapping:
Llama a [[yii\base\Application::preInit()|preInit()]], que configura algunas propiedades de alta prioridad de la aplicación, como [[yii\base\Application::basePath|basePath]].
Registra el [[yii\base\Application::errorHandler|error handler]].
Inicializa las propiedades de aplicación usando la configuración de la aplicación dada.
Llama a [[yii\base\Application::init()|init()]] que a su vez llama a [[yii\base\Application::bootstrap()|bootstrap()]] para ejecutar componentes de bootstrapping.
Incluye el archivo de manifiesto de extensiones ‘vendor/yiisoft/extensions.php’
Crea y ejecuta [compoentenes de bootstrap](structure-extensions.md#bootstrapping-classes) declarados por las extensiones.
Crea y ejecuta [componentes de aplicación](structure-application-components.md) y/o [módulos](structure-modules.md) que se declaran en la [propiedad bootstrap](structure-applications.md#bootstrap) de la aplicación.
Debido a que el trabajo de bootstrapping se tiene que ejecutar antes de gestionar *todas* las peticiones, es muy importante mantener este proceso ligero y optimizado lo máximo que sea posible.
Intenta no registrar demasiados componentes de bootstrapping. Un componente de bootstrapping sólo es necesario si tiene que interaccionar en todo el ciclo de vida de la gestión de la petición. Por ejemplo, si un modulo necesita registrar reglas de análisis de URL adicionales, se debe incluirse en la [propiedad bootstrap](structure-applications.md#bootstrap) para que la nueva regla de URL tenga efecto antes de que sea utilizada para resolver peticiones.
En modo de producción, hay que habilitar la cache bytecode, así como [APC](http://php.net/manual/es/book.apc.php), para minimizar el tiempo necesario para incluir y analizar archivos PHP.
Algunas grandes aplicaciones tienen [configuraciones](concept-configurations.md) de aplicación muy complejas que están dividida en muchos archivos de configuración más pequeños.
Información General
Información General
===============
Cada vez que una aplicación Yii gestiona una petición, se somete a una flujo de trabajo similar.
Cada vez que una aplicación Yii gestiona una petición, se somete a un flujo de trabajo similar.
1. Un usuario hace una petición al [script de entrada](structure-entry-scripts.md) ‘web/index.php’.
2. El script de entrada carga la [configuración](concept-configurations.md) y crea una instancia de la [aplicación](structure-applications.md) para gestionar la petición.
3. La aplicación resuelve la [ruta](runtime-routing.md) solicitada con la ayuda del componente [petición](runtime-requests.md) de la aplicación.
4. La aplicación crea una instancia del [controlador](structure-controllers.md) para gestionar la petición.
5. El controlador crea una instancia de la [acción](structure-controllers.md) y ejecuta los filtros para la acción.
6. Si algun filtro falla, se cancela la acción.
6. Si algún filtro falla, se cancela la acción.
7. Si pasa todos los filtros, se ejecuta la acción.
8. La acción carga un modelo de datos, posiblemente de la base de datos.
9. La acción interpreta una vista, proporcionandole el modelo de datos.
10. El resultado interpretado se devuelve al componente [respuesta](runtime-responses.md) de la aplicación.
11. El componente respuesta envía el resultado interpretado al navegador del usuario.
9. La acción renderiza una vista, proporcionándole el modelo de datos.
10. El resultado renderizado se devuelve al componente [respuesta](runtime-responses.md) de la aplicación.
11. El componente respuesta envía el resultado renderizado al navegador del usuario.
El siguiente diagrama muestra como una aplicación gestiona una petición.
![Request Lifecycle](images/application-lifecycle.png)
En esta sección, se describirá en detalle cómo funcionan algunos de estos pasos.
\ No newline at end of file
En esta sección, se describirá en detalle cómo funcionan algunos de estos pasos.
Peticiones
========
Las peticiones(requests) hechas a una aplicación son representadas como objetos [[yii\web\Request]] que proporcionan información como parámetros de la petición, cabeceras HTTP, cookies, etc. Dada una petición, se puede acceder al objeto request correspondiente a través del [componente de aplicación](structure-application-components.md) 'request' que, por defecto, es una instancia de [[yii\web\Request]]. En esta sección se describirá como hacer uso de este componente en las aplicaciones.
## Parámetros de Request <a name="request-parameters"></a>
Para obtener los parámetros de la petición, se puede llamar a los métodos [[yii\web\Request::get()|get()]] y [[yii\web\Request::post()|post()]] del componente 'request'. Estos devuelven los valores de '$_GET' y '$_POST', respectivamente. Por ejemplo:
```php
$request = Yii::$app->request;
$get = $request->get();
// equivalente a: $get = $_GET;
$id = $request->get('id');
// equivalente a: $id = isset($_GET['id']) ? $_GET['id'] : null;
$id = $request->get('id', 1);
// equivalente a: $id = isset($_GET['id']) ? $_GET['id'] : 1;
$post = $request->post();
// equivalente a: $post = $_POST;
$name = $request->post('name');
// equivalente a: $name = isset($_POST['name']) ? $_POST['name'] : null;
$name = $request->post('name', '');
// equivalente a: $name = isset($_POST['name']) ? $_POST['name'] : '';
```
>Info: En lugar de acceder directamente a '$_GET' y '$_POST' para obtener los parámetros de la petición, es recomendable que se obtengan mediante el componente 'request' como en el ejemplo anterior. Esto facilitará la creación de tests ya que se puede simular una componente de request con datos de peticiones personalizados.
Cuando se implementan [APIs RESTful](rest-quick-start.md), a menudo se necesita obtener parámetros enviados desde el formulario a través de PUT, PATCH u otros [métodos de request](runtime-requests.md#request-methods). Se pueden obtener estos parámetros llamando a los métodos [[yii\web\Request::getBodyParam()]]. Por ejemplo:
```php
$request = Yii::$app->request;
// devuelve todos los parámetros
$params = $request->bodyParams;
// devuelve el parámetro "id"
$param = $request->getBodyParam('id');
```
>Info: A diferencia de los parámetros 'GET', los parámetros enviados desde el formulario a través de 'POST', 'PUT', 'PATCH', etc. se envían en el cuerpo de la petición. El componente 'request' convierte los parámetros cuando se acceda a él a través de los métodos descritos anteriormente. Se puede personalizar la manera en como los parámetros se convierten configurando la propiedad [[yii\web\Request::parsers]].
## Métodos de Request <a name="request-methods"></a>
Se puede obtener el método HTTP usado por la petición actual a través de la expresión 'Yii::$app->request->method'. Se proporcionan un conjunto de propiedades booleanas para comprobar si el método actual es de un cierto tipo. Por ejemplo:
```php
$request = Yii::$app->request;
if ($request->isAjax) { // la request una request AJAX }
if ($request->isGet) { // el método de la request es GET }
if ($request->isPost) { // el método de la request es POST }
if ($request->isPut) { // el método de la request es PUT }
```
## URLs de Request <a name="request-urls"></a>
El componente 'request' proporciona muchas maneras de inspeccionar la URL solicitada actualmente.
Asumiendo que la URL que se está solicitando es 'http://example.com/admin/index.php/product?id=100', se pueden obtener varias partes de la URL explicadas en los siguientes puntos:
* [[yii\web\Request::url|url]]: devuelve `/admin/index.php/product?id=100`, que es la URL sin la parte de información del host.
* [[yii\web\Request::absoluteUrl|absoluteUrl]]: devuelve `http://example.com/admin/index.php/product?id=100`, que es la URL entera, incluyendo la parte de información del host.
* [[yii\web\Request::hostInfo|hostInfo]]: devuelve `http://example.com`, que es la parte de información del host dentro de la URL.
* [[yii\web\Request::pathInfo|pathInfo]]: devuelve `/product`, que es la parte posterior al script de entrada y anterior al interrogante (query string)
* [[yii\web\Request::queryString|queryString]]: devuelve `id=100`, que es la parte posterior al interrogante.
* [[yii\web\Request::baseUrl|baseUrl]]: devuelve `/admin`, que es la parte posterior a la información del host y anterior al nombre de script de entrada.
* [[yii\web\Request::scriptUrl|scriptUrl]]: devuelve `/admin/index.php`, que es la URL sin la información del la ruta ni la query string.
* [[yii\web\Request::serverName|serverName]]: devuelve `example.com`, que es el nombre del host dentro de la URL.
* [[yii\web\Request::serverPort|serverPort]]: devuelve 80, que es el puerto que usa el servidor web.
## Cabeceras HTTP <a name="http-headers"></a>
Se pueden obtener la información de las cabeceras HTTP a través de [[yii\web\HeaderCollection|header collection]] devueltas por la propiedad [[yii\web\Request::headers]]. Por ejemplo:
```php
// $headers es un objeto de yii\web\HeaderCollection
$headers = Yii::$app->request->headers;
// devuelve el valor Accept de la cabecera
$accept = $headers->get('Accept');
if ($headers->has('User-Agent')) { // la cabecera contiene un User-Agent }
```
El componente 'request' también proporciona soporte para acceder rápidamente a las cabeceras usadas más comúnmente, incluyendo:
* [[yii\web\Request::userAgent|userAgent]]: devuelve el valor de la cabecera 'User-Agen'.
* [[yii\web\Request::contentType|contentType]]: devuelve el valor de la cabecera `Content-Type` que indica el tipo MIME de los datos del cuerpo de la petición.
* [[yii\web\Request::acceptableContentTypes|acceptableContentTypes]]: devuelve los tipos de contenido MIME aceptado por los usuarios, ordenados por puntuación de calidad. Los que tienen mejor puntuación, se devolverán primero.
* [[yii\web\Request::acceptableLanguages|acceptableLanguages]]: devuelve los idiomas aceptados por el usuario. Los idiomas devueltos son ordenados según su orden de preferencia. El primer elemento representa el idioma preferido.
Si la aplicación soporta múltiples idiomas y se quiere mostrar las páginas en el idioma preferido por el usuario, se puede usar el método de negociación de idioma [[yii\web\Request::getPreferredLanguage()]]. Este método obtiene una lista de idiomas soportados por la aplicación, comparados con [[yii\web\Request::acceptableLanguages|acceptableLanguages]], y devuelve el idioma más apropiado.
>Consejo: También se puede usar el filtro [[yii\filters\ContentNegotiator|ContentNegotiator]] para determinar diatónicamente el content type y el idioma que debe usarse en la respuesta. El filtro implementa la negociación de contenido en la parte superior de las propiedades y métodos descritos anteriormente.
## Información del cliente <a name="client-information"></a>
Se puede obtener el nombre del host y la dirección IP de la máquina cliente a través de [[yii\web\Request::userHost|userHost]] y [[yii\web\Request::userIP|userIP]], respectivamente. Por ejemplo:
```php
$userHost = Yii::$app->request->userHost;
$userIP = Yii::$app->request->userIP;
```
Routing
=======
Cuando se llama al método [[yii\web\Application::run()|run()]] a través del [script de entrada](structure-entry-scripts.md), lo primero que hace es resolver la petición entrante e instanciar una [accion de controlador](structure-controllers.md) apropiada para gestionar la petición. A este proceso se le llama *routing*.
## Resolver una Ruta <a name="resolving-route"></a>
El primer paso el primer paso de routing es convertir la petición entrante una ruta que, tal y como se describe en la sección [Controladores](structure-controllers.md#routes), se usa para dirigirse a una acción de controlador. El método invoca al [gestor de URLs](runtime-url-handling.md) para hacer que la conversión de la petición actual funcione.
Por defecto, si la petición entrante contiene un parámetro 'GET' llamado 'r', su valor será considerado como la ruta. Sin embargo, si la [[yii\web\UrlManager::enablePrettyUrl|pretty URL feature]] esta habilitada, se tendrá que hacer más trabajo para determinar la ruta solicitada. Para conocer más detalles, por favor refiérase a la sección [generación y conversión de URLs](runtime-url-handling.md).
En el caso que una ruta no pueda ser determinada, el componente 'petición' lanzará una [[yii\web\NotFoundHttpException]].
### Ruta por defecto <a name="default-route"></a>
Si una petición entrante no especifica una ruta, cosa que sucede habitualmente en las paginas de inicio, se usará la ruta especificada por [[yii\web\Application::defaultRoute]]. El valor por defecto de esta propiedad es 'site/index', que hace referencia a la acción 'index' del controlador 'site'. Se puede personalizar esta propiedad en la configuración de aplicación como en el siguiente ejemplo:
```php
return [
// ...
'defaultRoute' => 'main/index',
];
```
### La ruta `catchAll` <a name="catchall-route"></a>
A veces, queremos poner una aplicación Web en modo de mantenimiento temporalmente y mostrar la misma pagina de información para todas las peticiones. Hay varias maneras de llevar esta operación a cabo. Pero una de las maneras más simples es configurando la propiedad [[yii\web\Application::catchAll]] como en la siguiente configuración de aplicación:
```php
return [
// ...
'catchAll' => ['site/offline'],
];
```
La propiedad 'catchAll' debe componerse de un array cuyo primer elemento especifique la ruta, y el resto de elementos(pares de nombre-valor) especifiquen los parámetros que van ligados a la acción.
Cuando se especifica la propiedad 'catchAll', esta reemplazará cualquier otra ruta resuelta a partir de la petición entrante. Con la anterior configuración, la misma acción 'site/offline' se usará para gestionar todas las peticiones entrantes.
## Crear una Acción <a name="creating-action"></a>
Una vez que se determina la ruta solicitada, el siguiente paso es crear el objecto de la acción correspondiente a la ruta.
La ruta se desglosa en múltiples partes mediante barras oblicuas '/'. Por ejemplo, 'site/index' será desglosado en 'site' y 'index'. Cada parte es un ID que puede hacer referencia a un modulo, un controlador o una acción.
Empezando por la primera parte de la ruta, la aplicación lleva a cabo los siguientes pasos para crear módulos(si los hay), el controlador y la acción.
1. Establece la aplicación como el modulo actual.
2. Comprueba si el [[yii\base\Module::controllerMap|controller map]] del modulo actual contiene un ID actual. Si lo tiene, se creará un objecto controlador de acuerdo con la configuración encontrada en el mapa, y ejecuta el Paso 5 con el resto de partes de la ruta.
3. Comprueba si el ID hace referencia a un modulo de la lista de la propiedad[[yii\base\Module::modules|modules]] del actual modulo. Si es así, se crea un modulo de acuerdo con la configuración encontrada en la lista del modulo, y se ejecuta el Paso 2 con la siguiente parte de la ruta dentro del contexto del modulo recién creado.
4. Trata el ID como un ID de controlador y crea un objeto controlador. Ejecuta el siguiente paso con el resto de la ruta.
5. El controlador busca el ID actual en su [[yii\base\Controller::actions()|action map]]. Si lo encuentra, crea una acción de acuerdo con la configuración encontrada en el mapa. De lo contrario, el controlador intentará crear una acción en linea que esta definida por el método de la acción correspondiente con el ID actual.
......@@ -31,8 +31,8 @@ Por defecto, los filtros declarados en una clase controlador, serán aplicados e
Además de en los controladores, se pueden declarar filtros en [modulos](structure-modules.md) o [aplicaciones](structure-applications.md).
Una vez hecho, los filtros serán aplicados a *todas* las acciones de controlador que pertenezcan a ese modulo o aplicación, a menos que las propiedades [[yii\base\ActionFilter::only|only]] y [[yii\base\ActionFilter::except|except]] sean configuradas como se ha descrito anteriormente.
>Nota: Cuando se declaran filtros en módulos o aplicaciones, deben usarse [rutas](structure-controllers.md#routes) en lugar de identificadores de acciones en las propiedades [[yii\base\ActionFilter::only|only]] y [[yii\base\ActionFilter::except|except]].
Esto es debido a que los identificadores de acciones no pueden especificar acciones dentro del ámbito de un modulo o una aplicación por si mismos.
>Nota: Cuando se declaran filtros en módulos o aplicaciones, deben usarse [rutas](structure-controllers.md#routes) en lugar de IDs de acciones en las propiedades [[yii\base\ActionFilter::only|only]] y [[yii\base\ActionFilter::except|except]].
Esto es debido a que los IDs de acciones no pueden especificar acciones dentro del ámbito de un modulo o una aplicación por si mismos.
Cuando se configuran múltiples filtros para una misma acción, se aplican de acuerdo a las siguientes reglas:
......
Modelos
Modelos
======
Los modelos forman parte de la arquitectura [MVC](http://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). Son objetos que representan datos de negocio, reglas y lógica.
......@@ -11,7 +11,7 @@ Se pueden crear clases modelo extendiendo a [[yii\base\Model]] o a sus clases hi
* [validación](#validation-rules): asegura la validez de los datos de entrada basándose en reglas declaradas;
* [Exportación de datos](#data-exporting): permite que los datos del modelo sean exportados en términos de arrays con formatos personalizables.
La clase 'modelo' también es una base base para modelos más avanzados, tales como [Registros Activos](db-active-record.md).
La clase 'modelo' también es una base para modelos más avanzados, tales como [Active Records](db-active-record.md).
>Info: No es obligatorio basar las clases modelo en [[yii\base\Model]]. Sin embargo, debido a que hay muchos componentes de Yii construidos para dar soporte a [[yii\base\Model]], por lo general es la clase base preferible para un modelo.
......@@ -156,7 +156,7 @@ class User extends ActiveRecord
}
```
> Info: En el anterior y en los siguientes ejemplos, las clases modelo extienden a [[yii\db\ActiveRecord]] porque el uso de múltiples escenarios normalmente sucede con clases de [Registros Activos](db-active-record.md).
> Info: En el anterior y en los siguientes ejemplos, las clases modelo extienden a [[yii\db\ActiveRecord]] porque el uso de múltiples escenarios normalmente sucede con clases de [Active Records](db-active-record.md).
El método 'scenarios()' devuelve un array cuyas claves son el nombre de escenario y los valores correspondientes a los *atributos activos*. Un atributo activo puede ser [asignado masivamente](#massive-assignment) y esta sujeto a [validación](#validation-rules). En el anterior ejemplo, los atributos 'username' y 'password' están activados en el escenario 'login'; mientras que en el escenario 'register', el atributo 'email' esta activado junto con 'username' y 'password'.
......@@ -370,13 +370,13 @@ En resumen, los modelos:
* pueden contener atributos para representar los datos de negocio;
* pueden contener reglas de validación para asegurar la validez e integridad de los datos;
* pueden contener métodos que para implementar la lógica de negocio;
* NO deben acceder directamente a peticiones, sesiones, o otro tipo de datos de entorno. Estos datos deben ser inyectados por los [controladores](structure-controllers.md) en los modelos.
* deben evitar embeber HTML o otro código de presentación – esto es mejor hacerlo en las [vistas](structure-views.md);
* NO deben acceder directamente a peticiones, sesiones, u otro tipo de datos de entorno. Estos datos deben ser inyectados por los [controladores](structure-controllers.md) en los modelos.
* deben evitar embeber HTML u otro código de presentación – esto es mejor hacerlo en las [vistas](structure-views.md);
* evitar tener demasiados [escenarios](#scenarios) en un mismo modelo.
Generalmente se puede considerar la última recomendación cuando se estén desarrollando grandes sistemas complejos. En estos sistemas, los modelos podrían ser muy grandes debido a que podrían ser usados en muchos lugares y por tanto contener muchos conjuntos de reglas y lógicas de negocio. A menudo esto desemboca en un código muy difícil de mantener ya que una simple modificación en el código puede afectar a muchos sitios diferentes. Para mantener el código más fácil de mantener, se puede seguir la siguiente estrategia:
* Definir un conjunto de clases modelo base que sean compartidas por diferentes [aplicaciones](structure-applications.md) o [módulos](structure-modules.md). Estas clases modelo deben contener el conjuntos mínimos de reglas y lógica que sean comunes para todos sus usos.
* Definir un conjunto de clases modelo base que sean compartidas por diferentes [aplicaciones](structure-applications.md) o [módulos](structure-modules.md). Estas clases modelo deben contener el conjunto mínimo de reglas y lógica que sean comunes para todos sus usos.
* En cada [aplicación](structure-applications.md) o [módulo](structure-modules.md) que use un modelo, definir una clase modelo concreta que extienda a la correspondiente clase modelo base. La clase modelo concreta debe contener reglas y lógica que sean específicas para esa aplicación o módulo.
Por ejemplo, en la [Plantilla de Aplicación Avanzada](tutorial-advanced-app.md), definiendo una clase modelo base 'common\models\Post'. Después en la aplicación front end, definiendo y usando una clase modelo concreta 'frontend\models\Post' que extienda a 'common\models\Post'. Y de forma similar en la aplicación back end, definiendo 'backend\models\Post'. Con esta estrategia, nos aseguramos que el código de 'frontend\models\Post' es específico para la aplicación front end, y si se efectúa algún cambio en el, no nos tenemos que preocupar de si el cambio afectará a la aplicación back end.
Widgets
=======
Los Widgets son bloques de código reutilizables utilizados en las [vistas](structure-views.md) para crear elementos de interfaz de usuario complejos y configurables de forma orientada a objetos. Por ejemplo, widget selector de fechas puede generar un selector de fechas de lujo que permita a los usuarios seleccionar una fecha. Todo lo que se tiene que hacer es insertar el siguiente código en una vista.
Los Widgets son bloques de código reutilizables utilizados en las [vistas](structure-views.md) para crear elementos de interfaz de usuario complejos y configurables de forma orientada a objetos. Por ejemplo, widget DatePicker puede generar un DatePicker de lujo que permita a los usuarios seleccionar una fecha. Todo lo que se tiene que hacer es insertar el siguiente código en una vista.
```php
<?php
......@@ -14,7 +14,7 @@ Hay un buen número de widgets incluidos en Yii, tales como [[yii\widgets\Active
## Uso de los Widgets <a name="using-widgets"></a>
Los Widgets son usados principalmente en las [vistas](structure-views.md). Se puede llamar al método [[yii\base\Widget::widget()]] para usar un widget en una vista. El método obtiene un array de [configuración](concept-configurations.md) para inicializar el widget y retorna la representación resultante del widget. Por ejemplo, el siguiente código inserta un widget selector de fechas que esta configurado para usar el idioma Ruso y mantener la entrada en atributo 'form_date' del '$model'.
Los Widgets son usados principalmente en las [vistas](structure-views.md). Se puede llamar al método [[yii\base\Widget::widget()]] para usar un widget en una vista. El método obtiene un array de [configuración](concept-configurations.md) para inicializar el widget y retorna la representación resultante del widget. Por ejemplo, el siguiente código inserta un widget DatePicker que esta configurado para usar el idioma Ruso y mantener la entrada en atributo 'form_date' del '$model'.
```php
<?php
......@@ -151,7 +151,6 @@ Los widgets son una manera orientada a objetos de reutilizar código de las vist
Cuando se crean widgets, se debería continuar manteniendo el patrón MVC. En general, se debería mantener la lógica en las clases del widget y mantener la presentación en las [vistas](structure-views.md).
Los widgets deberían ser diseñados para ser autónomos. Es decir, cuando se usa un widget, se debería poder poner en una vista sin hacer nada más. Esto puede resultar complicado si un widget requiere recursos externos, tales como CSS, JavaScript, imágenes, etc. Afortunadamente Yii proporciona soporte para [paquetes asset](structure-asset-bundles.md) que pueden ser utilizados para resolver el problema.
Los widgets deberían ser diseñados para ser autónomos. Es decir, cuando se usa un widget, se debería poder poner en una vista sin hacer nada más. Esto puede resultar complicado si un widget requiere recursos externos, tales como CSS, JavaScript, imágenes, etc. Afortunadamente Yii proporciona soporte para [paquetes de recursos](structure-asset-bundles.md) que pueden ser utilizados para resolver el problema.
Cuando un widget sólo contiene código de vista, este es muy similar a una [vista](structure-views.md). De hecho, en este caso, su única diferencia es que un widget es una clase redistribuible, mientras que una vista es sólo un script PHP llano que prefiere mantenerse dentro de su aplicación.
......@@ -31,7 +31,7 @@ Structure Application
---------------------
* [Vue d'ensemble](structure-overview.md)
* [Script d'entrée](structure-entry-scripts.md)
* [Scripts d'entrée](structure-entry-scripts.md)
* [Applications](structure-applications.md)
* [Composants application](structure-application-components.md)
* [Contrôleurs](structure-controllers.md)
......
docs/guide-fr/images/application-lifecycle.png

39.4 KB | W: 0px | H: 0px

docs/guide-fr/images/application-lifecycle.png

41.7 KB | W: 0px | H: 0px

  • 2-up
  • Swipe
  • Onion skin
......@@ -20,8 +20,8 @@
<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="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="69.712890625" x="15.1435546875" y="1.3671875">application
component<y:LabelModel>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="69.712890625" x="15.1435546875" y="1.3671875">composant
d'application<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
......@@ -38,7 +38,8 @@ component<y:LabelModel>
<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="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="70.28125" x="14.859375" y="8.43359375">entry script<y:LabelModel>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="70.28125" x="14.859375" y="8.43359375">script de
démarrage<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
......@@ -72,7 +73,7 @@ component<y:LabelModel>
<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="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="60.267578125" x="19.8662109375" y="8.433593750000007">controller<y:LabelModel>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="60.267578125" x="19.8662109375" y="8.433593750000007">contrôleur<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
......@@ -89,7 +90,7 @@ component<y:LabelModel>
<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="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="31.43359375" x="34.283203125" y="8.43359375">filter<y:LabelModel>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="31.43359375" x="34.283203125" y="8.43359375">filtre<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
......@@ -123,7 +124,7 @@ component<y:LabelModel>
<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="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="29.611328125" x="35.1943359375" y="8.43359375">view<y:LabelModel>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="29.611328125" x="35.1943359375" y="8.43359375">vue<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
......@@ -140,7 +141,7 @@ component<y:LabelModel>
<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="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="40.28125" x="29.859375" y="8.43359375">model<y:LabelModel>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="40.28125" x="29.859375" y="8.43359375">modèle<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
......
docs/guide-fr/images/application-structure.png

24.2 KB | W: 0px | H: 0px

docs/guide-fr/images/application-structure.png

25.5 KB | W: 0px | H: 0px

  • 2-up
  • Swipe
  • Onion skin
......@@ -2,7 +2,7 @@ Générer du code avec Gii
========================
Cette section décrit comment utiliser [Gii](tool-gii.md) pour générer du code qui implémente des fonctionnalités
courrantes de sites Web automatiquement. Utiliser Gii pour auto-générer du code consiste simplement à saisir les
courantes de sites Web automatiquement. Utiliser Gii pour auto-générer du code consiste simplement à saisir les
bonnes informations en suivant les instructions affichées sur les pages Web Gii.
Au long de ce tutoriel, vous apprendrez comment :
......@@ -47,7 +47,7 @@ ci-dessus. Vous pouvez maintenant accéder à Gii via l’URL suivante :
http://hostname/index.php?r=gii
```
> Note : Si vous accede à Gii depuis une machine autre que localhost, l’accès sera refuse par défaut pour des raisons
> Note : Si vous accède à Gii depuis une machine autre que localhost, l’accès sera refuse par défaut pour des raisons
> de sécurité. Vous pouvez configurer Gii pour ajouter les adresses IP autorisées comme suit,
>
```php
......@@ -81,7 +81,7 @@ Quand vous utilisez Gii, si vous aviez déjà créé le même fichier et que vou
Quand vous écrasez un fichier existant, cochez la case située à côté de "overwrite" et ensuite, cliquez sur le bouton
"Generate". Si vous créez un nouveau fichier, il suffit de cliquer sur "Generate".
Ensuite, vous verrez une page de confirmation indiquand que le code a été généré avec succès. Si vous aviez un fichier
Ensuite, vous verrez une page de confirmation indiquant que le code a été généré avec succès. Si vous aviez un fichier
existant, vous verrez également un message indiquant qu’il a été écrasé par le code nouvellement généré.
......
En savoir plus
=============
Si vous avez entièrement lu la section "Mise en Route", vous avec maintenant créé une application Yii complète. Ce
faisant, vous avez appris comment implémenter des fonctionnalités couramment utilisées, telles que recueillir des
données d'un utilisateur via un formulaire HTML, chercher des données dans une base de données, et afficher des données
de manière paginée. Vous avez également appris à utiliser [Gii](tool-gii.md) pour générer du code automatiquement.
Utiliser Gii pour générer du code rend le gros de votre processus de développement Web aussi simple que de remplir de
simples formulaires.
Cette section va résumer les ressources Yii disponibles pour vous aider à être plus productif dans l'utilisation du
framework.
* Documentation
- Le Guide définitif :
Comme son nom l'indique, le guide définit précisément comment Yii fonctionne et fournit des instructions générales
sur l'utilisation de Yii. C'est le tutoriel pour Yii le plus important, un que vous devriez lire avant d'écrire le
moindre code Yii.
- La Référence de Classes :
Elle spécifie l'usage de toutes les classes fournies par Yii. Elle doit être principalement utilisée lorsque
vous utilisez du code et souhaitez comprendre l'usage d'une classe, méthode ou propriété particulière.
L'utilisation de la référence de classe est plus appropriée quand vous avez une compréhension contextuelle du
framework entier.
- Les Articles Wiki:
Les articles wiki sont écrits par des utilisateurs de Yii en fonction de leurs propres expériences. Ils sont en
général écrits comme des recettes de cuisine, et montrent comment résoudre des problèmes pratiques en utilisant
Yii. Bien que la qualité de ces articles peut être inférieure à celle du Guide Définitif, ils sont utiles du fait
qu'ils couvrent des sujets plus vastes et peuvent fournir des solutions clef-en-main.
- Livres
* [Extensions](http://www.yiiframework.com/extensions/):
Yii est fort d'une librairie de milliers d'extensions créées par les utilisateurs, qui peuvent être facilement
ajoutées à votre application, rendant son développement encore plus facile et plus rapide.
* Communauté
- Forum : <http://www.yiiframework.com/forum/>
- Chat IRC : Les canal #yii sur le réseau freenode (<irc://irc.freenode.net/yii>)
- GitHub : <https://github.com/yiisoft/yii2>
- Facebook : <https://www.facebook.com/groups/yiitalk/>
- Twitter : <https://twitter.com/yiiframework>
- LinkedIn : <https://www.linkedin.com/groups/yii-framework-1483367>
......@@ -2,7 +2,7 @@ Fonctionnement des applications
===============================
Après avoir installé Yii, vous obtenez une application Yii fonctionnelle accessible via l'URL `http://hostname/basic/web/index.php` ou `http://hostname/index.php`, en fonction
de votre configuration. Cette section vous initiera aux fonctionalités intégrées à l'application,
de votre configuration. Cette section vous initiera aux fonctionnalités intégrées à l'application,
à la manière dont le code est organisé, et à la gestion des requêtes par l'application.
> Info: Par simplicité, au long de ce tutoriel de démarrage, nous supposerons que `basic/web` est la racine de votre
......@@ -11,22 +11,22 @@ de votre configuration. Cette section vous initiera aux fonctionalités intégrÃ
Pour vos besoins, merci d'ajuster les URLs dans notre description comme il convient.
Fonctionalité <a name="Functionality"></a>
-------------
Fonctionnalité <a name="Functionality"></a>
--------------
L'application basique installée contient quatre pages :
* La page d'accueil, affichée quand vous accédez à l'URL `http://hostname/index.php`,
* la page "About" (A Propos),
* la page "Contact", qui présente un formulaire de contact permettant aux utilisateurs finaux de vous contacter par email,
* et la page "Login" (Connexion), qui presente un formulaire de connexion qui peut être utilisé pour authentifier des utilisateurs finaux. Essayez de vous connecter
* et la page "Login" (Connexion), qui présente un formulaire de connexion qui peut être utilisé pour authentifier des utilisateurs finaux. Essayez de vous connecter
avec "admin/admin", et vous verrez l'élément "Login" du menu principal être remplacé par "Logout" (Déconnexion).
Ces pages ont en commun une entête et un pied de page. L'entête contient une barre de menu principal qui permet la navigation
entre les différentes pages.
Vous devriez également voir une barre d'outils en bas de votre fenêtre de navigation.
C'est un [outil de déboggage](tool-debugger.md) utile fourni par Yii pour enregistrer et afficher de nombreuses informations de déboggage, telles que des messages de logs, statuts de réponses, les requêtes lancées vers la base de données, et ainsi de suite.
C'est un [outil de débogage](tool-debugger.md) utile fourni par Yii pour enregistrer et afficher de nombreuses informations de débogage, telles que des messages de logs, statuts de réponses, les requêtes lancées vers la base de données, et ainsi de suite.
Structure de l'Application <a name="application-structure"></a>
......@@ -41,7 +41,7 @@ basic/ chemin de base de l'application
console.php configuration de l'application console
web.php configuration de l'application Web
commands/ contient les classes de commandes console
controllers/ contient les classes de controlleurs
controllers/ contient les classes de contrôleurs
models/ contient les classes de modèles
runtime/ contient les fichiers générés par Yii au cours de l'exécution, tels que les fichiers de logs ou de cache and cache
vendor/ contient les paquets Composer installés, y compris le framework Yii
......@@ -64,7 +64,7 @@ Le schéma suivant présente la structure statique d'une application.
Chaque application a un script de démarrage `web/index.php` qui est le seul script PHP de l'application accessible depuis le Web.
Le script de démarrage reçoit une requête et créé une instance d'[application](structure-applications.md) pour la traiter.
L'[application](structure-applications.md) résoud la requête avec l'aide de ses [composants](concept-components.md),
L'[application](structure-applications.md) résout la requête avec l'aide de ses [composants](concept-components.md),
et distribue la requête aux éléments MVC. Les [Widgets](structure-widgets.md) sont utilisés dans les [vues](structure-views.md)
pour aider à créer des éléments d'interface complexes et dynamiques.
......@@ -78,12 +78,12 @@ Le diagramme suivant présente la manière dont une application traite une requÃ
1. Un utilisateur fait une requête au [script de démarrage](structure-entry-scripts.md) `web/index.php`.
2. Le script de démarrage charge la [configuration](concept-configurations.md) de l'application et créé une instance d'[application](structure-applications.md) pour traiter la requête.
3. L'application resoud la [route](runtime-routing.md) requise avec l'aide du composant d'application [requête](runtime-requests.md).
3. L'application résout la [route](runtime-routing.md) requise avec l'aide du composant d'application [requête](runtime-requests.md).
4. L'application créé une instance de [contrôleur](structure-controllers.md) pour traiter la requête.
5. Le contrôleur créé une instance d'[action](structure-controllers.md) et effectue les filtres pour l'action.
6. Si un filtre échoue, l'action est annuléee.
6. Si un filtre échoue, l'action est annulée.
7. Si tous les filtres sont validés, l'action est exécutée.
8. L'action charge un modèle de donées, potentiellement depuis une base de données.
8. L'action charge un modèle de données, potentiellement depuis une base de données.
9. L'action génère une vue, lui fournissant le modèle de données.
10. Le résultat généré est renvoyé au composant d'application [réponse](runtime-responses.md).
11. Le composant réponse envoie le résultat généré au navigateur de l'utilisateur.
Scripts d'entrée
=============
Les scripts d'entrée sont la première chaîne dans le processus de d'amorçage de l'application. Une application (qu'elle
soit une application Web ou une application console) a un unique script de démarrage. Les utilisateurs font des
requêtes au scripts de démarrage qui instancient des instances d'application et leur transmettent les requêtes.
Les scripts d'entrée pour application Web doivent être placés dans des dossiers accessibles par le Web pour que les
utilisateurs puissent y accéder. Ils sont souvent nommés `index.php`, mais peuvent également avoir tout autre nom,
du moment que les serveurs Web peuvent les trouver.
Les scripts d'entrée pour les applications console sont généralement placés dans le [répertoire de base](structure-applications.md)
des applications et sont nommés `yii` (avec le suffixe `.php`). Ils doivent être rendus exécutables afin que les
utilisateurs puissent lancer des applications console grâce à la commande `./yii <route> [arguments] [options]`.
Les scipts de démarrage effectuent principalement les tâches suivantes :
* Définir des constantes globales;
* Enregistrer l'[autoloader Composer](http://getcomposer.org/doc/01-basic-usage.md#autoloading);
* Inclure le fichier de classe de [[Yii]];
* Charger la configuration de l'application;
* Créer et configurer une instance d'[application](structure-applications.md);
* Appeler [[yii\base\Application::run()]] pour traiter la requête entrante.
## Applications Web <a name="web-applications"></a>
Ce qui suit est le code du script de démarrage du [Modèle Basique d'Application Web](start-installation.md).
```php
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
// register Composer autoloader
require(__DIR__ . '/../vendor/autoload.php');
// include Yii class file
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
// load application configuration
$config = require(__DIR__ . '/../config/web.php');
// create, configure and run application
(new yii\web\Application($config))->run();
```
## Applications Console <a name="console-applications"></a>
De même, le code qui suit est le code du script de démarrage d'une application console :
```php
#!/usr/bin/env php
<?php
/**
* Yii console bootstrap file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
defined('YII_DEBUG') or define('YII_DEBUG', true);
// fcgi doesn't have STDIN and STDOUT defined by default
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w'));
// register Composer autoloader
require(__DIR__ . '/vendor/autoload.php');
// include Yii class file
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
// load application configuration
$config = require(__DIR__ . '/config/console.php');
$application = new yii\console\Application($config);
$exitCode = $application->run();
exit($exitCode);
```
## Définir des Constantes <a name="defining-constants"></a>
Les scripts de démarrage sont l'endroit idéal pour définir des constantes globales. Yii supporte les trois constantes suivantes :
* `YII_DEBUG` : spécifie si une application tourne en mode de débogage. Si elle est en mode de débogage, une
application loguera plus d'informations, et révélera des piles d'appels d'erreurs détaillées si des exceptions
sont lancées. C'est pour cette raison que le mode de débogage doit être utilisé principalement pendant la phase
de développement. La valeur par défaut de `YII_DEBUG` est faux.
* `YII_ENV` : spécifie sur quel environnement l'application est en train de tourner. Cela a été décrit plus en détails
dans la section [Configurations](concept-configurations.md#environment-constants). La valeur par défaut de `YII_ENV`
est `'prod'`, ce qui signifie que l'application tourne en environnement de production.
* `YII_ENABLE_ERROR_HANDLER` : spécifie si le gestionnaire d'erreurs fourni par Yii doit être activé. La valeur par
défaut de cette constantes est vrai.
Quand on définit une constant, on utilise souvent le code suivant :
```php
defined('YII_DEBUG') or define('YII_DEBUG', true);
```
qui est l'équivalent du code suivant :
```php
if (!defined('YII_DEBUG')) {
define('YII_DEBUG', true);
}
```
Clairement, le premier est plus succinct et plus aisé à comprendre.
Les définitions de constantes doit être faite au tout début d'un script de démarrage pour qu'elles puissent prendre
effet quand d'autres fichiers PHP sont inclus.
Vue d'ensemble
========
Les applications Yii sont organisées suivant le patron de conception
[model-view-controller (MVC)](http://wikipedia.org/wiki/Model-view-controller). Les [Modèles](structure-models.md)
représentent les données, la logique métier et les règles; les [vues](structure-views.md) sont les représentations
visuelles des modèles, et les [contrôleurs](structure-controllers.md) prennent une entrée et la convertissent en
commandes pour les [modèles](structure-models.md) et les [vues](structure-views.md).
En plus du MVC, les applications Yii ont les entités suivantes :
* [scripts de démarrage](structure-entry-scripts.md): ce sont des scripts PHP qui sont directement accessibles aux
utilisateurs. Ils sont responsables du démarrage d'un cycle de gestion de requête.
* [applications](structure-applications.md): ce sont des objets globalement accessibles qui gèrent les composants
d'application et les coordonnent pour satisfaire des requêtes.
* [composants d'application](structure-application-components.md): ce sont des objets enregistrés avec des applications et
qui fournissent différents services pour satisfaire des requêtes.
* [modules](structure-modules.md): ce sont des paquets auto-contenus qui contiennent du MVC complet. Une application peut
être organisée en termes de multiples modules.
* [filtres](structure-filters.md): ils représentent du code qui doit être invoqué avant et après la gestion effective
de chaque requête par des contrôleurs.
* [widgets](structure-widgets.md): ce sont des objets qui peuvent être intégrés dans des [vues](structure-views.md). Ils
peuvent contenir de la logique contrôleur et peuvent être réutilisés dans différentes vues.
Le diagramme suivant montre la structure statique d'une application :
![Static Structure of Application](images/application-structure.png)
Yii nima o`zi?
==============
Yii – bu tez ishlovchi komponentli PHP freymvork bo'lib, zamonaviy web ilovalarni tez yaratish uchun mo'ljallangan. Yii (`Yi` `[ji:]` kabi talaffuz qilinadi) so'zi xitoy tilida "oddiy va evolyutsiyalovchi" degan ma'noni anglatadi. Shuningdek Yii akronim sifatida qaralganda uning yoyilma matni **Yes It Is** tarzida qaralishi ham mumkin!
Yii ko'proq qanday masalalar uchun mos keladi?
----------------------------------------------
Yii – bu universal freymvork va uni barcha turdagi web ilovalar uchun qo'llash mumkin. Uning komponentli strukturasi va keshlashni juda zo'r qo'llab-quvvatlashi evaziga freymvork asosan portallar, forumlar, CMS, magazinlar yoki RESTful ilovalar kabi katta proyektlar uchun qo'l keladi.
Yii ni boshqa freymvorklar bilan solishtirish
---------------------------------------------
- Boshqa ko'pgina PHP freymvorklar singari Yii ham kodni tashkillashtirish uchun MVC (Model-View-Controller) modelidan foydalanadi.
- Yii faqat loyihalashtirishning ma'lum bir qolipiga ergashib dizaynni murakkablashtirmasdan sodda va elegantli kod yozish falsafasiga tayanadi.
- Yii full-stack freymvork hisoblanadi. Shuningdek o'z ichiga tekshirilgan va o'zini yaxshi ko'rsatgan relatsion va NoSQL ma'lumotlar ombori uchun yaratilgan ActiveRecord, REST API ni qo'llab quvvatlash, ko'p qatlamli keshlash kabi imkoniyatlarni oladi.
- Yii juda yaxhsi kengayishi mumkin. Siz asosiy kodni ixtiyoriy qismini almashtirishingiz yoki sozlashingiz mumkin. Kengaytirish arxitekturasiga bo'ysunib kodni boshqalar bilan ulashish yoki jamoatning kodidan foydalanish mumkin.
- Yii ning asosiy maqsadlaridan biri - ishlash tezligi.
Yii — bir odamning loyihasi emas. U unga yordam berayotgan ishlab chiquvchilar [katta jamoa][]si tomonidan qo'llab quvvatlanadi va rivojlantiriladi. Freymvork ishlab chiquvchilari web ishlab chiqish va boshqa ilovalarni maromini kuzatishadi. Ko'proq mos keluvchi imkoniyatlar va eng yaxshi sinalgan amaliyotlar freymvork sodda va elegantli interfeysi tarzida qo'llaniladi.
[katta jamoa]: http://www.yiiframework.com/about/
Yii talqinlari
--------------
Ayni vaqtda Yii ning ikkita yo'nalishi mavjud: 1.1 va 2.0. 1.1 yo'nalishi avvalgi avlod hisoblanadi va qo'llab quvvatlash holatida. 2.0 talqini - bu Composer, PSR, nomlar sohasi, treytlar(traits) va boshqa shular kabi ko'pgina oxirgi texnologiyalarni va *qaydnoma*larni qo'llovchi Yii ning to'liq boshqatdan yozilgan talqini. Mana shu talqinda navbatdagi yillarda uni yanada kuchaytirish nazarda tutilgan. Ushbu qo'llanma aynan 2.0 talqin haqida.
DT va bilimlarga talablar
-------------------------
Yii 2.0 PHP 5.4.0 va undan yuqorisini talab qiladi. Boshqa imkoniyatlar uchun talablarni bilish uchun har bir alohida yo'lga qo'yilgan freymvork bilan birga mos o'rnatilgan talablar tekshiruv skriptini ishga tushirishingiz mumkin.
Freymvork to'liq obektga mo'ljallangan dasturlashga (OMD) asoslanganligi bois Yii da ishlash uchun OMD ni umumiy tushunish talab etiladi. Shuningdek, PHP ning zamonaviy imkoniyatlari bo'lmish [nomlar soxasi](http://www.php.net/manual/ru/language.namespaces.php) va [treytlar](http://www.php.net/manual/ru/language.oop5.traits.php) ni o'rganish talab etiladi.
\ No newline at end of file
......@@ -90,14 +90,14 @@ Getting Data from Users
* [Creating Forms](input-forms.md)
* [Validating Input](input-validation.md)
* **TBD** [Uploading Files](input-file-upload.md)
* [Uploading Files](input-file-upload.md)
* **TBD** [Getting Data for Multiple Models](input-multiple-models.md)
Displaying Data
---------------
* **TBD** [Data Formatting](output-formatter.md)
* [Data Formatting](output-formatter.md)
* **TBD** [Pagination](output-pagination.md)
* **TBD** [Sorting](output-sorting.md)
* [Data Providers](output-data-providers.md)
......
......@@ -29,7 +29,8 @@ if ($data === false) {
Data caching relies on the so-called *cache components* which represent various cache storage,
such as memory, files, databases.
Cache components are usually registered as application components so that they can be globally configurable
Cache components are usually registered as [application components](structure-application-components.md) so
that they can be globally configurable
and accessible. The following code shows how to configure the `cache` application component to use
[memcached](http://memcached.org/) with two cache servers:
......
......@@ -97,7 +97,7 @@ Connecting to Database
----------------------
Active Record uses a [[yii\db\Connection|DB connection]] to exchange data with database. By default,
it uses the `db` application component as the connection. As explained in [Database basics](db-dao.md),
it uses the `db` [application component](structure-application-components.md) as the connection. As explained in [Database basics](db-dao.md),
you may configure the `db` component in the application configuration file like follows,
```php
......@@ -465,14 +465,14 @@ an `ActiveQuery` instance, while `$customer->orders` returns an array of `Order`
the query results in nothing).
Relations with Pivot Table
--------------------------
Relations with Junction Table
-----------------------------
Sometimes, two tables are related together via an intermediary table called [pivot table][]. To declare such relations,
Sometimes, two tables are related together via an intermediary table called [junction table][]. To declare such relations,
we can customize the [[yii\db\ActiveQuery]] object by calling its [[yii\db\ActiveQuery::via()|via()]] or
[[yii\db\ActiveQuery::viaTable()|viaTable()]] method.
For example, if table `order` and table `item` are related via pivot table `order_item`,
For example, if table `order` and table `item` are related via junction table `order_item`,
we can declare the `items` relation in the `Order` class like the following:
```php
......@@ -488,7 +488,7 @@ class Order extends \yii\db\ActiveRecord
The [[yii\db\ActiveQuery::via()|via()]] method is similar to [[yii\db\ActiveQuery::viaTable()|viaTable()]] except that
the first parameter of [[yii\db\ActiveQuery::via()|via()]] takes a relation name declared in the ActiveRecord class
instead of the pivot table name. For example, the above `items` relation can be equivalently declared as follows:
instead of the junction table name. For example, the above `items` relation can be equivalently declared as follows:
```php
class Order extends \yii\db\ActiveRecord
......@@ -506,7 +506,7 @@ class Order extends \yii\db\ActiveRecord
}
```
[pivot table]: http://en.wikipedia.org/wiki/Pivot_table "Pivot table on Wikipedia"
[junction table]: https://en.wikipedia.org/wiki/Junction_table "Junction table on Wikipedia"
Lazy and Eager Loading
......@@ -561,7 +561,7 @@ As you can see, only two SQL queries are needed for the same task!
> Info: In general, if you are eager loading `N` relations among which `M` relations are defined with `via()` or `viaTable()`,
> a total number of `1+M+N` SQL queries will be performed: one query to bring back the rows for the primary table, one for
> each of the `M` pivot tables corresponding to the `via()` or `viaTable()` calls, and one for each of the `N` related tables.
> each of the `M` junction tables corresponding to the `via()` or `viaTable()` calls, and one for each of the `N` related tables.
> Note: When you are customizing `select()` with eager loading, make sure you include the columns that link
> the related models. Otherwise, the related models will not be loaded. For example,
......
......@@ -76,7 +76,7 @@ $primaryConnection = \Yii::$app->db;
$secondaryConnection = \Yii::$app->secondDb;
```
If you don't want to define the connection as an application component you can instantiate it directly:
If you don't want to define the connection as an [application component](structure-application-components.md) you can instantiate it directly:
```php
$connection = new \yii\db\Connection([
......
......@@ -178,7 +178,7 @@ After applying a migration, the migration tool will keep a record in a database
table named `migration`. This allows the tool to identify which migrations
have been applied and which are not. If the `migration` table does not exist,
the tool will automatically create it in the database specified by the `db`
application component.
[application component](structure-application-components.md).
Sometimes, we may only want to apply one or a few new migrations. We can use the
following command:
......@@ -293,7 +293,7 @@ line:
migration history information. It defaults to `migration`. The table
structure is `version varchar(255) primary key, apply_time integer`.
* `db`: string, specifies the ID of the database application component.
* `db`: string, specifies the ID of the database [application component](structure-application-components.md).
Defaults to 'db'.
* `templateFile`: string, specifies the path of the file to be served as the code
......@@ -341,7 +341,7 @@ can be also configured this way.
### Migrating with Multiple Databases
By default, migrations will be applied to the database specified by the `db` application component.
By default, migrations will be applied to the database specified by the `db` [application component](structure-application-components.md).
You may change it by specifying the `--db` option, for example,
```
......
......@@ -168,7 +168,7 @@ class SettingsController extends Controller
```
In the code above we're using `indexBy` when retrieving models from database to make array indexed by model ids. These
will be later used to identify form fields. `loadMultiple` fills multiple modelds with the form data coming from POST
will be later used to identify form fields. `loadMultiple` fills multiple models with the form data coming from POST
and `validateMultiple` validates all models at once. In order to skip validation when saving we're passing `false` as
a parameter to `save`.
......
......@@ -391,7 +391,7 @@ class CountryValidator extends Validator
public function validateAttribute($model, $attribute)
{
if (!in_array($model->$attribute, ['USA', 'Web'])) {
$this->addError($attribute, 'The country must be either "USA" or "Web".');
$this->addError($model, $attribute, 'The country must be either "USA" or "Web".');
}
}
}
......
......@@ -135,13 +135,13 @@ You may specify various container HTML options passing arrays to:
- `footerOptions`
- `filterOptions`
#### Data column
#### Data column <a name="data-column"></a>
Data column is for displaying and sorting data. It is default column type so specifying class could be omitted when
using it.
The main setting of the data column is its format. It could be specified via `format` attribute. Its values are
corresponding to methods in `format` application component that is [[\yii\i18n\Formatter|Formatter]] by default:
corresponding to methods in `formatter` [application component](structure-application-components.md) that is [[\yii\i18n\Formatter|Formatter]] by default:
```php
<?= GridView::widget([
......
......@@ -16,7 +16,7 @@ The [[yii\web\ErrorHandler|error handler]] is enabled by default. You may disabl
## Using Error Handler <a name="using-error-handler"></a>
The [[yii\web\ErrorHandler|error handler]] is registered as an application component named `errorHandler`.
The [[yii\web\ErrorHandler|error handler]] is registered as an [application component](structure-application-components.md) named `errorHandler`.
You may configure it in the application configuration like the following:
```php
......
......@@ -63,7 +63,7 @@ severity levels and categories and then exports them to some medium. For example
exports the filtered log messages to a database table, while a [[yii\log\EmailTarget|email target]] exports
the log messages to specified email addresses.
You can register multiple log targets in an application by configuring them through the `log` application component
You can register multiple log targets in an application by configuring them through the `log` [application component](structure-application-components.md)
in the application configuration, like the following:
```php
......
......@@ -174,7 +174,10 @@ where 'BLOB' refers to the BLOB-type of your preferred DBMS. Below are the BLOB
- PostgreSQL: BYTEA
- MSSQL: BLOB
> Note: According to the php.ini setting of `session.hash_function`, you may need to adjust
the length of the `id` column. For example, if `session.hash_function=sha256`, you should use
length 64 instead of 40.
### Flash Data <a name="flash-data"></a>
......
......@@ -154,7 +154,7 @@ the [Wiki article](http://en.wikipedia.org/wiki/Role-based_access_control) for d
with other more traditional access control schemes.
Yii implements a General Hierarchical RBAC, following the [NIST RBAC model](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf).
It provides the RBAC functionality through the [[yii\rbac\ManagerInterface|authManager]] application component.
It provides the RBAC functionality through the [[yii\rbac\ManagerInterface|authManager]] [application component](structure-application-components.md).
Using RBAC involves two parts of work. The first part is to build up the RBAC authorization data, and the second
part is to use the authorization data to perform access check in places where it is needed.
......@@ -219,8 +219,8 @@ Building authorization data is all about the following tasks:
Depending on authorization flexibility requirements the tasks above could be done in different ways.
If your permissions hierarchy doesn't change at all and you have a fixed number of users you can create a console
command that will initialize authorization data once via APIs offered by `authManager`:
If your permissions hierarchy doesn't change at all and you have a fixed number of users you can create a
[console command](tutorial-console.md#create-command) command that will initialize authorization data once via APIs offered by `authManager`:
```php
<?php
......
......@@ -18,7 +18,7 @@ In particular, you should know how to create a database, and how to execute SQL
Preparing the Database <a name="preparing-database"></a>
--------------------
----------------------
To begin, create a database named `yii2basic`, from which you will fetch data in your application.
You may create an SQLite, MySQL, PostgreSQL, MSSQL or Oracle database, as Yii has built-in support for many database applications. For simplicity, MySQL will be assumed in the following description.
......
File mode changed from 100755 to 100644
......@@ -195,7 +195,7 @@ The rest of the array elements (key-value pairs) specify the parameters to be bo
#### [[yii\base\Application::components|components]] <a name="components"></a>
This is the single most important property. It allows you to register a list of named components
called [application components](#structure-application-components.md) that you can use in other places. For example,
called [application components](structure-application-components.md) that you can use in other places. For example,
```php
[
......
......@@ -4,7 +4,7 @@ Views
Views are part of the [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture.
They are code responsible for presenting data to end users. In a Web application, views are usually created
in terms of *view templates* which are PHP script files containing mainly HTML code and presentational PHP code.
They are managed by the [[yii\web\View|view]] application component which provides commonly used methods
They are managed by the [[yii\web\View|view]] [application component](structure-application-components.md) which provides commonly used methods
to facilitate view composition and rendering. For simplicity, we often call view templates or view template files
as views.
......
......@@ -6,7 +6,7 @@ Console applications
Yii has full featured support for console applications, whose structure is very similar to a Yii web application. A console application
consists of one or more [[yii\console\Controller]] classes, which are often referred to as "commands" in the console environment. Each controller can also have one or more actions, just like web controllers.
Usage
Usage <a name="usage"></a>
-----
You execute a console controller action using the following syntax:
......@@ -25,7 +25,7 @@ yii migrate/create --migrationTable=my_migration
In the above `yii` is the console application entry script described below.
Entry script
Entry script <a name="entry-script"></a>
------------
The console application entry script is equivalent to the `index.php` bootstrap file used for the web application. The console entry script is typically called `yii`, and located in your application's root directory. The contents of the console application entry script contains
......@@ -59,11 +59,11 @@ This script will be created as part of your application; you're free to edit it
not want to see a stack trace on error, and/or if you want to improve the overall performance. In both basic and advanced application
templates, the console application entry script has debugging enabled to provide a more developer-friendly environment.
Configuration
Configuration <a name="configuration"></a>
-------------
As can be seen in the code above, the console application uses its own configuration file, named `console.php`. In this file
you should configure various application components and properties for the console application in particular.
you should configure various [application components](structure-application-components.md) and properties for the console application in particular.
If your web application and the console application share a lot of configuration parameters and values, you may consider moving the common
parts into a separate file, and including this file in both of the application configurations (web and console). You can see an example of this in the "advanced" application template.
......@@ -81,7 +81,7 @@ yii <route> --appconfig=path/to/config.php ...
> command.
Creating your own console commands
Creating your own console commands <a name="create-command"></a>
----------------------------------
### Console Controller and Action
......
......@@ -71,7 +71,7 @@ echo \Yii::t('app', 'This is a string to translate!');
```
Yii tries to load an appropriate translation according to the current [[yii\base\Application::$language|application language]]
from one of the message sources defined in the `i18n` [application component](concept-components.md).
from one of the message sources defined in the `i18n` [application component](structure-application-components.md).
A message source is a set of files or a database that provides translation messages.
The following configuration example defines a messages source that takes the messages from PHP files:
......@@ -408,7 +408,7 @@ Instead of using `fileMap` you can simply use convention of category mapping to
Yii comes with default translation messages for validation errors and some other strings. These messages are all
in the category `yii`. Sometimes you want to correct default framework message translation for your application.
In order to do so configure the `i18n` [application component](concept-components.md) like the following:
In order to do so configure the `i18n` [application component](structure-application-components.md) like the following:
```php
'i18n' => [
......@@ -523,3 +523,8 @@ We recommend an ICU version greater or equal to version ICU 49 to be able to use
One major feature that is missing in Versions below 49 is the `#` placeholder in plural rules.
See <http://site.icu-project.org/download> for a list of available ICU versions. Note that the version numbering has changed after the
4.8 release so that the first digits are now merged: the sequence is ICU 4.8, ICU 49, ICU 50.
Additionally the information in the time zone database shipped with the ICU library may be outdated. Please refer
to the [ICU manual](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data) for details
on updating the time zone database. While for output formatting the ICU timezone database is used, the time zone database
used by PHP may be relevant too. You can update it by installing the latest version of the [pecl package `timezonedb`](http://pecl.php.net/package/timezonedb).
......@@ -78,7 +78,7 @@ return [
];
```
Note that `cache` application component should be configured.
Note that the `cache` [application component](structure-application-components.md) should be configured.
### Combining and Minimizing Assets
......
......@@ -106,7 +106,7 @@ which is not needed in this case and already handled by the existing application
Like in a Yii application, you should configure the application instance based on the environment running
the third-party system. For example, to use the [Active Record](db-active-record.md) feature, you need to configure
the `db` application component with the DB connection setting used by the third-party system.
the `db` [application component](structure-application-components.md) with the DB connection setting used by the third-party system.
Now you can use most features provided by Yii. For example, you can create Active Record classes and use them
to work with databases.
......
......@@ -57,7 +57,7 @@ Using the .less files of Bootstrap directly
If you want to include the [Bootstrap css directly in your less files](http://getbootstrap.com/getting-started/#customizing)
you may need to disable the original bootstrap css files to be loaded.
You can do this by setting the css property of the [[yii\bootstrap\BootstrapAsset|BootstrapAsset]] to be empty.
For this you need to configure the `assetManager` application component as follows:
For this you need to configure the `assetManager` [application component](structure-application-components.md) as follows:
```php
'assetManager' => [
......
Flujo de Trabajo de Traducción
==============================
Yii se traduce en muchos idiomas con el fin de ser útil para desarrolladores de aplicaciones e internacionales.
Dos áreas principales donde la contribución es muy bienvenida son la documentación y los mensajes del framework.
Mensajes del Framework
----------------------
El framework tiene dos tipos de mensajes: excepciones que están destinadas al desarrollador y nunca se traducen, y mensajes
que en realidad son visibles para el usuario final, tales como errores de validación.
El orden para comenzar con la traducción de mensajes:
1. Comprobar que en `framework/messages/config.php` su idioma aparece en `languages`. Si no, añade tu idioma allí (recuerda que debes mantener la lista en orden alfabético).
El formato de código de idioma debe seguir el [Código de Idiomas IETF](http://es.wikipedia.org/wiki/C%C3%B3digo_de_idioma_IETF), por ejemplo, `es`.
2. Ir al directorio `framework` y ejecutar el comando `yii message/extract messages/config.php`.
3. Traducir los mensajes en `framework/messages/tu-idioma/yii.php`. Asegúrate de guardar el archivo con codificación UTF-8.
4. [Crear un pull request](https://github.com/yiisoft/yii2/blob/master/docs/internals-es/git-workflow.md).
Con el fin de mantener la traducción al día puedes ejecutar `yii message/extract messages/config.php` nuevamente.
Se volverán a extraer automáticamente los mensajes de mantenimiento intactos sin los cambios.
En el archivo de traducción de cada elemento del `array` representa un mensaje (clave) y su la traducción (valor). Si el valor está vacío, el mensaje se considera como no traducido.
Los mensajes que ya no necesiten traducción tendrán sus traducciones encerrado entre un par de marcas '@@'. El texto de los mensajes se puede utilizar con el formato de formas plurales.
Chequea la [sección i18n de la guía](../guide-es/tutorial-i18n.md) para más detalles.
Documentación
-------------
Coloca las traducciones de la documentación bajo `docs/<original>-<language>` donde `<original>` es el nombre de la documentación original como `guide` o `internals`
y `<language>` es el código del idioma al que se está traduciendo. Para la traducción al español de la guía, es `docs/guide-es`.
Después de que el trabajo inicial está hecho, puedes obtener los cambios desde la última traducción del archivo usando un comando especial del directorio `build`:
```
php build translation "../docs/guide" "../docs/guide-es" "Reporte de traducción guia en Español" > report_guide_es.html
```
Si recibes un error de composer, ejecuta `composer install` en el directorio raíz.
Convenios para la traducción
----------------------------
Las palabras en inglés que son propias del framework o de PHP, o traducibles pero que están muy ligadas a conceptos extendidos o nombres de clases, se pueden dejar en idioma original.
Ejemplos: `namespace`, `assets`, `helper`, `widget`, etc.
......@@ -16,7 +16,7 @@ Os passos para iniciar a tradução de mensagens são:
Para manter as traduções sempre atualizadas, certifique-se que seu fork do Yii esteja com a última versão. Em seguida, basta executar o comando `yii message/extract messages/config.php` novamente e o mesmo irá adicionar automaticamente as novas mensagens a serem traduzidas.
No arquivo de tradução cada elemento do array representa a tradução de uma mensagem. Sendo que a "chave" representa o texto a ser traduzido e o "valor" a sua tradução. Se o "valor" estiver vazio, a mensagem é considerada como não traduzida. As mensagens que não precisam de tradução terão seus valores cercadas por um par de '@@'. Atentar para algumas mensagens que estão no formato de plural, para isso verifique a [seção i18n do guia](../guide/i18n.md) para mais detalhes.
No arquivo de tradução cada elemento do array representa a tradução de uma mensagem. Sendo que a "chave" representa o texto a ser traduzido e o "valor" a sua tradução. Se o "valor" estiver vazio, a mensagem é considerada como não traduzida. As mensagens que não precisam de tradução terão seus valores cercadas por um par de '@@'. Atentar para algumas mensagens que estão no formato de plural, para isso verifique a [seção i18n do guia](../guide-pt-BR/tutorial-i18n.md) para mais detalhes.
Documentação
......
......@@ -18,7 +18,7 @@ Yii переводится на множество языков, в том чи
В файле перевода находится массив. Его ключи — исходные строки, значения — перевод. Если значение пусто, сообщение
считается не переведённым. Переводы сообщений, которые больше не встречаются в коде, обрамлены `@@`. Для некоторых сообщений
необходимо использовать [специальный формат для поддержки употребления с числительными](../guide/i18n.md).
необходимо использовать [специальный формат для поддержки употребления с числительными](../guide-ru/tutorial-i18n.md).
Документация
------------
......
......@@ -14,7 +14,7 @@ Tarjimani yangilash uchun:
3. Habarlarni `framework/messages/uz/yii.php` ga ko`chiramiz. Muhimi fayllar UTF-8 kodlashda bo'lishi kerak.
4. `uz` dagi tarjimalar bilan [pull request qilamiz](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md), qolgan tillarga tegmaymiz.
Tarjima fayllarda massiv joylashgan. Uning kalitlari - boshlang'ich kodlar, qiymatlari - tarjima. Agar qiymat bo'sh bo'lsa habar tarjima qilinmagan hisoblanadi. Kodda boshqa uchramaydigan habarlar tarjimasi '@@' ga o'ralgan. Ayrim habarlar uchun [sonlar bilan qo'llanilishini qo'llab-quvvatlash uchun maxsus format](../guide/i18n.md) ni ishlatish zarur.
Tarjima fayllarda massiv joylashgan. Uning kalitlari - boshlang'ich kodlar, qiymatlari - tarjima. Agar qiymat bo'sh bo'lsa habar tarjima qilinmagan hisoblanadi. Kodda boshqa uchramaydigan habarlar tarjimasi '@@' ga o'ralgan. Ayrim habarlar uchun [sonlar bilan qo'llanilishini qo'llab-quvvatlash uchun maxsus format](../guide-uz/tutorial-i18n.md) ni ishlatish zarur.
Qo'llanma
---------
......
......@@ -40,6 +40,7 @@ Spanish
-------
- Luciano Baraglia, [@lucianobaraglia](https://github.com/lucianobaraglia)
- Marco Da Silva, [@markmarco16](https://github.com/markmarco16), markmarco16@gmail.com
Ukrainian
---------
......
......@@ -26,7 +26,7 @@ automatically re-extract messages keeping unchanged ones intact.
In the translation file each array element represents the translation (value) of a message (key). If the value is empty,
the message is considered as not translated. Messages that no longer need translation will have their translations
enclosed between a pair of '@@' marks. Message string can be used with plural forms format. Check [i18n section
of the guide](../guide/i18n.md) for details.
of the guide](../guide/tutorial-i18n.md) for details.
Documentation
-------------
......
......@@ -9,6 +9,7 @@ namespace yii\authclient;
use Yii;
use yii\base\Component;
use yii\base\InvalidConfigException;
use yii\base\NotSupportedException;
use yii\helpers\Inflector;
use yii\helpers\StringHelper;
......@@ -50,7 +51,23 @@ abstract class BaseClient extends Component implements ClientInterface
private $_userAttributes;
/**
* @var array map used to normalize user attributes fetched from external auth service
* in format: rawAttributeName => normalizedAttributeName
* in format: normalizedAttributeName => sourceSpecification
* 'sourceSpecification' can be:
* - string, raw attribute name
* - array, pass to raw attribute value
* - callable, PHP callback, which should accept array of raw attributes and return normalized value.
*
* For example:
*
* ```php
* 'normalizeUserAttributeMap' => [
* 'about' => 'bio',
* 'language' => ['languages', 0, 'name'],
* 'fullName' => function ($attributes) {
* return $attributes['firstName'] . ' ' . $attributes['lastName'];
* },
* ],
* ```
*/
private $_normalizeUserAttributeMap;
/**
......@@ -229,13 +246,37 @@ abstract class BaseClient extends Component implements ClientInterface
/**
* Normalize given user attributes according to [[normalizeUserAttributeMap]].
* @param array $attributes raw attributes.
* @throws InvalidConfigException on incorrect normalize attribute map.
* @return array normalized attributes.
*/
protected function normalizeUserAttributes($attributes)
{
foreach ($this->getNormalizeUserAttributeMap() as $normalizedName => $actualName) {
if (array_key_exists($actualName, $attributes)) {
$attributes[$normalizedName] = $attributes[$actualName];
if (is_scalar($actualName)) {
if (array_key_exists($actualName, $attributes)) {
$attributes[$normalizedName] = $attributes[$actualName];
}
} else {
if (is_callable($actualName)) {
$attributes[$normalizedName] = call_user_func($actualName, $attributes);
} elseif (is_array($actualName)) {
$haystack = $attributes;
$searchKeys = $actualName;
$isFound = true;
while (($key = array_shift($searchKeys)) !== null) {
if (is_array($haystack) && array_key_exists($key, $haystack)) {
$haystack = $haystack[$key];
} else {
$isFound = false;
break;
}
}
if ($isFound) {
$attributes[$normalizedName] = $haystack;
}
} else {
throw new InvalidConfigException('Invalid actual name "' . gettype($actualName) . '" specified at "' . get_class($this) . '::normalizeUserAttributeMap"');
}
}
}
......
......@@ -4,7 +4,7 @@ Yii Framework 2 authclient extension Change Log
2.0.0 under development
-----------------------
- no changes in this release.
- Enh #5135: Added ability to operate nested and complex attributes via `yii\authclient\BaseClient::normalizeUserAttributeMap` (zinzinday, klimov-paul)
2.0.0-rc September 27, 2014
......
......@@ -155,7 +155,6 @@ Following predefined auth clients are available:
- [[yii\authclient\clients\GoogleOAuth]] - [Google](https://www.google.com/) OAuth2 client
- [[yii\authclient\clients\GoogleOpenId]] - [Google](https://www.google.com/) OpenID client
- [[yii\authclient\clients\LinkedIn]] - [LinkedIn](http://www.linkedin.com/) OAuth2 client
- [[yii\authclient\clients\LinkedIn]] - [LinkedIn](http://www.linkedin.com/) OAuth2 client
- [[yii\authclient\clients\Live]] - [Microsoft Live](http://live.com/) OAuth2 client
- [[yii\authclient\clients\Twitter]] - [Twitter](https://twitter.com/) OAuth1 client
- [[yii\authclient\clients\VKontakte]] - [VKontakte](http://vk.com/) OAuth2 client
......
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* Asset bundle for the Twitter bootstrap default theme.
*
* @author Alexander Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class BootstrapThemeAsset extends AssetBundle
{
public $sourcePath = '@bower/bootstrap/dist';
public $css = [
'css/bootstrap-theme.css',
];
public $depends = [
'yii\bootstrap\BootstrapAsset',
];
}
......@@ -281,4 +281,4 @@ Then run command `php codecept.phar run --debug unit/SomeDebugTest` and you will
```
For further instructions refer to the testing section in the [Yii Definitive Guide](https://github.com/yiisoft/yii2/blob/master/docs/guide/testing.md).
For further instructions refer to the testing section in the [Yii Definitive Guide](https://github.com/yiisoft/yii2/blob/master/docs/guide/test-overview.md).
......@@ -60,7 +60,7 @@ use yii\db\ActiveRelationTrait;
* A relation is specified by [[link]] which represents the association between columns
* of different tables; and the multiplicity of the relation is indicated by [[multiple]].
*
* If a relation involves a pivot table, it may be specified by [[via()]].
* If a relation involves a junction table, it may be specified by [[via()]].
* This methods may only be called in a relational context. Same is true for [[inverseOf()]], which
* marks a relation as inverse of another relation.
*
......
......@@ -59,7 +59,7 @@ TBD
Using the ActiveRecord
----------------------
For general information on how to use yii's ActiveRecord please refer to the [guide](https://github.com/yiisoft/yii2/blob/master/docs/guide/active-record.md).
For general information on how to use yii's ActiveRecord please refer to the [guide](https://github.com/yiisoft/yii2/blob/master/docs/guide/db-active-record.md).
For defining an elasticsearch ActiveRecord class your record class needs to extend from [[yii\elasticsearch\ActiveRecord]] and
implement at least the [[yii\elasticsearch\ActiveRecord::attributes()|attributes()]] method to define the attributes of the record.
......
......@@ -388,12 +388,12 @@ class Generator extends \yii\gii\Generator
}
/**
* Checks if the given table is a pivot table.
* Checks if the given table is a junction table.
* For simplicity, this method only deals with the case where the pivot contains two PK columns,
* each referencing a column in a different table.
* @param \yii\db\TableSchema the table being checked
* @return array|boolean the relevant foreign key constraint information if the table is a pivot table,
* or false if the table is not a pivot table.
* @return array|boolean the relevant foreign key constraint information if the table is a junction table,
* or false if the table is not a junction table.
*/
protected function checkPivotTable($table)
{
......
......@@ -50,7 +50,7 @@ use yii\db\ActiveRelationTrait;
* A relation is specified by [[link]] which represents the association between columns
* of different tables; and the multiplicity of the relation is indicated by [[multiple]].
*
* If a relation involves a pivot table, it may be specified by [[via()]].
* If a relation involves a junction table, it may be specified by [[via()]].
* This methods may only be called in a relational context. Same is true for [[inverseOf()]], which
* marks a relation as inverse of another relation.
*
......@@ -102,7 +102,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
// lazy loading
if ($this->via instanceof self) {
// via pivot collection
$viaModels = $this->via->findPivotRows([$this->primaryModel]);
$viaModels = $this->via->findJunctionRows([$this->primaryModel]);
$this->filterByModels($viaModels);
} elseif (is_array($this->via)) {
// via relation
......
......@@ -4,7 +4,7 @@ Yii Framework 2 mongodb extension Change Log
2.0.0 under development
-----------------------
- no changes in this release.
- Bug #5303: Fixed `yii\mongodb\Collection` unable to fetch default database name from DSN with parameters (klimov-paul)
2.0.0-rc September 27, 2014
......
......@@ -148,7 +148,7 @@ class Connection extends Component
if ($this->defaultDatabaseName === null) {
if (isset($this->options['db'])) {
$this->defaultDatabaseName = $this->options['db'];
} elseif (preg_match('/^mongodb:\\/\\/.+\\/(.+)$/s', $this->dsn, $matches)) {
} elseif (preg_match('/^mongodb:\\/\\/.+\\/([^?&]+)/s', $this->dsn, $matches)) {
$this->defaultDatabaseName = $matches[1];
} else {
throw new InvalidConfigException("Unable to determine default database name from dsn.");
......
......@@ -64,7 +64,7 @@ use yii\db\QueryTrait;
* A relation is specified by [[link]] which represents the association between columns
* of different tables; and the multiplicity of the relation is indicated by [[multiple]].
*
* If a relation involves a pivot table, it may be specified by [[via()]].
* If a relation involves a junction table, it may be specified by [[via()]].
* This methods may only be called in a relational context. Same is true for [[inverseOf()]], which
* marks a relation as inverse of another relation.
*
......@@ -312,8 +312,8 @@ class ActiveQuery extends Component implements ActiveQueryInterface
if ($this->primaryModel !== null) {
// lazy loading
if ($this->via instanceof self) {
// via pivot table
$viaModels = $this->via->findPivotRows([$this->primaryModel]);
// via junction table
$viaModels = $this->via->findJunctionRows([$this->primaryModel]);
$this->filterByModels($viaModels);
} elseif (is_array($this->via)) {
// via relation
......
......@@ -73,7 +73,7 @@ use yii\db\ActiveRelationTrait;
* A relation is specified by [[link]] which represents the association between columns
* of different tables; and the multiplicity of the relation is indicated by [[multiple]].
*
* If a relation involves a pivot table, it may be specified by [[via()]].
* If a relation involves a junction table, it may be specified by [[via()]].
* This methods may only be called in a relational context. Same is true for [[inverseOf()]], which
* marks a relation as inverse of another relation.
*
......@@ -225,7 +225,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
// lazy loading a relational query
if ($this->via instanceof self) {
// via pivot index
$viaModels = $this->via->findPivotRows([$this->primaryModel]);
$viaModels = $this->via->findJunctionRows([$this->primaryModel]);
$this->filterByModels($viaModels);
} elseif (is_array($this->via)) {
// via relation
......
......@@ -4,7 +4,7 @@ Yii Framework 2 sphinx extension Change Log
2.0.0 under development
-----------------------
- no changes in this release.
- Enh #5211: `yii\sphinx\Query` now supports 'HAVING' (klimov-paul)
2.0.0-rc September 27, 2014
......
......@@ -8,6 +8,7 @@
namespace yii\sphinx;
use yii\base\InvalidParamException;
use yii\base\NotSupportedException;
use yii\base\Object;
use yii\db\Exception;
use yii\db\Expression;
......@@ -38,6 +39,24 @@ class QueryBuilder extends Object
*/
public $separator = " ";
/**
* @var array map of query condition to builder methods.
* These methods are used by [[buildCondition]] to build SQL conditions from array syntax.
*/
protected $conditionBuilders = [
'AND' => 'buildAndCondition',
'OR' => 'buildAndCondition',
'BETWEEN' => 'buildBetweenCondition',
'NOT BETWEEN' => 'buildBetweenCondition',
'IN' => 'buildInCondition',
'NOT IN' => 'buildInCondition',
'LIKE' => 'buildLikeCondition',
'NOT LIKE' => 'buildLikeCondition',
'OR LIKE' => 'buildLikeCondition',
'OR NOT LIKE' => 'buildLikeCondition',
'NOT' => 'buildNotCondition',
];
/**
* Constructor.
......@@ -55,12 +74,19 @@ class QueryBuilder extends Object
* @param Query $query the [[Query]] object from which the SQL statement will be generated
* @param array $params the parameters to be bound to the generated SQL statement. These parameters will
* be included in the result with the additional parameters generated during the query building process.
* @throws NotSupportedException if query contains 'join' option.
* @return array the generated SQL statement (the first array element) and the corresponding
* parameters to be bound to the SQL statement (the second array element). The parameters returned
* include those provided in `$params`.
*/
public function build($query, $params = [])
{
$query = $query->prepare($this);
if (!empty($query->join)) {
throw new NotSupportedException('Build of "' . get_class($query) . '::join" is not supported.');
}
$params = empty($params) ? $query->params : array_merge($params, $query->params);
$from = $query->from;
......@@ -76,6 +102,7 @@ class QueryBuilder extends Object
$this->buildWhere($query->from, $query->where, $params, $query->match),
$this->buildGroupBy($query->groupBy),
$this->buildWithin($query->within),
$this->buildHaving($query->from, $query->having, $params),
$this->buildOrderBy($query->orderBy),
$this->buildLimit($query->limit, $query->offset),
$this->buildOption($query->options, $params),
......@@ -501,15 +528,7 @@ class QueryBuilder extends Object
if (empty($condition)) {
return '';
}
$indexSchemas = [];
if (!empty($indexes)) {
foreach ($indexes as $indexName) {
$index = $this->db->getIndexSchema($indexName);
if ($index !== null) {
$indexSchemas[] = $index;
}
}
}
$indexSchemas = $this->getIndexSchemas($indexes);
$where = $this->buildCondition($indexSchemas, $condition, $params);
return $where === '' ? '' : 'WHERE ' . $where;
......@@ -525,6 +544,24 @@ class QueryBuilder extends Object
}
/**
* @param string[] $indexes list of index names, which affected by query
* @param string|array $condition
* @param array $params the binding parameters to be populated
* @return string the HAVING clause built from [[Query::$having]].
*/
public function buildHaving($indexes, $condition, &$params)
{
if (empty($condition)) {
return '';
}
$indexSchemas = $this->getIndexSchemas($indexes);
$having = $this->buildCondition($indexSchemas, $condition, $params);
return $having === '' ? '' : 'HAVING ' . $having;
}
/**
* Builds the ORDER BY and LIMIT/OFFSET clauses and appends them to the given SQL.
* @param string $sql the existing SQL (without ORDER BY/LIMIT/OFFSET)
* @param array $orderBy the order by columns. See [[Query::orderBy]] for more details on how to specify this parameter.
......@@ -623,19 +660,6 @@ class QueryBuilder extends Object
*/
public function buildCondition($indexes, $condition, &$params)
{
static $builders = [
'AND' => 'buildAndCondition',
'OR' => 'buildAndCondition',
'BETWEEN' => 'buildBetweenCondition',
'NOT BETWEEN' => 'buildBetweenCondition',
'IN' => 'buildInCondition',
'NOT IN' => 'buildInCondition',
'LIKE' => 'buildLikeCondition',
'NOT LIKE' => 'buildLikeCondition',
'OR LIKE' => 'buildLikeCondition',
'OR NOT LIKE' => 'buildLikeCondition',
];
if (!is_array($condition)) {
return (string) $condition;
} elseif (empty($condition)) {
......@@ -643,15 +667,14 @@ class QueryBuilder extends Object
}
if (isset($condition[0])) { // operator format: operator, operand 1, operand 2, ...
$operator = strtoupper($condition[0]);
if (isset($builders[$operator])) {
$method = $builders[$operator];
if (isset($this->conditionBuilders[$operator])) {
$method = $this->conditionBuilders[$operator];
} else {
$method = 'buildSimpleCondition';
}
array_shift($condition);
return $this->$method($indexes, $operator, $condition, $params);
} else { // hash format: 'column1' => 'value1', 'column2' => 'value2', ...
return $this->buildHashCondition($indexes, $condition, $params);
}
}
......@@ -714,6 +737,32 @@ class QueryBuilder extends Object
}
/**
* Inverts an SQL expressions with `NOT` operator.
* @param IndexSchema[] $indexes list of indexes, which affected by query
* @param string $operator the operator to use for connecting the given operands
* @param array $operands the SQL expressions to connect.
* @param array $params the binding parameters to be populated
* @return string the generated SQL expression
* @throws InvalidParamException if wrong number of operands have been given.
*/
public function buildNotCondition($indexes, $operator, $operands, &$params)
{
if (count($operands) != 1) {
throw new InvalidParamException("Operator '$operator' requires exactly one operand.");
}
$operand = reset($operands);
if (is_array($operand)) {
$operand = $this->buildCondition($indexes, $operand, $params);
}
if ($operand === '') {
return '';
}
return "$operator ($operand)";
}
/**
* Creates an SQL expressions with the `BETWEEN` operator.
* @param IndexSchema[] $indexes list of indexes, which affected by query
* @param string $operator the operator to use (e.g. `BETWEEN` or `NOT BETWEEN`)
......@@ -1042,4 +1091,22 @@ class QueryBuilder extends Object
return "$column $operator $phName";
}
}
/**
* @param array $indexes index names.
* @return IndexSchema[] index schemas.
*/
private function getIndexSchemas($indexes)
{
$indexSchemas = [];
if (!empty($indexes)) {
foreach ($indexes as $indexName) {
$index = $this->db->getIndexSchema($indexName);
if ($index !== null) {
$indexSchemas[] = $index;
}
}
}
return $indexSchemas;
}
}
......@@ -9,7 +9,9 @@ Yii Framework 2 Change Log
- Bug #5314: Fixed typo in the implementation of `yii\web\Session::getHasSessionId()` (qiangxue)
- Bug #5323: Nested dropdown does not work for `yii\bootstrap\DropDown` (aryraditya)
- Bug #5336: `yii\bootstrap\DropDown` should register bootstrap plugin asset (zelenin)
- Bug #5379: `Module::afterAction()` was called even when `beforeAction()` returned false (cebe)
- Bug #5423: `yii\behaviors\Cors` causes "undefined index" error when its `cors` is configured (qiangxue)
- Bug #5424: `Html::addCssStyle()` wasn't correctly setting style passed in array (kartik-v, samdark)
- Bug: Date and time formatting now assumes UTC as the timezone for input dates unless a timezone is explicitly given (cebe)
- Enh #4040: Added `$viewFile` and `$params` to the `EVENT_BEFORE_RENDER` and `EVENT_AFTER_RENDER` events for `View` (qiangxue)
- Enh #4275: Added `removeChildren()` to `yii\rbac\ManagerInterface` and implementations (samdark)
......
......@@ -134,6 +134,7 @@ class Controller extends Component implements ViewContextInterface
$modules = [];
$runAction = true;
// call beforeAction on modules
foreach ($this->getModules() as $module) {
if ($module->beforeAction($action)) {
array_unshift($modules, $module);
......@@ -145,16 +146,17 @@ class Controller extends Component implements ViewContextInterface
$result = null;
if ($runAction) {
if ($this->beforeAction($action)) {
$result = $action->runWithParams($params);
$result = $this->afterAction($action, $result);
}
}
if ($runAction && $this->beforeAction($action)) {
// run the action
$result = $action->runWithParams($params);
foreach ($modules as $module) {
/* @var $module Module */
$result = $module->afterAction($action, $result);
$result = $this->afterAction($action, $result);
// call afterAction on modules
foreach ($modules as $module) {
/* @var $module Module */
$result = $module->afterAction($action, $result);
}
}
$this->action = $oldAction;
......
......@@ -58,7 +58,7 @@ namespace yii\db;
* A relation is specified by [[link]] which represents the association between columns
* of different tables; and the multiplicity of the relation is indicated by [[multiple]].
*
* If a relation involves a pivot table, it may be specified by [[via()]] or [[viaTable()]] method.
* If a relation involves a junction table, it may be specified by [[via()]] or [[viaTable()]] method.
* These methods may only be called in a relational context. Same is true for [[inverseOf()]], which
* marks a relation as inverse of another relation and [[onCondition()]] which adds a condition that
* is to be added to relational query join condition.
......@@ -175,8 +175,8 @@ class ActiveQuery extends Query implements ActiveQueryInterface
$where = $this->where;
if ($this->via instanceof self) {
// via pivot table
$viaModels = $this->via->findPivotRows([$this->primaryModel]);
// via junction table
$viaModels = $this->via->findJunctionRows([$this->primaryModel]);
$this->filterByModels($viaModels);
} elseif (is_array($this->via)) {
// via relation
......@@ -655,9 +655,9 @@ class ActiveQuery extends Query implements ActiveQueryInterface
}
/**
* Specifies the pivot table for a relational query.
* Specifies the junction table for a relational query.
*
* Use this method to specify a pivot table when declaring a relation in the [[ActiveRecord]] class:
* Use this method to specify a junction table when declaring a relation in the [[ActiveRecord]] class:
*
* ```php
* public function getItems()
......@@ -667,11 +667,11 @@ class ActiveQuery extends Query implements ActiveQueryInterface
* }
* ```
*
* @param string $tableName the name of the pivot table.
* @param array $link the link between the pivot table and the table associated with [[primaryModel]].
* The keys of the array represent the columns in the pivot table, and the values represent the columns
* @param string $tableName the name of the junction table.
* @param array $link the link between the junction table and the table associated with [[primaryModel]].
* The keys of the array represent the columns in the junction table, and the values represent the columns
* in the [[primaryModel]] table.
* @param callable $callable a PHP callback for customizing the relation associated with the pivot table.
* @param callable $callable a PHP callback for customizing the relation associated with the junction table.
* Its signature should be `function($query)`, where `$query` is the query to be customized.
* @return static
* @see via()
......
......@@ -80,9 +80,9 @@ interface ActiveQueryInterface extends QueryInterface
public function with();
/**
* Specifies the relation associated with the pivot table for use in relational query.
* Specifies the relation associated with the junction table for use in relational query.
* @param string $relationName the relation name. This refers to a relation declared in the [[ActiveRelationTrait::primaryModel|primaryModel]] of the relation.
* @param callable $callable a PHP callback for customizing the relation associated with the pivot table.
* @param callable $callable a PHP callback for customizing the relation associated with the junction table.
* Its signature should be `function($query)`, where `$query` is the query to be customized.
* @return static the relation object itself.
*/
......
......@@ -365,15 +365,15 @@ interface ActiveRecordInterface
* to be the corresponding primary key value(s) in the other record.
* The record with the foreign key will be saved into database without performing validation.
*
* If the relationship involves a pivot table, a new row will be inserted into the
* pivot table which contains the primary key values from both records.
* If the relationship involves a junction table, a new row will be inserted into the
* junction table which contains the primary key values from both records.
*
* This method requires that the primary key value is not null.
*
* @param string $name the case sensitive name of the relationship.
* @param static $model the record to be linked with the current one.
* @param array $extraColumns additional column values to be saved into the pivot table.
* This parameter is only meaningful for a relationship involving a pivot table
* @param array $extraColumns additional column values to be saved into the junction table.
* This parameter is only meaningful for a relationship involving a junction table
* (i.e., a relation set with `[[ActiveQueryInterface::via()]]`.)
*/
public function link($name, $model, $extraColumns = []);
......
......@@ -44,7 +44,7 @@ trait ActiveRelationTrait
*/
public $link;
/**
* @var array|object the query associated with the pivot table. Please call [[via()]]
* @var array|object the query associated with the junction table. Please call [[via()]]
* to set this property instead of directly setting it.
* This property is only used in relational context.
* @see via()
......@@ -78,7 +78,7 @@ trait ActiveRelationTrait
}
/**
* Specifies the relation associated with the pivot table.
* Specifies the relation associated with the junction table.
*
* Use this method to specify a pivot record/table when declaring a relation in the [[ActiveRecord]] class:
*
......@@ -96,7 +96,7 @@ trait ActiveRelationTrait
* ```
*
* @param string $relationName the relation name. This refers to a relation declared in [[primaryModel]].
* @param callable $callable a PHP callback for customizing the relation associated with the pivot table.
* @param callable $callable a PHP callback for customizing the relation associated with the junction table.
* Its signature should be `function($query)`, where `$query` is the query to be customized.
* @return static the relation object itself.
*/
......@@ -195,10 +195,10 @@ trait ActiveRelationTrait
}
if ($this->via instanceof self) {
// via pivot table
// via junction table
/* @var $viaQuery ActiveRelationTrait */
$viaQuery = $this->via;
$viaModels = $viaQuery->findPivotRows($primaryModels);
$viaModels = $viaQuery->findJunctionRows($primaryModels);
$this->filterByModels($viaModels);
} elseif (is_array($this->via)) {
// via relation
......@@ -490,7 +490,7 @@ trait ActiveRelationTrait
* @param array $primaryModels either array of AR instances or arrays
* @return array
*/
private function findPivotRows($primaryModels)
private function findJunctionRows($primaryModels)
{
if (empty($primaryModels)) {
return [];
......
......@@ -1138,15 +1138,15 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* to be the corresponding primary key value(s) in the other model.
* The model with the foreign key will be saved into database without performing validation.
*
* If the relationship involves a pivot table, a new row will be inserted into the
* pivot table which contains the primary key values from both models.
* If the relationship involves a junction table, a new row will be inserted into the
* junction table which contains the primary key values from both models.
*
* Note that this method requires that the primary key value is not null.
*
* @param string $name the case sensitive name of the relationship
* @param ActiveRecordInterface $model the model to be linked with the current one.
* @param array $extraColumns additional column values to be saved into the pivot table.
* This parameter is only meaningful for a relationship involving a pivot table
* @param array $extraColumns additional column values to be saved into the junction table.
* This parameter is only meaningful for a relationship involving a junction table
* (i.e., a relation set with [[ActiveRelationTrait::via()]] or `[[ActiveQuery::viaTable()]]`.)
* @throws InvalidCallException if the method is unable to link two models.
*/
......
......@@ -15,11 +15,11 @@ use yii\base\NotSupportedException;
use yii\caching\Cache;
/**
* Connection represents a connection to a database via [PDO](http://www.php.net/manual/en/ref.pdo.php).
* Connection represents a connection to a database via [PDO](php.net/manual/en/book.pdo.php).
*
* Connection works together with [[Command]], [[DataReader]] and [[Transaction]]
* to provide data access to various DBMS in a common set of APIs. They are a thin wrapper
* of the [[PDO PHP extension]](http://www.php.net/manual/en/ref.pdo.php).
* of the [[PDO PHP extension]](php.net/manual/en/book.pdo.php).
*
* Connection supports database replication and read-write splitting. In particular, a Connection component
* can be configured with multiple [[masters]] and [[slaves]]. It will do load balancing and failover by choosing
......
......@@ -120,7 +120,7 @@ class Cors extends ActionFilter
}
/**
* Extract CORS headers fron the request
* Extract CORS headers from the request
* @return array CORS headers to handle
*/
public function extractHeaders()
......@@ -176,7 +176,7 @@ class Cors extends ActionFilter
* Handle classic CORS request to avoid duplicate code
* @param string $type the kind of headers we would handle
* @param array $requestHeaders CORS headers request by client
* @param array $responseHeaders CORS response headers sent to the clinet
* @param array $responseHeaders CORS response headers sent to the client
*/
protected function prepareAllowHeaders($type, $requestHeaders, &$responseHeaders)
{
......@@ -204,7 +204,7 @@ class Cors extends ActionFilter
/**
* Adds the CORS headers to the response
* @param Response $response
* @param array CORS headers which have been compouted
* @param array CORS headers which have been computed
*/
public function addCorsHeaders($response, $headers)
{
......
......@@ -1703,9 +1703,9 @@ class BaseHtml
}
}
}
$style = static::cssStyleFromArray(array_merge($oldStyle, $newStyle));
$style = array_merge($oldStyle, $newStyle);
}
$options['style'] = $style;
$options['style'] = is_array($style) ? static::cssStyleFromArray($style) : $style;
}
/**
......
......@@ -258,6 +258,7 @@ class Formatter extends Component
/**
* Formats the value as is without any formatting.
* This method simply returns back the parameter without any format.
* The only exception is a `null` value which will be formatted using [[nullDisplay]].
* @param mixed $value the value to be formatted.
* @return string the formatted result.
*/
......@@ -342,14 +343,15 @@ class Formatter extends Component
/**
* Formats the value as an image tag.
* @param mixed $value the value to be formatted.
* @param string $altText an optional `alt`-tag to be added to the image.
* @return string the formatted result.
*/
public function asImage($value)
public function asImage($value, $altText = '')
{
if ($value === null) {
return $this->nullDisplay;
}
return Html::img($value);
return Html::img($value, ['alt' => $altText]);
}
/**
......
......@@ -38,6 +38,7 @@ return [
'.hgignore',
'.hgkeep',
'/messages',
'/BaseYii.php', // contains examples about Yii:t()
],
// array, list of patterns that specify which files (not directories) should be processed.
// If empty or not set, all files will be processed.
......
......@@ -17,7 +17,7 @@
<span class="text"><?php if ($file !== null) echo 'in ' . $handler->htmlEncode($file); ?></span>
<?php if ($method !== null): ?>
<span class="call">
<?php if ($file !== null) echo '&ndash;' ?>
<?php if ($file !== null) echo '&ndash;'; ?>
<?= ($class !== null ? $handler->addTypeLinks("$class::$method") : $handler->htmlEncode($method)) . '(' . $handler->argumentsToString($args) . ')' ?>
</span>
<?php endif; ?>
......
......@@ -65,6 +65,10 @@ class DbSession extends Session
*
* When using DbSession in a production server, we recommend you create a DB index for the 'expire'
* column in the session table to improve the performance.
*
* Note that according to the php.ini setting of `session.hash_function`, you may need to adjust
* the length of the `id` column. For example, if `session.hash_function=sha256`, you should use
* length 64 instead of 40.
*/
public $sessionTable = '{{%session}}';
......
......@@ -55,25 +55,99 @@ class BaseClientTest extends TestCase
}
/**
* Data provider for [[testNormalizeUserAttributes()]]
* @return array test data
*/
public function dataProviderNormalizeUserAttributes()
{
return [
[
[
'name' => 'raw/name',
'email' => 'raw/email',
],
[
'raw/name' => 'name value',
'raw/email' => 'email value',
],
[
'name' => 'name value',
'email' => 'email value',
],
],
[
[
'name' => function ($attributes) {
return $attributes['firstName'] . ' ' . $attributes['lastName'];
},
],
[
'firstName' => 'John',
'lastName' => 'Smith',
],
[
'name' => 'John Smith',
],
],
[
[
'email' => ['emails', 'prime'],
],
[
'emails' => [
'prime' => 'some@email.com'
],
],
[
'email' => 'some@email.com',
],
],
[
[
'email' => ['emails', 0],
'secondaryEmail' => ['emails', 1],
],
[
'emails' => [
'some@email.com',
],
],
[
'email' => 'some@email.com',
],
],
[
[
'name' => 'file_get_contents',
],
[
'file_get_contents' => 'value',
],
[
'name' => 'value',
],
],
];
}
/**
* @dataProvider dataProviderNormalizeUserAttributes
*
* @depends testSetGet
*
* @param array $normalizeUserAttributeMap
* @param array $rawUserAttributes
* @param array $expectedNormalizedUserAttributes
*/
public function testNormalizeUserAttributes()
public function testNormalizeUserAttributes($normalizeUserAttributeMap, $rawUserAttributes, $expectedNormalizedUserAttributes)
{
$client = new Client();
$normalizeUserAttributeMap = [
'raw/name' => 'name',
'raw/email' => 'email',
];
$client->setNormalizeUserAttributeMap($normalizeUserAttributeMap);
$rawUserAttributes = [
'raw/name' => 'name value',
'raw/email' => 'email value',
];
$client->setUserAttributes($rawUserAttributes);
$normalizedUserAttributes = $client->getUserAttributes();
$expectedNormalizedUserAttributes = array_combine(array_keys($normalizeUserAttributeMap), array_values($rawUserAttributes));
$this->assertEquals($expectedNormalizedUserAttributes, $normalizedUserAttributes);
$this->assertEquals(array_merge($rawUserAttributes, $expectedNormalizedUserAttributes), $normalizedUserAttributes);
}
}
......
......@@ -61,7 +61,45 @@ class ConnectionTest extends MongoDbTestCase
}
/**
* Data provider for [[testFetchDefaultDatabaseName()]]
* @return array test data
*/
public function dataProviderFetchDefaultDatabaseName()
{
return [
[
'mongodb://travis:test@localhost:27017/dbname',
'dbname',
],
[
'mongodb://travis:test@localhost:27017/dbname?replicaSet=test&connectTimeoutMS=300000',
'dbname',
],
];
}
/**
* @dataProvider dataProviderFetchDefaultDatabaseName
*
* @param string $dsn
* @param string $databaseName
*/
public function testFetchDefaultDatabaseName($dsn, $databaseName)
{
$connection = new Connection();
$connection->dsn = $dsn;
$reflection = new \ReflectionObject($connection);
$method = $reflection->getMethod('fetchDefaultDatabaseName');
$method->setAccessible(true);
$method->invoke($connection);
$this->assertEquals($databaseName, $connection->defaultDatabaseName);
}
/**
* @depends testGetDatabase
* @depends testFetchDefaultDatabaseName
*/
public function testGetDefaultDatabase()
{
......
......@@ -132,6 +132,22 @@ class QueryTest extends SphinxTestCase
$this->assertEquals(['team', 'company', 'age'], $query->groupBy);
}
public function testHaving()
{
$query = new Query;
$query->having('id = :id', [':id' => 1]);
$this->assertEquals('id = :id', $query->having);
$this->assertEquals([':id' => 1], $query->params);
$query->andHaving('name = :name', [':name' => 'something']);
$this->assertEquals(['and', 'id = :id', 'name = :name'], $query->having);
$this->assertEquals([':id' => 1, ':name' => 'something'], $query->params);
$query->orHaving('age = :age', [':age' => '30']);
$this->assertEquals(['or', ['and', 'id = :id', 'name = :name'], 'age = :age'], $query->having);
$this->assertEquals([':id' => 1, ':name' => 'something', ':age' => '30'], $query->params);
}
public function testOrder()
{
$query = new Query;
......
<?php
namespace yii\web;
/**
* Mock for the time() function for web classes
* @return int
*/
function time()
{
return \yiiunit\framework\web\UserTest::$time ?: \time();
}
namespace yiiunit\framework\web;
use yii\base\NotSupportedException;
use yii\base\Component;
use yii\rbac\PhpManager;
use yii\web\IdentityInterface;
use yii\web\UrlManager;
use yii\web\UrlRule;
use yii\web\Request;
use Yii;
use yiiunit\TestCase;
/**
* @group web
*/
class UserTest extends TestCase
{
/**
* @var integer virtual time to be returned by mocked time() function.
* Null means normal time() behavior.
*/
public static $time;
protected function tearDown()
{
Yii::$app->session->removeAll();
static::$time = null;
parent::tearDown();
}
public function testLoginExpires()
{
if (getenv('TRAVIS') == 'true') {
$this->markTestSkipped('Can not reliably test this on travis-ci.');
}
$appConfig = [
'components' => [
'user' => [
'identityClass' => UserIdentity::className(),
'authTimeout' => 10,
],
'authManager' => [
'class' => PhpManager::className(),
'itemFile' => '@runtime/user_test_rbac_items.php',
'assignmentFile' => '@runtime/user_test_rbac_assignments.php',
'ruleFile' => '@runtime/user_test_rbac_rules.php',
]
],
];
$this->mockWebApplication($appConfig);
$am = Yii::$app->authManager;
$am->removeAll();
$am->add($role = $am->createPermission('rUser'));
$am->add($perm = $am->createPermission('doSomething'));
$am->addChild($role, $perm);
$am->assign($role, 'user1');
Yii::$app->session->removeAll();
static::$time = \time();
Yii::$app->user->login(UserIdentity::findIdentity('user1'));
// print_r(Yii::$app->session);
// print_r($_SESSION);
$this->mockWebApplication($appConfig);
$this->assertFalse(Yii::$app->user->isGuest);
$this->assertTrue(Yii::$app->user->can('doSomething'));
static::$time += 5;
$this->mockWebApplication($appConfig);
$this->assertFalse(Yii::$app->user->isGuest);
$this->assertTrue(Yii::$app->user->can('doSomething'));
static::$time += 11;
$this->mockWebApplication($appConfig);
$this->assertTrue(Yii::$app->user->isGuest);
$this->assertFalse(Yii::$app->user->can('doSomething'));
}
}
class UserIdentity extends Component implements IdentityInterface
{
private static $ids = [
'user1',
'user2',
'user3',
];
private $_id;
public static function findIdentity($id)
{
if (in_array($id, static::$ids)) {
$identitiy = new static();
$identitiy->_id = $id;
return $identitiy;
}
}
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException();
}
public function getId()
{
return $this->_id;
}
public function getAuthKey()
{
throw new NotSupportedException();
}
public function validateAuthKey($authKey)
{
throw new NotSupportedException();
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment