From af191953d0db8c3e809556b6a0aa6302f9742bde Mon Sep 17 00:00:00 2001 From: Marco Da Silva Date: Sun, 5 Oct 2014 20:12:52 -0430 Subject: [PATCH 01/43] Translation and fix reference - Fix names and references guides internals. - Add internals Spanish translation. - Drafting corrections Spanish guides. --- docs/guide-es/concept-configurations.md | 37 ++++---- docs/internals-es/translation-workflow.md | 59 ++++++++++++ docs/internals-pt-BR/translation-workflow.md | 60 ++++++++++++ docs/internals-pt-BR/translations.md | 60 ------------ docs/internals-ru/translation-workflow.md | 2 +- docs/internals-uz/translation-workflow.md | 136 +++++++++++++++++++++++++++ docs/internals-uz/translations.md | 136 --------------------------- docs/internals/translation-teams.md | 1 + docs/internals/translation-workflow.md | 2 +- 9 files changed, 275 insertions(+), 218 deletions(-) create mode 100644 docs/internals-es/translation-workflow.md create mode 100644 docs/internals-pt-BR/translation-workflow.md delete mode 100644 docs/internals-pt-BR/translations.md create mode 100644 docs/internals-uz/translation-workflow.md delete mode 100644 docs/internals-uz/translations.md diff --git a/docs/guide-es/concept-configurations.md b/docs/guide-es/concept-configurations.md index 88bedd5..f058603 100644 --- a/docs/guide-es/concept-configurations.md +++ b/docs/guide-es/concept-configurations.md @@ -1,9 +1,9 @@ Configuración ============== -Las configuraciones se utilizan ampliamente en Yii al crear nuevos objetos o inicializar los objetos existentes. Las configuraciones por lo general incluyen el nombre de la clase del objeto que se está creando, y una lista de los valores iniciales que debería ser asignada al del objeto [propiedades](concept-properties.md). Las configuraciones también pueden incluir una lista de manipuladores que deban imponerse a del objeto [eventos](concept-events.md) y/o una lista de [comportamiento](concept-behaviors.md) que también ha de atribuirse al objeto. +Las configuraciones se utilizan ampliamente en Yii al crear nuevos objetos o inicializar los objetos existentes. Las configuraciones por lo general incluyen el nombre de la clase del objeto que se está creando, y una lista de los valores iniciales que deberían ser asignadas a las del [propiedades](concept-properties.md) objeto. Las configuraciones también pueden incluir una lista de manipuladores que deban imponerse a del objeto [eventos](concept-events.md) y/o una lista de [comportamientos](concept-behaviors.md) que también ha de atribuirse al objeto. -A continuación, una configuración que se utiliza para crear e inicializar una conexión de base de datos: +A continuación, una configuración que se utiliza para crear e inicializar una conexión a base de datos: ```php $config = [ @@ -16,9 +16,7 @@ $config = [ $db = Yii::createObject($config); ``` - -El [[Yii::createObject()]] método toma una matriz de configuración como su argumento, y crea un objeto creando instanciando la clase llamada en la configuración. Cuando se crea una instancia del objeto, el resto de la configuración se utilizará para inicializar las propiedades del objeto, controladores de eventos y comportamientos. - +El método [[Yii::createObject()]] toma una matriz de configuración como su argumento, y crea un objeto intanciando la clase llamada en la configuración. Cuando se crea una instancia del objeto, el resto de la configuración se utilizará para inicializar las propiedades del objeto, controladores de eventos y comportamientos. Si usted ya tiene un objeto, puede usar [[Yii::configure()]] para inicializar las propiedades del objeto con una matriz de configuración: @@ -26,7 +24,7 @@ Si usted ya tiene un objeto, puede usar [[Yii::configure()]] para inicializar la Yii::configure($object, $config); ``` -Tenga en cuenta que, en este caso, la matriz de configuración no debe contener un elemento `class`. +Tenga en cuenta que en este caso, la matriz de configuración no debe contener un elemento `class`. ## Formato de Configuración @@ -44,9 +42,9 @@ El formato de una configuración se puede describir formalmente como: donde * El elemento `class` especifica un nombre de clase completo para el objeto que se está creando. -* Los elementos `propertyName` especifica los valores iniciales de la propiedad con nombre. Las claves son los nombres de las propiedades y los valores son los valores iniciales correspondientes. Sólo las variables miembro públicas y [propiedades](concept-properties.md) definido por getters/setters se pueden configurar. -* Los elementos `on eventName` especifican qué manejadores deberán adjuntarse al del objeto [eventos](concept-events.md). Observe que las claves de matriz se forman prefijando nombres de eventos con `on`. Por favor, consulte el [Eventos] sección(concept-events.md) para los formatos de controlador de eventos compatibles. -* Los elementos `as behaviorName` especifican qué [comportamiento](concept-behaviors.md) deben adjuntarse al objeto. Observe que las claves de matriz se forman prefijando nombres de comportamiento con `as`; el valor, `$ behaviorConfig`, representa la configuración para la creación de un comportamiento, como una configuración normal se describe aquí. +* Los elementos `propertyName` especifica los valores iniciales de la propiedad con nombre. Las claves son los nombres de las propiedades y los valores son los valores iniciales correspondientes. Sólo los miebros de variables públicas y [propiedades](concept-properties.md) definidas por getters/setters se pueden configurar. +* Los elementos `on eventName` especifican qué manipuladores deberán adjuntarse al del objeto [eventos](concept-events.md). Observe que las claves de matriz se forman prefijando nombres de eventos con `on`. Por favor, consulte la sección [Eventos](concept-events.md) para los formatos de controlador de eventos compatibles. +* Los elementos `as behaviorName` especifican qué [comportamientos](concept-behaviors.md) deben adjuntarse al objeto. Observe que las claves de matriz se forman prefijando nombres de comportamiento con `as`; el valor, `$behaviorConfig`, representa la configuración para la creación de un comportamiento, como una configuración normal descrita aquí. A continuación se muestra un ejemplo de una configuración con los valores de propiedad iniciales, controladores de eventos y comportamientos: @@ -72,7 +70,7 @@ Las configuraciones se utilizan en muchos lugares en Yii. Al comienzo de esta se ### Configuraciones de aplicación -Configuración para una [aplicación](structure-applications.md) es probablemente una de las configuraciones más complejas. Esto se debe a la clase [[yii\web\Application|application]] tiene un montón de propiedades y eventos configurables. Más importante aún, su propiedad [[yii\web\Application::components|components]] que puede recibir una gran variedad de configuraciones para crear componentes que se registran a través de la aplicación. El siguiente es un resumen de la aplicación archivo de configuración de la [plantilla básica de la aplicación](start-basic.md). +Configuración para una [aplicación](structure-applications.md) es probablemente una de las configuraciones más complejas. Esto se debe a que la clase [[yii\web\Application|application]] tiene un montón de propiedades y eventos configurables. Más importante aún, su propiedad [[yii\web\Application::components|components]] que puede recibir una gran variedad de configuraciones para crear componentes que se registran a través de la aplicación. Lo siguiente es un resumen del archivo de configuración de la aplicación para la [plantilla básica de la aplicación](start-basic.md). ```php $config = [ @@ -112,12 +110,12 @@ La configuración no tiene una clave `class`. Esto es porque se utiliza como sig (new yii\web\Application($config))->run(); ``` -Para más detalles sobre la configuración de la propiedad `components` de una aplicación se puede encontrar en la [Aplicación](structure-applications.md) sección y la sección [Localizador de Servicio](concept-service-locator.md). +Para más detalles sobre la configuración de la propiedad `components` de una aplicación se puede encontrar en la sección [Aplicación](structure-applications.md) y la sección [Localizador de Servicio](concept-service-locator.md). ### Configuración Widget -Cuando se utiliza [widgets](structure-widgets.md), a menudo es necesario utilizar las configuraciones para personalizar las propiedades de widgets. Tanto los metodos [[yii\base\Widget::widget()]] y [[yii\base\Widget::begin()]] puede usarse para crear un widget. Toman un arreglo de configuración, como la siguiente, +Cuando se utiliza [widgets](structure-widgets.md), a menudo es necesario utilizar las configuraciones para personalizar las propiedades de widgets. Tanto los metodos [[yii\base\Widget::widget()]] y [[yii\base\Widget::begin()]] pueden usarse para crear un widget. Toman un arreglo de configuración, como el siguiente, ```php use yii\widgets\Menu; @@ -131,15 +129,15 @@ echo Menu::widget([ ], ]); ``` -El código anterior crea un widget `Menu` e inicializa su propiedad `activeItems` es falsa. -La propiedad `items` también se configura con elementos de menú que se muestran. + +El código anterior crea un widget `Menu` e inicializa su propiedad `activeItems` en falsa. La propiedad `items` también se configura con elementos de menu que se muestran. Tenga en cuenta que debido a que el nombre de la clase ya está dado, la matriz de configuración no deben tener la clave `class`. ## Archivos de Configuración -Cuando una configuración es muy compleja, una práctica común es almacenar en uno o múltiples archivos PHP, conocidos como *Los archivos de configuración*. Un archivo de configuración devuelve un array de PHP que representa la configuración. Por ejemplo, es posible mantener una configuración de la aplicación en un archivo llamado `web.php`, como el siguiente, +Cuando una configuración es muy compleja, una práctica común es almacenarla en uno o múltiples archivos PHP, conocidos como *Los archivos de configuración*. Un archivo de configuración devuelve un array de PHP que representa la configuración. Por ejemplo, es posible mantener una configuración de la aplicación en un archivo llamado `web.php`, como el siguiente, ```php return [ @@ -150,8 +148,7 @@ return [ ]; ``` -Debido a la configuración `componentes` es compleja también, se guarda en un archivo separado llamado `components.php` -y "requerir" este archivo en `web.php` como se muestra arriba. El contenido de `components.php` es el siguiente, +Debido a que la configuración `componentes` es compleja también, se guarda en un archivo separado llamado `components.php` y "requerir" este archivo en `web.php` como se muestra arriba. El contenido de `components.php` es el siguiente, ```php return [ @@ -192,7 +189,7 @@ $config = require('path/to/web.php'); El método [[Yii::createObject()]] es implementado en base a [contenedor de inyección de dependencia](concept-di-container.md). Le permite especificar un conjunto de los llamados *configuraciones predeterminadas* que se aplicarán a todos los casos de las clases especificadas cuando se crean utilizando [[Yii::createObject()]]. Las configuraciones por defecto se puede especificar llamando `Yii::$container->set()` en el codigo [bootstrapping](runtime-bootstrapping.md). -Por ejemplo, si desea personalizar [[yii\widgets\LinkPager]] para que TODOS los buscas enlace mostrarán como máximo 5 botones de la página (el valor por defecto es 10), puede utilizar el siguiente código para lograr este objetivo, +Por ejemplo, si desea personalizar [[yii\widgets\LinkPager]] para que TODO enlace de búsqueda muestre como máximo 5 botones de página (el valor por defecto es 10), puede utilizar el siguiente código para lograr este objetivo, ```php \Yii::$container->set('yii\widgets\LinkPager', [ @@ -204,7 +201,7 @@ Sin utilizar las configuraciones predeterminadas, usted tendría que configurar ## Constantes de Entorno -Las configuraciones a menudo varían de acuerdo al entorno en que se ejecuta una aplicación. Por ejemplo, en el entorno de desarrollo, es posible que desee utilizar una base de datos llamada `mydb_dev`, mientras que en servidor de producción es posible que desee utilizar la base de datos `mydb_prod`. Para facilitar la conmutación de entornos, Yii proporciona una constante llamado `YII_ENV`que se puede definir en el [entrada script](structure-entry-scripts.md) de su aplicación. Por ejemplo, +Las configuraciones a menudo varían de acuerdo al entorno en que se ejecuta una aplicación. Por ejemplo, en el entorno de desarrollo, es posible que desee utilizar una base de datos llamada `mydb_dev`, mientras que en servidor de producción es posible que desee utilizar la base de datos `mydb_prod`. Para facilitar la conmutación de entornos, Yii proporciona una constante llamado `YII_ENV` que se puede definir en el [script de entrada](structure-entry-scripts.md) de su aplicación. Por ejemplo, ```php defined('YII_ENV') or define('YII_ENV', 'dev'); @@ -216,7 +213,7 @@ Usted puede definir `YII_ENV` como uno de los valores siguientes: - `dev`: entorno de desarrollo. La constante `YII_ENV_DEV` evaluará como verdadero. - `test`: entorno de pruebas. La constante `YII_ENV_TEST` evaluará como verdadero. -Con estas constantes de entorno, puede especificar sus configuraciones condicional basado en +Con estas constantes de entorno, puede especificar sus configuraciones condicionales basado en el entorno actual. Por ejemplo, la configuración de la aplicación puede contener el siguiente código para permitir que el [depurador y barra de herramientas de depuración](tool-debugger.md) en el entorno de desarrollo. diff --git a/docs/internals-es/translation-workflow.md b/docs/internals-es/translation-workflow.md new file mode 100644 index 0000000..62e22ac --- /dev/null +++ b/docs/internals-es/translation-workflow.md @@ -0,0 +1,59 @@ +Flujo de Trabajo de Traducción +============================== + +Yii se traduce en muchos idiomas con el fin de ser útil para desarrolladores de aplicaciones y internacionales. Dos áreas principales donde la contribución es muy bienvenida son la documentación y los mensajes del framework. + +Framework Mensajes +------------------ + +Framework tiene dos tipos de mensajes: excepciones que están destinados 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 `framework/messages/config.php` y asegúrese de que su lenguaje aparece en `lenguajes`. Si no, añadir su lenguaje allí (recuerde que debe mantener la lista en orden alfabético). El formato de código de idioma debe seguir [Código de Idiomas IETF](http://es.wikipedia.org/wiki/C%C3%B3digo_de_idioma_IETF), por ejemplo, `es`. +2. Ir al `framework` y ejecutar `yii message/extract messages/config.php`. +3. Traducir los mensajes en `framework/messages/your_lenguaje/yii.php`. Asegúrese 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 puede 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 de la matriz representa la traducción (valor) de un mensaje (clave). Si el valor está vacío, el mensaje se considera como no traducida. Los mensajes que ya no necesiten traducción tendrán sus traducciones encerrado entre un par de marcas »@@. Cadena de mensaje se puede utilizar con el formato de formas plurales. Compruebe [sección i18n de la guía](../guide-es/tutorial-i18n.md) para más detalles. + +Documentación +------------- + +Coloque traducciones de documentación bajo `docs/-` donde `` es el nombre de la documentación original como `guide` o `internals` y `` es el código de Lenguaje de los docs Lenguaje se convierten a. Para la traducción de guias es `docs/guide-es`. + +Después del trabajo inicial se lleva a cabo usted puede conseguir lo que ha cambiado desde la última traducción del fichero 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 se quejan de composer, realizar `composer install` en el fuente del directorio principal. + +Convenios para la traducción +---------------------------- + +- active record — sin traducción +- cache — sin traducción +- framework — sin traducción +- helper — sin traducción +- hash — sin traducción +- id — sin traducción +- widget — sin traducción +- script — sin traducción +- assets — sin traducción +- bootstrapping | bootstrap — sin traducción +- routing — sin traducción +- logging — sin traducción +- cookies — sin traducción +- controller — controlador +- model — modelo +- view — vista +- themes — temas o plantillas +- behaviors — comportamientos +- handlers — manipuladores +- instantiating — intanciando +- link — enlace diff --git a/docs/internals-pt-BR/translation-workflow.md b/docs/internals-pt-BR/translation-workflow.md new file mode 100644 index 0000000..aa32f37 --- /dev/null +++ b/docs/internals-pt-BR/translation-workflow.md @@ -0,0 +1,60 @@ +Como Colaborar Com a Tradução Para o Português do Brasil +======================================================== + +O Yii tem tradução para vários idiomas, incluindo o Português do Brasil. Existem duas áreas onde a contribuição para a tradução é muito bem-vindo. A primeira é a documentação e a segunda são as mensagens do framework. + +Mensagens do Framework +---------------------- + +O Framework tem dois tipos de mensagens: as exceções que são destinadas para o desenvolvedor e nunca são traduzidas, e as mensagens que são realmente visíveis para o usuário final, tais como erros de validação. + +Os passos para iniciar a tradução de mensagens são: + +1. Com o `console` entre na pasta `yii2/framework` e execute o seguinte comando: `yii message/extract messages/config.php`. +2. As mensagens a serem traduzidas encontram-se no seguinte caminho: `framework/messages/pt-BR/yii.php`. Certifique-se de salvar o arquivo com a codificação UTF-8 (Plain). +3. Após realizar as devidas traduções o passo seguinte é enviar as suas modificações para o respositório do Yii no github. [Veja aqui](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md) os passos necessários para o envio dos arquivos. + +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-pt-BR/tutorial-i18n.md) para mais detalhes. + + +Documentação +------------ + +As traduções da documentação para o português do Brasil devem ficar dentro do diretório `docs/` seguindo o padrão `docs/-` onde `` corresponde ao nome da pasta tal como `guide` ou `internals`. + +Com a tradução do documento concluída, você pode obter um diff das mudanças desde a última tradução, para isso, execute o seguinte comando a partir do diretório `build/` do framework: + +``` +build translation "../docs/guide" "../docs/guide-pt-BR" > report-guide-pt-BR.html +``` + +Antes de iniciar seus trabalhos de tradução certifique-se que o arquivo em qual irá trabalhar esteja disponível para ser traduzido. Para isso, acesse a [planilha no Google Docs](https://docs.google.com/spreadsheets/d/17JOpAjkJz2YZCjD6gWaUx32wskGRB-2CdFbed111iys/edit?usp=sharing). + + +Regras e Observações +-------------------- + +- Alguns termos não tem uma tradução muito boa para o português, em casos como esse convém escrever a palavra ou expressão em inglês primeiro em seguida sua possível tradução em parênteses. +- Se você acredita que alguma parte de sua tradução não faz sentido e você não tem certeza de como traduzi-la corretamente. Coloque este bloco de texto em itálico, isso ajudará na revisão. +- Para reduzir erros de digitação você pode utilizar um editor de texto como o MS Word para escrever pequenos blocos textos e em seguida copiar estes blocos para um editor visual de Markdown como o http://dillinger.io/. + +Convenções Para Tradução +------------------------ + +- action — ação +- active record — sem tradução +- cache — sem tradução +- CamelCase — sem tradução +- controller — controller (controlador) +- eager loading — eager loading (carregamento na inicialização) +- framework — sem tradução +- hash — sem tradução +- helper — sem tradução +- id — sem tradução +- lazy loading — lazy loading (carregamento retardado) +- model — model (modelo) +- view — view (visão) +- query builder — query builder (construtor de consulta) +- widget — sem tradução diff --git a/docs/internals-pt-BR/translations.md b/docs/internals-pt-BR/translations.md deleted file mode 100644 index b44b073..0000000 --- a/docs/internals-pt-BR/translations.md +++ /dev/null @@ -1,60 +0,0 @@ -Como Colaborar Com a Tradução Para o Português do Brasil -======================================================== - -O Yii tem tradução para vários idiomas, incluindo o Português do Brasil. Existem duas áreas onde a contribuição para a tradução é muito bem-vindo. A primeira é a documentação e a segunda são as mensagens do framework. - -Mensagens do Framework ----------------------- - -O Framework tem dois tipos de mensagens: as exceções que são destinadas para o desenvolvedor e nunca são traduzidas, e as mensagens que são realmente visíveis para o usuário final, tais como erros de validação. - -Os passos para iniciar a tradução de mensagens são: - -1. Com o `console` entre na pasta `yii2/framework` e execute o seguinte comando: `yii message/extract messages/config.php`. -2. As mensagens a serem traduzidas encontram-se no seguinte caminho: `framework/messages/pt-BR/yii.php`. Certifique-se de salvar o arquivo com a codificação UTF-8 (Plain). -3. Após realizar as devidas traduções o passo seguinte é enviar as suas modificações para o respositório do Yii no github. [Veja aqui](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md) os passos necessários para o envio dos arquivos. - -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. - - -Documentação ------------- - -As traduções da documentação para o português do Brasil devem ficar dentro do diretório `docs/` seguindo o padrão `docs/-` onde `` corresponde ao nome da pasta tal como `guide` ou `internals`. - -Com a tradução do documento concluída, você pode obter um diff das mudanças desde a última tradução, para isso, execute o seguinte comando a partir do diretório `build/` do framework: - -``` -build translation "../docs/guide" "../docs/guide-pt-BR" > report-guide-pt-BR.html -``` - -Antes de iniciar seus trabalhos de tradução certifique-se que o arquivo em qual irá trabalhar esteja disponível para ser traduzido. Para isso, acesse a [planilha no Google Docs](https://docs.google.com/spreadsheets/d/17JOpAjkJz2YZCjD6gWaUx32wskGRB-2CdFbed111iys/edit?usp=sharing). - - -Regras e Observações --------------------- - -- Alguns termos não tem uma tradução muito boa para o português, em casos como esse convém escrever a palavra ou expressão em inglês primeiro em seguida sua possível tradução em parênteses. -- Se você acredita que alguma parte de sua tradução não faz sentido e você não tem certeza de como traduzi-la corretamente. Coloque este bloco de texto em itálico, isso ajudará na revisão. -- Para reduzir erros de digitação você pode utilizar um editor de texto como o MS Word para escrever pequenos blocos textos e em seguida copiar estes blocos para um editor visual de Markdown como o http://dillinger.io/. - -Convenções Para Tradução ------------------------- - -- action — ação -- active record — sem tradução -- cache — sem tradução -- CamelCase — sem tradução -- controller — controller (controlador) -- eager loading — eager loading (carregamento na inicialização) -- framework — sem tradução -- hash — sem tradução -- helper — sem tradução -- id — sem tradução -- lazy loading — lazy loading (carregamento retardado) -- model — model (modelo) -- view — view (visão) -- query builder — query builder (construtor de consulta) -- widget — sem tradução diff --git a/docs/internals-ru/translation-workflow.md b/docs/internals-ru/translation-workflow.md index 07a6317..4b9682f 100644 --- a/docs/internals-ru/translation-workflow.md +++ b/docs/internals-ru/translation-workflow.md @@ -18,7 +18,7 @@ Yii переводится на множество языков, в том чи В файле перевода находится массив. Его ключи — исходные строки, значения — перевод. Если значение пусто, сообщение считается не переведённым. Переводы сообщений, которые больше не встречаются в коде, обрамлены `@@`. Для некоторых сообщений -необходимо использовать [специальный формат для поддержки употребления с числительными](../guide/i18n.md). +необходимо использовать [специальный формат для поддержки употребления с числительными](../guide-ru/tutorial-i18n.md). Документация ------------ diff --git a/docs/internals-uz/translation-workflow.md b/docs/internals-uz/translation-workflow.md new file mode 100644 index 0000000..c703be0 --- /dev/null +++ b/docs/internals-uz/translation-workflow.md @@ -0,0 +1,136 @@ +O'zbekchaga tarjima qilish bilan qanday ishlash kerak +===================================================== + +Yii juda ko'p tillarga tarjima qilinayabdi shu jumladan o'zbekchaga ham. Tarjima qo'llanma va habarlarni o'z ichiga oladi. + +Freymvork habari +---------------- + +Ikki turdagi habarlar bor: istisnolar, qaysiki ishlab chiquvchi nazarda tutgan va ular tarjima qilinmaydi va habarlar, qaysiki foydalanuvchilarga ko'rsatiladigan. Masalan, validatsiyaning xatoliklari. + +Tarjimani yangilash uchun: + +1. Konsolda `framework` direktoriyani ochamiz, `yii message/extract messages/config.php` ni ishga tushiramiz. +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-uz/tutorial-i18n.md) ni ishlatish zarur. + +Qo'llanma +--------- + +Qo'llanamani tarjimasi `docs/-uz` da joylashgan, bu yerda - original direktoriyalarga mos keladi, masalan, +`guide` yoki `internals`. + +Agar qo'llanma tarjimasi tugagan bo'lsa, build direktoriyasida konsolni ochib va quyidagini bajarib, originaldagi oxirgi tarjimadan keyingi diff o'zgarishlarni olish mumkin: + +``` +php build translation "../docs/guide" "../docs/guide-uz" "Uzbek guide translation report" > report_guide_uz.html +``` + +Agar composer uchun urushsa, bosh direktoriyada `composer install` ni bajaring. + +Tarjima qilishdan oldin hech kim shug'ullanmayotganligini tekshiring va o'zingizga [barcha tarjima qilinayotgan hujjatlarni ro'yhatini] yozib oling +//Ushbu manzilni ulardan olgandan keyin o'zgartirib qo'yish kerak bo'ladi. +(https://docs.google.com/spreadsheets/d/10dS7VB_3jSxUorryRlplB7nhA59e3i2vLYmTwn_1d3I/edit?usp=sharing). + +Barcha o'zgarishlarni quyidagi ko'rinishda olib boramiz [pull request](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md). + + +### Umumiy qoidalar + +- Ko'p terminlar o'zbekchada bitta ma'noga ega emas va o'zbekchada ko'p qo'llanilmaydigandir, shu sababli agar matnda + shunday terminlar uchrasa ularni birinchi bor qo'llanilgan joyida qavs ichida ingliz tilidagi varianti + ko'rsatilishi kerak; (terminlarning tarjimasini qo'llanilish variantlari quyida keltirilgan); +- Agar tarjima vaqtida matnning qaysidir qismi mazmuni o'zgarayotgan bo'lsa va siz uni shunday tarjima qilish + kerakligiga ishonchingiz komil bo'lmayotganday tuyulsa ushbu qismni * ichiga oling(ichidagi matn qiya holatga keladi). + Bu olib tashlash/to'g'rilashlar vaqtida ushbu matnlarga alohida e'tibor qaratishga imkon beradi; +- Tarjima vaqtida fakt xatoliklarni qilmang! +- Matnda tashqi manbalarga murojaatlar uchraydi, agar murojaat terminni izohlash maqolasiga olib boradigan bo'lsa, u holda + o'zbekchada tarjimasi bo'r bo'lgan vaziyatda o'zbekchasiga murojaat qilinadi. + Masalan `http://en.wikipedia.org/wiki/Captcha` → `http://uz.wikipedia.org/wiki/Captcha`. +- Sharhlar kodda tarjima qilinadi, agarda birinchi holatdagi mazmunini o'zgartirmasa; Matndagi vaqtinchalik sharhlarni + imkon qadar faqat *lokal*da ishlatish kerak! Aks holda uni reliz ga tushib qolish ehtimoli bor; +- Bo'limlarni tarjima qilish vaqtida `README.md` dagi tarjimani olib ketamiz; +- Shaxsiy qo'shimcha-sharhlarni qo'shish imkoni bor, lekin xaosdan qochish uchun original bitta bo'lishi kerak. Bunga zarurat vaqtida sharh oxiriga + "tar. shar." ni qo'shish kerak; +- Hujjatni umumiy to'g'rilashni o'tkazgandan so'ng mustaqil ravishda faqat ushbu bo'limga tegsihli bo'lgan grammatikadagi, fakt xatoliklardagi o'zgarishlarni kiritish talab darajasida tavsiya etiladi. Boshqa holatlarda gaplarni to'g'rilash, yaxshilash uchun va zarur hollarda o'zgarishlarni markazlashgan tarzda barcha bo'limlar uchun amalga oshirish uchun ularni tahlilga qo'yish zarur. + + +### Qo'llanma strukturasi + +Tarjima qilish vaqtida hujjatning struktura birligini to'g'ri nomlash muhim. Quyida keltirilgan strukturaga amal qilamiz : + +- Bob 1 + - Bo'lim 1 + - Bo'lim 2 + - Qism bo'lim 1 + - ... + - Bo'lim N +- Bob 2 +- ... +- Bob N + +### Maxsus habarlarni tarjimasi + +- Tip → Ko'rsatma +- Note → Eslatma +- Info → Ma'lumot + +### Rasmlarni tarjima qilish + +Qo'llanma uchun rasmlar `images` qism katalogida joylashgan. Ularning barchasi [yED](http://www.yworks.com/en/products_yed_about.html) da yaratilgan. +Zarurat tug'ilgan vaqtda fayl tarjima qilinayotgan katalogning `images` katalogiga nusxalanadi va tarjima qilinib png formatida saqlanadi. + +Rasmlardagi yozuvlar tarjima qilinadi. + +### Grammatika + + +Oxirgi variantni tashlashdan oldin uni umumiy stilini, orfografiyasini, punktlarini tekshiring. Tarjimani o'zbek tili uchun orfografiyani Wordda tekshirish imkoni bo'lmasada uning yordamida tayyorlashingiz mumkin; + +### Terminlar ro'yhati + +- action — amal. +- active record — tarjimasiz. +- attach handler — «qayta ishlovchini tayinlash». +- attribute of the model — model atributi. +- camel case — tarjimasiz. +- customization — (nozik) sozlash +- column — ustun (agar MO haqida gap ketayotgan bo'lsa). +- content — tashkil etuvchilari. +- controller — kontrollyor. +- debug (mode) — kod sozlash (tartibi) (production mode ga qarang). +- eager loading — ziqna yuklash uslubi/ziqna yuklash (lazy loading ga qarang). +- PHP extension — PHP kengaytmasi. +- field (of the table) — jadval (yoki atribut) maydoni. +- framework — freymvork. +- front-controller — front-kontrollyor. +- getter — getter. +- (event) handler — qayta ishlovchi (hodisa). +- hash — xesh. +- helper - yordamchi. +- id — qiymatlovchi(identifikatsiyalovchi). +- instance — nusxa. +- lazy loading — chetga olingan yuklash (qanday kerak bo'lsa shunday yuklasymiz va erta emas). +- method — metod (obektniki) //Diqqat! Obekt/klaslarda funksiyasi yo'q, faqat metodlari bor. +- model — model, ma`lumotlar modeli. +- model form — formalar modeli. +- parameter — parametr (metod yoki funksiyada va lekin klasda emas). +- to parse — qayta ishlash, agar *kontekst* tushunarsiz bo'lsa *parsing* qilish. +- placeholder — marker. +- production (mode) — ishlab chiqarish (rejimi) (см. debug mode). +- property — xususiyati (obekt). +- to render — *render* qilish, formallashtirish. +- related, relation — bog'langan, bog'lanish. +- resolve request — so'rovni oldindan qayta ishlash. +- route — marshrut. +- row (of the table) — satr(jadvallarniki). +- setter — setter. +- tabular input — tabli kiritish. +- to validate — tekshirish. +- valid — mos. +- validator — validator. +- validator class — validator klasi. +- view — namoyish. +- query builder — so'rovlar konstruktori. \ No newline at end of file diff --git a/docs/internals-uz/translations.md b/docs/internals-uz/translations.md deleted file mode 100644 index 49bd2b2..0000000 --- a/docs/internals-uz/translations.md +++ /dev/null @@ -1,136 +0,0 @@ -O'zbekchaga tarjima qilish bilan qanday ishlash kerak -===================================================== - -Yii juda ko'p tillarga tarjima qilinayabdi shu jumladan o'zbekchaga ham. Tarjima qo'llanma va habarlarni o'z ichiga oladi. - -Freymvork habari ----------------- - -Ikki turdagi habarlar bor: istisnolar, qaysiki ishlab chiquvchi nazarda tutgan va ular tarjima qilinmaydi va habarlar, qaysiki foydalanuvchilarga ko'rsatiladigan. Masalan, validatsiyaning xatoliklari. - -Tarjimani yangilash uchun: - -1. Konsolda `framework` direktoriyani ochamiz, `yii message/extract messages/config.php` ni ishga tushiramiz. -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. - -Qo'llanma ---------- - -Qo'llanamani tarjimasi `docs/-uz` da joylashgan, bu yerda - original direktoriyalarga mos keladi, masalan, -`guide` yoki `internals`. - -Agar qo'llanma tarjimasi tugagan bo'lsa, build direktoriyasida konsolni ochib va quyidagini bajarib, originaldagi oxirgi tarjimadan keyingi diff o'zgarishlarni olish mumkin: - -``` -php build translation "../docs/guide" "../docs/guide-uz" "Uzbek guide translation report" > report_guide_uz.html -``` - -Agar composer uchun urushsa, bosh direktoriyada `composer install` ni bajaring. - -Tarjima qilishdan oldin hech kim shug'ullanmayotganligini tekshiring va o'zingizga [barcha tarjima qilinayotgan hujjatlarni ro'yhatini] yozib oling -//Ushbu manzilni ulardan olgandan keyin o'zgartirib qo'yish kerak bo'ladi. -(https://docs.google.com/spreadsheets/d/10dS7VB_3jSxUorryRlplB7nhA59e3i2vLYmTwn_1d3I/edit?usp=sharing). - -Barcha o'zgarishlarni quyidagi ko'rinishda olib boramiz [pull request](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md). - - -### Umumiy qoidalar - -- Ko'p terminlar o'zbekchada bitta ma'noga ega emas va o'zbekchada ko'p qo'llanilmaydigandir, shu sababli agar matnda - shunday terminlar uchrasa ularni birinchi bor qo'llanilgan joyida qavs ichida ingliz tilidagi varianti - ko'rsatilishi kerak; (terminlarning tarjimasini qo'llanilish variantlari quyida keltirilgan); -- Agar tarjima vaqtida matnning qaysidir qismi mazmuni o'zgarayotgan bo'lsa va siz uni shunday tarjima qilish - kerakligiga ishonchingiz komil bo'lmayotganday tuyulsa ushbu qismni * ichiga oling(ichidagi matn qiya holatga keladi). - Bu olib tashlash/to'g'rilashlar vaqtida ushbu matnlarga alohida e'tibor qaratishga imkon beradi; -- Tarjima vaqtida fakt xatoliklarni qilmang! -- Matnda tashqi manbalarga murojaatlar uchraydi, agar murojaat terminni izohlash maqolasiga olib boradigan bo'lsa, u holda - o'zbekchada tarjimasi bo'r bo'lgan vaziyatda o'zbekchasiga murojaat qilinadi. - Masalan `http://en.wikipedia.org/wiki/Captcha` → `http://uz.wikipedia.org/wiki/Captcha`. -- Sharhlar kodda tarjima qilinadi, agarda birinchi holatdagi mazmunini o'zgartirmasa; Matndagi vaqtinchalik sharhlarni - imkon qadar faqat *lokal*da ishlatish kerak! Aks holda uni reliz ga tushib qolish ehtimoli bor; -- Bo'limlarni tarjima qilish vaqtida `README.md` dagi tarjimani olib ketamiz; -- Shaxsiy qo'shimcha-sharhlarni qo'shish imkoni bor, lekin xaosdan qochish uchun original bitta bo'lishi kerak. Bunga zarurat vaqtida sharh oxiriga - "tar. shar." ni qo'shish kerak; -- Hujjatni umumiy to'g'rilashni o'tkazgandan so'ng mustaqil ravishda faqat ushbu bo'limga tegsihli bo'lgan grammatikadagi, fakt xatoliklardagi o'zgarishlarni kiritish talab darajasida tavsiya etiladi. Boshqa holatlarda gaplarni to'g'rilash, yaxshilash uchun va zarur hollarda o'zgarishlarni markazlashgan tarzda barcha bo'limlar uchun amalga oshirish uchun ularni tahlilga qo'yish zarur. - - -### Qo'llanma strukturasi - -Tarjima qilish vaqtida hujjatning struktura birligini to'g'ri nomlash muhim. Quyida keltirilgan strukturaga amal qilamiz : - -- Bob 1 - - Bo'lim 1 - - Bo'lim 2 - - Qism bo'lim 1 - - ... - - Bo'lim N -- Bob 2 -- ... -- Bob N - -### Maxsus habarlarni tarjimasi - -- Tip → Ko'rsatma -- Note → Eslatma -- Info → Ma'lumot - -### Rasmlarni tarjima qilish - -Qo'llanma uchun rasmlar `images` qism katalogida joylashgan. Ularning barchasi [yED](http://www.yworks.com/en/products_yed_about.html) da yaratilgan. -Zarurat tug'ilgan vaqtda fayl tarjima qilinayotgan katalogning `images` katalogiga nusxalanadi va tarjima qilinib png formatida saqlanadi. - -Rasmlardagi yozuvlar tarjima qilinadi. - -### Grammatika - - -Oxirgi variantni tashlashdan oldin uni umumiy stilini, orfografiyasini, punktlarini tekshiring. Tarjimani o'zbek tili uchun orfografiyani Wordda tekshirish imkoni bo'lmasada uning yordamida tayyorlashingiz mumkin; - -### Terminlar ro'yhati - -- action — amal. -- active record — tarjimasiz. -- attach handler — «qayta ishlovchini tayinlash». -- attribute of the model — model atributi. -- camel case — tarjimasiz. -- customization — (nozik) sozlash -- column — ustun (agar MO haqida gap ketayotgan bo'lsa). -- content — tashkil etuvchilari. -- controller — kontrollyor. -- debug (mode) — kod sozlash (tartibi) (production mode ga qarang). -- eager loading — ziqna yuklash uslubi/ziqna yuklash (lazy loading ga qarang). -- PHP extension — PHP kengaytmasi. -- field (of the table) — jadval (yoki atribut) maydoni. -- framework — freymvork. -- front-controller — front-kontrollyor. -- getter — getter. -- (event) handler — qayta ishlovchi (hodisa). -- hash — xesh. -- helper - yordamchi. -- id — qiymatlovchi(identifikatsiyalovchi). -- instance — nusxa. -- lazy loading — chetga olingan yuklash (qanday kerak bo'lsa shunday yuklasymiz va erta emas). -- method — metod (obektniki) //Diqqat! Obekt/klaslarda funksiyasi yo'q, faqat metodlari bor. -- model — model, ma`lumotlar modeli. -- model form — formalar modeli. -- parameter — parametr (metod yoki funksiyada va lekin klasda emas). -- to parse — qayta ishlash, agar *kontekst* tushunarsiz bo'lsa *parsing* qilish. -- placeholder — marker. -- production (mode) — ishlab chiqarish (rejimi) (см. debug mode). -- property — xususiyati (obekt). -- to render — *render* qilish, formallashtirish. -- related, relation — bog'langan, bog'lanish. -- resolve request — so'rovni oldindan qayta ishlash. -- route — marshrut. -- row (of the table) — satr(jadvallarniki). -- setter — setter. -- tabular input — tabli kiritish. -- to validate — tekshirish. -- valid — mos. -- validator — validator. -- validator class — validator klasi. -- view — namoyish. -- query builder — so'rovlar konstruktori. \ No newline at end of file diff --git a/docs/internals/translation-teams.md b/docs/internals/translation-teams.md index 7a03094..120400a 100644 --- a/docs/internals/translation-teams.md +++ b/docs/internals/translation-teams.md @@ -40,6 +40,7 @@ Spanish ------- - Luciano Baraglia, [@lucianobaraglia](https://github.com/lucianobaraglia) +- Marco Da Silva, [@markmarco16](https://github.com/markmarco16), markmarco16@gmail.com Ukrainian --------- diff --git a/docs/internals/translation-workflow.md b/docs/internals/translation-workflow.md index 12f6448..2094e6c 100644 --- a/docs/internals/translation-workflow.md +++ b/docs/internals/translation-workflow.md @@ -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 ------------- From ddde2e4cc5903788693e47d387e12ba9a0148f18 Mon Sep 17 00:00:00 2001 From: Faxriddin Date: Mon, 6 Oct 2014 10:41:09 +0500 Subject: [PATCH 02/43] "intro-yii" file translated to uzbek language. --- docs/guide-uz/intro-yii.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 docs/guide-uz/intro-yii.md diff --git a/docs/guide-uz/intro-yii.md b/docs/guide-uz/intro-yii.md new file mode 100644 index 0000000..8ac8dbe --- /dev/null +++ b/docs/guide-uz/intro-yii.md @@ -0,0 +1,37 @@ +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 yozilgani 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 uchun 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 From aed34b63e78c0c5b80e3bf1434140da071e778f4 Mon Sep 17 00:00:00 2001 From: Faxriddin Date: Mon, 6 Oct 2014 10:49:34 +0500 Subject: [PATCH 03/43] translation to uzbek. Changed words. --- docs/guide-uz/intro-yii.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide-uz/intro-yii.md b/docs/guide-uz/intro-yii.md index 8ac8dbe..6e4883f 100644 --- a/docs/guide-uz/intro-yii.md +++ b/docs/guide-uz/intro-yii.md @@ -26,7 +26,7 @@ Yii — bir odamning loyihasi emas. U unga yordam berayotgan ishlab chiquvchilar 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 yozilgani talqini. Mana shu talqinda navbatdagi yillarda uni yanada kuchaytirish nazarda tutilgan. Ushbu qo'llanma aynan 2.0 talqin haqida. +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 @@ -34,4 +34,4 @@ 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 uchun 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 +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 From c7bb226027b06b2a56c228687fcf53c8bb906253 Mon Sep 17 00:00:00 2001 From: r3verser Date: Mon, 6 Oct 2014 09:59:55 +0300 Subject: [PATCH 04/43] typo in input-forms.md --- docs/guide/input-forms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/input-forms.md b/docs/guide/input-forms.md index 942e641..41b189c 100644 --- a/docs/guide/input-forms.md +++ b/docs/guide/input-forms.md @@ -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`. From 60b82e8b936d5e28ebb459011d0a92d052396752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt?= Date: Mon, 6 Oct 2014 11:27:45 +0200 Subject: [PATCH 05/43] Create start-looking-ahead.md --- docs/guide-fr/start-looking-ahead.md | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 docs/guide-fr/start-looking-ahead.md diff --git a/docs/guide-fr/start-looking-ahead.md b/docs/guide-fr/start-looking-ahead.md new file mode 100644 index 0000000..5d8117f --- /dev/null +++ b/docs/guide-fr/start-looking-ahead.md @@ -0,0 +1,39 @@ +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 : + - Chat IRC : Les canal #yii sur le réseau freenode () + - GitHub : + - Facebook : + - Twitter : + - LinkedIn : From 2e165a1649ac906a24bf2b433b5795b2b14f86e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt?= Date: Mon, 6 Oct 2014 15:54:06 +0200 Subject: [PATCH 06/43] Create structure-overview.md --- docs/guide-fr/structure-overview.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 docs/guide-fr/structure-overview.md diff --git a/docs/guide-fr/structure-overview.md b/docs/guide-fr/structure-overview.md new file mode 100644 index 0000000..142b805 --- /dev/null +++ b/docs/guide-fr/structure-overview.md @@ -0,0 +1,27 @@ +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) From 52c315e6a38d83dc31e974edb73b6e3e934e0068 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Oct 2014 16:01:02 +0200 Subject: [PATCH 07/43] added test for web\User authTimeout --- tests/unit/framework/web/UserTest.php | 133 ++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 tests/unit/framework/web/UserTest.php diff --git a/tests/unit/framework/web/UserTest.php b/tests/unit/framework/web/UserTest.php new file mode 100644 index 0000000..b62f9d0 --- /dev/null +++ b/tests/unit/framework/web/UserTest.php @@ -0,0 +1,133 @@ +session->removeAll(); + static::$time = null; + parent::tearDown(); + } + + public function testLoginExpires() + { + $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 From 6dbb6c13e9f79467025d015077bdb18a7f4db796 Mon Sep 17 00:00:00 2001 From: MarsuBoss Date: Mon, 6 Oct 2014 16:15:28 +0200 Subject: [PATCH 08/43] Fix translate --- docs/guide-fr/start-workflow.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/guide-fr/start-workflow.md b/docs/guide-fr/start-workflow.md index 2b3b2a3..38aefc0 100644 --- a/docs/guide-fr/start-workflow.md +++ b/docs/guide-fr/start-workflow.md @@ -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é -------------- +Fonctionnalité +-------------- 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 @@ -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. From e287382dbc94771bebf180686fb9526dca476d33 Mon Sep 17 00:00:00 2001 From: MarsuBoss Date: Mon, 6 Oct 2014 16:44:45 +0200 Subject: [PATCH 09/43] Translate Images --- docs/guide-fr/images/application-lifecycle.graphml | 36 ++++++++++++--------- docs/guide-fr/images/application-lifecycle.png | Bin 40306 -> 42728 bytes docs/guide-fr/images/application-structure.graphml | 15 +++++---- docs/guide-fr/images/application-structure.png | Bin 24774 -> 26128 bytes 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/docs/guide-fr/images/application-lifecycle.graphml b/docs/guide-fr/images/application-lifecycle.graphml index f701c62..acd21ac 100644 --- a/docs/guide-fr/images/application-lifecycle.graphml +++ b/docs/guide-fr/images/application-lifecycle.graphml @@ -28,7 +28,7 @@ - user + utilisateur @@ -48,7 +48,7 @@ - model + modèle @@ -65,7 +65,7 @@ - database + base de donnée @@ -93,7 +93,7 @@ - view + vue @@ -113,7 +113,7 @@ - controller + contrôleur @@ -139,7 +139,7 @@ - create action + créer l'action @@ -156,7 +156,8 @@ - perform filters + effectue +les filtres @@ -202,7 +203,7 @@ - load model + charge un modèle @@ -219,7 +220,7 @@ - render view + génère une vue @@ -240,7 +241,7 @@ - response + réponse @@ -257,7 +258,7 @@ - request + requête @@ -303,7 +304,7 @@ - resolve route + résout la route @@ -320,7 +321,8 @@ - create controller + crée une instance +de contrôleur @@ -342,7 +344,7 @@ - entry script + script de démarrage @@ -368,7 +370,8 @@ - load app config + charge la configuration +de l'application @@ -385,7 +388,8 @@ - run application + créé une instance +d'application diff --git a/docs/guide-fr/images/application-lifecycle.png b/docs/guide-fr/images/application-lifecycle.png index 1a47ee99dd5df6b3f8d9a59ad21e003f265940bd..22ce9d58ac991fb2dd4d3db208426b17bd2031c6 100644 GIT binary patch literal 42728 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 Z3XP=4&l+RdW9~@TZq8qSb<-*E+~4F#ey0Ec diff --git a/docs/guide-fr/images/application-structure.graphml b/docs/guide-fr/images/application-structure.graphml index f6fce48..002fa9b 100644 --- a/docs/guide-fr/images/application-structure.graphml +++ b/docs/guide-fr/images/application-structure.graphml @@ -20,8 +20,8 @@ - application -component + composant +d'application @@ -38,7 +38,8 @@ component - entry script + script de +démarrage @@ -72,7 +73,7 @@ component - controller + contrôleur @@ -89,7 +90,7 @@ component - filter + filtre @@ -123,7 +124,7 @@ component - view + vue @@ -140,7 +141,7 @@ component - model + modèle diff --git a/docs/guide-fr/images/application-structure.png b/docs/guide-fr/images/application-structure.png index d3a55498889d296ca707527f5c9ab5fae217c1c5..b86321bf372ea9672e725f68f86681e320b85bdd 100644 GIT binary patch literal 26128 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 E2TQ7Y=>Px# literal 24774 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

WTZ1E~fy3MKk*Z_$vB~k~vQcv2R?7fOep@ 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 z Date: Mon, 6 Oct 2014 16:51:16 +0200 Subject: [PATCH 10/43] Fix translate --- docs/guide-fr/start-gii.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/guide-fr/start-gii.md b/docs/guide-fr/start-gii.md index 00e11f8..80f1d68 100644 --- a/docs/guide-fr/start-gii.md +++ b/docs/guide-fr/start-gii.md @@ -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é. From a6b5e62f017decc0e45815c8a8f58b6403bab650 Mon Sep 17 00:00:00 2001 From: Larnu Date: Mon, 6 Oct 2014 18:04:45 +0200 Subject: [PATCH 11/43] fix grammar, typo and translate conventions --- docs/guide-es/concept-configurations.md | 12 ++++---- docs/guide-es/images/application-lifecycle.graphml | 2 +- docs/guide-es/images/application-lifecycle.png | Bin 37006 -> 40097 bytes docs/guide-es/images/application-structure.png | Bin 15874 -> 15309 bytes docs/guide-es/runtime-overview.md | 14 +++++----- docs/guide-es/structure-filters.md | 4 +-- docs/guide-es/structure-models.md | 10 +++---- docs/guide-es/structure-modules.md | 31 ++++++++++----------- docs/guide-es/structure-widgets.md | 2 +- docs/internals-es/translation-workflow.md | 9 +++--- 10 files changed, 41 insertions(+), 43 deletions(-) diff --git a/docs/guide-es/concept-configurations.md b/docs/guide-es/concept-configurations.md index f058603..8176140 100644 --- a/docs/guide-es/concept-configurations.md +++ b/docs/guide-es/concept-configurations.md @@ -1,4 +1,4 @@ -Configuración +Configuración ============== Las configuraciones se utilizan ampliamente en Yii al crear nuevos objetos o inicializar los objetos existentes. Las configuraciones por lo general incluyen el nombre de la clase del objeto que se está creando, y una lista de los valores iniciales que deberían ser asignadas a las del [propiedades](concept-properties.md) objeto. Las configuraciones también pueden incluir una lista de manipuladores que deban imponerse a del objeto [eventos](concept-events.md) y/o una lista de [comportamientos](concept-behaviors.md) que también ha de atribuirse al objeto. @@ -42,7 +42,7 @@ El formato de una configuración se puede describir formalmente como: donde * El elemento `class` especifica un nombre de clase completo para el objeto que se está creando. -* Los elementos `propertyName` especifica los valores iniciales de la propiedad con nombre. Las claves son los nombres de las propiedades y los valores son los valores iniciales correspondientes. Sólo los miebros de variables públicas y [propiedades](concept-properties.md) definidas por getters/setters se pueden configurar. +* Los elementos `propertyName` especifica los valores iniciales de la propiedad con nombre. Las claves son los nombres de las propiedades y los valores son los valores iniciales correspondientes. Sólo los miembros de variables públicas y [propiedades](concept-properties.md) definidas por getters/setters se pueden configurar. * Los elementos `on eventName` especifican qué manipuladores deberán adjuntarse al del objeto [eventos](concept-events.md). Observe que las claves de matriz se forman prefijando nombres de eventos con `on`. Por favor, consulte la sección [Eventos](concept-events.md) para los formatos de controlador de eventos compatibles. * Los elementos `as behaviorName` especifican qué [comportamientos](concept-behaviors.md) deben adjuntarse al objeto. Observe que las claves de matriz se forman prefijando nombres de comportamiento con `as`; el valor, `$behaviorConfig`, representa la configuración para la creación de un comportamiento, como una configuración normal descrita aquí. @@ -130,7 +130,7 @@ echo Menu::widget([ ]); ``` -El código anterior crea un widget `Menu` e inicializa su propiedad `activeItems` en falsa. La propiedad `items` también se configura con elementos de menu que se muestran. +El código anterior crea un widget `Menu` e inicializa su propiedad `activeItems` en falsa. La propiedad `items` también se configura con elementos de menú que se muestran. Tenga en cuenta que debido a que el nombre de la clase ya está dado, la matriz de configuración no deben tener la clave `class`. @@ -187,7 +187,7 @@ $config = require('path/to/web.php'); ## Configuraciones por Defecto -El método [[Yii::createObject()]] es implementado en base a [contenedor de inyección de dependencia](concept-di-container.md). Le permite especificar un conjunto de los llamados *configuraciones predeterminadas* que se aplicarán a todos los casos de las clases especificadas cuando se crean utilizando [[Yii::createObject()]]. Las configuraciones por defecto se puede especificar llamando `Yii::$container->set()` en el codigo [bootstrapping](runtime-bootstrapping.md). +El método [[Yii::createObject()]] es implementado en base a [contenedor de inyección de dependencia](concept-di-container.md). Le permite especificar un conjunto de los llamados *configuraciones predeterminadas* que se aplicarán a todos los casos de las clases especificadas cuando se crean utilizando [[Yii::createObject()]]. Las configuraciones por defecto se puede especificar llamando `Yii::$container->set()` en el código [bootstrapping](runtime-bootstrapping.md). Por ejemplo, si desea personalizar [[yii\widgets\LinkPager]] para que TODO enlace de búsqueda muestre como máximo 5 botones de página (el valor por defecto es 10), puede utilizar el siguiente código para lograr este objetivo, @@ -213,9 +213,7 @@ Usted puede definir `YII_ENV` como uno de los valores siguientes: - `dev`: entorno de desarrollo. La constante `YII_ENV_DEV` evaluará como verdadero. - `test`: entorno de pruebas. La constante `YII_ENV_TEST` evaluará como verdadero. -Con estas constantes de entorno, puede especificar sus configuraciones condicionales basado en -el entorno actual. Por ejemplo, la configuración de la aplicación puede contener el siguiente -código para permitir que el [depurador y barra de herramientas de depuración](tool-debugger.md) en el entorno de desarrollo. +Con estas constantes de entorno, puede especificar sus configuraciones condicionales basado en el entorno actual. Por ejemplo, la configuración de la aplicación puede contener el siguiente código para permitir que el [depurador y barra de herramientas de depuración](tool-debugger.md) en el entorno de desarrollo. ```php $config = [...]; diff --git a/docs/guide-es/images/application-lifecycle.graphml b/docs/guide-es/images/application-lifecycle.graphml index 49bbfba..533eaf0 100644 --- a/docs/guide-es/images/application-lifecycle.graphml +++ b/docs/guide-es/images/application-lifecycle.graphml @@ -219,7 +219,7 @@ - interpretar vista + renderizar vista diff --git a/docs/guide-es/images/application-lifecycle.png b/docs/guide-es/images/application-lifecycle.png index 046749fabe1475034e4d82c7fa9cb261003fd915..554d64bf47f5fd3340ab0bf6d6ccef20a072cbbc 100644 GIT binary patch literal 40097 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 diff --git a/docs/guide-es/images/application-structure.png b/docs/guide-es/images/application-structure.png index b0199c954318934f611ad39639e944696b2800a8..4d120c2b31e3ff77256c8cd2bde3ea4a7caf0ede 100644 GIT binary patch literal 15309 zcmbWec|26_|NlQK^_HYfi?w9SR$(a1NMzrVF^oY78T;6mp%PNrx2z+w4Tdn7u_f8E zjBQMer83rGBs<}I^m={1pU?O9``x~OeBEw!J7>;yo$ET+xvuARe?Fei6KSZg!FH1K zBnSjz)6!Hk0)dz)z(1e=90z_;{4($w1X4)UQd2SZ8(qp|jWs4WlpRc~FohlqyDB1j zyU<-t?P0Fw1#e?x!~6Fh7P#kp31z>Kw3XdK$bG5C)cni+xaOBvF&8fPtKPVsi27P{ zx}&J#l=mAa|7CFh*t^#SpFh4zq2cO+8#c2>#@D?ZQCXMW-LiM?u+QsBuTtvnM-CIA?%U5aAr{B{t1n53P8v1mfrhS9 zjQ7z|gdLq8^m34=oc`_2CM##Inniuj!J8)sysW6dMqsIdQpMw z_DLDADdRkQRZm?&79s0IYTc6(LTW-!!}_;<>RJk{XB^7cz59!2BSK;S^$~C&kL35t^g2o!a!>b$-v#o%F!v$VJR;N)?>Z z*?xjr^fY5Q)d}d94_X$jU#dFD=j-(YBS@(SUPboFY3z9-EvHR$<%j5V>`?MuMM+pB zwn5Z5Dg>oMtu45erZD~TGuB)XKcUpKH`P#WeF;Mr5^zax3t9J}`XynZqCE(cMn`;R zJW@tK&n>Ci)5W2hgnJr@Z%RBnDYMx-wXLj!^N#~wG6#&c`0FEnD2tAu7=CNK>dV;O zf@X1W2mT@$%Y%Ty4O%-qF{En%iEV9R!(f(^8F$=nloJl2U9Chdg+8r?8RZ? z?@sV)C8=&=tUt8d!o#)PnS8v^IDNU2mUanv^Tr<$94t_BvO~sG*L^k>=&#u4770$q z4V+1_;KnlqZE?|t)`!(+`g887JX`1za(o-|Z+DZvuE#X# zDSuSHC3a_9r<%B5NPoQ&ewQb%7$@DP z*w>9UONy@Cd)fhZfe`Gez1{w6@E30xE997yXz;lwjih)dOJHdj=AocEKg!lm!@orH zoli^~>d=}JIF_{27JU-?YKo%E8dof!WUpq(IqYo_DVSzLv4!px&3h@yde#ZZXlX(7 z;ANa9t;I&rpN~R;x10~9PdFdG_ib95%i%QCnmx9QW4wKw4sGRSk(zYq1m6VKRN+sg zb&@vKss2MCtSKnhw(HHY5Ao&*EKe!cq*LCi%y8wL_s9IDMToPT^7O7aVdeo21cHiE zY=q6{qx))Z0jqfFKChd2aLx0>H9b`Ie_i1Ba4!$nsASi=Dt*czfA`GENIT(!D}epr zSo8_xc^^Am^(|mu3450@Flmk^kuUphPzM~m-FyPoL)9k%z5*kwQQ3p7akKtTijO>Jt zEDgS~0BZGlc%j#qPJL8&wAnl?oPnvnJ}iw+wdR z;I(#>AHkT%R1t8S2*X)|?=d}a`+ z(2UT#vh4;b+bZd)d>gIH3f!p@6=jGRO86<}aM&wh4#e;|n* z-rG=-aM2ci*wAYPP)J*tvb>e?=I~Hnh?4Z9*3YC(V5jRy0no@j;Qaz-`hD!pfOb*@ zVX3&Cket8rLD#=&TW0eI7Q&4NI!dHo8mq|f)mcB!ry&}TcHK>5b~U$Uk5&hsWc)|h z_=wC9W~}L+yO!o^P_*X1KQ;zP80qLXX0M$DZXejOe)L0fc6|-{?u1oI;K<+(YCDcpv-JMr5RSv4It) z9} znM)~&ZR|f3`_rj>K4{{Ur{jPQu8UDWpw~3FW}L>TlLaq!$(hu)aS0QaGefZHcl|SV z-BoQz6)Vf+NewG+>c*E~R&N@3k~0hSGPe?xZP&Tnx=-bi9lmnyC^ zPc(!@)o%dq(t_ULuTgsvLwa^DcswG4JbU6xxCMRHh-sB~s&Z`hE@oEs8eftzLAx*| zN}{BXMn>p>AG(`><$pA& zyirCWTndq;Ms3Y}H;F`!o{zpe)=<7SGql#ud-tkdIbk@DBFv{O04|d%44EAAT3JfD z13j|0o?}+DvaIA`HR10IQBnr)x64_@jZRE9tr<>CU!%~BlA2y#Q*;DVgMg_aQ?M_r z{UDPxDHX1_vi;$ifBV*{=)KFl+^2Oi5WY%*A=tI*S^TtPi(uA-61!L6Bz#0(SCGKh zTPvc6J7=yOr(yNXF$ zQ&mS%(8Ikef+2?>f4~x>*wcOY1WN_`dpp3ENn-D{;9(_VDObVEeb;wtcDLn4DSxNK z2V@A#QBYh5FGBHK{;9jW&>5lO=y*CgiG{%GbhkJy_g+Z7@ERd;z8 zEnONbz26L!No=BXIZg2?lrs@|bj*~c5P!3vc6a=X+KfhB!QDFnn293f z^!*vK_xI-!Jn?Dzl;?j(Ed|l^QaWT?XeQ;>RSIX4lUfKS6gzWgiH6371lu_-B){7# z52>dt?r%|B9od596Esn9eFU}@k-}+LG-O_~FqQ)hesb9Vahnt;Z=M2{MK%7)V_KUL zpKe;;!*y^Fd~V0c$tE_YtI$RzF3(o>I$)Sa3ic>vLbE_&XUZj%!!GxIVyHbUuU3RQHY?co$JPNSNez3jVJMlgf#g2@4^f zDyGF%B?$+`9rzc7>8~qAS1F9BW3?j=Z%DEHlB)#}%x+1xz#GJyYl?e&s{;e2#SPQS z6W>YGtLGj`lpN&MNK1Auu3d>n#EGHwjz7Gy%8E%9+*udv#IaGD@wuEy^sbupbdP+1 zUu_s0tlem$2>Q?BYIlQ24I#Z3yxH)mM`>km5!H~}JBHgGoVD=DBg_|^a3ofjujA#c zW_~vztZ^Pj<$BWXsk`O3(dm;!VbjL8gCKP?+US|#lXgz4+3*50V9E6_NfOJTnbXQa z?Nxg;_>l0>Rmy7}d zxV@lZb89wMIWsoIn^IXqR>;mT<7K@C&HE^_i$WaY&HhVH8vOQ0lL|XGwCU@-wAwao z*g-$H%w;3>Q?i@A4f81U@15#R1CosI*N22@>^XZ9Z}V^Yiblk0Yf6)6BVpo18nv#% zIK|@61NPaE|A)cL|f>BNgjyO|Gkk(M1ltLQz;-9dIa|QD==5lT{V?9BbQkc3_ z6#Jvim+?+oS%#qqF(c%7daTiu4J)U-id;%D=MgP0t5PIaK5|r-&{k|LcqdXa1p&=d zp!G$U{T8Vk4sFQij? zb_ZH|F(#qkY%{s|n83(`%^2+*xL!VjtF5{r@CFS#Jug2S&PAQs?W*`gcXDg& zp4RD&;B{t@6{z`f&bip{Cp*ZWN3(>Sn$D*{z@8Z zCc?+blh}YIQyC~HOzOSsU%$|omcs~#J%`hYn5^Kz|EMnt@Im=-gLtS3S9jFrw7APnkNaCkIYT8r|$S#&T`&HhGgUyZwO zq8OUh_oh&I-mpMTcj@pzG4j~O?LW=4Xs1AX7mddB$Vdf8=sny5(+zVC_G1Ko7%fe$ zXkW)vR5zgJsVIJ7<9RT&I!17~6oQs`+PMwGJY?>c>zNJzMNE|v<2I2zE}#dPFrXTo ztuS#Xk_5Y`SXIyIrxcl2tEidp&^n=v3{&1hzaXVsOG-@1##Ci9b>j>d_5d;i>{ARb zWg!hYLpLfD<5eoOXi&aJ8F=3qlsmJ1U`OsB&(8YwvG(=G%8wuWN>^nU;h2<@?=~-E zrXi$lMZS~Ug;LIyoS&X-tX=QlmkE9gFyCv00`E9Hm%%D+l@eg_&?}JC+0O3K6f%E} z2Imi_?kf?39(OLYX~on!73J)eEbW=MmEW+AQh~Gqi~wb2KOK=2AN*tArEHbS0%C}% znredEHK`#FZMdc1&h9KMIoa7_B>BM4R&^nn7aOLd5h&be$1>?U{-?3vHLi|#d3E!x zHEh?J{z*zb;s#jhGjj7jv3Hl&qE3A_6ze4M6`HwFJS*U>vE(pz2S>$!)^{64HG+?$HZrAh-GZpoB1^~k1|+z zQ5}aDg|T=76loOyXQc;LI~C3QOWSVEN7n3iO?|w<1uE~43 z0}!S^CB><6>o?iqWB%Y4hp&Nw%dEytab2n_^paB@hmwcJAV1}EWPrj~%KJ@CT;0Ve zfE;WDmt&-YxeFJz7RAfDo}c#0Ogv~g88V=W71Iv6Z}oiWoFHYsunO>s0#H$$r*15; zZ)LVGyCe-Iu;Sb@8S`P%kCa5GfldCM68l0N+)`s0=)=?P{z0FOMtp^LMi$F%%au!c zolv8wiQ=K+0XdXJ#$DzNMPI@CQT!;bZUJ5dw{4=Yrjo8-nIb=Sv`ePs6>gB9m-5yQ znRT@PV3$x**aWk}!LtgooaP4b9+Q}%bBXo}Y)Q!)xK&)!7apa#a^p*3SS*j({l4z^?VnR*@1I#QIRWr@j)dh290W0!IIlZ`-RXj|JI>f+MwvDQYQTIr*+rqB9@Y z(C$7LYWV7XuQrpc4j{(YdVTV}Zv1zqwR7{rKb+VUdItF9@{PRFeoA+!9v`nReIP$o z`lE#ww$V|mUf8{tmj{^Bqgq}ovsi4JtR%(H8%q=F1V#nx6>&0*F`XW=|u z{eHC#JCZ}(8xJ??pzU+3@6qf&WwMha@|G1*u%p*0KW~qXW+k6(O8LkMsg(ztk{qu? z2TE9V63ZecC#ml*K#%Ykeel-BE7m+EKxI2H-`fd7TvmG9q==;#UHTO#ie2g+_3v9I z5rwaOMMx;lXFMz#$i>2;(7^rqmO&c!+>du>+iRuuxzmsW9|Cn)9s52E69eq&-yTkC zL)X~}UQQmoQk4iE$DiA^4_hJE2%w!)Hw-tQkrpwh$x zl6Km!faT1;Np#?gAF^wX$opSqi7!rB(8Y|)j23Ec?38#H8wvj~`YMC$-1Rr*hq0Sg z#yWPIxs7nG^;lD`!Um$I7lywfj-|X>6pw!loxTH3EYQ|O22~Bd=)L7df26D*YL`2K z+Ju1PEnXtDscoh(P8ob(NvFTJCr_A#a<&6Cv(!6<`)Ty|C2%)Yu0lfm`o~^rnfWA2qPYs1*SX)JA)*8xCo5yXb?#Cu1){5ykJ}m$4YTE2vV3 z6p+`fl^J00@830CUq12PbiSDLuhjg&=7|W5A$|N%gT87Bn| z?iBK8B1z?>*>KkM%m(<{;Wfh+)ZXAZPhs}ko4XOCn3?1i;QGX0Dp$chLoj8BPw)7J z5|&m`2B8Qh!jXG=U%fZ{XC`W?V@sFb?M@WU$WER!CPCZ@e>uAO#{6Ii;WJ|D!{gD^ zsc!VQZ?cS=UESl}*0=P@t*NMn`LQ+Zq;R7fV?K3cI?YMxPyzu7z;O|4QUGc`Hx?w8 zt;@*md3nZII51jAX4Fre7Pzc;$huo8ZgMp?0k;k`SVKK#+2ts=WG@R7kO%}$De&Dc z5=sr!lIFzRpdjdfJAQQqh5j*9y(wBc;pssQjC5&BZKh|g_N+s0HN*}4%dNE`G6k#^ z(x@IhFYTmVEPVvhh2HO(t=1R!wYdx`v?E~2Zh*ht>Zb)Q1M8N_jX%M;s_pzKriZR@ z3a7TUw@#0oCCtFtQDIUY-qECxRsYr(!n_<`WiVXgey(KzfE)*P;L!wZ+SWIw`BhS# zfXIkCv}47CGwTM$&v9+1va$8asl_NYk+S^f^E@U~VtEQ4Dnp1AnIi-0A<*zzT>Tp7Er;Ap(d zmWC=lLAZZ^TE5Mp9RHU%nC_K!;-w$v<|#|+HwAM(s2P2V2wX+}DR@I{1cr?z(doxD&2 z%;25)!wbbUc*Nnx-ueSJNOJIf{$g*yp@`&%vE(KLI;H3yrm;6*J7H(`mBckO+d*3^ zk|8E$H4z>{uk4$(#$05@ksDo_8{*d?s&~Eu_cQ+4gvRS_j6{ryX6fNPn#`RAzLBIp zV9zZfFe+w^`bmE6W_<&Gxun@2f3WshZYms7H7kJFC(;!XRH^qXFF$JkSX0-mtgbcsOmX#QtLb+LFeNhoy^swveUXH~u;|ph zcI6;ao~FJ?+LdLJ^gE zdKS5sE>YxU$AZx&*pyGf#wKSvV>oFK)tvL|GTo_p6?w2AjeWMAzdiQYg*^_#aaxRY zvv8?6Vz=9inm${XOpf}XJJM*6qxLH{yEuJdV=)G!#r^)I;szJ2j}Tpple>x0#mSvh zug!?wda@Ikxy?Roea?1w2>bOezqeZdMeJua8&Vps%nV4qUbn=cA<@R-Wp$bKr*cQe zUt3#isbpGLz05Pm>kgx9i1`ZHkAzFevRA!rG+ebh+FhXw5zwN$iY4mG|C8A-DrPNj z8+K?UAxb3lrp`JURoGuIuodCZs{d6fTCbXRgxS5MBc|iySH3 zsrEADgZ<>&&f2D`@iDg{p|<4Dp)J;el6c(6tD$oV4aV%Mr50tcYjh_ZRSX`j?7C{e z+e$TDqrlgy)Vv4Htiq=@{V+`qr|L#u3@?UB$?FoZFMY4!k4W8oLDfsDpox9PSj~1EBAPOYO}ghLA=$ z`HkS&RaevW6;0 z0RM%JW@B-%Ylp553n~oxf1Koq;$UPfVpCkMrmV64yO3Ek*rW6yu( zo~)7C)Id6~XN}bv-PP4A&A-U&GXX#-ue0MZMDM)bLECuq+WKT~Q?xFjF{qAk#UX8% zaidx4r{GkRxU?@NtQp0dRo#T}EET5uaA@Hca3}{|>`LJU1)_cQ;LA>LvJ$M$Hir9q zuQIy!P-~|)I6kkNN|UdlkL+$H&=>sIakDB)V}iCC`T5XD*p!2ncNP%p^{u0pHC`1& zvhDush%o|ZF==TVEo@O89N8w*qVFwz;t3Kp%tr#)3cUEmHpZQcxBfO5(IN?Q=WN(eoiEUulb-N(r@|M77nJ5X<0tbX>WCB8-OOrNi z@F2kC2fd^EZHUYXD)#MVXGUfqH96PABUK&MQ1E7u3|A0|}{0}O`L#bHnKqUQEn z1WRpCd|*!)^XjQI1)d{%ORAd0`elcVt#$+&wi6L;1#WJqcKC=kU%@64;++hMY`7_j zv9v)NE@38Mk){-nslo2L{d00aBq2@=*yy2~ae!NjlWXHTp=I;0J{7KIxPttSKq<|4 ztT|Td0ng$=Ktejf#APT&e|<$zUt*TtK;_imbJV)!CO`?I--tsnv!xLu5eA$-9|EoC zd+tu}kg3IE|GHtR0cG^sc$b+VU`8INVKuc?chk9cOS4~ZCFYJE6I#J)Lqh=hFGYOn zP=*AkWl&M65*;}W*RY@W9VpDM!a731CF;5lj|xN@y&${0G;uy{<&v3(8?a0xt&6?C)w^H-wk)RpF zlNkv7GT7q)4eKZf(2M@Y@c_#gC#Hh?OW(jTQ!H@uf4%VRvjN!fsRs!*uTy5Nq71b%|2CBg%xztQs~`4lz35{wT;_ zhsgC9_-cvbnXP08PMz-ZGo38vyHbfE`$ z$Q-#~`C@6>;8%i0WzS{^mrfEpr%R_TWyDsQIFyB^^9FuMq%Sz`nQ@^*1NYaq9-5}@YmWHVqeXis_ z7q{{~3}#1b>uwf{@};H;An|5#$b2IrNF(lP0vyhj>Of6e32Fr*x~?X)xJNoKYAo3K zC(|8vXMb}X1>GZTUyaEy5eV9y?5*6>`={K-bll+3OSglciqr!ptJ@$@V#0l#*=e0E zhj)li4wpZ{*g&A^pTmkqqqfOg<_0IXpWk|3#t8y_ZI$-_P(?Ti38fwQXOTR(tiV9s zqvHqLAwm0tvt}4(Nabgv3C-fhUDe$%s#5=~B`c@YUfXO_(0+tR6A+0{R8d3P?FMWS z>keLh;|{jOH5>um>->TZgi*}hF;6A>t^-T0DqBMo2sr1wcTiwdWSf72FJAX;WFEhM zde#v5*(Q57CU{1=plvf0Csxcf^B!YVWlr3K8m5FM8*t|dflOYOrWb`#4^tW z=FM`Hm4o%%#s?RO`P*J0pmZqY{ncvzNc}w#|8O)=JvFZ^xqRp~w|vYo9XEXt=&`EA z9JfuX$9VbWxt(H8dGGZAeB+x3kdR;glkyWbfjRwOxj@Ja?MzKFwXgkR)v55G{d22f z%$aUp7kSvR_6(=yQst2KE6`6tgF&w4-_7s|Ez3TfRxF?){-ir`NTr3|nBFtmp^a}E zAXD;po1&jr+AQ;}o0)yD50LK%B-rU<&@*`6nD7A6u*8@vIhn$0ri zAC<&IC@U?MwROL93Y48MG8^d?#!NBQsGxRfd%4v0soS>i{!z01M!q;^U@nr|0s;*Q zOy7xHc-c7YC*&x2WnuL>GwE}W@VBF%ZTTmDZUtiszC{6v6b~297wOZ|Rn0bSePM}( za>8i7ZC=@?W(Tb;_+ao87fJ_|>fz%&+70Aj#LlXv`Tt(*h%^@V^tRKSJ=6IfW*X1~ zdy_4?Ke=7+)C~TuVKe0wg|>_S-=)RZ)HuCGo4(C)^G6m|vRJ_QvK)x}kP{z)91D4a zkNO`}#peW{Lh5At$GA==AGZgASTxwuhoroP>T*P%mVYEu+01L!6pC*QWD5(&_y}KilM%-S@Y=*z$U(4^Rg= z4<}P=KXTKxQEBF5L(t{B*iI(-mQi2lj)jX(W)0)qMY?G<)ERFD$6HBJUFv~ zPH&A7`Ggc*((8thp_75P>if>y9p+<1>frdU<7pop3%I_Tod*HryvWU%3OfCYt!{WW z@5qc&n*)L52_Z$?hnxgR9mpraOH$-9O?Ic!ZJHYzwl7af-!YL;yu%$1>`y@MU|KSL z1rkEK?1Lv&pBA_EdKVA)?P7p4P3EWk51)bu1BgvW0M}cOElqYyoW+XXsmy1#Qwqk) zLloKr4|ll3zMS$ZUGs%3?*z@PYPR`-P2s6iO2Cc?>a(B`|A0O9mia0C1Cz7aA9yk2 zdN{Gk(RA%=gOVXGG0MZ6*I*zTd}nRm!L>JcyI{B3pj%=`uO_}Yt1oBv>+n!#X(B)kcRe(tBR4HNl;u13KO#@oU7PxuGa9XaR`#0_}F-zmIKY z6PA@@A&b@1GxmQ({49K<2)h_I%Sn9OSj|na@51&>qjc+7=*{CT^x0IpM=T-EwkImx znUU4rJ>EDlmI~w}PAhs|LS&8^xr8IgX`4%i*i`?v0;=+Zf^#UPW$XxpVO9SlCV{&5 zab3x`tD>i9VWi7J>3a-jnRug;&pFelmCK5#B`2Go&n4%d?=<$ydbA?BVds*s^`1r1 z${@qfPnlrpKPx4d@0zAy`x#v1T`dd%)FC~99T@vzgnf+`J0sR^27xc?L2*keGT^# z5y%ttN@3yUBO{|s!Y@ZkI9t92O=96(3t%93&^{svV?v_@!xkBq)e{MzX*>^I-Xkb$v zPZh_+ImOWeRtGM@CyT2BR=hW>8dJu4>z%_7&eja_e5>?@9~Dfxe=}{RWr+SXXf^QQ zDbGzUZQQ1Eofz1aOtr#C*KIWB8?(qh!fhWyGT^;E?EJmh6-r4#xH0OBD|8+~8?pO5 z!NhGNl>o7yx&-9i2sSC--vkwMxpspnS!k)!it_Yep(!~=L4@L({-&&M_l^+`TB7#qjf+gmaz$xdeo+YsFz(>2Dl4)t(G3t#L4=Fk zN$OvKGlHq?4TD50=3gT>AnZ`%aKj_(bfAjy_AW)61--od*gw<4d0Q zzRHjUaTs)-cWl$p*I~7|G%7`)xlr3|DsXd~SU3Bz#%MXkdGC?-yZB;G&7vx-Q|XHL z&2LqK%7htnb`(Iq%mwdn$G*Y_R(3)q!U8u=!;kSP3yDNx;~vS3ud}|uT7jL@2z_IP zo-Z8LGtL^b=}bVc!ft<=T|e~^$Es5^o+Z!)EhB%@WQ#L)DQ-eu;kHUXCeoZ0#Na4W zHxiDjE5WM_)~{2?f3#=x$s-1fh;rtk`Tr~qe4*I}ayKfiLa**;6n051r+;>}T*h45 zxCM3M@gZj0zoJd$RNRs4fh@}K1lZ2Z9#NJym5 zYtJaVaJdC_SPo1=m%rWAA>iCYNN%H!h_0{ONBhYBosv%{7{hVDTT@J6TTPY2OI~|- zPBO(e`(X$WJxDs*2fkCOrL6g@+Ms+*qaJ-GIGh8r3IFvZjrSke_JJR=x>?+Jm*o@y z)d#m;0|Y;Y8cosA*9wuGpY^XkFlht`L`3*JtH?H+!Is0f42Rv66)*trcT+JMx`F8U z;HI$#e@F{8s0YA&{o&cOgVmy2r>5$f*^dG2s~!}uq05T>E`6%v50pB!jRhLuJ|%Ha z`+Qwz%**s`B5*!bn6}1)IiRodLDGYUxBm<|Br|WuL{}{o>GSaJpQ#1^IYrv4XRHFG zjv*b$V8ekrFXuMWYgD&~?z>6GFLeEI$X9+0bTiV_T>NRrP(e7PCcx2%-FV@a?U@LG zurIKB&op$sKn}u}&KcJ5&hIR`p9VO2PSgR|*`y;Z;)wYrmYHppfESQmITR+9+KYQ? z$G;0afPB}QA^-Uij@{ex;yskV1q^c*46;rRLWtu}YnUxWfTUR3laI`QY5g}q>o9=U zD}nUi$I4y?1@bTZluE`1&F&B%Xzhu(-Ih-WyoAf>`*)omoXOm`{(Wi}$glk=_!rkN z6T|<(b#SjCt9(SCYBRy!l-p|$%9cq)^}r`v`7z2{^=_F?AC>x_&a;6GeTD}ArS*YB zTIX^1IvxpycB3U~muAZ#xhFGx|97S+6UfUc-cYok#oS`M|Lpzw*rB!Zb&t$>bzxMlGWgFQ3EOXpzfL^7_IBk8_b!v{ z9UySh=Th{f=*eGF{|!#eoZIoa#?~IaxgFS6UMx|YQhojH>7$^&r6RQ=HQ`l!+p4Bm zk0FL#+>h5)vYGeHSMbE>Us4YPfjUK!<^&q=B7&8DLRupOJO_N^>CacWf|6gBfyXtH zgQF121HHW~yob(#18_IgKZKrhNa)anY|hC4B6O)Xdc~)&+{;WLWHc&KJLmNDC9X_W z0S<53_gzdap1OmRvsZmMK=*>REkv)_sIaT7j*uf~Ck)GFq>h3_&gB99kS~Gf^*-4& zVPm^EhLt|_>S7i1!-eNN7hhv-?{AIkJq9wI1&Y^JS@JMgp@sO0=Rgrdf3I42_MM^IG}mLSgEn6YeZwQ5^3x{6G&Tq=O}e?C+0P9T89v{6XJ?j6j(ll_@LFxg$3Tc$DWVL=!EGAIXOn24YU z9R>$pGjDFq*uEuwH^u+@?tc02<)nlMdR^=PYX1)ACz5Z=>vkSyWC9^EWIUbeJtCqt ze0+J;I6nH(KT1+j^>Mww^VS=)1Wa6~C~P#4^UC=T?swpM{yz{t4L)q?8KBtn9xC=< zrY;8z$aDpZQ`>~&TaV!R_k*%kG_^s1bisS3%vGs zGj(!e_;-(aAB=7Ue|7d`i*i}MiLt|ZsQw}{I6XI&sj{vk#WRv6a)&IQKOQGZ*{Us` zNlPc((hM4hO*p#hW)h@@-qr11YA)aLp9$c8;z~31oDw=gg;^6eR?RREuq#221sj{H zhG_v4(B|77&E%Ozv?Ie-2*Ox<^8yhFd;{fKkZ;wywSUy5-KKhd3@_wYYP+fMs9R~v z=2lQE*No8k(8)u^B-!C<&UCMkXrIXlV zASVaN=Tz8n)RMP*IwB&lI{5N_ zR3Dj@K0&xBEPp)u&hS_i`|)-aoUIV2@4y|;8VUC3yL*~%lk;r-$W)hQ!L~WmZUpHl zDOG`X%Tw+q+i>m=c_Hvpqysa(|98P8Pj}s~u*V48cC6UFC==GrMIOY|kd}&YOiK)l zc9xvPZQnod7Rh*d5AJV+I&%%xEArcOAHZ(t^6o8pub*%9pNj4wC$?A&1lf|*Ek~i9T0f_T-V~6n>6vwy3t7PH+lRl4pc-Hyu>uOesw~HV~Y9 zV^7OsCmb0nM?g6Z!6SKc$H)~}^+6U5s2%ormk=xxCKYv4Sl-bw1M6KG^=4+TfOlpG zoht#~xG^ipNGpaPa}zaG6#bE<)rt2*W!6ekAQ_%|ey?@&4_v^_`yF%_LoKdG= z_E6vP+Og`7=|`+ygFWL+F4jLM$~1RuTF3du#|5?bRzHc+iF!Ef{WsWz+zfv+_W>jF zn04qt`#jv(>;7Q0<$%hMH_yJ^g?fZ{tu*LdBduV*Az9lCPJ3F_Nm_x6SpMS9Gcvn=# zX>6VK$cWQK_r*4jMiP`qQ=GMRhnVME5rfbXp#-(R4W?%M!eNv11og-?8XX?v4 zNp72~bv3|Yiz4%(fuYYePDCZi=nER{VG09G0fD|T_Hg#Gb>S-?7O6CiuId$>*Ef#u zSzNzi`L!^f!LAXJQ+hYv9pePNR>4Q(QVC0UmNeT1;K9{xTG*sc@w|&te1DBiq-#_E zk_@rHFwbP1VW?+u-K5sd`tKK$sBvZNxku}aw|vZ$&)8Cu^dd&jCy?ppDviXNVsr0dOao zMGr1jKbyM#5S7{SkR>+sPzpM5*v>eweqSFhfhRk-H-p8OsgB%yk)4hCnX zt!5kh;JaqG*f(=@^%lB1eJa0Xq#+=}#l`hw5jTJ-|4)C0*89p&zeYtpS-bZRDh7wSa9zs%DLXegonn93m1SAz1kd|&xQltiul5`NHQ@R|a zyF2zhy4L%>-#+%geH<__&pdI*73X)Zd?IJ z%5$Gg;oyk1%gab=dW^59k!WhZoW5-Ajk-b<<~-b%o6HD%q#i#I|obzZQ~2Mu)Or6_?sB*QKL% zGhIBanS90h+tGr;*44AwEfo?FBH$@ zSOnzZ6xEarVvaLwE3sezuaUQ~FSsy52p*iG34H_mf&&f29x*}ugMGn)G=n48P~2Cr zFOK36n;!1f3n4sHtR*q?7f^xf1w*}Fn?G{-5Jrq zXY@@#&Y38rXXQJ=-uh4RZZdxONnpE!VDhns9DKkNTAR#%OZ|lgFOwc6c2cMaB-dFW zM_o*sXq$P&(5bE*qt4SELoN%VAR*j!)sd0Cq#yA|E-zO|rebZ?kEIV?IDV2ny!6_m z&vpBBmZx9SVeI2QC|Io99xdq15wrFw;-1KfI?ug|SF?r-Rj+-vKW-O>Xn%mli?{iR zTqRR4&z!O6+vSVltNM9oNY{Jj!T%bFJg3>i?xbzf4oB7~KG-do(n*R(o9aB-@d>)a z2R3)##plZ0kD7GbJ;?b|jKlz#ZES~}-u`^-YYnu`qmTJu!gIzA?+08I+MhH|SuU_z z(k}UB-#EE{`ujSQh0+%u?4Fu*)8Y%;GOw#MJr(+J;G*sITCCC_n<{usDYzPm+}Y6U zF@FJ53Xl0k*qEF^6E`#a4SN2Vj?Zq*`ZxX)b_!pwWom=BxiH&DyF&V-KEALMr{Y_} zcRu_x_A@M4`;YMyS|JFcxoCoeI1n`w7-9NsNZt!X1KsQ1!u-iFq&y;4g&<3Qb-ygj zd5qr0#qu+n4>oDkqpS6_fPCf$zrA&<4ErCm(=Oi{Qf(#MjgKxTp&WC-9YM0CmM8y2 zw^RSnc=}QG7v}YL!wf2X@84qi77pO4ia>fdj#fUuIoFUo9+nHoax}!@IL`rr= zBeJl@79QzzSx6t263)-QZ_3aAJTndf+zHR-;OR58$hPa`ue>$c-MPUX|11ObtrA9> zd$Dg*zA~z|HRS1h+wprf>u2%5*Fg!*(k=7XJJ;EgNe+6Jj1Yg_RTg^`*zsR?Wx)C@ z@Mi3h|J%PGQD;$2>5?otRDSn^H8bHu@D6`V%=gXM1~)SP8#uD051Ab(`nLNq1*aMI zwvoW&75S9Eh7$B#dG=9ywwH9O<>{0od8G`9VtHnkmMlU-x&=d~YS^fD{U$m24+?e` zmZnT>Y&($6Q7?TcDk?fYK8|_}g4pZxrHze)gM$~BijN;RZEbNwAt3aiuIm*Eh>E68 zg{kL%kH*DbXmYqQr4%+kt_QmdW@4iM)4C!kDCiT?$H(XN^tALH_Fm1f$%%>3C;x!S z+J@%S1}7&|{XN^|i=G`AS5FTv7*bIG)YSU?ytzkCvTW8j(?54_-YO0s9@d84#NOM% z)YR1RIxiT9BZaiIv>8IQ`#M<7NA{2xqk$j@V#D^IWd+aq`vU^;OA7Yx~4`* zOw8wZYj_Yb4QZO$00B0xE6t#vJbB`ExM5iSLRmo}Wa&YSHV)V)lN0EIJf$?n`pSy1 z-$h;0pOZ)X(0r+}vHxH<4(A8Fy1aaMvc~04Y<3Jo=BeRgpY&(9s{@d|sY1I!5@)#B z9mWx;+N!jhAe@nt%lewq+Y|if8BNJG+}J%pq1bmMMqVcSPPrR1*oRP$xMp1jV1v7D z`+kY5Uw&T&o%FjOW293fc3=I%(O5GQFqsoEl%v!Xd9{~@{Bvs4e6I;S)Ze!tH<9=` z1RF13@A7jO=4|&;V+Z)A;#iS!&)O=?`}*G`f_*Nq#sBigpA`geu;-@TEYhxZS?qZd z3PlD4{2Urm)@!sUgnLkJ7gQNafl>z6-xfDLMA* zrFF$Dn&~S0osiX$5_ebEqoX4Vu}{%xOh76WBf1P-qnG2A8%zU;#W&XI}Y;=u@eiP z>S@2dj0z=UY4@6IUoEO5gEksh=e`wb{vrOqGea4_g;Wemu|Q z?M=4)vrrOaL9LoBo`ep+ul&gin1aZehx{C{wXRnIHjV;xffankd|lqJ3WlszRaFst z--BwATA#B0hg+x99b*w88aZ?ozyIapKn*Z$kEIpccj+A?#@(n8>U1$ z7sPsXdVewy zExyJe8r_pBSA8ub=W$7VE3zz!YZF4w*_FgAM^RK*820WRw}ku;3SuD<9j|-)rSqZT z3U?5aXcn4%4S!bnk&=An`%;2@PNJ=sgzT;(3o*C5`7Gfzd*Ru!6hg+w&`6Or)K9@xy|7WxKn50V%zHraqG{bCc*!#Nnri-NrI=GFFXLO;7f{f!h>zYvk5gX^5 zQ8%)L^fQk{N2DMS8ps2=oexRZp0p^$nTJA^QdJdUw$^&^(WG5~wxH?I?d@${U0uEp z{g!9v=g9IOv1WXNg4D#1Ceh=)TE374olQR^-T8s*Et>wBhknz`St3Vjq@Vi8OoEXy zg2l5C`B?A9H~HB6?@C*(1-r+g@2acVwW3L`Pcn3+=UX8V7Cj&*z&-T(qI91u^q8T+v!P;A;O&;rEJ6{Crl3 zMtUv%(gljKEQds)B%fr9Oop0|arj^-6&O?Kf?53;W}<$Pwo{%@qlVtE6D{JiG}z(8 znwyJ67RAU>ED#@b{u#qHLSo{Gu&_rS>-ygHTfg$I16PA&Wf|YCKav0FnA?f|Whk$K zf05?)Hkmhw)hXR*2F;g;M0PLU3aoj1zJpycH@7vfkw8Rih)7~ux^9$Q6NoG@(YPZM zhq9p!=0IeTiiU=UvvXNc&~;uSt(%?!Sad6rhTP`M7;9^4dJLS((b4ho+5%Sc1})DKR#P5Lw!%l=XIb$X}^^+5NV267}MDtZAO3TUszZe zz%_XBA{R-`4YL)m6r+~Jg-qa)E(H=%(=#x5d3ogt9&b$5GLp*c=~3;NT72O?rxCS8 zUSqD@mE^JMEtQM>$Ib(T!AQA}m6>;b{rVMb=qNs{i@Cg^p@ET+kynYXt%a49^{1w; zE~UW=3nZh%L>>bZ2rw7@b}~)FrE1)rZ2UYwvRt`yEQpIz-=o(5WxbG5&5~|BDjG5b zSr|`+52DhjTWmLFH&)f>*3PE4$1KNMDx~Lg@RHr(L@zqyOf^?e;QoRo)o)>oq^AkmzrBhIGstKob={M;56=Ugs{5zIJs4TREC zQ7I@X@wpHSF)_6!d4^cLL5>s>Dot0f{EQ+jL-mSsO`~}|v5!~yCQ#q@v92yP+H_Cl zQMR1v9*cW?82ys{!H=om(Bjcdx?&~7{lgIbL>^sL68mxai91ECUk0N(7pBpHkxQMw zbx>)md*zZB^AJ|2+(~byODmn`30z#4UJH@gsB|6`0kkDw+ zK;_2F;$ludK35M93ZsfVq)X;$vntrC?9Emk&<huZgIT!nTTd|kKEDKOaGix?L9giNTtN1Xg7 z>eHXq{V049og$ik$Nn~CwKbiDjDmvYvq?v+zP^5%)w;+y`i%D%vOjwtV}?l*KO=;? zJ*DrG#((PJ;bCXT@za_P67#Dq@rh~jbIiKqMn8Uxl738NM z&$U#}a`DuG{P5ykbKErW^OIm~Q8_D+5Gf|lojY7%Mh^QpQo+{RBJ^rsN;jilptB!?&BzG3jiQtj!}cUuZqcOl);*5xy3x(C!Vj<{HG zgfcw$+FMdncuMn9m6;JuOG^vjDDh02{5JyR?8*Kr4GoRBxcFjE8n0G4aQ`n~V*M1; z6>>7wR(pcm_3^iq_~8^7Q)up-4qM!`=W3Cpq$F`FQH_E9X0|#ZkAtEjL?Sgg+4^F8 zmxzd{p!HKpN!5m}tDD=&$;q{A*P>^_{Zg?Zh4Z733;eXE!?8(^h`=fL!D;>aHVVbb z$cSuoT&$e1cll-5Qd3hiHZ~S9g)T9wSLj5zy2jEKefsn+B!oxncxS$Id3m|Cw6wp! z|G_G|PBGj@0K`V3%_Dl6&FOkC?;#MbQHD|;G-VjCsG@;;bR$2n$BVO^ul#nOoI)EK z8V0&UuU@|{vhqTpLXU=uYGsrob>Z9KpazAQ)9gPqjESEor>Cb!Mt&SV?ZXMzGpA+Q z&6(%kzPQ50Rg##P*xD+)z8UjD2R@n(&24;}L7V#Ot?artO0cG0^tu@7*I*HE5QU`| zWU~4_yu3szZH~}Lh|5CPEm?MUb_RO-F4cjDfn>cz9rMn-RTBdxQVuUg_Xr@WTq-o} zPxa_%YlR>DK4uQkq0Et}`g%-WlG7^IVAbu6;qMBBPB-ZG@As!jz3Pv!xIJ8y{jC1N zKVRU94Z-@PCFk^MhwRDMSc>E0m3k?krOqDqSizQdgf%H*C(z z$}&S>l551g4s56E#?pD;r>5Gtg7@l;e@zjjSH+rmV^ zmFRGP|LWDNNF?(3_}JXc?8ZE>th0SmbQ7T$ZCf2bKfjfg6;D!_FEIlHgWuV2y3?bh zMDJ{bQM&JJ=sXyjQxOqVAS{(b?eKVt^89E30CvdcUcN-E{odEpjd5@FY*xq!?NcAy zV^hWPJ4NkP(sZn7{{ZxJq2O3@2o$=I{Rb4*gz6{CJoai>BHsLD|K`mb+>?VbR6fZc zCgq)4>Cu+qeQN%ajltT7{X7(IJ4Z$S z`r4?iOIfd1#LMa)1Y5JGPy#44;=Db2PC)}||LE+qD~2Zi3kaxv#9CX8a;7ZXAU4}u zBc?{<(6=*=5~8DLKM{p_%k2JEs3oLP=i}!m1I)XnMgBqb>(@9r>hi2x*<9{ROH03I zh@aR5yPw( z9SqI2I)`?ZOkajX7-UBO~X-0U8^4M*AeSz#YV#_ zV*NssP0Q3YvwV{&w)gXpb%)Wsvk*t`)|TTAt9kWcH8dre-aMtwZA-SXxKaM_WmdEF z>ETQQ*?KaO3;HTY40Z8oxrg6m-ZClKqifhUGlZP~7HO?EV`h`ttaSuQPT}_5F(z5n;WnD@U_?zMiYF95+s6hDO zvo$kK$+f0R@2dp>wJ+|?;?pGp0s>1ediO^M^;{o6el+7`=5YW39w1KJuz-MnqN7d| zbzWbXb8&Hv`<|Vhf#`>6*R{t4BNE@t3Xu-3PSW)GjPUM`)-zO`_WGd|GzKFQiB|c} z7mEgyiBvlKR5kVWsn1RE7jke(OYu$}Uq~N9IId&hY&<-q>8`>MKa}9ul05`Ix+6YC zYN&(9F)v-EcGb4s0wwRZ)n`kI})-Zaq68wuZx%&tzp<@w)i!j{W6AeYpYnWib zlE7~M%EqR!avo99yLay@5xBjvcny>ppqZyd_w=ZgaTn(SiR22@Z4xRfLQ6;l7(x~_2#eg+vAs5&0koYryl+02dW8FuGiBsI-Os05bHLT9=)(=U7cik;U(xy zhDGm2KA5T}FdGh?Bcn5AsEUtw-7cm%0d5{rihQE~7JDn;BH~7{IisG&?9K^MU9^JR z*%R%I9{-JnyB#A~IPS~#mWtl^MQ8ie+8gOB)$nE2Acc*AmY{99`QM) zkn>V|kpX7iMYogloXqxt?l&~aREr8r&6{s;l`5M?|IFOp64RN$m6wTHgTo-DBW*sEV1bi!`siKT zm=JbE?&Xev1sWUE%`iyf@rBIegZ+WFE~&XyIMy{MkQ9Zmr^1suPN&nH!4lN&KfOuw z+(iBgoT4`hC!+MP;I@W9ROn4jPTD>KC8ISr=*HR_jExOl8*gWgv74x*Y#D4| zh5G`l!-2XnKt_g!p2*62dU$MY2EKl0mxdKKo6)IAkbpx%L-FwNwtGOC1_wS`-0wFl zl%u}9zTU0$Oj|o}odj!}l?YBH?m<8k`1trtZew*tQ8LbW>5_PTc)<|c9RgnZgPk2~ z8=GeB8$cNxHEmD_pUK(?aG*fk1euDLK3&jZ`e1#6nwlC2yrn`|0Wv*oGw5YwY!eFF zlAv|Qv%0(-)ozvwl;bTfWq~48d}=)=xB8#qiG-mE8hlEC<@=x`XwXn z`?Uv7Y_fvFz8qA+qrJVVTU_Qp0Dw3@KM(ATD_h9T&7GZ{t*(9)EF-l~hRp=NAl!1= zyal88=GCEcU3oNBg7-3xC%`E+cC}~0MHf^+Zy`%Ho;n~G{pr4on2i( z$~f5C`p^h$4)Tn*5%}R3SsqcJy9Md$v03d}l0w%oyw2KxC;E z(4|M?E-ri(LRk4D-o4v8I3Ok>>hA0WWF?ai+yZE@Zsr~yi9Dudj#5(owqbK~bN>EU z4r`XsG%%&>(*K7@FqX76r|g*^esQzVaI&*c)O%GKa01Ar#d0T>NB=l8l=>Wqo(41S zUemVk>U3x`7+ugDF65=6Y`Wv)`kslVO($r2#MV0wnUm*s7L7yKV_-arfGZb}CJ|Xwx2t;s%UohF&k+?qo zy}ZmCmj1}eKf+c?s}hs4_mq>nka0V2ApbzI30+Qn>VAcQ+z_T;+11&pSS?Tkr1;!| z)#O+#oGhKxn`lNt$QQbj7{au*wPj^w5;MLtISibxmLTAY&*$h+D3{-(DvvRl5QP|X zo+O~O85kI-sonDFe>U}EX=tGO*^8oeEN6mEPEB=3Zj6;%>@IW@k8)nB z%r7ckuUv2etPO-6g&cLx1oFDNE1ngN$Y7v&7Z$=U!U`H2C1!BVj}An=>f}j4?wJZ0 z8^C8#c+Ru8auYJxK?E=g1d=5k6Bb6;(6_bz>cAt079^rt{PLXJH=*gu&;?46y(lT2 zMsx9j%iE)Em;VVsT4W$;2(hP;lxKp|0zsaDkJ=@XrM>=F(6^6xD}tLgj81M=Dk%H1 zvvrHp1T$uZ>F0{D?zubcTReNYgA8m2BEH0$J;u1c>ts4@`~j&$ZqJu5J0P>IJ;wwF z2LAf>3)FVtqtTW^4T`g?^+p$4`3#hNA1-v6j5!G}SJo3weGfUYRhNm@*jQm3j=~}9 z^73*qQPHDA!#iz^aJ<1}Y`AEJ;%L)e<$sKFhvPEu{>kDhO+ z>(#mr?9Ec*%kKz@G`iR6fy`MJ3Is79&E)TKcNNXjX<=-M1@d&;FO!XbuRIX9E@PGc zAK@%TrY*mb!&KL%CVx7#u^j|_N}u1LN;x)GV>`x^Mc$~cZkrbhNgG6OZhB5%(zYkZ zyj>EE zm8Y_$mP|uHEv|yQ-Tl0|5Tm8??lc3VkZyn`8?bb`vb$}XaIkDMu%*r_QWFPhJT^c^ z7!+^i^%sh#`RqqD^h7@aB24jjO^rb4#TKJ>RXBByER^dfc`?3OdqH)68=5c91Z2Ii z2B*(Z?R-r@pOpv|!hzNVj#_f{zOp@@HRKZ4^wz$vi_gNVb5|Qats_9o zKc&hh9C3Y~z9fk210`p@Xq5dt*sqon#y+_Om5sN^HzIn~tIC{7Lw9Mp?w9t|o1X>1 z&j>1ArmB(cjb~eKR~3B>vc2A{q&`y_i0yxnC09fF;l|gLbEhg_Hnuxmo%*AiHi0vb zawv`%4ms@>q~>z$%ktXVJ~n!unr9i^;1wgy9tZV^V}$dbL9c$Ge#BPRU+VY`-9&>; zrnLID2AMag=)~gNax(l8SQw!gQ*Do{27$a(;x~UJuX3k$Qw3TdyBZ5$YMw9WBTLdr z3~4}Cq4I|b8^NkX1P3Q++C@c0fh^I6EHcILGLD@&uD{WI0)M~NUz#doO$5ERVTlRU zN!p7@QD}R65xuQeW~P3`$6@=K6%l=KSLGYS<|;ePs7+Z)QofX%Oc{-x)nFy}41=11 z!5Sz*ewNEbp&Z9c<^z%4@al_aUoXW-FG}gvRj$zA3b<_;u$o}T`>>&II-@L~R&AJ_T%xkv56 zu3%vw6US{mp5lb7)R{C324^ot(2t7K2dAn9>X8Hxywm=fnMP1q26VH=fHS5&V1)Gc z)YOz)dQw>#PqW1ZNE*rP$%4t!dERn7j(VWsL!zUzQ@P#)ec_O{w6?~#PoD`OYatAj zvdJHCa47%u1R3}sgECz9`N~Tf0GHsp0ETcrb#z31+HdP2PRamGzW-Q_E$;6J?+|jR z`w^aaPu$!pm(Kc1u4+R;A-DjMOE-Lxx8MOVpK|v=QxlFhB{-}IJOH*L0$7$@{mtnv z5+H2i{rw>7{rh_>wE#yvvW{=NAPtsrEheTB4$!&=FpV%F2?>`$_13|J!^{^e4SV}y zpmv(YsP~UKns4;=-RzbJVxgqu8})qeopxr2+V#rov>rG*L}1ISZ)Dei@zxlq;PvdJ zNKy)S^Lhq>Dv*KXH!#iM;9#oo*5DWV1w-mab+%(=0E-pMfR(Vwsj3p>=5_?#2NA-T z0@6FXyE*DsIy&Uqj9?bK{o~^+i;Fs%nsYxdkqSA{Pajn0Q8uBQ+Mg8+Jt+D7nT`C& z7*wJS7W_b)fg|K8Jewmrq4P`*D7UdAK(l{758(QvANRfW^;1I6je*bxDhoi}g13OB zE>8e@eqY}+xv3~y8z31hH)^oOsd$#%0uP9zq@@KBDynn7*e84)oFpS7V`lbXV;Pj$ z6Q5Y}QIW<-eRRAo*ngS${{1heOBfifOLmZJs!A|QUpH7LEM*mt(7T{Ut7>9m0*EZN zTO3%ud% zCI8i-zuHX*@W%ZQ`{DqwwbQ4AsZNP&rqxtW#oS9u^)Ev6J=xSqvW@ zk7L(CeF7oPd(^awi=BOUch{x1f0HO% zzLqUb#a;;asZv!`jA=Im`vI?%-Kw8kP}MZ5c0}}~3ZX55*eN3uaQs4~wP_ZKd{b`P zGL=3T9Ubj2w~_oYFOT`rqel-P_Q$?k{t%!Yvjc3np-n`j2IQaGn;)$?`h&hk0kr6HQDlkYPXBQVIJ2eEib6qO6zC;j0r8wS>)jcg$&?1|bmCgWilpo)z2;XSp3Ais^R> zpRp7hH%|BWV}Ad3*_ag4;4dgBP*hYru3F63WTQ$ut{O=VLU0hd-fTu!=9Ds1f@?Vm z<8__dV_xa&=^bHy{?y!c$g;Gwg!9Y#_|$7P)RT&#p+DR`JjAfbKOG6GIvo_$G&J*a z>}+hAnVCvj4c^Djo}QkzwzjUWeC;Pd_ma2ix|TlAzlG5<@MvY!*$bpKVxP$+$UkN-CxIxyJ$_YoVuZk(X- z#m=rMcyJ`>=jVrEh&ugE?I597<|0o|PW=7-(P%VKTzPnS0xS82ayLO0O@6#vb><9Z$2R&GVbBM5lOh%@>>iI1SMIKsAK>%crog74xa8jC{b2z@zov`;+(zE6a&=pg|v-px{Vz z^V^3D>+6O_M#NzDK+jl*`kG64Ef;O~>yVUZ3s&Q{yf|2pn|wUnJC>zdI&U)?nSnT6 zt%?4AcfpArV$?GC(00Tr-YEcCVsXD<>~^onJxM5*ECR)&$DZl_{cpk3#bykU5?{{q z3S-b=?nm}okvNwU-1TIlB3M_G zw((p{8X{4fWr?I0hdJ}|i}a&&^{|p494=~fdQ~4~>Am+xu6p{~{Ry8{!LCJ>%KdwS zN)0_lbK;qeM!WDm?RejJ^}7$5x9y%7TxHYs$aoGj0Q=g`bz7P(PPh}V$Ic8<@=E+r z{EpOx@|e!D&|ziVDyh+=i|F~Y^C<~J&*dVLd~`IOm^_kFPKB{fTPf}^t?s)jMYVJH z=kRt-6=<&WG+Hx;P!X-w;AMJorEx^!4BhtMC`ZlS3zsWazd6$ra1a+cX{koCW|KHu ztaO2j-~-K|*$uj~DZ0@iv|Ylqs*;jfOjJUG;Hhz?nFz!|%p;mE_s&r}x%+mrS^L($ zd`%opl}8U*Pn}wHEvFST(bl|NBgK4YdyyGNP+}z$eW)*YgeEuAQIoZ`L}>gGJ7Kn* zEJ5doc{Oi7aoFy=w5G@Xa6Bh@!>)UFuwB4J$f2Y$wfrMqyyvCDvsoqlGBJyb%QK8} zl2WUIzjFR7fig$8c1qvGGEMQz9MB-8EcT50PVP-M=7qaiQdA$Dc}kvfM#|rZXkhL} z>U;a4-jVQdSxxo*&)f~xN-U~8$`19%Xdt>OHSa9s8z|)xZSlQUm|HW{ebl*?*|Ue- zDz}i|cmS4Tq5%R`TW_y>NL9o*C%M3L%%1dqwAUH3LrveAMKTw+p;L+_PpXWYj1&HV z*Tt!csglO7h@af4Wp1kO{kRq5)GS^!*Mr_})^u5ww7*vyP|lsf5R;D&`p}Fm zK~)8`pvV#s-?(9EXZLcq++~5|%y+e|?$~|pk!P|5jU4fOE!QXS;=}dYh^oFV+***%q!Zm$q*EHHnTwom;?nwhT<5&Me@sjatFl|>{sxdh9=Aqm?2;c{ zMY1k!j(>+Cq)1tUJ(hp>1FPIYd5ihEapu*X7oXD2DlQFvPkkXFO$B_IOXzsA8Jnf){`s$Ata0{6 zIffYh(lrPC1lujY1@nvmq~mW8B*apXf1}Z#KcMse%3q1)zd(ljf1l#!BVL<&rT*(j zWP$KU9dJ!Ljq4uy;}U4A&d3mF`LsmC4M0#BEndz!1r87LBr$*DE<>p zgQ6kV(VDZubJd-$-@kXc?n;pPd@xPZ(o0d->o{cNjDM=_&=C)|M#v{10EI#U)C340=xItGTlRoZoLl66{3z)$ z{-7JDTU}324}cIYt+*I*x9gycqI4xmXRqaUw!~>~S6|=zd~yUx>j-mP0A8rf#7Ia; z)K-O7@@uhF!52u>r48VV6NcemzY1&ASm@{^NWZWGfGcx1CMhX+|0+NQ)QPM^Q=g5&rXginBiAGCMG5! zp;v%Iu*H1_Y@@txcp zs1etEj3*hKB!}*H6Hiv3$kvo)wm_;KJ7a8Rf$${Kr>DJ(m;3LK=I&K;l~@e>WR=f7;Fh4I7$bW~s^=c&;mPS6V?H6wiP22hUb zU0?!k;)UssQQC9PHPq7y5A7@^)r4W5laJ-7fkz_{2vAv}q@(!v)L$r2Jb-fthliQs6sFGNo0pQEMN1st z@84O3R=2lX+NdvGyBm62Z zK1cGoE4HSHwV?RxG)d#8NZkwjWve>)xG0AXPpKY9nBvUvW6mZfXahGqkfsZ5xh7xP zLXa|0o0GR^x-9?k@E9GGYK8>c8&HwY}`GC8k{*kE_NQj`&4ilwe@~Qg5_+w8U?zev4eJI7~r?SF<(5^(@P$#AHf6Te#5TsG2(PE zOMAY>y9|3(;(KJpIHBK7#3E2GC^0||O?zQ;du)dv=6edhUxi*Q)9n!F3~0@m`lihS zhd=OIC!e%5CEl%$yINwpL$Ton3br71eE%-PBnuK|Me*EAS%CK=^l4N@due?Xy!r8w z>?2Ow=+%?xAHQ2qbB#O|8#BZ8I!}ZIA5%B~%O_@ERBn?M2WSg7KG}X)$^;_>73C7Y zwvCJXf{#T;>yFo^gZ7%U6@3$UyNvL3%Cx9;TW|HCjdu5-#PD3M>~n3F><=`F2M?3A zk2zBsU!P`9Dillo3;s)q{t%;^H=C4xV=!t!69esbTBx>+`mzjtNM=DWmp8n}NUWG4xHO{y{u&92YdclQx!t=dNxPs+N4J4z)tX`HIsnKt?O_6r8kYVii z7Z09#^vs`FTlsycpD#YGnH1Q^@p42u(Op?*1K>Byc&XEBGxMA~FEz!$GQ`c$cQJb} zi47vcF|QG8J(edo`<=WOG>knYpKS>%U6TV&gX7neiu>3IJqfY!Bt~%mi38a@&$t)D3k-c7rwGzqtPfhAW5$~gj$r`Vw#t9 zso%F4BK}n4JWi5NHUA7a1KCCq?Iw9HO;`u=xfX%C=y^T!>s6vJ6a1t=D(j5rxP7*| zx~i|GHSanRvJQiNP5$I~aizFc`w?R&$>ht%hJ|mcHAUu`NQeZbYJ7&aGdidL)$UkC z)`?qN+u3*q{O?c*##aNxzFi^?+Mdsjv9C)#n9YfFVcrhl{53`AD8#cKu36?C-taq; zJ}-5`;W(L(%zRR_nlXb{TuY!X7M(i+v8fpE>QYii8E}%*{=fr8Phfq%HtppkqG+1? z+swAd8<5@_gX?!_*!rP7{b<*-?>ZiiSM@#U+zBEGSSNCd*jd6(YX$lZl!0(uf#e`j zh-Ha-xX-$->1|}|v6}W?Nob3BAtHi!pftvw-L2XP?#i#$qd#d|cfee~960_^cwP3o zQeb;Y5-_3H$h_OV8^1Wky_PvRZyC*P9!(_Mo!rIOso>ri2N~(Mej+h*)f`p^NdG>z zWrmLpL{0UuHSJ!_KV3Qhcbx(k7WVHq`2L6u*X&I&p);}1ue<0&{M>}D7LY-&5m#;j zHZb}P7B)O>OFp4J-q6!xUBP{Eak+Aj+~hXIPeS+%WD8WJE~&Av#=Pl7M+LPVyeM9# zT{m)5*7MIfw?Ul$5`|FZrORswqdZR--WN!SXHSCH#I)8FAh{u^kH}#55o(ZJe9uRk zIvU$<$~x^x%v+r9EPwc>Rh8Iyp|kyioS{G%4^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: diff --git a/docs/guide-es/structure-models.md b/docs/guide-es/structure-models.md index e80cf47..294bff9 100644 --- a/docs/guide-es/structure-models.md +++ b/docs/guide-es/structure-models.md @@ -1,4 +1,4 @@ -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 [Registros Activos](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. @@ -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. diff --git a/docs/guide-es/structure-modules.md b/docs/guide-es/structure-modules.md index 4501ec8..461c9a5 100644 --- a/docs/guide-es/structure-modules.md +++ b/docs/guide-es/structure-modules.md @@ -1,4 +1,4 @@ -Módulos +Módulos ======= Los módulos son unidades de software independientes que consisten en [modelos](structure-models.md), [vistas](structure-views.md), [controladores](structure-controllers.md), y otros componentes de apoyo. Los usuarios finales pueden acceder a los controladores de un módulo cuando éste está instalado en la [aplicación](structure-applications.md). Por éstas razones, los módulos a menudo se considerados como mini-aplicaciones. Los módulos difieren de las [aplicaciones](structure-applications.md) en que los módulos no pueden ser desplegados solos y tienen que residir dentro de aplicaciones. @@ -50,7 +50,7 @@ public function init() } ``` -donde el archivo de configuracion ‘config.php’ puede contaner el siguiente contenido, similar al de [configuraciones de aplicacion](structure-applications.md#application-configurations). +donde el archivo de configuración ‘config.php’ puede contener el siguiente contenido, similar al de [configuraciones de aplicación](structure-applications.md#application-configurations). ```php -Cuando se crean controladores en un modelo, una convención es poner las clases controlador debajo del sub espacio de nombres de ‘controllers’ del espacio de nombres de la clase módulo. Esto también significa que los archivos de la clase controlador deben ponerse en el directorio ‘controllers’ dentro del [[yii\base\Module::basePath|base path]] del módulo. Por ejemplo, para crear un controlador ‘post’ en el módulo ‘forum’ mostrado en la última subdivisión, se debe declarar la clase controlador de la siguiente manera: +Cuando se crean controladores en un modelo, una convención es poner las clases controlador debajo del sub-espacio de nombres de ‘controllers’ del espacio de nombres de la clase módulo. Esto también significa que los archivos de la clase controlador deben ponerse en el directorio ‘controllers’ dentro del [[yii\base\Module::basePath|base path]] del módulo. Por ejemplo, para crear un controlador ‘post’ en el módulo ‘forum’ mostrado en la última subdivisión, se debe declarar la clase controlador de la siguiente manera: ```php namespace app\modules\forum\controllers; @@ -79,13 +79,13 @@ class PostController extends Controller } ``` -Se puede personalizar el espacio de nombres de las clases controlador configurando la propiedad [[yii\base\Module::controllerNamespace]]. En el caso que alguno de los controladores esté fuera del espacio de nombres, se puede hacer acesible configurando la propiedad [[yii\base\Module::controllerMap]], similar a [como se hace en una aplicación](structure-applications.md#controller-map). +Se puede personalizar el espacio de nombres de las clases controlador configurando la propiedad [[yii\base\Module::controllerNamespace]]. En el caso que alguno de los controladores esté fuera del espacio de nombres, se puede hacer accesible configurando la propiedad [[yii\base\Module::controllerMap]], similar a [como se hace en una aplicación](structure-applications.md#controller-map). ### Vistas en Módulos -Las vistas en un módulo deben deben alojarse en el directorio ‘views’ dentro del módulo del [[yii\base\Module::basePath|base path]]. Las vistas interpretadas por un controlador en el módulo, deben alojarse en el directorio ‘views/ControllerID’, donde el ‘ControllerID’ hace referencia al [identificador del controlador](structure-controllers.md#routes). Por ejemplo, si la clase controlador es ‘PostController’, el directorio sería ‘views/post’ dentro del [[yii\base\Module::basePath|base path]] del módulo. +Las vistas en un módulo deben alojarse en el directorio ‘views’ dentro del módulo del [[yii\base\Module::basePath|base path]]. Las vistas renderizadas por un controlador en el módulo, deben alojarse en el directorio ‘views/ControllerID’, donde el ‘ControllerID’ hace referencia al [ID del controlador](structure-controllers.md#routes). Por ejemplo, si la clase controlador es ‘PostController’, el directorio sería ‘views/post’ dentro del [[yii\base\Module::basePath|base path]] del módulo. -Un modulo puede especificar un [layout](structure-views.md#layouts) que se aplica a las vistas interpretadas por los controladores del módulo. El layout debe alojarse en el directorio ‘views/layouts’ por defecto, y se puede configurar la propiedad [[yii\base\Module::layout]] para apuntar al nombre del layout. Si no se configura la propiedad ‘layout’, se usar el layout de la aplicación. +Un modulo puede especificar un [layout](structure-views.md#layouts) que se aplica a las vistas renderizadas por los controladores del módulo. El layout debe alojarse en el directorio ‘views/layouts’ por defecto, y se puede configurar la propiedad [[yii\base\Module::layout]] para apuntar al nombre del layout. Si no se configura la propiedad ‘layout’, se usar el layout de la aplicación. ## Uso de los Módulos @@ -102,35 +102,35 @@ Para usar un módulo en una aplicación, simplemente se tiene que configurar la ] ``` -La propiedad [[yii\base\Application::modules|modules]] contiene un array de configuraciones de módulo. Cada clave del array representa un *identificador de módulo* que identifica de forma única el módulo de entre todos los módulos de la aplicación, y el correspondiente valor del array es la [configuración](concept-configurations.md) para crear el módulo. +La propiedad [[yii\base\Application::modules|modules]] contiene un array de configuraciones de módulo. Cada clave del array representa un *ID de módulo* que identifica de forma única el módulo de entre todos los módulos de la aplicación, y el correspondiente valor del array es la [configuración](concept-configurations.md) para crear el módulo. ### Rutas -De Igual manera que el acceso a los controladores en una aplicacion, las [rutas](structure-controllers.md#routes) se utiliza para dirigirse a los controladores en un módulo. Una ruta para un controlador dentro de un módulo debe empezar con el identificador del módulo seguido por el identificador del controlador y el identificador de la acción. Por ejemplo, si una aplicación usa un módulo llamado ‘forum’, la ruta ‘forum/post/index’ representaría la acción ‘index’ del controlador ‘post’ en el módulo. Si la ruta sólo contiene el identificador del módulo, entonces la propiedad [[yii\base\Module::defaultRoute]] que por defecto es ‘default’, determinara que controlador/acción debe usarse. Esto significa que la ruta ‘forum’ representaría el controlador ‘default’ en el módulo ‘forum’. +De Igual manera que el acceso a los controladores en una aplicación, las [rutas](structure-controllers.md#routes) se utiliza para dirigirse a los controladores en un módulo. Una ruta para un controlador dentro de un módulo debe empezar con el ID del módulo seguido por el ID del controlador y el ID de la acción. Por ejemplo, si una aplicación usa un módulo llamado ‘forum’, la ruta ‘forum/post/index’ representaría la acción ‘index’ del controlador ‘post’ en el módulo. Si la ruta sólo contiene el ID del módulo, entonces la propiedad [[yii\base\Module::defaultRoute]] que por defecto es ‘default’, determinara que controlador/acción debe usarse. Esto significa que la ruta ‘forum’ representaría el controlador ‘default’ en el módulo ‘forum’. ### Acceder a los Módulos -Dentro de un módulo, se puede necesitar obtener la instancia de la [clase módulo](#module-classes) para poder acceder al identificador del módulo, componentes del módulo, etc. Se puede hacer usando la siguiente declaración: +Dentro de un módulo, se puede necesitar obtener la instancia de la [clase módulo](#module-classes) para poder acceder al ID del módulo, componentes del módulo, etc. Se puede hacer usando la siguiente declaración: ```php $module = MyModuleClass::getInstance(); ``` -donde ‘MyModuleClass’ hace referencia al nombre de la clase módulo en la que estemos interesados. El método ‘getInstance()’ devolverá la instancia actualmente solicitada de la clase módulo. Si no se solicita el módulo, el método devolverá nulo. Hay que tener en cuenta que si se crea una nueva instancia del módulo, esta será diferente a la creada por Yii en respuesta a la solicitud. +Dónde ‘MyModuleClass’ hace referencia al nombre de la clase módulo en la que estemos interesados. El método ‘getInstance()’ devolverá la instancia actualmente solicitada de la clase módulo. Si no se solicita el módulo, el método devolverá nulo. Hay que tener en cuenta que si se crea una nueva instancia del módulo, esta será diferente a la creada por Yii en respuesta a la solicitud. ->Info: Cuando se desarrolla un módulo, no se debe dar por sentado que el módulo usará un identificador fijo. Esto se debe a que un módulo puede asociarse a un identificador arbitrario cuando se usa en una aplicación o dentro de otro módulo. Para obtener el identificador del módulo, primero se debe usar el código del anterior ejemplo para obtener la instancia y luego el identificador mediante ‘$modeule->id’. +>Info: Cuando se desarrolla un módulo, no se debe dar por sentado que el módulo usará un ID fijo. Esto se debe a que un módulo puede asociarse a un ID arbitrario cuando se usa en una aplicación o dentro de otro módulo. Para obtener el ID del módulo, primero se debe usar el código del anterior ejemplo para obtener la instancia y luego el ID mediante ‘$modeule->id’. También se puede acceder a la instancia de un módulo usando las siguientes declaraciones: ```php -// obtiene el modulo hijo cuyo identificador es “forum” +// obtiene el modulo hijo cuyo ID es “forum” $module = \Yii::$app->getModule('forum'); // obtiene el módulo al que pertenece la petición actual $module = \Yii::$app->controller->module; ``` -El primer ejemplo sólo es útil cuando conocemos el identificador del módulo, mientras que el segundo es mejor usarlo cuando conocemos los controladores que se están solicitando. +El primer ejemplo sólo es útil cuando conocemos el ID del módulo, mientras que el segundo es mejor usarlo cuando conocemos los controladores que se están solicitando. Una vez obtenida la instancia del módulo, se puede acceder a parámetros o componentes registrados con el módulo. Por ejemplo: @@ -140,7 +140,7 @@ $maxPostCount = $module->params['maxPostCount']; ### Bootstrapping Módulos -Puede darse el caso en que necesitemos que un módulo se ejecute en cada petición. El módulo [[yii\debug\Module|debug]] es un ejemplo. Para hacerlo, tenemos que listar los identificadores de los módulos en la propiedad [[yii\base\Application::bootstrap|bootstrap]] de la aplicación. +Puede darse el caso en que necesitemos que un módulo se ejecute en cada petición. El módulo [[yii\debug\Module|debug]] es un ejemplo. Para hacerlo, tenemos que listar los IDs de los módulos en la propiedad [[yii\base\Application::bootstrap|bootstrap]] de la aplicación. Por ejemplo, la siguiente configuración de aplicación se asegura de que el módulo ‘debug’ siempre se cargue: @@ -179,7 +179,7 @@ class Module extends \yii\base\Module } ``` -En un controlador dentro de un módulo anidado, la ruta debe incluir el identificador de todos los módulos antecesores. Por ejemplo, la ruta ‘forum/admin/dashboard/index’ representa la acción ‘index’ del controlador ‘dashboard’ en el módulo ‘admin’ que es el módulo hijo del módulo ‘forum’. +En un controlador dentro de un módulo anidado, la ruta debe incluir el ID de todos los módulos antecesores. Por ejemplo, la ruta ‘forum/admin/dashboard/index’ representa la acción ‘index’ del controlador ‘dashboard’ en el módulo ‘admin’ que es el módulo hijo del módulo ‘forum’. >Info: El método [[yii\base\Module::getModule()|getModule()]] sólo devuelve el módulo hijo que pertenece directamente a su padre. La propiedad [[yii\base\Application::loadedModules]] contiene una lista de los módulos cargados, incluyendo los hijos directos y los anidados, indexados por sus nombres de clase. @@ -188,4 +188,3 @@ En un controlador dentro de un módulo anidado, la ruta debe incluir el identifi Es mejor usar los módulos en grandes aplicaciones en las que sus funcionalidades puedan ser divididas en diferentes grupos, cada uno compuesto por funcionalidades directamente relacionadas. Cada grupo de funcionalidades se puede desarrollar como un módulo que puede ser desarrollado y mantenido por un programador o equipo específico. Los módulos también son una buena manera de reutilizar código a nivel de grupo de funcionalidades. Algunas funcionalidades de uso común, tales como la gestión de usuarios o la gestión de comentarios, pueden ser desarrollados como módulos para que puedan ser fácilmente reutilizados en futuros proyectos. - diff --git a/docs/guide-es/structure-widgets.md b/docs/guide-es/structure-widgets.md index c128089..389647b 100644 --- a/docs/guide-es/structure-widgets.md +++ b/docs/guide-es/structure-widgets.md @@ -151,7 +151,7 @@ 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. diff --git a/docs/internals-es/translation-workflow.md b/docs/internals-es/translation-workflow.md index 62e22ac..1d2d409 100644 --- a/docs/internals-es/translation-workflow.md +++ b/docs/internals-es/translation-workflow.md @@ -1,7 +1,7 @@ -Flujo de Trabajo de Traducción +Flujo de Trabajo de Traducción ============================== -Yii se traduce en muchos idiomas con el fin de ser útil para desarrolladores de aplicaciones y internacionales. Dos áreas principales donde la contribución es muy bienvenida son la documentación y los mensajes del framework. +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. Framework Mensajes ------------------ @@ -31,7 +31,7 @@ Después del trabajo inicial se lleva a cabo usted puede conseguir lo que ha cam php build translation "../docs/guide" "../docs/guide-es" "Reporte de traducción guia en Español" > report_guide_es.html ``` -Si se quejan de composer, realizar `composer install` en el fuente del directorio principal. +Si se quejan de composer, ejecutar `composer install` en el directorio raíz. Convenios para la traducción ---------------------------- @@ -55,5 +55,6 @@ Convenios para la traducción - themes — temas o plantillas - behaviors — comportamientos - handlers — manipuladores -- instantiating — intanciando +- instantiating — instanciando - link — enlace +- render – sin traducción From 84efa4b733601a2f9c3d53504644e8c6de7d5516 Mon Sep 17 00:00:00 2001 From: Vasileios Lourdas Date: Mon, 6 Oct 2014 21:41:11 +0300 Subject: [PATCH 12/43] Updated Greek translation. --- framework/messages/el/app.php | 21 +++++++++++ framework/messages/el/yii.php | 86 +++++++++++++++++++++++++++++++------------ 2 files changed, 83 insertions(+), 24 deletions(-) create mode 100644 framework/messages/el/app.php diff --git a/framework/messages/el/app.php b/framework/messages/el/app.php new file mode 100644 index 0000000..59ee854 --- /dev/null +++ b/framework/messages/el/app.php @@ -0,0 +1,21 @@ + 'Γεια σου, {username}!', +]; diff --git a/framework/messages/el/yii.php b/framework/messages/el/yii.php index 2785e87..ce53d7b 100644 --- a/framework/messages/el/yii.php +++ b/framework/messages/el/yii.php @@ -17,49 +17,87 @@ * NOTE: this file must be saved in UTF-8 encoding. */ return [ + 'Are you sure you want to delete this item?' => 'Είστε σίγουροι για τη διαγραφή του αντικειμένου;', + 'Only files with these MIME types are allowed: {mimeTypes}.' => 'Επιτρέπονται μόνο αρχεία με τους ακόλουθους τύπους MIME: {mimeTypes}.', + 'The requested view "{name}" was not found.' => 'Δε βρέθηκε η αιτούμενη όψη "{name}".', + 'in {delta, plural, =1{a day} other{# days}}' => 'σε {delta, plural, =1{μία ημέρα} other{# ημέρες}}', + 'in {delta, plural, =1{a minute} other{# minutes}}' => 'σε {delta, plural, =1{ένα λεπτό} other{# λεπτά}}', + 'in {delta, plural, =1{a month} other{# months}}' => 'σε {delta, plural, =1{ένα μήνα} other{# μήνες}}', + 'in {delta, plural, =1{a second} other{# seconds}}' => 'σε {delta, plural, =1{ένα δευτερόλεπτο} other{# δευτερόλεπτα}}', + 'in {delta, plural, =1{a year} other{# years}}' => 'σε {delta, plural, =1{ένα έτος} other{# έτη}}', + 'in {delta, plural, =1{an hour} other{# hours}}' => 'σε {delta, plural, =1{μία ώρα} other{# ώρες}}', + 'just now' => 'μόλις τώρα', + '{delta, plural, =1{a day} other{# days}} ago' => 'πριν {delta, plural, =1{μία ημέρα} other{# ημέρες}}', + '{delta, plural, =1{a minute} other{# minutes}} ago' => 'πριν {delta, plural, =1{ένα λεπτό} other{# λεπτά}}', + '{delta, plural, =1{a month} other{# months}} ago' => 'πριν {delta, plural, =1{ένα μήνα} other{# μήνες}}', + '{delta, plural, =1{a second} other{# seconds}} ago' => 'πριν {delta, plural, =1{ένα δευτερόλεπτο} other{# δευτερόλεπτα}}', + '{delta, plural, =1{a year} other{# years}} ago' => 'πριν {delta, plural, =1{ένα έτος} other{# έτη}}', + '{delta, plural, =1{an hour} other{# hours}} ago' => 'πριν {delta, plural, =1{μία ώρα} other{# ώρες}}', + '{nFormatted} B' => '{nFormatted} B', + '{nFormatted} GB' => '{nFormatted} GB', + '{nFormatted} GiB' => '{nFormatted} GiB', + '{nFormatted} KB' => '{nFormatted} KB', + '{nFormatted} KiB' => '{nFormatted} KiB', + '{nFormatted} MB' => '{nFormatted} MB', + '{nFormatted} MiB' => '{nFormatted} MiB', + '{nFormatted} PB' => '{nFormatted} PB', + '{nFormatted} PiB' => '{nFormatted} PiB', + '{nFormatted} TB' => '{nFormatted} TB', + '{nFormatted} TiB' => '{nFormatted} TiB', + '{nFormatted} {n, plural, =1{byte} other{bytes}}' => '{nFormatted} {n, plural, =1{byte} other{bytes}}', + '{nFormatted} {n, plural, =1{gibibyte} other{gibibytes}}' => '{nFormatted} {n, plural, =1{gibibyte} other{gibibytes}}', + '{nFormatted} {n, plural, =1{gigabyte} other{gigabytes}}' => '{nFormatted} {n, plural, =1{gigabyte} other{gigabytes}}', + '{nFormatted} {n, plural, =1{kibibyte} other{kibibytes}}' => '{nFormatted} {n, plural, =1{kibibyte} other{kibibytes}}', + '{nFormatted} {n, plural, =1{kilobyte} other{kilobytes}}' => '{nFormatted} {n, plural, =1{kilobyte} other{kilobytes}}', + '{nFormatted} {n, plural, =1{mebibyte} other{mebibytes}}' => '{nFormatted} {n, plural, =1{mebibyte} other{mebibytes}}', + '{nFormatted} {n, plural, =1{megabyte} other{megabytes}}' => '{nFormatted} {n, plural, =1{megabyte} other{megabytes}}', + '{nFormatted} {n, plural, =1{pebibyte} other{pebibytes}}' => '{nFormatted} {n, plural, =1{pebibyte} other{pebibytes}}', + '{nFormatted} {n, plural, =1{petabyte} other{petabytes}}' => '{nFormatted} {n, plural, =1{petabyte} other{petabytes}}', + '{nFormatted} {n, plural, =1{tebibyte} other{tebibytes}}' => '{nFormatted} {n, plural, =1{tebibyte} other{tebibytes}}', + '{nFormatted} {n, plural, =1{terabyte} other{terabytes}}' => '{nFormatted} {n, plural, =1{terabyte} other{terabytes}}', + 'No help for unknown command "{command}".' => 'Δεν υπάρχει βοήθεια για την άγνωστη εντολή "{command}".', + 'No help for unknown sub-command "{command}".' => 'Δεν υπάρχει βοήθεια για την άγνωστη υπό-εντολή "{command}".', + 'Unknown command "{command}".' => 'Άγνωστη εντολή "{command}".', '(not set)' => '(μη ορισμένο)', - 'An internal server error occurred.' => 'Σφάλμα διακομιστή.', + 'An internal server error occurred.' => 'Υπήρξε ένα εσωτερικό σφάλμα του διακομιστή.', 'Delete' => 'Διαγραφή', 'Error' => 'Σφάλμα', 'File upload failed.' => 'Η μεταφόρτωση απέτυχε.', 'Home' => 'Αρχική', 'Invalid data received for parameter "{param}".' => 'Μη έγκυρα δεδομένα για την παράμετρο "{param}".', 'Login Required' => 'Απαιτείται είσοδος', - 'Missing required arguments: {params}' => 'Απουσιάζουν απαραίτητες επιλογές: {params}', + 'Missing required arguments: {params}' => 'Απουσιάζουν απαραίτητα ορίσματα: {params}', 'Missing required parameters: {params}' => 'Απουσιάζουν απαραίτητες παράμετροι: {params}', 'No' => 'Όχι', - 'No help for unknown command "{command}".' => 'Δεν υπάρχει τεκμηρίωση για την εντολή "{command}".', - 'No help for unknown sub-command "{command}".' => 'Δεν υπάρχει τεκμηρίωση για την υπό-εντολή "{command}".', - 'No results found.' => 'Δεν βρέθηκαν αποτελέσματα.', + 'No results found.' => 'Δε βρέθηκαν αποτελέσματα.', 'Only files with these extensions are allowed: {extensions}.' => 'Επιτρέπονται αρχεία μόνο με καταλήξεις: {extensions}.', - 'Page not found.' => 'Η σελίδα δεν βρέθηκε.', + 'Page not found.' => 'Η σελίδα δε βρέθηκε.', 'Please fix the following errors:' => 'Παρακαλώ διορθώστε τα παρακάτω σφάλματα:', 'Please upload a file.' => 'Παρακαλώ μεταφορτώστε ένα αρχείο.', - 'Showing {begin, number}-{end, number} of {totalCount, number} {totalCount, plural, one{item} other{items}}.' => 'Παρουσιάζονται {begin, number}-{end, number} από {totalCount, number}.', + 'Showing {begin, number}-{end, number} of {totalCount, number} {totalCount, plural, one{item} other{items}}.' => 'Εμφανίζονται {begin, number}-{end, number} από {totalCount, number}.', 'The file "{file}" is not an image.' => 'Το αρχείο «{file}» δεν είναι εικόνα.', - 'The file "{file}" is too big. Its size cannot exceed {limit, number} {limit, plural, one{byte} other{bytes}}.' => 'Το αρχείο «{file}» είναι πολύ μεγάλο . Το μέγεθος του δεν μπορεί να είναι πάνω από {limit, number} {limit, plural, one{byte} other{bytes}}.', - 'The file "{file}" is too small. Its size cannot be smaller than {limit, number} {limit, plural, one{byte} other{bytes}}.' => 'Το αρχείο «{file}» είναι πολύ μικρό. Το μέγεθος του δεν μπορεί να είναι μικρότερο από {limit, number} {limit, plural, one{byte} few{bytes} many{bytes} other{bytes}}.', - 'The format of {attribute} is invalid.' => 'Ο τύπος του «{attribute}» δεν είναι έγκυρος.', - 'The image "{file}" is too large. The height cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Το αρχείο «{file}» είναι πολύ μεγάλο. Το ύψος δεν μπορεί να είναι μεγαλύτερο από {limit, number} {limit, plural, one{pixel} few{pixels} many{pixels} other{pixels}}.', - 'The image "{file}" is too large. The width cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Το αρχείο «{file}» είναι πολύ μεγάλο. Το πλάτος δεν μπορεί να είναι μεγαλύτερο από {limit, number} {limit, plural, one{pixel} few{pixels} many{pixels} other{pixels}}.', - 'The image "{file}" is too small. The height cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Το αρχείο «{file}» είναι πολύ μικρό. To ύψος δεν μπορεί να είναι μικρότερο από {limit, number} {limit, plural, one{pixel} few{pixels} many{pixels} other{pixels}}.', - 'The image "{file}" is too small. The width cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Το αρχείο «{file}» είναι πολύ μικρό. Το πλάτος του δεν μπορεί να είναι μικρότερο από {limit, number} {limit, plural, one{pixel} few{pixels} many{pixels} other{pixels}}.', + 'The file "{file}" is too big. Its size cannot exceed {limit, number} {limit, plural, one{byte} other{bytes}}.' => 'Το αρχείο «{file}» είναι πολύ μεγάλο . Το μέγεθός του δεν μπορεί να είναι πάνω από {limit, number} {limit, plural, one{byte} other{bytes}}.', + 'The file "{file}" is too small. Its size cannot be smaller than {limit, number} {limit, plural, one{byte} other{bytes}}.' => 'Το αρχείο «{file}» είναι πολύ μικρό. Το μέγεθός του δεν μπορεί να είναι μικρότερο από {limit, number} {limit, plural, one{byte} few{bytes} many{bytes} other{bytes}}.', + 'The format of {attribute} is invalid.' => 'Η μορφή του «{attribute}» δεν είναι έγκυρη.', + 'The image "{file}" is too large. The height cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Η εικόνα «{file}» είναι πολύ μεγάλη. Το ύψος δεν μπορεί να είναι μεγαλύτερο από {limit, number} {limit, plural, one{pixel} few{pixels} many{pixels} other{pixels}}.', + 'The image "{file}" is too large. The width cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Η εικόνα «{file}» είναι πολύ μεγάλη. Το πλάτος δεν μπορεί να είναι μεγαλύτερο από {limit, number} {limit, plural, one{pixel} few{pixels} many{pixels} other{pixels}}.', + 'The image "{file}" is too small. The height cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Η εικόνα «{file}» είναι πολύ μικρή. To ύψος δεν μπορεί να είναι μικρότερο από {limit, number} {limit, plural, one{pixel} few{pixels} many{pixels} other{pixels}}.', + 'The image "{file}" is too small. The width cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Η εικόνα «{file}» είναι πολύ μικρή. Το πλάτος του δεν μπορεί να είναι μικρότερο από {limit, number} {limit, plural, one{pixel} few{pixels} many{pixels} other{pixels}}.', 'The verification code is incorrect.' => 'Ο κωδικός επαλήθευσης είναι εσφαλμένος.', 'Total {count, number} {count, plural, one{item} other{items}}.' => 'Συνολικά {count, number} {count, plural, one{αντικείμενο} few{αντικείμενα} many{αντικείμενα} other{αντικείμενα}}.', 'Unable to verify your data submission.' => 'Δεν ήταν δυνατή η επαλήθευση των απεσταλμένων δεδομένων.', - 'Unknown command "{command}".' => 'Άγνωστη εντολή "{command}".', - 'Unknown option: --{name}' => 'Άγνωστη επιλογή : --{name}', + 'Unknown option: --{name}' => 'Άγνωστη επιλογή: --{name}', 'Update' => 'Ενημέρωση', 'View' => 'Προβολή', 'Yes' => 'Ναι', - 'You are not allowed to perform this action.' => 'Δεν επιτρέπεται να εκτελέσετε αυτή τη δράση.', - 'You can upload at most {limit, number} {limit, plural, one{file} other{files}}.' => 'Μπορείτε να μεταφορτώσετε το πολύ {limit, number} {limit, plural, one{αρχείο} few{αρχεία} many{αρχεία} other{αρχεία}}.', + 'You are not allowed to perform this action.' => 'Δεν επιτρέπεται να εκτελέσετε αυτή την ενέργεια.', + 'You can upload at most {limit, number} {limit, plural, one{file} other{files}}.' => 'Μπορείτε να ανεβάσετε το πολύ {limit, number} {limit, plural, one{αρχείο} few{αρχεία} many{αρχεία} other{αρχεία}}.', 'the input value' => 'η τιμή εισόδου', - '{attribute} "{value}" has already been taken.' => '{attribute} «{value}» έχει ήδη καταχωρηθεί.', + '{attribute} "{value}" has already been taken.' => 'Το {attribute} «{value}» έχει ήδη καταχωρηθεί.', '{attribute} cannot be blank.' => 'Το «{attribute}» δεν μπορεί να είναι κενό.', '{attribute} is invalid.' => 'Το «{attribute}» δεν είναι έγκυρο.', - '{attribute} is not a valid URL.' => 'Το «{attribute}» δεν είναι έγκυρο URL.', - '{attribute} is not a valid email address.' => 'Η διεύθυνση email «{attribute}» δεν είναι έγκυρη .', + '{attribute} is not a valid URL.' => 'Το «{attribute}» δεν είναι έγκυρη διεύθυνση URL.', + '{attribute} is not a valid email address.' => 'Η διεύθυνση email «{attribute}» δεν είναι έγκυρη.', '{attribute} must be "{requiredValue}".' => 'Το «{attribute}» πρέπει να είναι «{requiredValue}».', '{attribute} must be a number.' => 'Το «{attribute}» πρέπει να είναι αριθμός.', '{attribute} must be a string.' => 'Το «{attribute}» πρέπει να είναι συμβολοσειρά.', @@ -69,10 +107,10 @@ return [ '{attribute} must be greater than or equal to "{compareValue}".' => 'Το «{attribute}» πρέπει να είναι μεγαλύτερο ή ίσο με «{compareValue}».', '{attribute} must be less than "{compareValue}".' => 'Το «{attribute}» πρέπει να είναι μικρότερο από «{compareValue}».', '{attribute} must be less than or equal to "{compareValue}".' => 'Το «{attribute}» πρέπει να είναι μικρότερο ή ίσο με «{compareValue}».', - '{attribute} must be no greater than {max}.' => 'Το «{attribute}» πρέπει να μην ξεπερνά το {max}.', - '{attribute} must be no less than {min}.' => 'Το «{attribute}» πρέπει να μην είναι λιγότερο από {min}.', + '{attribute} must be no greater than {max}.' => 'Το «{attribute}» δεν πρέπει να ξεπερνά το {max}.', + '{attribute} must be no less than {min}.' => 'Το «{attribute}» δεν πρέπει να είναι λιγότερο από {min}.', '{attribute} must be repeated exactly.' => 'Το «{attribute}» πρέπει να επαναληφθεί ακριβώς.', - '{attribute} must not be equal to "{compareValue}".' => 'Το «{attribute}» πρέπει να μην είναι ίσο με «{compareValue}».', + '{attribute} must not be equal to "{compareValue}".' => 'Το «{attribute}» δεν πρέπει να είναι ίσο με «{compareValue}».', '{attribute} should contain at least {min, number} {min, plural, one{character} other{characters}}.' => 'Το «{attribute}» πρέπει να περιέχει το λιγότερο {min, number} {min, plural, one{χαρακτήρα} few{χαρακτήρες} many{χαρακτήρες} other{χαρακτήρες}}.', '{attribute} should contain at most {max, number} {max, plural, one{character} other{characters}}.' => 'Το «{attribute}» πρέπει να περιέχει το πολύ {max, number} {max, plural, one{χαρακτήρα} few{χαρακτήρες} many{χαρακτήρες} other{χαρακτήρες}}.', '{attribute} should contain {length, number} {length, plural, one{character} other{characters}}.' => 'Το «{attribute}» πρέπει να περιέχει {length, number} {length, plural, one{χαρακτήρα} few{χαρακτήρες} many{χαρακτήρες} other{χαρακτήρες}}.', From 675d640e5b17d569728c19ffab9b1d561e61b262 Mon Sep 17 00:00:00 2001 From: Larnu Date: Mon, 6 Oct 2014 20:46:09 +0200 Subject: [PATCH 13/43] translate routing and bootstrapping --- docs/guide-es/README.md | 6 ++-- docs/guide-es/runtime-bootstrapping.md | 24 ++++++++++++++++ docs/guide-es/runtime-routing.md | 51 ++++++++++++++++++++++++++++++++++ docs/guide-es/structure-models.md | 4 +-- 4 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 docs/guide-es/runtime-bootstrapping.md create mode 100644 docs/guide-es/runtime-routing.md diff --git a/docs/guide-es/README.md b/docs/guide-es/README.md index d39c1db..c66f122 100644 --- a/docs/guide-es/README.md +++ b/docs/guide-es/README.md @@ -1,4 +1,4 @@ -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/). @@ -48,8 +48,8 @@ Gestión de las peticiones ------------------------- * [Información general](runtime-overview.md) -* **TBD** [Bootstrapping](runtime-bootstrapping.md) -* **TBD** [Rutas](runtime-routing.md) +* [Bootstrapping](runtime-bootstrapping.md) +* [Routing](runtime-routing.md) * **TBD** [Peticiones](runtime-requests.md) * **TBD** [Respuestas](runtime-responses.md) * **TBD** [Sesiones y Cookies](runtime-sessions-cookies.md) diff --git a/docs/guide-es/runtime-bootstrapping.md b/docs/guide-es/runtime-bootstrapping.md new file mode 100644 index 0000000..669bb6f --- /dev/null +++ b/docs/guide-es/runtime-bootstrapping.md @@ -0,0 +1,24 @@ +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. diff --git a/docs/guide-es/runtime-routing.md b/docs/guide-es/runtime-routing.md new file mode 100644 index 0000000..49c8863 --- /dev/null +++ b/docs/guide-es/runtime-routing.md @@ -0,0 +1,51 @@ +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 + +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 + +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 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 + +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. diff --git a/docs/guide-es/structure-models.md b/docs/guide-es/structure-models.md index 294bff9..608d52a 100644 --- a/docs/guide-es/structure-models.md +++ b/docs/guide-es/structure-models.md @@ -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 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'. From 5617f2956364d13690491f4837f2e76c765d58de Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Oct 2014 20:48:02 +0200 Subject: [PATCH 14/43] removed app.php --- framework/messages/el/app.php | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 framework/messages/el/app.php diff --git a/framework/messages/el/app.php b/framework/messages/el/app.php deleted file mode 100644 index 59ee854..0000000 --- a/framework/messages/el/app.php +++ /dev/null @@ -1,21 +0,0 @@ - 'Γεια σου, {username}!', -]; From dfd68954a513b17c7e424ca25a44249e67992cd4 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Oct 2014 20:48:44 +0200 Subject: [PATCH 15/43] finished guide on formatting --- docs/guide/caching-data.md | 3 +- docs/guide/db-active-record.md | 2 +- docs/guide/db-dao.md | 2 +- docs/guide/db-migrations.md | 6 +- docs/guide/output-data-widgets.md | 4 +- docs/guide/output-formatter.md | 139 ++++++++++++++++++++---------- docs/guide/runtime-handling-errors.md | 2 +- docs/guide/runtime-logging.md | 2 +- docs/guide/security-authorization.md | 2 +- docs/guide/structure-applications.md | 2 +- docs/guide/structure-views.md | 2 +- docs/guide/tutorial-console.md | 2 +- docs/guide/tutorial-i18n.md | 4 +- docs/guide/tutorial-performance-tuning.md | 2 +- docs/guide/tutorial-yii-integration.md | 2 +- docs/guide/widget-bootstrap.md | 2 +- framework/i18n/Formatter.php | 6 +- 17 files changed, 118 insertions(+), 66 deletions(-) diff --git a/docs/guide/caching-data.md b/docs/guide/caching-data.md index 2b9a284..8dd1460 100644 --- a/docs/guide/caching-data.md +++ b/docs/guide/caching-data.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: diff --git a/docs/guide/db-active-record.md b/docs/guide/db-active-record.md index c9af514..dd1c732 100644 --- a/docs/guide/db-active-record.md +++ b/docs/guide/db-active-record.md @@ -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 diff --git a/docs/guide/db-dao.md b/docs/guide/db-dao.md index 94d9ba6..05fe922 100644 --- a/docs/guide/db-dao.md +++ b/docs/guide/db-dao.md @@ -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([ diff --git a/docs/guide/db-migrations.md b/docs/guide/db-migrations.md index 79f52eb..01f2d1b 100755 --- a/docs/guide/db-migrations.md +++ b/docs/guide/db-migrations.md @@ -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, ``` diff --git a/docs/guide/output-data-widgets.md b/docs/guide/output-data-widgets.md index 07a33c7..75447d7 100644 --- a/docs/guide/output-data-widgets.md +++ b/docs/guide/output-data-widgets.md @@ -135,13 +135,13 @@ You may specify various container HTML options passing arrays to: - `footerOptions` - `filterOptions` -#### Data column +#### Data column 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 formatter->asDate('2014-01-01'); // output: 1 января 2014 > is the same. See also: [Setting up your PHP environment for internationalization](tutorial-i18n.md#setup-environment). -Configuring the format ----------------------- +Configuring the formatter +------------------------- -The default format of the Formatter class can be adjusted using the properties of the formatter class. +The default formats used by the formatter methods can be adjusted using the properties of the [[yii\i18n\Formatter|formatter class]]. You can adjust these values application wide by configuring the `formatter` component in your [application config](concept-configurations.md#application-configurations). An example configuration is shown in the following. -For more details about the available properties check out the [[yii\i18n\Formatter|API documentation of the Formatter class]]. +For more details about the available properties check out the [[yii\i18n\Formatter|API documentation of the Formatter class]] and the following subsections. ```php 'components' => [ @@ -72,63 +72,112 @@ For more details about the available properties check out the [[yii\i18n\Formatt ], ``` -Formatting Dates ----------------- +Formatting Date and Time values +------------------------------- -> Note: This section is under development. +The formatter class provides different methods for formatting date and time values. These are: -TDB +- [[yii\i18n\Formatter::asDate()|date]] - the value is formatted as a date e.g. `January, 01 2014`. +- [[yii\i18n\Formatter::asTime()|time]] - the value is formatted as a time e.g. `14:23`. +- [[yii\i18n\Formatter::asDatetime()|datetime]] - the value is formatted as date and time e.g. `January, 01 2014 14:23`. +- [[yii\i18n\Formatter::asTimestamp()|timestamp]] - the value is formatted as a [unix timestamp](http://en.wikipedia.org/wiki/Unix_time) e.g. `1412609982`. +- [[yii\i18n\Formatter::asRelativeTime()|relativeTime]] - the value is formatted as the time interval between a date + and now in human readable form e.g. `1 hour ago`. -See http://site.icu-project.org/ for the format. +The date and time format for the [[yii\i18n\Formatter::asDate()|date]], [[yii\i18n\Formatter::asTime()|time]], and +[[yii\i18n\Formatter::asDatetime()|datetime]] method can be specified globally by configuring the formatters +properties [[yii\i18n\Formatter::$dateFormat|$dateFormat]], [[yii\i18n\Formatter::$timeFormat|$timeFormat]], and +[[yii\i18n\Formatter::$datetimeFormat()|$datetimeFormat]]. -- [[\yii\i18n\Formatter::asDate()|date]] - the value is formatted as date. -- [[\yii\i18n\Formatter::asTime()|time]] - the value is formatted as time. -- [[\yii\i18n\Formatter::asDatetime()|datetime]] - the value is formatted as datetime. -- [[\yii\i18n\Formatter::asTimestamp()|timestamp]] - the value is formatted as a unix timestamp. -- [[\yii\i18n\Formatter::asRelativeTime()|relativeTime]] - the value is formatted as the time interval between a date - and now in human readable form. +By default the formatter uses a shortcut format that is interpreted differently according to the currently active locale +so that dates and times are formatted in a way that is common for the users country and language. +There are four different shortcut formats available: +- `short` in `en_GB` locale will print for example `06/10/2014` for date and `15:58` for time, while +- `medium` will print `6 Oct 2014` and `15:58:42`, +- `long` will print `6 October 2014` and `15:58:42 GMT`, +- and `full` will print `Monday, 6 October 2014` and `15:58:42 GMT`. -The input value for date and time formatting is assumed to be in UTC unless a timezone is explicitly given. +Additionally you can specify custom formats using the syntax defined by the +[ICU Project](http://site.icu-project.org/) which is described in the ICU manual under the following URL: +. Alternatively you can use the syntax that can be recognized by the +PHP [date()](http://php.net/manual/de/function.date.php)-function using a string that is prefixed with `php:`. -Formatting Numbers ------------------- +```php +// ICU format +echo Yii::$app->formatter->asDate('now', 'yyyy-MM-dd'); // 2014-10-06 +// PHP date()-format +echo Yii::$app->formatter->asDate('now', 'php:Y-m-d'); // 2014-10-06 +``` -> Note: This section is under development. +### Time zones -TDB +When formatting date and time values, Yii will convert them to the [[yii\i18n\Formatter::timeZone|configured time zone]]. +Therefor the input value is assumed to be in UTC unless a time zone is explicitly given. For this reason +it is recommended to store all date and time values in UTC preferably as a UNIX timestamp, which is always UTC by definition. +If the input value is in a time zone different from UTC, the time zone has to be stated explicitly like in the following example: -See http://site.icu-project.org/ for the format. +```php +// assuming Yii::$app->timeZone = 'Europe/Berlin'; +echo Yii::$app->formatter->asTime(1412599260); // 14:41:00 +echo Yii::$app->formatter->asTime('2014-10-06 12:41:00'); // 14:41:00 +echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00 +``` -- [[\yii\i18n\Formatter::asInteger()|integer]] - the value is formatted as an integer. -- [[\yii\i18n\Formatter::asDecimal()|decimal]] - the value is formatted as a number with decimal and thousand separators. -- [[\yii\i18n\Formatter::asPercent()|percent]] - the value is formatted as a percent number. -- [[\yii\i18n\Formatter::asScientific()|scientific]] - the value is formatted as a number in scientific format. -- [[\yii\i18n\Formatter::asCurrency()|currency]] - the value is formatted as a currency value. -- [[\yii\i18n\Formatter::asSize()|size]] - the value that is a number of bytes is formatted as a human readable size. -- [[\yii\i18n\Formatter::asShortSize()|shortSize]] - the value that is a number of bytes is formatted as a human readable size. +Formatting Numbers +------------------ +For formatting numeric values the formatter class provides the following methods: -Other formatters ----------------- +- [[yii\i18n\Formatter::asInteger()|integer]] - the value is formatted as an integer e.g. `42`. +- [[yii\i18n\Formatter::asDecimal()|decimal]] - the value is formatted as a decimal number considering decimal and thousand separators e.g. `42.123`. +- [[yii\i18n\Formatter::asPercent()|percent]] - the value is formatted as a percent number e.g. `42%`. +- [[yii\i18n\Formatter::asScientific()|scientific]] - the value is formatted as a number in scientific format e.g. `4.2E4`. +- [[yii\i18n\Formatter::asCurrency()|currency]] - the value is formatted as a currency value e.g. `£420.00`. +- [[yii\i18n\Formatter::asSize()|size]] - the value that is a number of bytes is formatted as a human readable size e.g. `410 kibibytes`. +- [[yii\i18n\Formatter::asShortSize()|shortSize]] - is the short version of [[yii\i18n\Formatter::asSize()|size]], e.g. `410 KiB`. + +The format for number formatting can be adjusted using the [[yii\i18n\Formatter::decimalSeparator|decimalSeparator]] and +[[yii\i18n\Formatter::thousandSeparator|thousandSeparator]] which are set by default according to the locale. + +For more advanced configuration, [[yii\i18n\Formatter::numberFormatterOptions]] and [[yii\i18n\Formatter::numberFormatterTextOptions]] +can be used to configure the interally used [Numberformatter class](http://php.net/manual/en/class.numberformatter.php) -> Note: This section is under development. +For example to adjust the maximum and minimum value of fraction digits you can configure this property like the following: -TDB +```php +[ + NumberFormatter::MIN_FRACTION_DIGITS => 0, + NumberFormatter::MAX_FRACTION_DIGITS => 2, +] +``` +Other formatters +---------------- -Here's the bundled formatters list: +Additional to date, time and number formatting, Yii provides a set of other useful formatters for different purposes: -- [[\yii\i18n\Formatter::asRaw()|raw]] - the value is outputted as is. -- [[\yii\i18n\Formatter::asText()|text]] - the value is HTML-encoded. This format is used by default. -- [[\yii\i18n\Formatter::asNtext()|ntext]] - the value is formatted as an HTML-encoded plain text with newlines converted +- [[yii\i18n\Formatter::asRaw()|raw]] - the value is outputted as is, this is a pseudo-formatter that has no effect except that + `null` values will be formatted using [[nullDisplay]]. +- [[yii\i18n\Formatter::asText()|text]] - the value is HTML-encoded. + This is the default format used by the [GridView DataColumn](output-data-widgets.md#data-column). +- [[yii\i18n\Formatter::asNtext()|ntext]] - the value is formatted as an HTML-encoded plain text with newlines converted into line breaks. -- [[\yii\i18n\Formatter::asParagraphs()|paragraphs]] - the value is formatted as HTML-encoded text paragraphs wrapped +- [[yii\i18n\Formatter::asParagraphs()|paragraphs]] - the value is formatted as HTML-encoded text paragraphs wrapped into `

` tags. -- [[\yii\i18n\Formatter::asHtml()|html]] - the value is purified using [[HtmlPurifier]] to avoid XSS attacks. You can +- [[yii\i18n\Formatter::asHtml()|html]] - the value is purified using [[HtmlPurifier]] to avoid XSS attacks. You can pass additional options such as `['html', ['Attr.AllowedFrameTargets' => ['_blank']]]`. -- [[\yii\i18n\Formatter::asEmail()|email]] - the value is formatted as a mailto link. -- [[\yii\i18n\Formatter::asImage()|image]] - the value is formatted as an image tag. -- [[\yii\i18n\Formatter::asUrl()|url]] - the value is formatted as a hyperlink. -- [[\yii\i18n\Formatter::asBoolean()|boolean]] - the value is formatted as a boolean. You can set what's rendered for - true and false values by calling `Yii::$app->formatter->booleanFormat = ['No', 'Yes'];` before outputting GridView. +- [[yii\i18n\Formatter::asEmail()|email]] - the value is formatted as a `mailto`-link. +- [[yii\i18n\Formatter::asImage()|image]] - the value is formatted as an image tag. +- [[yii\i18n\Formatter::asUrl()|url]] - the value is formatted as a hyperlink. +- [[yii\i18n\Formatter::asBoolean()|boolean]] - the value is formatted as a boolean. By default `true` is rendered + as `Yes` and `false` as `No`, translated to the application language. You adjust this by configuring + the [[yii\i18n\Formatter::booleanFormat]]-property. + +`null`-values +------------- + +For values that are `null` in PHP, the formatter class will print a placeholder instead of and empty string which +defaults to `(not set)` translated to the current application language. You can configure the +[[yii\i18n\Formatter::nullDisplay|nullDisplay]]-property to set a custom placeholder. +If you want no special handling for `null` values, you can set [[yii\i18n\Formatter::nullDisplay|nullDisplay]] to `null`. diff --git a/docs/guide/runtime-handling-errors.md b/docs/guide/runtime-handling-errors.md index e9272a3..c3d498f 100644 --- a/docs/guide/runtime-handling-errors.md +++ b/docs/guide/runtime-handling-errors.md @@ -16,7 +16,7 @@ The [[yii\web\ErrorHandler|error handler]] is enabled by default. You may disabl ## Using Error Handler -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 diff --git a/docs/guide/runtime-logging.md b/docs/guide/runtime-logging.md index 24e2178..dcb7f1d 100644 --- a/docs/guide/runtime-logging.md +++ b/docs/guide/runtime-logging.md @@ -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 diff --git a/docs/guide/security-authorization.md b/docs/guide/security-authorization.md index 2fac706..6a09699 100644 --- a/docs/guide/security-authorization.md +++ b/docs/guide/security-authorization.md @@ -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. diff --git a/docs/guide/structure-applications.md b/docs/guide/structure-applications.md index 9a600b1..0298fff 100644 --- a/docs/guide/structure-applications.md +++ b/docs/guide/structure-applications.md @@ -195,7 +195,7 @@ The rest of the array elements (key-value pairs) specify the parameters to be bo #### [[yii\base\Application::components|components]] 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 [ diff --git a/docs/guide/structure-views.md b/docs/guide/structure-views.md index 1b13333..85c3b6d 100644 --- a/docs/guide/structure-views.md +++ b/docs/guide/structure-views.md @@ -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. diff --git a/docs/guide/tutorial-console.md b/docs/guide/tutorial-console.md index 6f2132b..ae96419 100644 --- a/docs/guide/tutorial-console.md +++ b/docs/guide/tutorial-console.md @@ -63,7 +63,7 @@ Configuration ------------- 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. diff --git a/docs/guide/tutorial-i18n.md b/docs/guide/tutorial-i18n.md index cada4c9..d56f33f 100644 --- a/docs/guide/tutorial-i18n.md +++ b/docs/guide/tutorial-i18n.md @@ -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' => [ diff --git a/docs/guide/tutorial-performance-tuning.md b/docs/guide/tutorial-performance-tuning.md index 2cfba00..5bdb928 100644 --- a/docs/guide/tutorial-performance-tuning.md +++ b/docs/guide/tutorial-performance-tuning.md @@ -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 diff --git a/docs/guide/tutorial-yii-integration.md b/docs/guide/tutorial-yii-integration.md index ba4b3d6..492b887 100644 --- a/docs/guide/tutorial-yii-integration.md +++ b/docs/guide/tutorial-yii-integration.md @@ -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. diff --git a/docs/guide/widget-bootstrap.md b/docs/guide/widget-bootstrap.md index 40771e2..937d32e 100644 --- a/docs/guide/widget-bootstrap.md +++ b/docs/guide/widget-bootstrap.md @@ -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' => [ diff --git a/framework/i18n/Formatter.php b/framework/i18n/Formatter.php index 14d97ce..6e3773f 100644 --- a/framework/i18n/Formatter.php +++ b/framework/i18n/Formatter.php @@ -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]); } /** From 3bdf04a6afa370ddc489da0db1e45ee71bd8d9cd Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Oct 2014 20:52:45 +0200 Subject: [PATCH 16/43] exclude BaseYii from message command --- framework/messages/config.php | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/messages/config.php b/framework/messages/config.php index 4c7abb9..9813d46 100644 --- a/framework/messages/config.php +++ b/framework/messages/config.php @@ -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. From 01487aa13d55e919267f1d175b0038b5ecf6a464 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Oct 2014 21:10:53 +0200 Subject: [PATCH 17/43] added note about timezone database update to the guide fixes #5128 --- docs/guide/output-formatter.md | 7 +++++++ docs/guide/tutorial-i18n.md | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/docs/guide/output-formatter.md b/docs/guide/output-formatter.md index 8dd0326..3c63a53 100644 --- a/docs/guide/output-formatter.md +++ b/docs/guide/output-formatter.md @@ -124,6 +124,13 @@ echo Yii::$app->formatter->asTime('2014-10-06 12:41:00'); // 14:41:00 echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00 ``` +> Note: As time zones are subject to rules made by the governments around the world and may change frequently, it is +> likely that you do not have the latest information in the time zone database installed on your system. +> You may 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. +> See also: [Setting up your PHP environment for internationalization](tutorial-i18n.md#setup-environment). + + Formatting Numbers ------------------ diff --git a/docs/guide/tutorial-i18n.md b/docs/guide/tutorial-i18n.md index d56f33f..2e4cf8f 100644 --- a/docs/guide/tutorial-i18n.md +++ b/docs/guide/tutorial-i18n.md @@ -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 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). From 4054b2196fc8622ce872fb96732e5b3fb4e932ee Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Oct 2014 22:04:59 +0200 Subject: [PATCH 18/43] fixed broken links --- docs/guide/output-formatter.md | 2 +- docs/guide/start-databases.md | 2 +- extensions/codeception/README.md | 2 +- extensions/elasticsearch/README.md | 2 +- framework/db/Connection.php | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/guide/output-formatter.md b/docs/guide/output-formatter.md index 3c63a53..7ec3d59 100644 --- a/docs/guide/output-formatter.md +++ b/docs/guide/output-formatter.md @@ -87,7 +87,7 @@ The formatter class provides different methods for formatting date and time valu The date and time format for the [[yii\i18n\Formatter::asDate()|date]], [[yii\i18n\Formatter::asTime()|time]], and [[yii\i18n\Formatter::asDatetime()|datetime]] method can be specified globally by configuring the formatters properties [[yii\i18n\Formatter::$dateFormat|$dateFormat]], [[yii\i18n\Formatter::$timeFormat|$timeFormat]], and -[[yii\i18n\Formatter::$datetimeFormat()|$datetimeFormat]]. +[[yii\i18n\Formatter::$datetimeFormat|$datetimeFormat]]. By default the formatter uses a shortcut format that is interpreted differently according to the currently active locale so that dates and times are formatted in a way that is common for the users country and language. diff --git a/docs/guide/start-databases.md b/docs/guide/start-databases.md index 119e76e..c9e7e27 100644 --- a/docs/guide/start-databases.md +++ b/docs/guide/start-databases.md @@ -18,7 +18,7 @@ In particular, you should know how to create a database, and how to execute SQL Preparing the Database --------------------- +---------------------- 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. diff --git a/extensions/codeception/README.md b/extensions/codeception/README.md index 68ced92..16eb02f 100644 --- a/extensions/codeception/README.md +++ b/extensions/codeception/README.md @@ -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). diff --git a/extensions/elasticsearch/README.md b/extensions/elasticsearch/README.md index ee569fe..2236a99 100644 --- a/extensions/elasticsearch/README.md +++ b/extensions/elasticsearch/README.md @@ -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. diff --git a/framework/db/Connection.php b/framework/db/Connection.php index d3df89d..7e16f60 100644 --- a/framework/db/Connection.php +++ b/framework/db/Connection.php @@ -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 From 280f499ae16b9248471aa8185604c3593e47fe9b Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Oct 2014 22:05:17 +0200 Subject: [PATCH 19/43] skip test on travis --- tests/unit/framework/web/UserTest.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/unit/framework/web/UserTest.php b/tests/unit/framework/web/UserTest.php index b62f9d0..9acb83b 100644 --- a/tests/unit/framework/web/UserTest.php +++ b/tests/unit/framework/web/UserTest.php @@ -44,6 +44,10 @@ class UserTest extends TestCase public function testLoginExpires() { + if (getenv('TRAVIS') == 'true') { + $this->markTestSkipped('Can not reliably test this on travis-ci.'); + } + $appConfig = [ 'components' => [ 'user' => [ @@ -71,8 +75,8 @@ class UserTest extends TestCase static::$time = \time(); Yii::$app->user->login(UserIdentity::findIdentity('user1')); - print_r(Yii::$app->session); - print_r($_SESSION); +// print_r(Yii::$app->session); +// print_r($_SESSION); $this->mockWebApplication($appConfig); $this->assertFalse(Yii::$app->user->isGuest); From 366bc54520f1707cc48848b624f8ff31e36e86c1 Mon Sep 17 00:00:00 2001 From: Larnu Date: Mon, 6 Oct 2014 22:56:04 +0200 Subject: [PATCH 20/43] fix spanish docs and add DatePicker into conventions --- docs/guide-es/concept-components.md | 41 +++---- docs/guide-es/structure-views.md | 171 ++++++++++-------------------- docs/guide-es/structure-widgets.md | 5 +- docs/internals-es/translation-workflow.md | 3 +- 4 files changed, 72 insertions(+), 148 deletions(-) diff --git a/docs/guide-es/concept-components.md b/docs/guide-es/concept-components.md index 78003cd..da8b491 100644 --- a/docs/guide-es/concept-components.md +++ b/docs/guide-es/concept-components.md @@ -1,17 +1,14 @@ -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,17 @@ 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: -- 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 +57,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 +74,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. diff --git a/docs/guide-es/structure-views.md b/docs/guide-es/structure-views.md index e766bdd..74d37b3 100644 --- a/docs/guide-es/structure-views.md +++ b/docs/guide-es/structure-views.md @@ -1,17 +1,14 @@ -Vistas +Vistas ====== Las Vistas (views) son una parte de la arquitectura [MVC](http://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). -Estas son el código responsable de presentar los datos al usuario final. En una aplicación Web, las vistas son usualmente creadas -en términos de *templates* que son archivos PHP que contienen principalmente HTML y PHP. -Son manejadas por el componente de la aplicación [[yii\web\View|view]], el cual provee métodos comúnmente utilizados -para facilitar la composición y el renderizado de las mismas. Por simplicidad, a menudo las llamamos *templates* o *archivos de templates*. +Estas son el código responsable de presentar los datos al usuario final. En una aplicación Web, las vistas son usualmente creadas en términos de *templates* que son archivos PHP que contienen principalmente HTML y PHP. +Son manejadas por el componente de la aplicación [[yii\web\View|view]], el cual provee métodos comúnmente utilizados para facilitar la composición y el renderizado de las mismas. Por simplicidad, a menudo las llamamos *templates* o *archivos de templates*. ## Creando Vistas -Como fue mencionado, una vista es simplemente un archivo PHP que mezcla código PHP y HTML. La siguiente es una vista -que muestra un formulario de login. Como puedes ver, el código PHP utilizado es para generar contenido dinámico, como el +Como fue mencionado, una vista es simplemente un archivo PHP que mezcla código PHP y HTML. La siguiente es una vista que muestra un formulario de login. Como puedes ver, el código PHP utilizado es para generar contenido dinámico, como el título de la página y el formulario mismo, mientras que el código HTML organiza estos elementos en una página HTML mostrable. ```php @@ -36,25 +33,19 @@ $this->title = 'Login'; ``` -Dentro de una vista, puedes acceder a la variable `$this` referida al [[yii\web\View|componente view]] que maneja -y renderiza la vista actual. +Dentro de una vista, puedes acceder a la variable `$this` referida al [[yii\web\View|componente view]] que maneja y renderiza la vista actual. -Además de `$this`, puede haber otras variables predefinidas en una vista, como `$form` y `$model` en el ejemplo -anterior. Estas variables representan los datos que son *inyectados* a la vista desde el [controlador](structure-controllers.md) +Además de `$this`, puede haber otras variables predefinidas en una vista, como `$form` y `$model` en el ejemplo anterior. Estas variables representan los datos que son *inyectados* a la vista desde el [controlador](structure-controllers.md) o algún otro objeto que dispara la [renderización de la vista](#rendering-views). -> Tip: La lista de variables predefinidas están listadas en un bloque de comentario al principio de la vista así pueden ser - reconocidas por las IDEs. Esto es también una buena manera de documentar tus propias vistas. +> Tip: La lista de variables predefinidas están listadas en un bloque de comentario al principio de la vista así pueden ser reconocidas por las IDEs. Esto es también una buena manera de documentar tus propias vistas. ### Seguridad -Al crear vistas que generan páginas HTML, es importante que codifiques (encode) y/o filtres los datos provenientes -de los usuarios antes de mostrarlos. De otro modo, tu aplicación puede estar expuesta a -ataques tipo [cross-site scripting](http://es.wikipedia.org/wiki/Cross-site_scripting). +Al crear vistas que generan páginas HTML, es importante que codifiques (encode) y/o filtres los datos provenientes de los usuarios antes de mostrarlos. De otro modo, tu aplicación puede estar expuesta a ataques tipo [cross-site scripting](http://es.wikipedia.org/wiki/Cross-site_scripting). -Para mostrar un texto plano, codifícalos previamente utilizando [[yii\helpers\Html::encode()]]. Por ejemplo, el siguiente código -aplica una codificación del nombre de usuario antes de mostrarlo: +Para mostrar un texto plano, codifícalos previamente utilizando [[yii\helpers\Html::encode()]]. Por ejemplo, el siguiente código aplica una codificación del nombre de usuario antes de mostrarlo: ```php ``` -> Tip: Aunque HTMLPurifier hace un excelente trabajo al hacer la salida más segura, no es rápido. Deberías considerar - utilizar [caching](caching-overview.md) al resultado de aplicar el filtro si tu aplicación requiere un gran desempeño (performance). +> Tip: Aunque HTMLPurifier hace un excelente trabajo al hacer la salida más segura, no es rápido. Deberías considerar utilizar [caching](caching-overview.md) al resultado de aplicar el filtro si tu aplicación requiere un gran desempeño (performance). ### Organizando Vistas @@ -119,13 +109,10 @@ methodName($view, $params = []) Dentro de los [controladores](structure-controllers.md), puedes llamar al siguiente método del controlador para renderizar una vista: -* [[yii\base\Controller::render()|render()]]: renderiza la [vista nombrada](#named-views) y aplica un [layout](#layouts) - al resultado de la renderización. +* [[yii\base\Controller::render()|render()]]: renderiza la [vista nombrada](#named-views) y aplica un [layout](#layouts) al resultado de la renderización. * [[yii\base\Controller::renderPartial()|renderPartial()]]: renderiza la [vista nombrada](#named-views) sin ningún layout aplicado. -* [[yii\web\Controller::renderAjax()|renderAjax()]]: renderiza la [vista nombrada](#named-views) sin layout, - e inyecta todos los scripts y archivos JS/CSS registrados. Esto sucede usualmente en respuestas a llamadas a AJAX `requests`. -* [[yii\base\Controller::renderFile()|renderFile()]]: renderiza la vista especificada en términos de la ruta al archivo o - [alias](concept-aliases.md). +* [[yii\web\Controller::renderAjax()|renderAjax()]]: renderiza la [vista nombrada](#named-views) sin layout, e inyecta todos los scripts y archivos JS/CSS registrados. Esto sucede usualmente en respuestas a llamadas a AJAX `requests`. +* [[yii\base\Controller::renderFile()|renderFile()]]: renderiza la vista especificada en términos de la ruta al archivo o [alias](concept-aliases.md). Por ejemplo: @@ -160,8 +147,7 @@ class PostController extends Controller Dentro de [widgets](structure-widgets.md), puedes llamar a cualquier de los siguientes métodos de widget para renderizar una vista. * [[yii\base\Widget::render()|render()]]: renderiza la [vista nombrada](#named-views). -* [[yii\base\Widget::renderFile()|renderFile()]]: renderiza la vista especificada en términos de ruta al archivo o - [alias](concept-aliases.md). +* [[yii\base\Widget::renderFile()|renderFile()]]: renderiza la vista especificada en términos de ruta al archivo o [alias](concept-aliases.md). Por ejemplo: @@ -191,13 +177,10 @@ class ListWidget extends Widget Puedes renderizar una vista dentro de otra vista llamando a algunos de los siguientes métodos provistos por el [[yii\base\View|componente view]]: * [[yii\base\View::render()|render()]]: renderiza la [vista nombrada](#named-views). -* [[yii\web\View::renderAjax()|renderAjax()]]: renderiza la [vista nombrada](#named-views) e inyecta todos los - archivos y scripts JS/CSS. Esto sucede usualmente en respuestas a llamadas a AJAX `requests`. -* [[yii\base\View::renderFile()|renderFile()]]: renderiza la vista especificada en términos de ruta al archivo o - [alias](concept-aliases.md). +* [[yii\web\View::renderAjax()|renderAjax()]]: renderiza la [vista nombrada](#named-views) e inyecta todos los archivos y scripts JS/CSS. Esto sucede usualmente en respuestas a llamadas a AJAX `requests`. +* [[yii\base\View::renderFile()|renderFile()]]: renderiza la vista especificada en términos de ruta al archivo o [alias](concept-aliases.md). -Por ejemplo, el siguiente código en una vista renderiza el template `_overview.php` encontrado en el mismo directorio -de la vista renderizada actualmente. Recuerda que la variable `$this` en una vista se refiere al componente [[yii\base\View|view]]: +Por ejemplo, el siguiente código en una vista renderiza el template `_overview.php` encontrado en el mismo directorio de la vista renderizada actualmente. Recuerda que la variable `$this` en una vista se refiere al componente [[yii\base\View|view]]: ```php render('_overview') ?> @@ -222,36 +205,25 @@ utilizarías la primera porque es más concisa y flexible. *Vistas nombradas* so Un nombre de vista es resuelto a su correspondiente ruta de archivo siguiendo las siguientes reglas: -* Un nombre de vista puede omitir la extensión del archivo. En estos casos se utilizará `.php` como extensión del archivo. Por ejemplo, - el nombre de vista `about` corresponde al archivo `about.php`. +* Un nombre de vista puede omitir la extensión del archivo. En estos casos se utilizará `.php` como extensión del archivo. Por ejemplo, el nombre de vista `about` corresponde al archivo `about.php`. * Si el nombre de la vista comienza con doble barra (`//`), la ruta al archivo correspondiente será `@app/views/ViewName`. - Esto quiere decir que la vista es buscada bajo el [[yii\base\Application::viewPath|view path de la aplicación]]. - Por ejemplo, `//site/about` será resuelto como `@app/views/site/about.php`. -* Si el nombre de la vista comienza con una barra simple `/`, la ruta al archivo de la vista utilizará como prefijo el nombre de la vista - con el [[yii\base\Module::viewPath|view path]] del [módulo](structure-modules.md) utilizado actualmente. - Si no hubiera módulo activo se utilizará `@app/views/ViewName`. Por ejemplo, `/user/create` será resuelto a - `@app/modules/user/views/user/create.php` si el módulo activo es `user`. Si no hubiera módulo activo, - la ruta al archivo será `@app/views/user/create.php`. -* Si la vista es renderizada con un [[yii\base\View::context|context]] y dicho contexto implementa [[yii\base\ViewContextInterface]], - la ruta al archivo se forma utilizando como prefijo el [[yii\base\ViewContextInterface::getViewPath()|view path]] - del contexto de la vista. Esto principalmente aplica a vistas renderizadas en controladores y widgets. Por ejemplo, - `site/about` será resuelto a `@app/views/site/about.php` si el contexto es el controlador `SiteController`. -* Si la vista es renderizada dentro de otra vista, el directorio que contiene la otra vista será prefijado - al nuevo nombre de la vista para formar la ruta a la vista. Por ejemplo, `item` sera resuelto a `@app/views/post/item` - si está siendo renderizado desde la vista `@app/views/post/index.php`. +Esto quiere decir que la vista es buscada bajo el [[yii\base\Application::viewPath|view path de la aplicación]]. +Por ejemplo, `//site/about` será resuelto como `@app/views/site/about.php`. +* Si el nombre de la vista comienza con una barra simple `/`, la ruta al archivo de la vista utilizará como prefijo el nombre de la vista con el [[yii\base\Module::viewPath|view path]] del [módulo](structure-modules.md) utilizado actualmente. +Si no hubiera módulo activo se utilizará `@app/views/ViewName`. Por ejemplo, `/user/create` será resuelto a `@app/modules/user/views/user/create.php` si el módulo activo es `user`. Si no hubiera módulo activo, la ruta al archivo será `@app/views/user/create.php`. +* Si la vista es renderizada con un [[yii\base\View::context|context]] y dicho contexto implementa [[yii\base\ViewContextInterface]], la ruta al archivo se forma utilizando como prefijo el [[yii\base\ViewContextInterface::getViewPath()|view path]] del contexto de la vista. Esto principalmente aplica a vistas renderizadas en controladores y widgets. Por ejemplo, `site/about` será resuelto a `@app/views/site/about.php` si el contexto es el controlador `SiteController`. +* Si la vista es renderizada dentro de otra vista, el directorio que contiene la otra vista será prefijado al nuevo nombre de la vista para formar la ruta a la vista. Por ejemplo, `item` sera resuelto a `@app/views/post/item` si está siendo renderizado desde la vista `@app/views/post/index.php`. De acuerdo a las reglas mencionadas, al llamar a `$this->render('view')` en el controlador `app\controllers\PostController` se renderizará el template `@app/views/post/view.php`, mientras que llamando a `$this->render('_overview')` en la vista renderizará el template `@app/views/post/_overview.php`. - ### Accediendo a Datos en la Vista Hay dos modos posibles de acceder a los datos en la vista: push (inyectar) y pull (traer). Al pasar los datos como segundo parámetro en algún método de renderización, estás utilizando el modo push. -Los datos deberían ser representados como un array de pares clave-valor. Cuando la vista está siendo renderizada, la función PHP -`extract()` será llamada sobre este array así se extraen las variables que contiene a la vista actual . +Los datos deberían ser representados como un array de pares clave-valor. Cuando la vista está siendo renderizada, la función PHP `extract()` será llamada sobre este array así se extraen las variables que contiene a la vista actual . Por ejemplo, el siguiente código de renderización en un controlador inyectará dos variables a la vista `report`: `$foo = 1` and `$bar = 2`. @@ -262,35 +234,26 @@ echo $this->render('report', [ ]); ``` -El modo pull obtiene los datos del [[yii\base\View|componente view]] u otros objetos accesibles -en las vistas (ej. `Yii::$app`). Utilizando el código anterior como ejemplo, dentro de una vista puedes acceder al objeto del controlador -a través de la expresión `$this->context`. Como resultado, te es posible acceder a cualquier propiedad o método -del controlador en la vista `report`, tal como el ID del controlador como se muestra a continuación: +El modo pull obtiene los datos del [[yii\base\View|componente view]] u otros objetos accesibles en las vistas (ej. `Yii::$app`). Utilizando el código anterior como ejemplo, dentro de una vista puedes acceder al objeto del controlador a través de la expresión `$this->context`. Como resultado, te es posible acceder a cualquier propiedad o método del controlador en la vista `report`, tal como el ID del controlador como se muestra a continuación: ```php El ID del controlador es: context->id ?> ?> ``` -Para acceder a datos en la vista, normalmente se prefiere el modo push, ya que hace a la vista menos dependiente -de los objetos del contexto. La contra es que tienes que construir el array manualmente cada vez, lo que podría -volverse tedioso y propenso al error si la misma vista es compartida y renderizada desde diferentes lugares. - +Para acceder a datos en la vista, normalmente se prefiere el modo push, ya que hace a la vista menos dependiente de los objetos del contexto. La contra es que tienes que construir el array manualmente cada vez, lo que podría volverse tedioso y propenso al error si la misma vista es compartida y renderizada desde diferentes lugares. ### Compartiendo Datos Entre las Vistas -El [[yii\base\View|componente view]] provee la propiedad [[yii\base\View::params|params]] para que puedas compartir -datos entre diferentes vistas. +El [[yii\base\View|componente view]] provee la propiedad [[yii\base\View::params|params]] para que puedas compartir datos entre diferentes vistas. -Por ejemplo, en una vista `about`, podrías tener el siguiente código que especifica el segmento actual -del breadcrumbs (migas de pan). +Por ejemplo, en una vista `about`, podrías tener el siguiente código que especifica el segmento actual del breadcrumbs (migas de pan). ```php $this->params['breadcrumbs'][] = 'Acerca de Nosotros'; ``` -Entonces, en el archivo del [layout](#layouts), que es también una vista, puedes mostrar el breadcrumbs utilizando los datos -pasados a través de [[yii\base\View::params|params]]: +Entonces, en el archivo del [layout](#layouts), que es también una vista, puedes mostrar el breadcrumbs utilizando los datos pasados a través de [[yii\base\View::params|params]]: ```php ``` - ## Layouts -Los layouts son un tipo especial de vista que representan partes comunes de otras múltiples vistas. Por ejemplo, las páginas -de la mayoría de las aplicaciones Web comparten el mismo encabezado y pie de página. Aunque puedes repetirlos en todas y cada una -de las vistas, una mejor forma es hacerlo sólo en el layout e incrustar el resultado de la renderización de la vista en -un lugar apropiado del mismo. - +Los layouts son un tipo especial de vista que representan partes comunes de otras múltiples vistas. Por ejemplo, las páginas de la mayoría de las aplicaciones Web comparten el mismo encabezado y pie de página. Aunque puedes repetirlos en todas y cada una de las vistas, una mejor forma es hacerlo sólo en el layout e incrustar el resultado de la renderización de la vista en un lugar apropiado del mismo. ### Creando Layouts -Dado que los layouts son también vistas, pueden ser creados de manera similar a las vistas comunes. Por defecto, los layouts -son guardados en el directorio `@app/views/layouts`. Para layouts utilizados dentro de un [módulo](structure-modules.md), -deberían ser guardados en el directorio `views/layouts` bajo el [[yii\base\Module::basePath|directorio del módulo]]. -Puedes personalizar el directorio de layouts por defecto configurando la propiedad [[yii\base\Module::layoutPath]] de -la aplicación o módulos. +Dado que los layouts son también vistas, pueden ser creados de manera similar a las vistas comunes. Por defecto, los layouts son guardados en el directorio `@app/views/layouts`. Para layouts utilizados dentro de un [módulo](structure-modules.md), deberían ser guardados en el directorio `views/layouts` bajo el [[yii\base\Module::basePath|directorio del módulo]]. +Puedes personalizar el directorio de layouts por defecto configurando la propiedad [[yii\base\Module::layoutPath]] de la aplicación o módulos. -El siguiente ejemplo muestra cómo debe verse un layout. Ten en cuenta que por motivos ilustrativos, hemos simplificado bastante -el código del layout. En la práctica, probablemente le agregues más contenido, como tags en el `head`, un menú principal, etc. +El siguiente ejemplo muestra cómo debe verse un layout. Ten en cuenta que por motivos ilustrativos, hemos simplificado bastante el código del layout. En la práctica, probablemente le agregues más contenido, como tags en el `head`, un menú principal, etc. ```php `, -el layout imprime la variable `$content`, que representa el resultado de la renderización del contenido de cada vista y es incrustado -dentro del layout cuando se llama al método [[yii\base\Controller::render()]]. +el layout imprime la variable `$content`, que representa el resultado de la renderización del contenido de cada vista y es incrustado dentro del layout cuando se llama al método [[yii\base\Controller::render()]]. -La mayoría de layouts deberían llamar a los siguientes métodos (como fue mostrado recién). Estos métodos principalmente disparan eventos -acerca del proceso de renderizado así los scripts y tags registrados en otros lugares pueden ser propiamente inyectados en -los lugares donde los métodos son llamados. +La mayoría de layouts deberían llamar a los siguientes métodos (como fue mostrado recién). Estos métodos principalmente disparan eventos acerca del proceso de renderizado así los scripts y tags registrados en otros lugares pueden ser propiamente inyectados en los lugares donde los métodos son llamados. - [[yii\base\View::beginPage()|beginPage()]]: Este método debería ser llamado bien al principio del layout. - Esto dispara el evento [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]], el cual indica el comienzo de la página. +Esto dispara el evento [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]], el cual indica el comienzo de la página. - [[yii\base\View::endPage()|endPage()]]: Este método debería ser llamado al final del layout. - Esto dispara el evento [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]], indicando el final de la página. +Esto dispara el evento [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]], indicando el final de la página. - [[yii\web\View::head()|head()]]: Este método debería llamarse dentro de la sección `` de una página HTML. - Esto genera un espacio vacío que será reemplazado con el código del head HTML registrado (ej. link tags, meta tags) - cuando una página finaliza el renderizado. +Esto genera un espacio vacío que será reemplazado con el código del head HTML registrado (ej. link tags, meta tags) cuando una página finaliza el renderizado. - [[yii\base\View::beginBody()|beginBody()]]: Este método debería llamarse al principio de la sección ``. - Esto dispara el evento [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]] y genera un espacio vacío que será - reemplazado con el código HTML registrado (ej. JavaScript) que apunta al principio del body. +Esto dispara el evento [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]] y genera un espacio vacío que será reemplazado con el código HTML registrado (ej. JavaScript) que apunta al principio del body. - [[yii\base\View::endBody()|endBody()]]: Este método debería llamarse al final de la sección ``. - Esto dispara el evento [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]], que genera un espacio vacío a ser reemplazado - por el código HTML registrado (ej. JavaScript) que apunta al final del body. +Esto dispara el evento [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]], que genera un espacio vacío a ser reemplazado por el código HTML registrado (ej. JavaScript) que apunta al final del body. ### Accediendo a Datos en Layouts Dentro de un layout, tienes acceso a dos variables predefinidas: `$this` y `$content`. La primera se refiere -al componente [[yii\base\View|view]], como en cualquier vista, mientras que la última contiene el resultado de la renderización del contenido -de la vista que está siendo renderizada all llamar al método [[yii\base\Controller::render()|render()]] en los controladores. +al componente [[yii\base\View|view]], como en cualquier vista, mientras que la última contiene el resultado de la renderización del contenido de la vista que está siendo renderizada all llamar al método [[yii\base\Controller::render()|render()]] en los controladores. -Si quieres acceder a otros datos en los layouts, debes utilizar el modo pull que fue descrito en la sub-sección -[Accediendo a Datos en la Vista](#accessing-data-in-views). Si quieres pasar datos desde al contenido de la vista -a un layout, puedes utilizar el método descrito en la sub-sección [Compartiendo Datos Entre las Vistas](#sharing-data-among-views). +Si quieres acceder a otros datos en los layouts, debes utilizar el modo pull que fue descrito en la sub-sección +[Accediendo a Datos en la Vista](#accessing-data-in-views). Si quieres pasar datos desde al contenido de la vista a un layout, puedes utilizar el método descrito en la sub-sección [Compartiendo Datos Entre las Vistas](#sharing-data-among-views). ### Utilizando Layouts @@ -569,14 +515,11 @@ Al igual que con [[yii\web\View::registerMetaTag()|registerMetaTags()]], puedes ## Eventos de Vistas -Los [[yii\base\View|componentes de vistas]] disparan varios eventos durante el proceso de renderizado de la vista. Puedes responder -a estos eventos para inyectar contenido a la vista o procesar el resultado de la renderización antes de que sea enviada al usuario final. +Los [[yii\base\View|componentes de vistas]] disparan varios eventos durante el proceso de renderizado de la vista. Puedes responder a estos eventos para inyectar contenido a la vista o procesar el resultado de la renderización antes de que sea enviada al usuario final. -- [[yii\base\View::EVENT_BEFORE_RENDER|EVENT_BEFORE_RENDER]]: disparado al principio del renderizado de un archivo - en un controlador. Los manejadores de este evento pueden definir [[yii\base\ViewEvent::isValid]] como `false` para cancelar el proceso de renderizado. +- [[yii\base\View::EVENT_BEFORE_RENDER|EVENT_BEFORE_RENDER]]: disparado al principio del renderizado de un archivo en un controlador. Los manejadores de este evento pueden definir [[yii\base\ViewEvent::isValid]] como `false` para cancelar el proceso de renderizado. - [[yii\base\View::EVENT_AFTER_RENDER|EVENT_AFTER_RENDER]]: disparado por la llamada a [[yii\base\View::beginPage()]] en layouts. - Los manejadores de este evento pueden obtener el resultado de la renderización a través de [[yii\base\ViewEvent::output]] y entonces modificar - esta propiedad para así cambiar el mismo. +Los manejadores de este evento pueden obtener el resultado de la renderización a través de [[yii\base\ViewEvent::output]] y entonces modificar esta propiedad para así cambiar el mismo. - [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]]: disparado por la llamada a [[yii\base\View::beginPage()]] en layouts. - [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]]: disparado por la llamada a [[yii\base\View::endPage()]] en layouts. - [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]]: disparado por la llamada a [[yii\web\View::beginBody()]] en layouts. @@ -591,10 +534,9 @@ Por ejemplo, el siguiente código inyecta la fecha actual al final del body de l ``` -## Renderizando Página Estáticas +## Renderizando Páginas Estáticas -Con páginas estáticas nos referimos a esas páginas cuyo contenido es mayormente estático y sin necesidad de acceso -a datos dinámicos enviados desde los controladores. +Con páginas estáticas nos referimos a esas páginas cuyo contenido es mayormente estático y sin necesidad de acceso a datos dinámicos enviados desde los controladores. Puedes generar páginas estáticas utilizando un código como el que sigue dentro de un controlador: @@ -606,8 +548,7 @@ public function actionAbout() ``` Si un sitio Web contiene muchas páginas estáticas, resultaría tedioso repetir el mismo código en muchos lados. -Para resolver este problema, puedes introducir una [acción independiente](structure-controllers.md#standalone-actions) -llamada [[yii\web\ViewAction]] en el controlador. Por ejemplo, +Para resolver este problema, puedes introducir una [acción independiente](structure-controllers.md#standalone-actions) llamada [[yii\web\ViewAction]] en el controlador. Por ejemplo, ```php namespace app\controllers; @@ -627,16 +568,13 @@ class SiteController extends Controller } ``` -Ahora, si creamos una vista llamada `about` bajo el directorio `@app/views/site/pages`, serás capáz -de mostrarla en la siguiente URL: +Ahora, si creamos una vista llamada `about` bajo el directorio `@app/views/site/pages`, serás capáz de mostrarla en la siguiente URL: ``` http://localhost/index.php?r=site/page&view=about ``` -El parámetro `GET` `view` le comunica a [[yii\web\ViewAction]] cuál es la vista solicitada. La acción entonces buscará -esta vista dentro de `@app/views/site/pages`. Puedes configurar la propiedad [[yii\web\ViewAction::viewPrefix]] -para cambiar el directorio en el que se buscarán dichas páginas. +El parámetro `GET` `view` le comunica a [[yii\web\ViewAction]] cuál es la vista solicitada. La acción entonces buscará esta vista dentro de `@app/views/site/pages`. Puedes configurar la propiedad [[yii\web\ViewAction::viewPrefix]] para cambiar el directorio en el que se buscarán dichas páginas. ## Buenas Prácticas @@ -646,15 +584,14 @@ Las vistas son responsables de la presentación de modelos en el formato que el * deberían contener principalmente sólo código de presentación, como HTML, y PHP simple para recorrer, dar formato y renderizar datos. * no deberían contener código que realiza consultas a la base de datos. Ese tipo de código debe ir en los modelos. * deberían evitar el acceso directo a datos del `request`, como `$_GET` y/o `$_POST`. Esto es una responsabilidad de los controladores. - Si se necesitan datos del `request`, deben ser inyectados a la vista desde el controlador. +Si se necesitan datos del `request`, deben ser inyectados a la vista desde el controlador. * pueden leer propiedades del modelo, pero no debería modificarlas. Para hacer las vistas más manejables, evita crear vistas que son demasiado complejas o que contengan código redundante. Puedes utilizar estas técnicas para alcanzar dicha meta: * utiliza [layouts](#layouts) para representar secciones comunes (ej. encabezado y footer de la página). -* divide una vista compleja en varias más simples. Las vistas pequeñas pueden ser renderizadas y unidas una mayor - utilizando los métodos de renderización antes descritos. +* divide una vista compleja en varias más simples. Las vistas pequeñas pueden ser renderizadas y unidas una mayor utilizando los métodos de renderización antes descritos. * crea y utiliza [widgets](structure-widgets.md) como bloques de construcción de la vista. * crea y utilizar helpers para transformar y dar formato a los datos en la vista. diff --git a/docs/guide-es/structure-widgets.md b/docs/guide-es/structure-widgets.md index 389647b..72129ae 100644 --- a/docs/guide-es/structure-widgets.md +++ b/docs/guide-es/structure-widgets.md @@ -1,7 +1,7 @@ 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 -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 Date: Tue, 7 Oct 2014 01:13:17 +0400 Subject: [PATCH 21/43] Fixes #5382: renamed "pivot table" to "junction table" since it's correct term to use --- docs/guide/db-active-record.md | 14 +++++++------- extensions/elasticsearch/ActiveQuery.php | 2 +- extensions/gii/generators/model/Generator.php | 6 +++--- extensions/mongodb/ActiveQuery.php | 4 ++-- extensions/redis/ActiveQuery.php | 6 +++--- extensions/sphinx/ActiveQuery.php | 4 ++-- framework/db/ActiveQuery.php | 18 +++++++++--------- framework/db/ActiveQueryInterface.php | 4 ++-- framework/db/ActiveRecordInterface.php | 8 ++++---- framework/db/ActiveRelationTrait.php | 12 ++++++------ framework/db/BaseActiveRecord.php | 8 ++++---- 11 files changed, 43 insertions(+), 43 deletions(-) diff --git a/docs/guide/db-active-record.md b/docs/guide/db-active-record.md index dd1c732..43805b3 100644 --- a/docs/guide/db-active-record.md +++ b/docs/guide/db-active-record.md @@ -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, diff --git a/extensions/elasticsearch/ActiveQuery.php b/extensions/elasticsearch/ActiveQuery.php index 7c67177..c31ae53 100644 --- a/extensions/elasticsearch/ActiveQuery.php +++ b/extensions/elasticsearch/ActiveQuery.php @@ -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. * diff --git a/extensions/gii/generators/model/Generator.php b/extensions/gii/generators/model/Generator.php index ffbac25..276e7ef 100644 --- a/extensions/gii/generators/model/Generator.php +++ b/extensions/gii/generators/model/Generator.php @@ -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) { diff --git a/extensions/mongodb/ActiveQuery.php b/extensions/mongodb/ActiveQuery.php index 8a50d08..e296a4b 100644 --- a/extensions/mongodb/ActiveQuery.php +++ b/extensions/mongodb/ActiveQuery.php @@ -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 diff --git a/extensions/redis/ActiveQuery.php b/extensions/redis/ActiveQuery.php index dce68e0..3a6248a 100644 --- a/extensions/redis/ActiveQuery.php +++ b/extensions/redis/ActiveQuery.php @@ -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 diff --git a/extensions/sphinx/ActiveQuery.php b/extensions/sphinx/ActiveQuery.php index ac0747e..e670cce 100644 --- a/extensions/sphinx/ActiveQuery.php +++ b/extensions/sphinx/ActiveQuery.php @@ -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 diff --git a/framework/db/ActiveQuery.php b/framework/db/ActiveQuery.php index 1ee8407..8f7f87f 100644 --- a/framework/db/ActiveQuery.php +++ b/framework/db/ActiveQuery.php @@ -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() diff --git a/framework/db/ActiveQueryInterface.php b/framework/db/ActiveQueryInterface.php index 52d807c..6b0af91 100644 --- a/framework/db/ActiveQueryInterface.php +++ b/framework/db/ActiveQueryInterface.php @@ -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. */ diff --git a/framework/db/ActiveRecordInterface.php b/framework/db/ActiveRecordInterface.php index 87ea5f7..6b57815 100644 --- a/framework/db/ActiveRecordInterface.php +++ b/framework/db/ActiveRecordInterface.php @@ -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 = []); diff --git a/framework/db/ActiveRelationTrait.php b/framework/db/ActiveRelationTrait.php index d916131..a952702 100644 --- a/framework/db/ActiveRelationTrait.php +++ b/framework/db/ActiveRelationTrait.php @@ -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 []; diff --git a/framework/db/BaseActiveRecord.php b/framework/db/BaseActiveRecord.php index 3f71077..17320cc 100644 --- a/framework/db/BaseActiveRecord.php +++ b/framework/db/BaseActiveRecord.php @@ -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. */ From 238b220c6ac9857127a473bd03834f9df0dd2d58 Mon Sep 17 00:00:00 2001 From: Marco Da Silva Date: Mon, 6 Oct 2014 22:13:54 -0430 Subject: [PATCH 22/43] Spanish translation updates and small fixes --- docs/guide-es/README.md | 2 +- docs/guide-es/concept-components.md | 3 +- docs/guide-es/concept-service-locator.md | 71 ++++++++++++++ docs/guide-es/structure-views.md | 151 +++++++++--------------------- docs/internals-es/translation-workflow.md | 1 + 5 files changed, 118 insertions(+), 110 deletions(-) create mode 100644 docs/guide-es/concept-service-locator.md diff --git a/docs/guide-es/README.md b/docs/guide-es/README.md index c66f122..8fe1a9f 100644 --- a/docs/guide-es/README.md +++ b/docs/guide-es/README.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) diff --git a/docs/guide-es/concept-components.md b/docs/guide-es/concept-components.md index da8b491..4ce239a 100644 --- a/docs/guide-es/concept-components.md +++ b/docs/guide-es/concept-components.md @@ -27,8 +27,7 @@ Las propiedades del widget son fácilmente modificables porque la clase se extie 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". - Siempre llama al constructor del "padre" al *final* de su propio constructor. diff --git a/docs/guide-es/concept-service-locator.md b/docs/guide-es/concept-service-locator.md new file mode 100644 index 0000000..8a74ef2 --- /dev/null +++ b/docs/guide-es/concept-service-locator.md @@ -0,0 +1,71 @@ +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; + }, + ], +]; +``` diff --git a/docs/guide-es/structure-views.md b/docs/guide-es/structure-views.md index 74d37b3..83dd2e5 100644 --- a/docs/guide-es/structure-views.md +++ b/docs/guide-es/structure-views.md @@ -8,8 +8,7 @@ Son manejadas por el componente de la aplicación [[yii\web\View|view]], el cual ## Creando Vistas -Como fue mencionado, una vista es simplemente un archivo PHP que mezcla código PHP y HTML. La siguiente es una vista que muestra un formulario de login. Como puedes ver, el código PHP utilizado es para generar contenido dinámico, como el -título de la página y el formulario mismo, mientras que el código HTML organiza estos elementos en una página HTML mostrable. +Como fue mencionado, una vista es simplemente un archivo PHP que mezcla código PHP y HTML. La siguiente es una vista que muestra un formulario de login. Como puedes ver, el código PHP utilizado es para generar contenido dinámico, como el título de la página y el formulario mismo, mientras que el código HTML organiza estos elementos en una página HTML mostrable. ```php title = 'Login'; Dentro de una vista, puedes acceder a la variable `$this` referida al [[yii\web\View|componente view]] que maneja y renderiza la vista actual. -Además de `$this`, puede haber otras variables predefinidas en una vista, como `$form` y `$model` en el ejemplo anterior. Estas variables representan los datos que son *inyectados* a la vista desde el [controlador](structure-controllers.md) -o algún otro objeto que dispara la [renderización de la vista](#rendering-views). +Además de `$this`, puede haber otras variables predefinidas en una vista, como `$form` y `$model` en el ejemplo anterior. Estas variables representan los datos que son *inyectados* a la vista desde el [controlador](structure-controllers.md) o algún otro objeto que dispara la [renderización de la vista](#rendering-views). > Tip: La lista de variables predefinidas están listadas en un bloque de comentario al principio de la vista así pueden ser reconocidas por las IDEs. Esto es también una buena manera de documentar tus propias vistas. @@ -57,8 +55,7 @@ use yii\helpers\Html; ``` -Para mostrar contenido HTML, utiliza [[yii\helpers\HtmlPurifier]] para filtrarlo antes. Por ejemplo, el siguiente -código filtra el contenido del post antes de mostrarlo en pantalla: +Para mostrar contenido HTML, utiliza [[yii\helpers\HtmlPurifier]] para filtrarlo antes. Por ejemplo, el siguiente código filtra el contenido del post antes de mostrarlo en pantalla: ```php -Puedes renderizar vistas desde [controllers](structure-controllers.md), [widgets](structure-widgets.md), o cualquier -otro lugar llamando a los métodos de renderización de vistas. Estos métodos comparten una firma similar, como se muestra a continuación: +Puedes renderizar vistas desde [controllers](structure-controllers.md), [widgets](structure-widgets.md), o cualquier otro lugar llamando a los métodos de renderización de vistas. Estos métodos comparten una firma similar, como se muestra a continuación: ``` /** @@ -200,8 +190,7 @@ echo \Yii::$app->view->renderFile('@app/views/site/license.php'); ### Vistas Nombradas -Cuando renderizas una vista, puedes especificar el template utilizando tanto el nombre de la vista o la ruta/alias al archivo. En la mayoría de los casos, -utilizarías la primera porque es más concisa y flexible. *Vistas nombradas* son vistas especificadas mediante un nombre en vez de una ruta al archivo o alias. +Cuando renderizas una vista, puedes especificar el template utilizando tanto el nombre de la vista o la ruta/alias al archivo. En la mayoría de los casos, utilizarías la primera porque es más concisa y flexible. *Vistas nombradas* son vistas especificadas mediante un nombre en vez de una ruta al archivo o alias. Un nombre de vista es resuelto a su correspondiente ruta de archivo siguiendo las siguientes reglas: @@ -209,23 +198,17 @@ Un nombre de vista es resuelto a su correspondiente ruta de archivo siguiendo la * Si el nombre de la vista comienza con doble barra (`//`), la ruta al archivo correspondiente será `@app/views/ViewName`. Esto quiere decir que la vista es buscada bajo el [[yii\base\Application::viewPath|view path de la aplicación]]. Por ejemplo, `//site/about` será resuelto como `@app/views/site/about.php`. -* Si el nombre de la vista comienza con una barra simple `/`, la ruta al archivo de la vista utilizará como prefijo el nombre de la vista con el [[yii\base\Module::viewPath|view path]] del [módulo](structure-modules.md) utilizado actualmente. -Si no hubiera módulo activo se utilizará `@app/views/ViewName`. Por ejemplo, `/user/create` será resuelto a `@app/modules/user/views/user/create.php` si el módulo activo es `user`. Si no hubiera módulo activo, la ruta al archivo será `@app/views/user/create.php`. +* Si el nombre de la vista comienza con una barra simple `/`, la ruta al archivo de la vista utilizará como prefijo el nombre de la vista con el [[yii\base\Module::viewPath|view path]] del [módulo](structure-modules.md) utilizado actualmente. Si no hubiera módulo activo se utilizará `@app/views/ViewName`. Por ejemplo, `/user/create` será resuelto a `@app/modules/user/views/user/create.php` si el módulo activo es `user`. Si no hubiera módulo activo, la ruta al archivo será `@app/views/user/create.php`. * Si la vista es renderizada con un [[yii\base\View::context|context]] y dicho contexto implementa [[yii\base\ViewContextInterface]], la ruta al archivo se forma utilizando como prefijo el [[yii\base\ViewContextInterface::getViewPath()|view path]] del contexto de la vista. Esto principalmente aplica a vistas renderizadas en controladores y widgets. Por ejemplo, `site/about` será resuelto a `@app/views/site/about.php` si el contexto es el controlador `SiteController`. * Si la vista es renderizada dentro de otra vista, el directorio que contiene la otra vista será prefijado al nuevo nombre de la vista para formar la ruta a la vista. Por ejemplo, `item` sera resuelto a `@app/views/post/item` si está siendo renderizado desde la vista `@app/views/post/index.php`. -De acuerdo a las reglas mencionadas, al llamar a `$this->render('view')` en el controlador `app\controllers\PostController` -se renderizará el template `@app/views/post/view.php`, mientras que llamando a `$this->render('_overview')` en la vista -renderizará el template `@app/views/post/_overview.php`. +De acuerdo a las reglas mencionadas, al llamar a `$this->render('view')` en el controlador `app\controllers\PostController` se renderizará el template `@app/views/post/view.php`, mientras que llamando a `$this->render('_overview')` en la vista renderizará el template `@app/views/post/_overview.php`. ### Accediendo a Datos en la Vista Hay dos modos posibles de acceder a los datos en la vista: push (inyectar) y pull (traer). -Al pasar los datos como segundo parámetro en algún método de renderización, estás utilizando el modo push. -Los datos deberían ser representados como un array de pares clave-valor. Cuando la vista está siendo renderizada, la función PHP `extract()` será llamada sobre este array así se extraen las variables que contiene a la vista actual . -Por ejemplo, el siguiente código de renderización en un controlador inyectará dos variables a la vista `report`: -`$foo = 1` and `$bar = 2`. +Al pasar los datos como segundo parámetro en algún método de renderización, estás utilizando el modo push. Los datos deberían ser representados como un array de pares clave-valor. Cuando la vista está siendo renderizada, la función PHP `extract()` será llamada sobre este array así se extraen las variables que contiene a la vista actual. Por ejemplo, el siguiente código de renderización en un controlador inyectará dos variables a la vista `report`: `$foo = 1` and `$bar = 2`. ```php echo $this->render('report', [ @@ -261,14 +244,15 @@ Entonces, en el archivo del [layout](#layouts), que es también una vista, puede ]) ?> ``` + ## Layouts Los layouts son un tipo especial de vista que representan partes comunes de otras múltiples vistas. Por ejemplo, las páginas de la mayoría de las aplicaciones Web comparten el mismo encabezado y pie de página. Aunque puedes repetirlos en todas y cada una de las vistas, una mejor forma es hacerlo sólo en el layout e incrustar el resultado de la renderización de la vista en un lugar apropiado del mismo. + ### Creando Layouts -Dado que los layouts son también vistas, pueden ser creados de manera similar a las vistas comunes. Por defecto, los layouts son guardados en el directorio `@app/views/layouts`. Para layouts utilizados dentro de un [módulo](structure-modules.md), deberían ser guardados en el directorio `views/layouts` bajo el [[yii\base\Module::basePath|directorio del módulo]]. -Puedes personalizar el directorio de layouts por defecto configurando la propiedad [[yii\base\Module::layoutPath]] de la aplicación o módulos. +Dado que los layouts son también vistas, pueden ser creados de manera similar a las vistas comunes. Por defecto, los layouts son guardados en el directorio `@app/views/layouts`. Para layouts utilizados dentro de un [módulo](structure-modules.md), deberían ser guardados en el directorio `views/layouts` bajo el [[yii\base\Module::basePath|directorio del módulo]]. Puedes personalizar el directorio de layouts por defecto configurando la propiedad [[yii\base\Module::layoutPath]] de la aplicación o módulos. El siguiente ejemplo muestra cómo debe verse un layout. Ten en cuenta que por motivos ilustrativos, hemos simplificado bastante el código del layout. En la práctica, probablemente le agregues más contenido, como tags en el `head`, un menú principal, etc. @@ -299,43 +283,29 @@ use yii\helpers\Html; endPage() ?> ``` -Como puedes ver, el layout genera los tags HTML comunes a todas las páginas. Dentro de la sección ``, -el layout imprime la variable `$content`, que representa el resultado de la renderización del contenido de cada vista y es incrustado dentro del layout cuando se llama al método [[yii\base\Controller::render()]]. +Como puedes ver, el layout genera los tags HTML comunes a todas las páginas. Dentro de la sección ``,el layout imprime la variable `$content`, que representa el resultado de la renderización del contenido de cada vista y es incrustado dentro del layout cuando se llama al método [[yii\base\Controller::render()]]. La mayoría de layouts deberían llamar a los siguientes métodos (como fue mostrado recién). Estos métodos principalmente disparan eventos acerca del proceso de renderizado así los scripts y tags registrados en otros lugares pueden ser propiamente inyectados en los lugares donde los métodos son llamados. -- [[yii\base\View::beginPage()|beginPage()]]: Este método debería ser llamado bien al principio del layout. -Esto dispara el evento [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]], el cual indica el comienzo de la página. -- [[yii\base\View::endPage()|endPage()]]: Este método debería ser llamado al final del layout. -Esto dispara el evento [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]], indicando el final de la página. -- [[yii\web\View::head()|head()]]: Este método debería llamarse dentro de la sección `` de una página HTML. -Esto genera un espacio vacío que será reemplazado con el código del head HTML registrado (ej. link tags, meta tags) cuando una página finaliza el renderizado. -- [[yii\base\View::beginBody()|beginBody()]]: Este método debería llamarse al principio de la sección ``. -Esto dispara el evento [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]] y genera un espacio vacío que será reemplazado con el código HTML registrado (ej. JavaScript) que apunta al principio del body. -- [[yii\base\View::endBody()|endBody()]]: Este método debería llamarse al final de la sección ``. -Esto dispara el evento [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]], que genera un espacio vacío a ser reemplazado por el código HTML registrado (ej. JavaScript) que apunta al final del body. +- [[yii\base\View::beginPage()|beginPage()]]: Este método debería ser llamado bien al principio del layout. Esto dispara el evento [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]], el cual indica el comienzo de la página. +- [[yii\base\View::endPage()|endPage()]]: Este método debería ser llamado al final del layout. Esto dispara el evento [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]], indicando el final de la página. +- [[yii\web\View::head()|head()]]: Este método debería llamarse dentro de la sección `` de una página HTML. Esto genera un espacio vacío que será reemplazado con el código del head HTML registrado (ej. link tags, meta tags) cuando una página finaliza el renderizado. +- [[yii\base\View::beginBody()|beginBody()]]: Este método debería llamarse al principio de la sección ``. Esto dispara el evento [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]] y genera un espacio vacío que será reemplazado con el código HTML registrado (ej. JavaScript) que apunta al principio del body. +- [[yii\base\View::endBody()|endBody()]]: Este método debería llamarse al final de la sección ``. Esto dispara el evento [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]], que genera un espacio vacío a ser reemplazado por el código HTML registrado (ej. JavaScript) que apunta al final del body. ### Accediendo a Datos en Layouts -Dentro de un layout, tienes acceso a dos variables predefinidas: `$this` y `$content`. La primera se refiere -al componente [[yii\base\View|view]], como en cualquier vista, mientras que la última contiene el resultado de la renderización del contenido de la vista que está siendo renderizada all llamar al método [[yii\base\Controller::render()|render()]] en los controladores. +Dentro de un layout, tienes acceso a dos variables predefinidas: `$this` y `$content`. La primera se refiere al componente [[yii\base\View|view]], como en cualquier vista, mientras que la última contiene el resultado de la renderización del contenido de la vista que está siendo renderizada all llamar al método [[yii\base\Controller::render()|render()]] en los controladores. -Si quieres acceder a otros datos en los layouts, debes utilizar el modo pull que fue descrito en la sub-sección -[Accediendo a Datos en la Vista](#accessing-data-in-views). Si quieres pasar datos desde al contenido de la vista a un layout, puedes utilizar el método descrito en la sub-sección [Compartiendo Datos Entre las Vistas](#sharing-data-among-views). +Si quieres acceder a otros datos en los layouts, debes utilizar el modo pull que fue descrito en la sub-sección [Accediendo a Datos en la Vista](#accessing-data-in-views). Si quieres pasar datos desde al contenido de la vista a un layout, puedes utilizar el método descrito en la sub-sección [Compartiendo Datos Entre las Vistas](#sharing-data-among-views). ### Utilizando Layouts -Como se describe en la sub-sección [Renderizando en Controllers](#rendering-in-controllers), cuando renderizas una vista -llamando al método [[yii\base\Controller::render()|render()]] en un controlador, al resultado de dicha renderización -le será aplicado un layout. Por defecto, el layout `@app/views/layouts/main.php` será el utilizado. +Como se describe en la sub-sección [Renderizando en Controllers](#rendering-in-controllers), cuando renderizas una vista llamando al método [[yii\base\Controller::render()|render()]] en un controlador, al resultado de dicha renderización le será aplicado un layout. Por defecto, el layout `@app/views/layouts/main.php` será el utilizado. -Puedes utilizar un layout diferente configurando la propiedad [[yii\base\Application::layout]] o [[yii\base\Controller::layout]]. -El primero se refiere al layout utilizado por todos los controladores, mientras que el último sobrescribe el layout en controladores individuales. -Por ejemplo, el siguiente código hace que el controlador `post` utilice `@app/views/layouts/post.php` como layout -al renderizar sus vistas. Otros controladores, asumiendo que su propiedad `layout` no fue modificada, utilizarán -`@app/views/layouts/main.php` como layout. +Puedes utilizar un layout diferente configurando la propiedad [[yii\base\Application::layout]] o [[yii\base\Controller::layout]]. El primero se refiere al layout utilizado por todos los controladores, mientras que el último sobrescribe el layout en controladores individuales. Por ejemplo, el siguiente código hace que el controlador `post` utilice `@app/views/layouts/post.php` como layout al renderizar sus vistas. Otros controladores, asumiendo que su propiedad `layout` no fue modificada, utilizarán `@app/views/layouts/main.php` como layout. ```php namespace app\controllers; @@ -350,31 +320,20 @@ class PostController extends Controller } ``` -Para controladores que pertencen a un módulo, puedes también configurar la propiedad [[yii\base\Module::layout|layout]] y así -utilizar un layout en particular para esos controladores. +Para controladores que pertencen a un módulo, puedes también configurar la propiedad [[yii\base\Module::layout|layout]] y así utilizar un layout en particular para esos controladores. -Dado que la propiedad `layout` puede ser configurada en diferentes niveles (controladores, módulos, aplicación), -detrás de escena Yii realiza dos pasos para determinar cuál es el archivo de layout siendo utilizado para un controlador en particular. +Dado que la propiedad `layout` puede ser configurada en diferentes niveles (controladores, módulos, aplicación), detrás de escena Yii realiza dos pasos para determinar cuál es el archivo de layout siendo utilizado para un controlador en particular. En el primer paso, determina el valor del layout y el módulo de contexto: -- Si la propiedad [[yii\base\Controller::layout]] no es `null`, la utiliza como valor del layout y - el [[yii\base\Controller::module|módulo]] del controlador como el módulo de contexto. -- Si [[yii\base\Controller::layout|layout]] es `null`, busca a través de todos los módulos ancestros del controlador y - encuentra el primer módulo cuya propiedad [[yii\base\Module::layout|layout]] no es `null`. Utiliza ese módulo y - su valor de [[yii\base\Module::layout|layout]] como módulo de contexto y como layout seleccionado. - Si tal módulo no puede ser encontrado, significa que no se aplicará ningún layout. +- Si la propiedad [[yii\base\Controller::layout]] no es `null`, la utiliza como valor del layout y el [[yii\base\Controller::module|módulo]] del controlador como el módulo de contexto. +- Si [[yii\base\Controller::layout|layout]] es `null`, busca a través de todos los módulos ancestros del controlador y encuentra el primer módulo cuya propiedad [[yii\base\Module::layout|layout]] no es `null`. Utiliza ese módulo y su valor de [[yii\base\Module::layout|layout]] como módulo de contexto y como layout seleccionado. Si tal módulo no puede ser encontrado, significa que no se aplicará ningún layout. -En el segundo paso, se determina el archivo de layout actual de acuerdo al valor de layout y el módulo de contexto -determinado en el primer paso. El valor de layout puede ser: +En el segundo paso, se determina el archivo de layout actual de acuerdo al valor de layout y el módulo de contexto determinado en el primer paso. El valor de layout puede ser: - un alias de ruta (ej. `@app/views/layouts/main`). -- una ruta absoluta (ej. `/main`): el valor del layout comienza con una barra. El archivo de layout actual será - buscado bajo el [[yii\base\Application::layoutPath|layout path]] de la aplicación, que es por defecto - `@app/views/layouts`. -- una ruta relativa (ej. `main`): El archivo de layout actual será buscado bajo el - [[yii\base\Module::layoutPath|layout path]] del módulo de contexto, que es por defecto el directorio `views/layouts` - bajo el [[yii\base\Module::basePath|directorio del módulo]]. +- una ruta absoluta (ej. `/main`): el valor del layout comienza con una barra. El archivo de layout actual será buscado bajo el [[yii\base\Application::layoutPath|layout path]] de la aplicación, que es por defecto `@app/views/layouts`. +- una ruta relativa (ej. `main`): El archivo de layout actual será buscado bajo el [[yii\base\Module::layoutPath|layout path]] del módulo de contexto, que es por defecto el directorio `views/layouts` bajo el [[yii\base\Module::basePath|directorio del módulo]]. - el valor booleano `false`: no se aplicará ningún layout. Si el valor de layout no contiene una extensión de tipo de archivo, utilizará por defecto `.php`. @@ -382,10 +341,7 @@ Si el valor de layout no contiene una extensión de tipo de archivo, utilizará ### Layouts Anidados -A veces podrías querer anidar un layout dentro de otro. Por ejemplo, en diferentes secciones de un sitio Web, podrías -querer utilizar layouts diferentes, mientras que todos esos layouts comparten el mismo layout básico que genera la -estructura general de la página en HTML5. Esto es posible llamando a los métodos [[yii\base\View::beginContent()|beginContent()]] y -[[yii\base\View::endContent()|endContent()]] en los layouts hijos como se muestra a continuación: +A veces podrías querer anidar un layout dentro de otro. Por ejemplo, en diferentes secciones de un sitio Web, podrías querer utilizar layouts diferentes, mientras que todos esos layouts comparten el mismo layout básico que genera la estructura general de la página en HTML5. Esto es posible llamando a los métodos [[yii\base\View::beginContent()|beginContent()]] y [[yii\base\View::endContent()|endContent()]] en los layouts hijos como se muestra a continuación: ```php beginContent('@app/views/layouts/base.php'); ?> @@ -395,19 +351,14 @@ estructura general de la página en HTML5. Esto es posible llamando a los métod endContent(); ?> ``` -Como se acaba de mostrar, el contenido del layout hijo debe ser encerrado dentro de [[yii\base\View::beginContent()|beginContent()]] y -[[yii\base\View::endContent()|endContent()]]. El parámetro pasado a [[yii\base\View::beginContent()|beginContent()]] -especifica cuál es el módulo padre. Este puede ser tanto un archivo layout como un alias. +Como se acaba de mostrar, el contenido del layout hijo debe ser encerrado dentro de [[yii\base\View::beginContent()|beginContent()]] y [[yii\base\View::endContent()|endContent()]]. El parámetro pasado a [[yii\base\View::beginContent()|beginContent()]] especifica cuál es el módulo padre. Este puede ser tanto un archivo layout como un alias. Utilizando la forma recién mencionada, puedes anidar layouts en más de un nivel. ## Utilizando Componentes de Vista -Los [[yii\base\View|componentes de vista]] proveen características relacionadas a las vistas. Aunque puedes obtener componentes de vista -creando instancias individuales de [[yii\base\View]] o sus clases hijas, en la mayoría de los casos utilizarías el -componente `view` del a aplicación. Puedes configurar este componente en la [configuración de la aplicación](structure-applications.md#application-configurations) -como a continuación: +Los [[yii\base\View|componentes de vista]] proveen características relacionadas a las vistas. Aunque puedes obtener componentes de vista creando instancias individuales de [[yii\base\View]] o sus clases hijas, en la mayoría de los casos utilizarías el componente `view` del a aplicación. Puedes configurar este componente en la [configuración de la aplicación](structure-applications.md#application-configurations) como a continuación: ```php [ @@ -435,9 +386,7 @@ Puedes también utilizar frecuentemente el siguiente menor pero útil grupo de c ### Definiendo Títulos de Página -Toda página Web debería tener un título. Normalmente el tag de título es generado en [layout](#layouts). De todos modos, en la práctica -el título es determinado en el contenido de las vistas más que en layouts. Para resolver este problema, [[yii\web\View]] provee -la propiedad [[yii\web\View::title|title]] para que puedas pasar información del título desde el contenido de la vista a los layouts. +Toda página Web debería tener un título. Normalmente el tag de título es generado en [layout](#layouts). De todos modos, en la práctica el título es determinado en el contenido de las vistas más que en layouts. Para resolver este problema, [[yii\web\View]] provee la propiedad [[yii\web\View::title|title]] para que puedas pasar información del título desde el contenido de la vista a los layouts. Para utilizar esta característica, en cada contenido de la vista, puedes definir el título de la siguiente manera: @@ -456,11 +405,9 @@ Entonces en el layout, asegúrate de tener el siguiente código en la sección ` ### Registrando Meta Tags -Las páginas Web usualmente necesitan generar varios meta tags necesarios por diferentes grupos (ej. Facebook, motores de búsqueda, etc). -Cómo los títulos de página, los meta tags aparecen en la sección `` y son usualmente generado en los layouts. +Las páginas Web usualmente necesitan generar varios meta tags necesarios por diferentes grupos (ej. Facebook, motores de búsqueda, etc). Cómo los títulos de página, los meta tags aparecen en la sección `` y son usualmente generado en los layouts. -Si quieres especificar cuáles meta tags generar en las vistas, puedes llamar a [[yii\web\View::registerMetaTag()]] -dentro de una de ellas, como se muestra a continuación: +Si quieres especificar cuáles meta tags generar en las vistas, puedes llamar a [[yii\web\View::registerMetaTag()]] dentro de una de ellas, como se muestra a continuación: ```php registerMetaTag(['name' => 'keywords', 'content' => 'yii, framework, php' ?> ``` -El código anterior registrará el meta tag "keywords" a través del componente view. El meta tag registrado no -se renderiza hasta que finaliza el renderizado del layout. Para entonces, el siguiente código HTML será insertado -en el lugar donde llamas a [[yii\web\View::head()]] en el layout, generando el siguiente HTML: +El código anterior registrará el meta tag "keywords" a través del componente view. El meta tag registrado no se renderiza hasta que finaliza el renderizado del layout. Para entonces, el siguiente código HTML será insertado en el lugar donde llamas a [[yii\web\View::head()]] en el layout, generando el siguiente HTML: ```php ``` -Ten en cuenta que si llamas a [[yii\web\View::registerMetaTag()]] varias veces, esto registrará varios meta tags, -sin tener en cuenta si los meta tags son los mismo o no. +Ten en cuenta que si llamas a [[yii\web\View::registerMetaTag()]] varias veces, esto registrará varios meta tags, sin tener en cuenta si los meta tags son los mismo o no. -Para asegurarte de que sólo haya una instancia de cierto tipo de meta tag, puedes especificar una clave al llamar al método. -Por ejemplo, el siguiente código registra dos meta tags "description", aunque sólo el segundo será renderizado. +Para asegurarte de que sólo haya una instancia de cierto tipo de meta tag, puedes especificar una clave al llamar al método. Por ejemplo, el siguiente código registra dos meta tags "description", aunque sólo el segundo será renderizado. ```html $this->registerMetaTag(['name' => 'description', 'content' => 'Este es mi sitio Web cool hecho con Yii!'], 'description'); @@ -490,9 +433,7 @@ $this->registerMetaTag(['name' => 'description', 'content' => 'Este sitio Web es ### Registrando Link Tags -Tal como los [meta tags](#adding-meta-tags), los link tags son útiles en muchos casos, como personalizar el ícono (favicon) del sitio, apuntar a -una fuente de RSS o delegar OpenID a otro servidor. Puedes trabajar con link tags, al igual que con meta tags, -utilizando [[yii\web\View::registerLinkTag()]]. Por ejemplo, en el contenido de una vista, puedes registrar un link tag como se muestra a continuación: +Tal como los [meta tags](#adding-meta-tags), los link tags son útiles en muchos casos, como personalizar el ícono (favicon) del sitio, apuntar a una fuente de RSS o delegar OpenID a otro servidor. Puedes trabajar con link tags, al igual que con meta tags, utilizando [[yii\web\View::registerLinkTag()]]. Por ejemplo, en el contenido de una vista, puedes registrar un link tag como se muestra a continuación: ```php $this->registerLinkTag([ @@ -509,8 +450,7 @@ El resultado del código es el siguiente: ``` -Al igual que con [[yii\web\View::registerMetaTag()|registerMetaTags()]], puedes especificar una clave al llamar a -[[yii\web\View::registerLinkTag()|registerLinkTag()]] para evitar registrar link tags repetidos. +Al igual que con [[yii\web\View::registerMetaTag()|registerMetaTags()]], puedes especificar una clave al llamar a [[yii\web\View::registerLinkTag()|registerLinkTag()]] para evitar registrar link tags repetidos. ## Eventos de Vistas @@ -547,8 +487,7 @@ public function actionAbout() } ``` -Si un sitio Web contiene muchas páginas estáticas, resultaría tedioso repetir el mismo código en muchos lados. -Para resolver este problema, puedes introducir una [acción independiente](structure-controllers.md#standalone-actions) llamada [[yii\web\ViewAction]] en el controlador. Por ejemplo, +Si un sitio Web contiene muchas páginas estáticas, resultaría tedioso repetir el mismo código en muchos lados. Para resolver este problema, puedes introducir una [acción independiente](structure-controllers.md#standalone-actions) llamada [[yii\web\ViewAction]] en el controlador. Por ejemplo, ```php namespace app\controllers; @@ -587,11 +526,9 @@ Las vistas son responsables de la presentación de modelos en el formato que el Si se necesitan datos del `request`, deben ser inyectados a la vista desde el controlador. * pueden leer propiedades del modelo, pero no debería modificarlas. -Para hacer las vistas más manejables, evita crear vistas que son demasiado complejas o que contengan código redundante. -Puedes utilizar estas técnicas para alcanzar dicha meta: +Para hacer las vistas más manejables, evita crear vistas que son demasiado complejas o que contengan código redundante. Puedes utilizar estas técnicas para alcanzar dicha meta: * utiliza [layouts](#layouts) para representar secciones comunes (ej. encabezado y footer de la página). * divide una vista compleja en varias más simples. Las vistas pequeñas pueden ser renderizadas y unidas una mayor utilizando los métodos de renderización antes descritos. * crea y utiliza [widgets](structure-widgets.md) como bloques de construcción de la vista. * crea y utilizar helpers para transformar y dar formato a los datos en la vista. - diff --git a/docs/internals-es/translation-workflow.md b/docs/internals-es/translation-workflow.md index e7938f2..80e0759 100644 --- a/docs/internals-es/translation-workflow.md +++ b/docs/internals-es/translation-workflow.md @@ -59,3 +59,4 @@ Convenios para la traducción - link — enlace - render — sin traducción - DatePicker — sin traducción +- rendering — renderizando From 798a22be4d3fc9f69cc53b5ae599352893e67759 Mon Sep 17 00:00:00 2001 From: Jared Feng Date: Tue, 7 Oct 2014 15:18:08 +0800 Subject: [PATCH 23/43] add missing semicolon, fixes #5393 --- framework/views/errorHandler/callStackItem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/views/errorHandler/callStackItem.php b/framework/views/errorHandler/callStackItem.php index 84fc1dc..e86f44f 100644 --- a/framework/views/errorHandler/callStackItem.php +++ b/framework/views/errorHandler/callStackItem.php @@ -17,7 +17,7 @@ htmlEncode($file); ?> - + addTypeLinks("$class::$method") : $handler->htmlEncode($method)) . '(' . $handler->argumentsToString($args) . ')' ?> From df82aabe7b3ee4a802c14df34e8364c838ef4bdb Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Tue, 7 Oct 2014 12:17:42 +0400 Subject: [PATCH 24/43] Fixes #5395: added note about session table id column length --- docs/guide/runtime-sessions-cookies.md | 2 +- framework/web/DbSession.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/guide/runtime-sessions-cookies.md b/docs/guide/runtime-sessions-cookies.md index eda136f..d0d28d9 100644 --- a/docs/guide/runtime-sessions-cookies.md +++ b/docs/guide/runtime-sessions-cookies.md @@ -174,7 +174,7 @@ where 'BLOB' refers to the BLOB-type of your preferred DBMS. Below are the BLOB - PostgreSQL: BYTEA - MSSQL: BLOB - +Note that length of id column should be adjusted if `session.hash_function` is changed in `php.ini`. ### Flash Data diff --git a/framework/web/DbSession.php b/framework/web/DbSession.php index 96fa8b2..e4bd7ff 100644 --- a/framework/web/DbSession.php +++ b/framework/web/DbSession.php @@ -65,6 +65,8 @@ 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 length of id column should be adjusted if `session.hash_function` is changed in `php.ini`. */ public $sessionTable = '{{%session}}'; From eb1b557827cda16e97fe80d8e8b3b05336aafd38 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Tue, 7 Oct 2014 13:32:26 +0300 Subject: [PATCH 25/43] `yii\sphinx\Query` updated to be more consistent with `yii\db\Query` --- extensions/sphinx/Query.php | 475 ++++------------------------- extensions/sphinx/QueryBuilder.php | 117 +++++-- tests/unit/extensions/sphinx/QueryTest.php | 16 + 3 files changed, 165 insertions(+), 443 deletions(-) diff --git a/extensions/sphinx/Query.php b/extensions/sphinx/Query.php index 397bb02..77e4ac3 100644 --- a/extensions/sphinx/Query.php +++ b/extensions/sphinx/Query.php @@ -8,10 +8,9 @@ namespace yii\sphinx; use Yii; -use yii\base\Component; use yii\base\InvalidCallException; +use yii\base\NotSupportedException; use yii\db\Expression; -use yii\db\QueryInterface; use yii\db\QueryTrait; /** @@ -46,31 +45,8 @@ use yii\db\QueryTrait; * @author Paul Klimov * @since 2.0 */ -class Query extends Component implements QueryInterface +class Query extends \yii\db\Query { - use QueryTrait; - - /** - * @var array the columns being selected. For example, `['id', 'group_id']`. - * This is used to construct the SELECT clause in a SQL statement. If not set, if means selecting all columns. - * @see select() - */ - public $select; - /** - * @var string additional option that should be appended to the 'SELECT' keyword. - */ - public $selectOption; - /** - * @var boolean whether to select distinct rows of data only. If this is set true, - * the SELECT clause would be changed to SELECT DISTINCT. - */ - public $distinct; - /** - * @var array the index(es) to be selected from. For example, `['idx_user', 'idx_user_delta']`. - * This is used to construct the FROM clause in a SQL statement. - * @see from() - */ - public $from; /** * @var string|Expression text, which should be searched in fulltext mode. * This value will be composed into MATCH operator inside the WHERE clause. @@ -80,11 +56,6 @@ class Query extends Component implements QueryInterface */ public $match; /** - * @var array how to group the query results. For example, `['company', 'department']`. - * This is used to construct the GROUP BY clause in a SQL statement. - */ - public $groupBy; - /** * @var string WITHIN GROUP ORDER BY clause. This is a Sphinx specific extension * that lets you control how the best row within a group will to be selected. * The possible value matches the [[orderBy]] one. @@ -97,11 +68,6 @@ class Query extends Component implements QueryInterface */ public $options; /** - * @var array list of query parameter values indexed by parameter placeholders. - * For example, `[':name' => 'Dan', ':age' => 31]`. - */ - public $params = []; - /** * @var callable PHP callback, which should be used to fetch source data for the snippets. * Such callback will receive array of query result rows as an argument and must return the * array of snippet source strings in the order, which match one of incoming rows. @@ -165,55 +131,33 @@ class Query extends Component implements QueryInterface /** * Creates a Sphinx command that can be used to execute this query. - * @param Connection $connection the Sphinx connection used to generate the SQL statement. + * @param Connection $db the Sphinx connection used to generate the SQL statement. * If this parameter is not given, the `sphinx` application component will be used. * @return Command the created Sphinx command instance. */ - public function createCommand($connection = null) + public function createCommand($db = null) { - $this->setConnection($connection); - $connection = $this->getConnection(); - list ($sql, $params) = $connection->getQueryBuilder()->build($this); + $this->setConnection($db); + $db = $this->getConnection(); + list ($sql, $params) = $db->getQueryBuilder()->build($this); - return $connection->createCommand($sql, $params); + return $db->createCommand($sql, $params); } /** - * Executes the query and returns all results as an array. - * @param Connection $db the Sphinx connection used to generate the SQL statement. - * If this parameter is not given, the `sphinx` application component will be used. - * @return array the query results. If the query results in nothing, an empty array will be returned. + * @inheritdoc */ - public function all($db = null) + public function populate($rows) { - $rows = $this->createCommand($db)->queryAll(); - $rows = $this->fillUpSnippets($rows); - if ($this->indexBy === null) { - return $rows; - } - $result = []; - foreach ($rows as $row) { - if (is_string($this->indexBy)) { - $key = $row[$this->indexBy]; - } else { - $key = call_user_func($this->indexBy, $row); - } - $result[$key] = $row; - } - - return $result; + return parent::populate($this->fillUpSnippets($rows)); } /** - * Executes the query and returns a single row of result. - * @param Connection $db the Sphinx connection used to generate the SQL statement. - * If this parameter is not given, the `sphinx` application component will be used. - * @return array|boolean the first row (in terms of an array) of the query result. False is returned if the query - * results in nothing. + * @inheritdoc */ public function one($db = null) { - $row = $this->createCommand($db)->queryOne(); + $row = parent::one($db); if ($row !== false) { list ($row) = $this->fillUpSnippets([$row]); } @@ -222,168 +166,6 @@ class Query extends Component implements QueryInterface } /** - * Returns the query result as a scalar value. - * The value returned will be the first column in the first row of the query results. - * @param Connection $db the Sphinx connection used to generate the SQL statement. - * If this parameter is not given, the `sphinx` application component will be used. - * @return string|boolean the value of the first column in the first row of the query result. - * False is returned if the query result is empty. - */ - public function scalar($db = null) - { - return $this->createCommand($db)->queryScalar(); - } - - /** - * Executes the query and returns the first column of the result. - * @param Connection $db the Sphinx connection used to generate the SQL statement. - * If this parameter is not given, the `sphinx` application component will be used. - * @return array the first column of the query result. An empty array is returned if the query results in nothing. - */ - public function column($db = null) - { - return $this->createCommand($db)->queryColumn(); - } - - /** - * Returns the number of records. - * @param string $q the COUNT expression. Defaults to '*'. - * Make sure you properly quote column names in the expression. - * @param Connection $db the Sphinx connection used to generate the SQL statement. - * If this parameter is not given, the `sphinx` application component will be used. - * @return integer number of records - */ - public function count($q = '*', $db = null) - { - $this->select = ["COUNT($q)"]; - - return $this->createCommand($db)->queryScalar(); - } - - /** - * Returns the sum of the specified column values. - * @param string $q the column name or expression. - * Make sure you properly quote column names in the expression. - * @param Connection $db the Sphinx connection used to generate the SQL statement. - * If this parameter is not given, the `sphinx` application component will be used. - * @return integer the sum of the specified column values - */ - public function sum($q, $db = null) - { - $this->select = ["SUM($q)"]; - - return $this->createCommand($db)->queryScalar(); - } - - /** - * Returns the average of the specified column values. - * @param string $q the column name or expression. - * Make sure you properly quote column names in the expression. - * @param Connection $db the Sphinx connection used to generate the SQL statement. - * If this parameter is not given, the `sphinx` application component will be used. - * @return integer the average of the specified column values. - */ - public function average($q, $db = null) - { - $this->select = ["AVG($q)"]; - - return $this->createCommand($db)->queryScalar(); - } - - /** - * Returns the minimum of the specified column values. - * @param string $q the column name or expression. - * Make sure you properly quote column names in the expression. - * @param Connection $db the Sphinx connection used to generate the SQL statement. - * If this parameter is not given, the `sphinx` application component will be used. - * @return integer the minimum of the specified column values. - */ - public function min($q, $db = null) - { - $this->select = ["MIN($q)"]; - - return $this->createCommand($db)->queryScalar(); - } - - /** - * Returns the maximum of the specified column values. - * @param string $q the column name or expression. - * Make sure you properly quote column names in the expression. - * @param Connection $db the Sphinx connection used to generate the SQL statement. - * If this parameter is not given, the `sphinx` application component will be used. - * @return integer the maximum of the specified column values. - */ - public function max($q, $db = null) - { - $this->select = ["MAX($q)"]; - - return $this->createCommand($db)->queryScalar(); - } - - /** - * Returns a value indicating whether the query result contains any row of data. - * @param Connection $db the Sphinx connection used to generate the SQL statement. - * If this parameter is not given, the `sphinx` application component will be used. - * @return boolean whether the query result contains any row of data. - */ - public function exists($db = null) - { - $this->select = [new Expression('1')]; - - return $this->scalar($db) !== false; - } - - /** - * Sets the SELECT part of the query. - * @param string|array $columns the columns to be selected. - * Columns can be specified in either a string (e.g. "id, name") or an array (e.g. ['id', 'name']). - * The method will automatically quote the column names unless a column contains some parenthesis - * (which means the column contains a Sphinx expression). - * @param string $option additional option that should be appended to the 'SELECT' keyword. - * @return static the query object itself - */ - public function select($columns, $option = null) - { - if (!is_array($columns)) { - $columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY); - } - $this->select = $columns; - $this->selectOption = $option; - - return $this; - } - - /** - * Sets the value indicating whether to SELECT DISTINCT or not. - * @param boolean $value whether to SELECT DISTINCT or not. - * @return static the query object itself - */ - public function distinct($value = true) - { - $this->distinct = $value; - - return $this; - } - - /** - * Sets the FROM part of the query. - * @param string|array $tables the table(s) to be selected from. This can be either a string (e.g. `'idx_user'`) - * or an array (e.g. `['idx_user', 'idx_user_delta']`) specifying one or several index names. - * The method will automatically quote the table names unless it contains some parenthesis - * (which means the table is given as a sub-query or Sphinx expression). - * @return static the query object itself - */ - public function from($tables) - { - if (!is_array($tables)) { - $tables = preg_split('/\s*,\s*/', trim($tables), -1, PREG_SPLIT_NO_EMPTY); - } - $this->from = $tables; - - return $this; - } - - /** * Sets the fulltext query text. This text will be composed into * MATCH operator inside the WHERE clause. * Note: this value will be processed by [[Connection::escapeMatchValue()]], @@ -405,210 +187,35 @@ class Query extends Component implements QueryInterface } /** - * Sets the WHERE part of the query. - * - * The method requires a $condition parameter, and optionally a $params parameter - * specifying the values to be bound to the query. - * - * The $condition parameter should be either a string (e.g. 'id=1') or an array. - * If the latter, it must be in one of the following two formats: - * - * - hash format: `['column1' => value1, 'column2' => value2, ...]` - * - operator format: `[operator, operand1, operand2, ...]` - * - * A condition in hash format represents the following SQL expression in general: - * `column1=value1 AND column2=value2 AND ...`. In case when a value is an array or a Query object, - * an `IN` expression will be generated. And if a value is null, `IS NULL` will be used - * in the generated expression. Below are some examples: - * - * - `['type' => 1, 'status' => 2]` generates `(type = 1) AND (status = 2)`. - * - `['id' => [1, 2, 3], 'status' => 2]` generates `(id IN (1, 2, 3)) AND (status = 2)`. - * - `['status' => null] generates `status IS NULL`. - * - `['id' => $query]` generates `id IN (...sub-query...)` - * - * A condition in operator format generates the SQL expression according to the specified operator, which - * can be one of the followings: - * - * - `and`: the operands should be concatenated together using `AND`. For example, - * `['and', 'id=1', 'id=2']` will generate `id=1 AND id=2`. If an operand is an array, - * it will be converted into a string using the rules described here. For example, - * `['and', 'type=1', ['or', 'id=1', 'id=2']]` will generate `type=1 AND (id=1 OR id=2)`. - * The method will NOT do any quoting or escaping. - * - * - `or`: similar to the `and` operator except that the operands are concatenated using `OR`. - * - * - `between`: operand 1 should be the column name, and operand 2 and 3 should be the - * starting and ending values of the range that the column is in. - * For example, `['between', 'id', 1, 10]` will generate `id BETWEEN 1 AND 10`. - * - * - `not between`: similar to `between` except the `BETWEEN` is replaced with `NOT BETWEEN` - * in the generated condition. - * - * - `in`: operand 1 should be a column or DB expression with parenthesis. Operand 2 can be an array - * or a Query object. If the former, the array represents the range of the values that the column - * or DB expression should be in. If the latter, a sub-query will be generated to represent the range. - * For example, `['in', 'id', [1, 2, 3]]` will generate `id IN (1, 2, 3)`; - * `['in', 'id', (new Query)->select('id')->from('user'))]` will generate - * `id IN (SELECT id FROM user)`. The method will properly quote the column name and escape values in the range. - * The `in` operator also supports composite columns. In this case, operand 1 should be an array of the columns, - * while operand 2 should be an array of arrays or a `Query` object representing the range of the columns. - * - * - `not in`: similar to the `in` operator except that `IN` is replaced with `NOT IN` in the generated condition. - * - * - `like`: operand 1 should be a column or DB expression, and operand 2 be a string or an array representing - * the values that the column or DB expression should be like. - * For example, `['like', 'name', '%tester%']` will generate `name LIKE '%tester%'`. - * When the value range is given as an array, multiple `LIKE` predicates will be generated and concatenated - * using `AND`. For example, `['like', 'name', ['%test%', '%sample%']]` will generate - * `name LIKE '%test%' AND name LIKE '%sample%'`. - * The method will properly quote the column name and escape values in the range. - * Sometimes, you may want to add the percentage characters to the matching value by yourself, you may supply - * a third operand `false` to do so. For example, `['like', 'name', '%tester', false]` will generate `name LIKE '%tester'`. - * - * - `or like`: similar to the `like` operator except that `OR` is used to concatenate the `LIKE` - * predicates when operand 2 is an array. - * - * - `not like`: similar to the `like` operator except that `LIKE` is replaced with `NOT LIKE` - * in the generated condition. - * - * - `or not like`: similar to the `not like` operator except that `OR` is used to concatenate - * the `NOT LIKE` predicates. - * - * @param string|array $condition the conditions that should be put in the WHERE part. - * @param array $params the parameters (name => value) to be bound to the query. - * @return static the query object itself - * @see andWhere() - * @see orWhere() + * @inheritdoc */ - public function where($condition, $params = []) + public function join($type, $table, $on = '', $params = []) { - $this->where = $condition; - $this->addParams($params); - return $this; + throw new NotSupportedException('"' . __METHOD__ . '" is not supported.'); } /** - * Adds an additional WHERE condition to the existing one. - * The new condition and the existing one will be joined using the 'AND' operator. - * @param string|array $condition the new WHERE condition. Please refer to [[where()]] - * on how to specify this parameter. - * @param array $params the parameters (name => value) to be bound to the query. - * @return static the query object itself - * @see where() - * @see orWhere() + * @inheritdoc */ - public function andWhere($condition, $params = []) + public function innerJoin($table, $on = '', $params = []) { - if ($this->where === null) { - $this->where = $condition; - } else { - $this->where = ['and', $this->where, $condition]; - } - $this->addParams($params); - return $this; - } - - /** - * Adds an additional WHERE condition to the existing one. - * The new condition and the existing one will be joined using the 'OR' operator. - * @param string|array $condition the new WHERE condition. Please refer to [[where()]] - * on how to specify this parameter. - * @param array $params the parameters (name => value) to be bound to the query. - * @return static the query object itself - * @see where() - * @see andWhere() - */ - public function orWhere($condition, $params = []) - { - if ($this->where === null) { - $this->where = $condition; - } else { - $this->where = ['or', $this->where, $condition]; - } - $this->addParams($params); - return $this; - } - - /** - * Sets the GROUP BY part of the query. - * @param string|array $columns the columns to be grouped by. - * Columns can be specified in either a string (e.g. "id, name") or an array (e.g. ['id', 'name']). - * The method will automatically quote the column names unless a column contains some parenthesis - * (which means the column contains a DB expression). - * @return static the query object itself - * @see addGroupBy() - */ - public function groupBy($columns) - { - if (!is_array($columns)) { - $columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY); - } - $this->groupBy = $columns; - - return $this; - } - - /** - * Adds additional group-by columns to the existing ones. - * @param string|array $columns additional columns to be grouped by. - * Columns can be specified in either a string (e.g. "id, name") or an array (e.g. ['id', 'name']). - * The method will automatically quote the column names unless a column contains some parenthesis - * (which means the column contains a DB expression). - * @return static the query object itself - * @see groupBy() - */ - public function addGroupBy($columns) - { - if (!is_array($columns)) { - $columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY); - } - if ($this->groupBy === null) { - $this->groupBy = $columns; - } else { - $this->groupBy = array_merge($this->groupBy, $columns); - } - - return $this; + throw new NotSupportedException('"' . __METHOD__ . '" is not supported.'); } /** - * Sets the parameters to be bound to the query. - * @param array $params list of query parameter values indexed by parameter placeholders. - * For example, `[':name' => 'Dan', ':age' => 31]`. - * @return static the query object itself - * @see addParams() + * @inheritdoc */ - public function params($params) + public function leftJoin($table, $on = '', $params = []) { - $this->params = $params; - - return $this; + throw new NotSupportedException('"' . __METHOD__ . '" is not supported.'); } /** - * Adds additional parameters to be bound to the query. - * @param array $params list of query parameter values indexed by parameter placeholders. - * For example, `[':name' => 'Dan', ':age' => 31]`. - * @return static the query object itself - * @see params() + * @inheritdoc */ - public function addParams($params) + public function rightJoin($table, $on = '', $params = []) { - if (!empty($params)) { - if (empty($this->params)) { - $this->params = $params; - } else { - foreach ($params as $name => $value) { - if (is_integer($name)) { - $this->params[] = $value; - } else { - $this->params[$name] = $value; - } - } - } - } - - return $this; + throw new NotSupportedException('"' . __METHOD__ . '" is not supported.'); } /** @@ -759,4 +366,36 @@ class Query extends Component implements QueryInterface ->callSnippets($from, $source, $match, $this->snippetOptions) ->queryColumn(); } + + /** + * Creates a new Query object and copies its property values from an existing one. + * The properties being copies are the ones to be used by query builders. + * @param Query $from the source query object + * @return Query the new Query object + */ + public static function create($from) + { + return new self([ + 'where' => $from->where, + 'limit' => $from->limit, + 'offset' => $from->offset, + 'orderBy' => $from->orderBy, + 'indexBy' => $from->indexBy, + 'select' => $from->select, + 'selectOption' => $from->selectOption, + 'distinct' => $from->distinct, + 'from' => $from->from, + 'groupBy' => $from->groupBy, + 'join' => $from->join, + 'having' => $from->having, + 'union' => $from->union, + 'params' => $from->params, + // Sphinx specifics : + 'options' => $from->options, + 'within' => $from->within, + 'match' => $from->match, + 'snippetCallback' => $from->snippetCallback, + 'snippetOptions' => $from->snippetOptions, + ]); + } } diff --git a/extensions/sphinx/QueryBuilder.php b/extensions/sphinx/QueryBuilder.php index 00c1023..e5e9cf4 100644 --- a/extensions/sphinx/QueryBuilder.php +++ b/extensions/sphinx/QueryBuilder.php @@ -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; + } } diff --git a/tests/unit/extensions/sphinx/QueryTest.php b/tests/unit/extensions/sphinx/QueryTest.php index 28858fd..2fdf7fb 100644 --- a/tests/unit/extensions/sphinx/QueryTest.php +++ b/tests/unit/extensions/sphinx/QueryTest.php @@ -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; From b9520596649a97b6851d91a9ccf849d798ba3354 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Tue, 7 Oct 2014 13:35:07 +0300 Subject: [PATCH 26/43] Issue #5211 added to CHANGELOG --- extensions/sphinx/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/sphinx/CHANGELOG.md b/extensions/sphinx/CHANGELOG.md index 9f19298..9996936 100644 --- a/extensions/sphinx/CHANGELOG.md +++ b/extensions/sphinx/CHANGELOG.md @@ -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 From f3a6b1985df669d479c0c5a3ae40e635c8add3f9 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Tue, 7 Oct 2014 15:21:21 +0200 Subject: [PATCH 27/43] do not call afterAction() if beforeAction returned false fixes #5379 --- framework/CHANGELOG.md | 3 ++- framework/base/Controller.php | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 564e9d3..863dcde 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -8,7 +8,8 @@ Yii Framework 2 Change Log - Bug #5260: `yii\i18n\Formatter::decimalSeparator` and `yii\i18n\Formatter::thousandSeparator` where not configurable when intl is not installed (execut, cebe) - 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 #5336: `yii\bootstrap\DropDown` should register bootstrap plugin asset (zelenin) +- Bug #5379: `Module::afterAction()` was called even when `beforeAction()` returned false (cebe) - 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) diff --git a/framework/base/Controller.php b/framework/base/Controller.php index 072984b..b08fc66 100644 --- a/framework/base/Controller.php +++ b/framework/base/Controller.php @@ -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; From ee2ea4fcbd010e8b436cb15dbe6e152b4183302f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt?= Date: Tue, 7 Oct 2014 16:02:54 +0200 Subject: [PATCH 28/43] Update README.md --- docs/guide-fr/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide-fr/README.md b/docs/guide-fr/README.md index 80eed47..642d348 100644 --- a/docs/guide-fr/README.md +++ b/docs/guide-fr/README.md @@ -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) From 3611b51bd3236e8a106af616d62aff2dce05452d Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 7 Oct 2014 18:31:25 +0400 Subject: [PATCH 29/43] typo fix --- framework/filters/Cors.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/filters/Cors.php b/framework/filters/Cors.php index f4bb94e..6870495 100644 --- a/framework/filters/Cors.php +++ b/framework/filters/Cors.php @@ -15,7 +15,7 @@ use yii\web\Response; /** * Cors filter implements [Cross Origin Resource Sharing](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing). * Make sure to read carefully what CORS does and does not. CORS do not secure your API, - * but allow the developper to grant access to third party code (ajax calls from external domain) + * but allow the developer to grant access to third party code (ajax calls from external domain) * * You may use CORS filter by attaching it as a behavior to a controller or module, like the following, * @@ -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() @@ -177,7 +177,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) { @@ -205,7 +205,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) { From 3abefac692580c82dbad41af5c7adb8161548607 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Tue, 7 Oct 2014 17:43:05 +0300 Subject: [PATCH 30/43] Fixed `yii\mongodb\Collection` unable to fetch default database name from DSN with parameters --- extensions/mongodb/CHANGELOG.md | 2 +- extensions/mongodb/Connection.php | 2 +- tests/unit/extensions/mongodb/ConnectionTest.php | 38 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/extensions/mongodb/CHANGELOG.md b/extensions/mongodb/CHANGELOG.md index b54f53d..994d132 100644 --- a/extensions/mongodb/CHANGELOG.md +++ b/extensions/mongodb/CHANGELOG.md @@ -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 diff --git a/extensions/mongodb/Connection.php b/extensions/mongodb/Connection.php index d97ce67..27578ed 100644 --- a/extensions/mongodb/Connection.php +++ b/extensions/mongodb/Connection.php @@ -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."); diff --git a/tests/unit/extensions/mongodb/ConnectionTest.php b/tests/unit/extensions/mongodb/ConnectionTest.php index 72e1c88..b97c661 100644 --- a/tests/unit/extensions/mongodb/ConnectionTest.php +++ b/tests/unit/extensions/mongodb/ConnectionTest.php @@ -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() { From 22dac1af6289b8fa34f96b0cba825ba6dc3b13a1 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Tue, 7 Oct 2014 10:50:39 -0400 Subject: [PATCH 31/43] wording fix [skip ci] --- docs/guide/runtime-sessions-cookies.md | 5 ++++- framework/web/DbSession.php | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/guide/runtime-sessions-cookies.md b/docs/guide/runtime-sessions-cookies.md index d0d28d9..2ce169e 100644 --- a/docs/guide/runtime-sessions-cookies.md +++ b/docs/guide/runtime-sessions-cookies.md @@ -174,7 +174,10 @@ where 'BLOB' refers to the BLOB-type of your preferred DBMS. Below are the BLOB - PostgreSQL: BYTEA - MSSQL: BLOB -Note that length of id column should be adjusted if `session.hash_function` is changed in `php.ini`. +> 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 diff --git a/framework/web/DbSession.php b/framework/web/DbSession.php index e4bd7ff..3ab6082 100644 --- a/framework/web/DbSession.php +++ b/framework/web/DbSession.php @@ -66,7 +66,9 @@ 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 length of id column should be adjusted if `session.hash_function` is changed in `php.ini`. + * 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}}'; From 0b566b7e7d5fe8e6ca7aadb257282c14f06424a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt?= Date: Tue, 7 Oct 2014 17:29:23 +0200 Subject: [PATCH 32/43] Create structure-entry-scripts.md --- docs/guide-fr/structure-entry-scripts.md | 117 +++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 docs/guide-fr/structure-entry-scripts.md diff --git a/docs/guide-fr/structure-entry-scripts.md b/docs/guide-fr/structure-entry-scripts.md new file mode 100644 index 0000000..2ddc67f --- /dev/null +++ b/docs/guide-fr/structure-entry-scripts.md @@ -0,0 +1,117 @@ +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 [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 + +Ce qui suit est le code du script de démarrage du [Modèle Basique d'Application Web](start-installation.md). + +```php +run(); +``` + + +## Applications Console + +De même, le code qui suit est le code du script de démarrage d'une application console : + +```php +#!/usr/bin/env php +run(); +exit($exitCode); +``` + + +## Définir des Constantes + +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 fait au tout début d'un script de démarrage pour qu'elles puissent prendre +effet quand d'autres fichiers PHP sont inclus. From ea2f9f61afdb82aa5f179298b8af526eb0d29fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt?= Date: Tue, 7 Oct 2014 17:29:51 +0200 Subject: [PATCH 33/43] Update structure-entry-scripts.md --- docs/guide-fr/structure-entry-scripts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide-fr/structure-entry-scripts.md b/docs/guide-fr/structure-entry-scripts.md index 2ddc67f..760a28f 100644 --- a/docs/guide-fr/structure-entry-scripts.md +++ b/docs/guide-fr/structure-entry-scripts.md @@ -113,5 +113,5 @@ if (!defined('YII_DEBUG')) { Clairement, le premier est plus succinct et plus aisé à comprendre. -Les définitions de constantes doit être fait au tout début d'un script de démarrage pour qu'elles puissent prendre +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. From d3da84c45bd93a5bb255a43c5074e969af50df6e Mon Sep 17 00:00:00 2001 From: pana1990 Date: Tue, 7 Oct 2014 17:45:49 +0200 Subject: [PATCH 34/43] Fix spanish docs [skip ci] --- docs/guide-es/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide-es/README.md b/docs/guide-es/README.md index 8fe1a9f..b412fd7 100644 --- a/docs/guide-es/README.md +++ b/docs/guide-es/README.md @@ -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) From 1ba327098287475fab1487d4670c02dc0e40945e Mon Sep 17 00:00:00 2001 From: Luciano Baraglia Date: Tue, 7 Oct 2014 14:11:44 -0300 Subject: [PATCH 35/43] Spanish translation workflow updates [skip ci] --- docs/internals-es/translation-workflow.md | 56 +++++++++++-------------------- 1 file changed, 20 insertions(+), 36 deletions(-) diff --git a/docs/internals-es/translation-workflow.md b/docs/internals-es/translation-workflow.md index 80e0759..3492ae4 100644 --- a/docs/internals-es/translation-workflow.md +++ b/docs/internals-es/translation-workflow.md @@ -1,62 +1,46 @@ 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. +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. -Framework Mensajes ------------------- +Mensajes del Framework +---------------------- -Framework tiene dos tipos de mensajes: excepciones que están destinados al desarrollador y nunca se traducen y mensajes +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 `framework/messages/config.php` y asegúrese de que su lenguaje aparece en `lenguajes`. Si no, añadir su lenguaje allí (recuerde que debe mantener la lista en orden alfabético). El formato de código de idioma debe seguir [Código de Idiomas IETF](http://es.wikipedia.org/wiki/C%C3%B3digo_de_idioma_IETF), por ejemplo, `es`. -2. Ir al `framework` y ejecutar `yii message/extract messages/config.php`. -3. Traducir los mensajes en `framework/messages/your_lenguaje/yii.php`. Asegúrese de guardar el archivo con codificación UTF-8. +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 puede ejecutar `yii message/extract messages/config.php` nuevamente. Se volverán a extraer automáticamente los mensajes de mantenimiento intactos sin los cambios. +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 de la matriz representa la traducción (valor) de un mensaje (clave). Si el valor está vacío, el mensaje se considera como no traducida. Los mensajes que ya no necesiten traducción tendrán sus traducciones encerrado entre un par de marcas »@@. Cadena de mensaje se puede utilizar con el formato de formas plurales. Compruebe [sección i18n de la guía](../guide-es/tutorial-i18n.md) para más detalles. +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 ------------- -Coloque traducciones de documentación bajo `docs/-` donde `` es el nombre de la documentación original como `guide` o `internals` y `` es el código de Lenguaje de los docs Lenguaje se convierten a. Para la traducción de guias es `docs/guide-es`. +Coloca las traducciones de la documentación bajo `docs/-` donde `` es el nombre de la documentación original como `guide` o `internals` +y `` 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 del trabajo inicial se lleva a cabo usted puede conseguir lo que ha cambiado desde la última traducción del fichero usando un comando especial del directorio `build`: +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 se quejan de composer, ejecutar `composer install` en el directorio raíz. +Si recibes un error de composer, ejecuta `composer install` en el directorio raíz. Convenios para la traducción ---------------------------- -- active record — sin traducción -- cache — sin traducción -- framework — sin traducción -- helper — sin traducción -- hash — sin traducción -- id — sin traducción -- widget — sin traducción -- script — sin traducción -- assets — sin traducción -- bootstrapping | bootstrap — sin traducción -- routing — sin traducción -- logging — sin traducción -- cookies — sin traducción -- controller — controlador -- model — modelo -- view — vista -- themes — temas o plantillas -- behaviors — comportamientos -- handlers — manipuladores -- instantiating — instanciando -- link — enlace -- render — sin traducción -- DatePicker — sin traducción -- rendering — renderizando +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. From 10761a929b9209d02a28454ce5298f1cb6dd0094 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Tue, 7 Oct 2014 15:08:39 -0400 Subject: [PATCH 36/43] Fixes #5360: Added back BootstrapThemeAsset. --- extensions/bootstrap/BootstrapThemeAsset.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 extensions/bootstrap/BootstrapThemeAsset.php diff --git a/extensions/bootstrap/BootstrapThemeAsset.php b/extensions/bootstrap/BootstrapThemeAsset.php new file mode 100644 index 0000000..60747a9 --- /dev/null +++ b/extensions/bootstrap/BootstrapThemeAsset.php @@ -0,0 +1,27 @@ + + * @since 2.0 + */ +class BootstrapThemeAsset extends AssetBundle +{ + public $sourcePath = '@bower/bootstrap/dist'; + public $css = [ + 'css/bootstrap-theme.css', + ]; + public $depends = [ + 'yii\bootstrap\BootstrapAsset', + ]; +} From e53cdbe33986b4d858fd54155d07932088550a13 Mon Sep 17 00:00:00 2001 From: Larnu Date: Wed, 8 Oct 2014 00:52:40 +0200 Subject: [PATCH 37/43] translate requests into spanish --- docs/guide-es/README.md | 2 +- docs/guide-es/runtime-requests.md | 108 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 docs/guide-es/runtime-requests.md diff --git a/docs/guide-es/README.md b/docs/guide-es/README.md index b412fd7..4ee6e45 100644 --- a/docs/guide-es/README.md +++ b/docs/guide-es/README.md @@ -50,7 +50,7 @@ Gestión de las peticiones * [Información general](runtime-overview.md) * [Bootstrapping](runtime-bootstrapping.md) * [Routing](runtime-routing.md) -* **TBD** [Peticiones](runtime-requests.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) diff --git a/docs/guide-es/runtime-requests.md b/docs/guide-es/runtime-requests.md new file mode 100644 index 0000000..bfc2748 --- /dev/null +++ b/docs/guide-es/runtime-requests.md @@ -0,0 +1,108 @@ +Requests +======== +Las requests hechas a una aplicación son representadas como objetos [[yii\web\Request]] que proporcionan información como parámetros de request, cabeceras HTTP, cookies, etc. Dada una request, 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 + +Para obtener los parámetros de la request, 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 request, 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 request 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 body de la request. El componente 'request' convierte los parámetros cuando se acceda a el a través de los métodos descritos anteriormente. See puede personalizar la manera en como los parámetros se convierten configurando la propiedad [[yii\web\Request::parsers]]. + +## Métodos de Request + +Se puede obtener el método HTTP usado por la request 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 + +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 informacion del host y anterior al nombre de script de entrara. +* [[yii\web\Request::scriptUrl|scriptUrl]]: devuelve `/admin/index.php`, que es la URL sin la informacion 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 + +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 body de la request. +* [[yii\web\Request::acceptableContentTypes|acceptableContentTypes]]: devuelve el los tipos de contenido MIME aceptado por los usuarios, ordenados por puntuacion 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 paginas 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 response. El filtro implementa la negociación de contenido en la parte superior de las propiedades y métodos descritos anteriormente. + +## Información del cliente + +Se puede obtener el nombre del host y la dirección IP de la maquina 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; +``` From 9c1750b2eeec1ba0af31b4a6342100a63bee4d15 Mon Sep 17 00:00:00 2001 From: Vadim <4ws@mail.ru> Date: Wed, 8 Oct 2014 14:28:51 +0400 Subject: [PATCH 38/43] Update input-validation.md --- docs/guide/input-validation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/input-validation.md b/docs/guide/input-validation.md index 964706f..0122046 100644 --- a/docs/guide/input-validation.md +++ b/docs/guide/input-validation.md @@ -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".'); } } } From 03b88dd618ea0df622e1b08da3928a5387956531 Mon Sep 17 00:00:00 2001 From: Kartik Visweswaran Date: Wed, 8 Oct 2014 14:37:50 +0530 Subject: [PATCH 39/43] Fixes #5424: `Html::addCssStyle()` wasn't correctly setting style passed in array --- framework/CHANGELOG.md | 1 + framework/helpers/BaseHtml.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 863dcde..9760448 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -10,6 +10,7 @@ Yii Framework 2 Change Log - 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 #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) diff --git a/framework/helpers/BaseHtml.php b/framework/helpers/BaseHtml.php index 829632b..443929a 100644 --- a/framework/helpers/BaseHtml.php +++ b/framework/helpers/BaseHtml.php @@ -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; } /** From 165e9ede6d36ea3689e3287b3b7dfecbda8d2a98 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Wed, 8 Oct 2014 17:14:52 +0300 Subject: [PATCH 40/43] Added ability to operate nested and complex attributes via `yii\authclient\BaseClient::normalizeUserAttributeMap` --- extensions/authclient/BaseClient.php | 47 +++++++++++- extensions/authclient/CHANGELOG.md | 2 +- extensions/authclient/README.md | 1 - .../unit/extensions/authclient/BaseClientTest.php | 87 +++++++++++++++++++--- 4 files changed, 120 insertions(+), 17 deletions(-) diff --git a/extensions/authclient/BaseClient.php b/extensions/authclient/BaseClient.php index 95b0d30..b22d9bb 100644 --- a/extensions/authclient/BaseClient.php +++ b/extensions/authclient/BaseClient.php @@ -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"'); + } } } diff --git a/extensions/authclient/CHANGELOG.md b/extensions/authclient/CHANGELOG.md index 0025be7..f74330d 100644 --- a/extensions/authclient/CHANGELOG.md +++ b/extensions/authclient/CHANGELOG.md @@ -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 diff --git a/extensions/authclient/README.md b/extensions/authclient/README.md index 8591327..20cd29a 100644 --- a/extensions/authclient/README.md +++ b/extensions/authclient/README.md @@ -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 diff --git a/tests/unit/extensions/authclient/BaseClientTest.php b/tests/unit/extensions/authclient/BaseClientTest.php index 95bdcbd..bca1dd1 100644 --- a/tests/unit/extensions/authclient/BaseClientTest.php +++ b/tests/unit/extensions/authclient/BaseClientTest.php @@ -55,25 +55,88 @@ 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', + ], + ], + ]; + } + + /** + * @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); } } From 4c843671ea5550234cb4e46c73041095ea9debdc Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Wed, 8 Oct 2014 17:16:50 +0300 Subject: [PATCH 41/43] Additional check added to `yiiunit\extensions\authclient\BaseClientTest::testNormalizeUserAttributes()` --- tests/unit/extensions/authclient/BaseClientTest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/unit/extensions/authclient/BaseClientTest.php b/tests/unit/extensions/authclient/BaseClientTest.php index bca1dd1..af1beaa 100644 --- a/tests/unit/extensions/authclient/BaseClientTest.php +++ b/tests/unit/extensions/authclient/BaseClientTest.php @@ -116,6 +116,17 @@ class BaseClientTest extends TestCase 'email' => 'some@email.com', ], ], + [ + [ + 'name' => 'file_get_contents', + ], + [ + 'file_get_contents' => 'value', + ], + [ + 'name' => 'value', + ], + ], ]; } From 6624ad3dc6b0074613a7d0473d870a0eda249b0b Mon Sep 17 00:00:00 2001 From: Valentin Ts Date: Wed, 8 Oct 2014 15:52:44 +0400 Subject: [PATCH 42/43] Update authorization guide and Remove TBD from readme.md where it is no longer needed close #5430 --- docs/guide/README.md | 4 ++-- docs/guide/db-migrations.md | 0 docs/guide/security-authorization.md | 4 ++-- docs/guide/structure-application-components.md | 0 docs/guide/tutorial-console.md | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) mode change 100755 => 100644 docs/guide/db-migrations.md mode change 100755 => 100644 docs/guide/structure-application-components.md diff --git a/docs/guide/README.md b/docs/guide/README.md index 614ac4c..224132a 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -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) diff --git a/docs/guide/db-migrations.md b/docs/guide/db-migrations.md old mode 100755 new mode 100644 diff --git a/docs/guide/security-authorization.md b/docs/guide/security-authorization.md index 6a09699..703bb0e 100644 --- a/docs/guide/security-authorization.md +++ b/docs/guide/security-authorization.md @@ -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 ----- 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 ------------ 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,7 +59,7 @@ 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 ------------- As can be seen in the code above, the console application uses its own configuration file, named `console.php`. In this file @@ -81,7 +81,7 @@ yii --appconfig=path/to/config.php ... > command. -Creating your own console commands +Creating your own console commands ---------------------------------- ### Console Controller and Action From d33580c9aab935f1174551a7a2a11ccd950180ce Mon Sep 17 00:00:00 2001 From: pana1990 Date: Wed, 8 Oct 2014 18:50:25 +0200 Subject: [PATCH 43/43] Fix spanish docs [skip ci] --- docs/guide-es/runtime-requests.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/guide-es/runtime-requests.md b/docs/guide-es/runtime-requests.md index bfc2748..a0ad13b 100644 --- a/docs/guide-es/runtime-requests.md +++ b/docs/guide-es/runtime-requests.md @@ -1,10 +1,10 @@ -Requests +Peticiones ======== -Las requests hechas a una aplicación son representadas como objetos [[yii\web\Request]] que proporcionan información como parámetros de request, cabeceras HTTP, cookies, etc. Dada una request, 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. +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 -Para obtener los parámetros de la request, 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: +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; @@ -28,7 +28,7 @@ $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 request, 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 request personalizados. +>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: @@ -42,11 +42,11 @@ $params = $request->bodyParams; $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 body de la request. El componente 'request' convierte los parámetros cuando se acceda a el a través de los métodos descritos anteriormente. See puede personalizar la manera en como los parámetros se convierten configurando la propiedad [[yii\web\Request::parsers]]. +>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 -Se puede obtener el método HTTP usado por la request 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: +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; @@ -68,8 +68,8 @@ Asumiendo que la URL que se está solicitando es 'http://example.com/admin/index * [[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 informacion del host y anterior al nombre de script de entrara. -* [[yii\web\Request::scriptUrl|scriptUrl]]: devuelve `/admin/index.php`, que es la URL sin la informacion del la ruta ni la query string. +* [[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. @@ -90,17 +90,17 @@ 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 body de la request. -* [[yii\web\Request::acceptableContentTypes|acceptableContentTypes]]: devuelve el los tipos de contenido MIME aceptado por los usuarios, ordenados por puntuacion de calidad. Los que tienen mejor puntuación, se devolverán primero. +* [[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 paginas 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. +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 response. El filtro implementa la negociación de contenido en la parte superior de las propiedades y métodos descritos anteriormente. +>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 -Se puede obtener el nombre del host y la dirección IP de la maquina cliente a través de [[yii\web\Request::userHost|userHost]] y [[yii\web\Request::userIP|userIP]], respectivamente. Por ejemplo: +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;