Commit 35eea62c by Riverlet

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

parents c15a5a1f 604b464e
......@@ -17,6 +17,7 @@ AppAsset::register($this);
<head>
<meta charset="<?= Yii::$app->charset ?>"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
......
......@@ -18,6 +18,7 @@ AppAsset::register($this);
<head>
<meta charset="<?= Yii::$app->charset ?>"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
......
......@@ -17,6 +17,7 @@ AppAsset::register($this);
<head>
<meta charset="<?= Yii::$app->charset ?>"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
......
Generando Código con Gii
========================
En esta sección, explicaremos cómo utilizar [Gii](tool-gii.md) para generar código que automáticamente
implementa algunas características comunes de una aplicación. Para lograrlo, todo lo que tienes que hacer es
ingresar la información de acuerdo a las instrucciones mostradas en la páginas web de Gii.
A lo largo de este tutorial, aprenderás
* Cómo activar Gii en tu aplicación;
* Cómo utilizar Gii para generar una clase Active Record;
* Cómo utilizar Gii para generar el código que implementa las operaciones ABM de una tabla de la base de datos.
* Cómo personalizar el código generado por Gii.
Comenzando con Gii <a name="starting-gii"></a>
------------------
[Gii](tool-gii.md) es provisto por Yii en forma de [módulo](structure-modules.md). Puedes habilitar Gii
configurándolo en la propiedad [[yii\base\Application::modules|modules]] de la aplicación. En particular,
puedes encontrar que el siguiente código ya está incluido en el archivo `config/web.php` - la configuración de la aplicación,
```php
$config = [ ... ];
if (YII_ENV_DEV) {
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = 'yii\gii\Module';
}
```
La configuración mencionada arriba dice que al estar en el [entorno de desarrollo](concept-configurations.md#environment-constants),
la aplicación debe incluir un módulo llamado `gii`, cuya clase es [[yii\gii\Module]].
Si chequeas el [script de entrada](structure-entry-scripts.md) `web/index.php` de tu aplicación, encontrarás la línea
que esencialmente define la constante `YII_ENV_DEV` como true.
```php
defined('YII_ENV') or define('YII_ENV', 'dev');
```
De esta manera, tu aplicación ha habilitado Gii, y puedes acceder al módulo a través de la URL:
```
http://hostname/index.php?r=gii
```
![Gii](images/start-gii.png)
Generando una Clase Active Record <a name="generating-ar"></a>
---------------------------------
Para poder generar una clase Active Record con Gii, selecciona "Model Generator" completa el formulario de la siguiente manera,
* Table Name: `country`
* Model Class: `Country`
![Model Generator](images/start-gii-model.png)
Haz click el el botón "Preview". Verás que `models/Country.php` es listado en el cuadro de resultado.
Puedes hacer click en él para previsualizar su contenido.
Debido a que en la última sección ya habías creado el archivo `models/Country.php`, si haces click
en el botón `diff` cercano al nombre del archivo, verás las diferencias entre el código a ser generado
y el código que ya habías escrito.
![Previsualización del Model Generator](images/start-gii-model-preview.png)
Marca el checkbox que se encuentra al lado de "overwrite" y entonces haz click en el botón "Generate".
Verás una página de confirmación indicando que el código ha sido generado correctamente y tu archivo `models/Country.php`
ha sido sobrescrito con el código generado ahora.
Generando código de ABM (CRUD en inglés) <a name="generating-crud"></a>
----------------------------------------
Para generar un ABM, selecciona "CRUD Generator". Completa el formulario de esta manera:
* Model Class: `app\models\Country`
* Search Model Class: `app\models\CountrySearch`
* Controller Class: `app\controllers\CountryController`
![Generador de ABM](images/start-gii-crud.png)
Al hacer click en el botón "Preview" verás la lista de archivos a ser generados.
Asegúrate de haber marcado el checkbox de sobrescribir (overwrite) para ambos archivos: `controllers/CountryController.php` y
`views/country/index.php`. Esto es necesario ya que los archivos habían sido creados manualmente antes
en la sección anterior y ahora los quieres sobrescribir para poder tener un ABM funcional.
Intentándolo <a name="trying-it-out"></a>
------------
Para ver cómo funciona, accede desde tu navegador a la siguiente URL:
```
http://hostname/index.php?r=country/index
```
Verás una grilla de datos mostrando los países de la base de datos. Puedes ordenar la grilla
o filtrar los resultados escribiendo alguna condición en los encabezados de las columnas.
Por cada país mostrado en la grilla, puedes elegir ver el registro en completo, actualizarlo o eliminarlo.
Puedes incluso hacer click en el botón "Create Country" que se encuentra sobre la grilla y así cargar
un nuevo país en la base de datos.
![Grilla de Países](images/start-gii-country-grid.png)
![Actualizando un País](images/start-gii-country-update.png)
La siguiente es la lista de archivos generados en caso de que quieras inspeccionar cómo el ABM está generado,
o si quisieras personalizarlos.
* Controlador: `controllers/CountryController.php`
* Modelos: `models/Country.php` y `models/CountrySearch.php`
* Vistas: `views/country/*.php`
> Información: Gii está diseñado para ser una herramienta altamente configurable. Utilizándola con sabiduría
puede acelerar enormemente la velocidad de desarrollo de tu aplicación. Para más detalles, consulta la
sección [Gii](tool-gii.md).
Resumen <a name="summary"></a>
-------
En esta sección, has aprendido a utilizar Gii para generar el código que implementa completamente las características
de un ABM de acuerdo a una determinada tabla de la base de datos.
Diciendo Hola
============
Esta sección describe cómo crear una nueva página "Hola" en tu aplicación.
Para lograr este objetivo, vas a crear un [action](structure-controllers.md#creating-actions) (una acción) y
un [view](structure-views.md) (una vista):
* La aplicación enviará la petición de la página a la acción
* y la acción regresará el render de la vista que muestra la palabra "Hola" al usuario final.
A lo largo de este tutorial, aprenderás tres cosas:
1. Cómo crear un [action](structure-controllers.md) (acción) para responder peticiones (request),
2. cómo crear un [view](structure-views.md) (vista) para armar el contenido de la respuesta, y
3. cómo una aplicación responde una petición a [actions](structure-controllers.md#creating-actions).
Creando una Acción <a name="creating-action"></a>
------------------
Para la tarea "Hola", crearás un [action](structure-controllers.md#creating-actions) `dice` que lee
un parámetro `mensaje` de la petición y muestra este mensaje de vuelta al usuario. Si la petición
no provee un parámetro `mensaje`, la acción mostrará el mensaje por defecto "Hola".
> Info: [Actions](structure-controllers.md#creating-actions) son objetos que los usuarios finales pueden utilizar directamente para
su ejecución. Las Acciones están agrupadas por [controllers](structure-controllers.md) (controladores). El resultado de la ejecución de
una acción es la respuesta que el usuario final recibirá.
Las Acciones deben ser declaradas en [controllers](structure-controllers.md). Para simplificar, puedes
declarar la acción `dice` en el `SiteController` existente. Este controlador está definido
en el archivo de clase `controllers/SiteController.php`. Aquí está el inicio de la nueva acción:
```php
<?php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
// ...código existente...
public function actionDice($mensaje = 'Hola')
{
return $this->render('dice', ['mensaje' => $mensaje]);
}
}
```
En el código de arriba, la acción `dice` está definida por un método llamado `actionDice` en la clase `SiteController`.
Yii utiliza el prefijo `action` para diferenciar los métodos de acciones de otros métodos en las clases de los controladores.
El nombre que le sigue al prefijo `action` se mapea al ID de la acción.
Cuando se trata de nombrar las acciones, debes entender como Yii trata los ID de las acciones. Los ID de las acciones siempre son
referenciados en minúscula. Si un ID de acción requiere múltiples palabras, estas serán concatenadas con guiones
(p.e., `crear-comentario`). Los nombres de los métodos de las acciones son mapeados a los ID de las acciones
removiendo los guiones, colocando en mayúscula la primera letra de cada palabra, y colocando el prefijo `action` al resultado. Por ejemplo,
el ID de la acción `crear-comentario` corresponde al nombre de método de acción `actionCrearComentario`.
El método de acción en nuestro ejemplo toma un parámetro `$mensaje`, el cual tiene como valor por defecto `"Hola"` (de la misma manera
que se coloca un valor por defecto a un argumento en cualquier función o método en PHP). Cuando una aplicación
recibe una petición y determina que la acción `dice` es responsable de manejar dicha petición, la aplicación llenará
el parámetro con el parámetro que tenga el mismo nombre en la petición. En otras palabras, si la petición incluye un
parámetro `mensaje` con el valor de `"Adios"`, la variable `$mensaje` dentro de la acción será sustituida por este valor.
Dentro del método de acción, [[yii\web\Controller::render()|render()]] es llamado para hacer render (mostrar o visualizar) un
archivo [view](structure-views.md) llamado `dice`. El parámetro `mensaje` tambien es pasado al view para que pueda ser utilizado ahí.
El resultado es regresado al método action. Ese resultado será recibido por la aplicación y mostrado al usuario final en el
navegador (como parte de una página HTML completa).
Creando una Vista <a name="creating-view"></a>
-----------------
[Views](structure-views.md) (vistas) son scripts que escribes para generar una respuesta de contenido.
Para la tarea "Hola", vas a crear una vista `dice` que imprime el parámetro `mensaje` recibido desde el método action, y pasado por la acción a la vista:
```php
<?php
use yii\helpers\Html;
?>
<?= Html::encode($mensaje) ?>
```
El view `dice` debe ser guardado en el archivo `views/site/dice.php`. Cuando el método [[yii\web\Controller::render()|render()]]
es llamado en una acción, buscará un archivo PHP llamado `views/ControllerID/NombreView.php`.
Nota que en el código de arriba, el parámetro `mensaje` es [[yii\helpers\Html::encode()|HTML-encoded]]
antes de ser impreso. Esto es necesario ya que el parámetro viene de un usuario final, haciéndolo vulnerable a
[ataques cross-site scripting (XSS)](http://es.wikipedia.org/wiki/Cross-site_scripting) pudiendo inyectar código de Javascript malicioso dentro del parámetro.
Naturalmente, puedes colocar mas contenido en el view `dice`. El contenido puede consistir de etiquetas HTML, texto plano, e inlcusive código PHP.
De hecho, el view `dice` es sólo un script PHP que es ejecutado por el método [[yii\web\Controller::render()|render()]].
El contenido impreso por el script view será regresado a la aplicación como la respuesta del resultado. La aplicación a cambio mostrará el resultado al usuario final.
Probando <a name="trying-it-out"></a>
--------
Después de crear la acción y la vista, puedes abrir la nueva página abriendo el siguiente URL:
```
http://hostname/index.php?r=site/dice&mensaje=Hello+World
```
![Hello World](images/start-hello-world.png)
Esta URL resultará en una página mostrando "Hello World". La página comparte el mismo encabezado y pie de página de las otras páginas de la aplicación.
Si omites el parámetro `mensaje` en el URL, verás que la página muestra sólo "Hola". Esto es porque `mensaje` es pasado como un parámetro al método `actionDice()`, y cuando es omitido, el valor por defecto `"Hola"` será utilizado.
> Info: La nueva página comparte el mismo encabezado y pie de página que otras páginas porque el método [[yii\web\Controller::render()|render()]]
automáticamente inyectará el resultado del view `dice` en la plantilla [layout](structure-views.md#layouts) que en este
caso está localizada en `views/layouts/main.php`.
El parámetro `r` en el URL de arriba requiere más explicación. Significa [route](runtime-routing.md) (ruta), y es el ID amplio y único de una aplicación
que refiere a una acción. El formato de las rutas es `ControllerID/ActionID`. Cuando la aplicación recibe una petición, revisará este parámetro, utilizando la parte del `ControllerID` para determinar cual clase de controlador será inicializado para manejar la petición. Entonces, el controlador utilizará la parte `ActionID` para determinar cual acción debe ser inizializada para hacer realmente el trabajo. En este ejemplo, la ruta `site/dice`
será respondida por la clase controlador `SiteController` y la acción `dice`. Como resultado,
el método `SiteController::actionDice()` será llamado para manejar el requerimiento.
> Info: Al igual que las acciones, los controladores tambien tienen ID únicos que los identifican en una aplicación.
Los ID de los Controladores utilizan las mismas reglas de nombrado que los ID de las acciones. Los nombres de las clases de los Controladores son derivados de los ID de los controladores removiendo los guiones de los ID, colocando la primera letra en mayúscula en cada palabra, y colocando el sufijo `Controller` al resultado. Por ejemplo, el ID del controlador `post-comentarios` corresponde
al nombre de clase de controlador `PostComentarioController`.
Resumen <a name="summary"></a>
-------
En esta sección, has tocado las partes del controlador y la vista del patrón de diseño MVC.
Has creado una acción como parte de un controlador para manejar una petición específica. Y también has creado una vista para armar el contenido de la respuesta. En este simple ejemplo, ningún modelo ha sido involucrado ya que el único dato que fue utilizado fue el parámetro `mensaje`.
También has aprendido acerca de las rutas en Yii, que actúan como puentes entre la petición del usuario y las acciones del controlador.
En la próxima sección, aprenderás como crear un modelo, y agregar una nueva página que contenga un formulario HTML.
......@@ -34,7 +34,7 @@ Structure Application
* [Script d'entrée](structure-entry-scripts.md)
* [Applications](structure-applications.md)
* [Composants application](structure-application-components.md)
* [Controlleurs](structure-controllers.md)
* [Contrôleurs](structure-controllers.md)
* [Modèles](structure-models.md)
* [Vues](structure-views.md)
* **TBD** [Filtres](structure-filters.md)
......@@ -129,7 +129,7 @@ Services Web RESTful
* [Démarrage rapide](rest-quick-start.md)
* [Ressources](rest-resources.md)
* [Controlleurs](rest-controllers.md)
* [Contrôleurs](rest-controllers.md)
* [Gestion des routes](rest-routing.md)
* [Formattage des réponses](rest-response-formatting.md)
* [Authentification](rest-authentication.md)
......
Mise à jour depuis la version 1.1
=================================
Il y a beaucoup de différences entre les versions 1.1 et 2.0 de Yii, le framework ayant été complètement réécrit pour
la 2.0. En conséquence, la mise à jour depuis la version 1.1 n'est pas aussi triviale que la mise à jour entre deux
versions mineures. Dans ce guide, vous trouverez les principales différences entre les deux versions.
Si vous n'avez pas utilisé Yii 1.1 avant, vous pouvez ignorer cette section et passer directement à la partie
"[Mise en route] (start-installation.md)".
Merci de noter que Yii 2.0 introduit plus de nouvelles fonctionnalités que celles abordées ici. Il est fortement
recommandé de lire tout le guide de référence pour en apprendre davantage. Il y a des chances que certaines
fonctionnalités, que vous aviez préalablement développées pour vous, fassent désormais partie du code du noyau.
Installation
------------
Yii 2.0 exploite pleinement [Composer] (https://getcomposer.org/), le gestionnaire de paquet PHP. L'installation
du framework, ainsi que des extensions, sont gérées par Composer. Merci de lire la partie
[Installer Yii](start-installation.md) pour apprendre comment installer Yii 2.0. Si vous voulez
créer de nouvelles extensions, ou rendre vos extensions existantes 1.1 compatibles 2.0, merci de lire
la partie [Créer des extensions](extend-creating-extensions.md) de ce guide.
Pré-requis PHP
--------------
Yii 2.0 requiert PHP 5.4 ou plus, ce qui est une grosse amélioration par rapport à PHP 5.2 qui était requis pour Yii 1.1.
Par conséquent, il y a beaucoup de différences au niveau du langage pour lesquelles vous devriez prêter attention.
Voici un résumé des principaux changements concernant PHP:
- [Espaces de noms](http://php.net/manual/fr/language.namespaces.php).
- [Fonctions anonymes](http://php.net/manual/fr/functions.anonymous.php).
- Syntaxe courte pour les tableaux : `[...éléments...]` est utilisé au lieu de `array(...éléments...)`.
- Syntaxe courte pour echo : `<?=` est utilisé dans les vues. Cela ne pose aucun problème à partir de PHP 5.4.
- [Classes SPL et interfaces](http://php.net/manual/fr/book.spl.php).
- [Late Static Bindings (résolution statique à la volée)](http://php.net/manual/fr/language.oop5.late-static-bindings.php).
- [Date et heure](http://php.net/manual/fr/book.datetime.php).
- [Traits](http://php.net/manual/fr/language.oop5.traits.php).
- [intl](http://php.net/manual/fr/book.intl.php). Yii 2.0 utilise l'extension PHP `intl` pour les fonctionnalités
d'internationalisation.
Espaces de Noms
---------------
Le changement le plus évident dans Yii 2.0 est l'utilisation des espaces de noms. La majorité des classes du noyau
utilise les espace de noms, par exemple, `yii\web\Request`. Le préfixe «C» n'est plus utilisé dans les noms de classe.
Le schéma de nommage suit maintenant la structure des répertoires. Par exemple, `yii\web\Request`
indique que le fichier de classe correspondant est `web/Request.php` dans le dossier du framework.
(Vous pouvez utiliser n'importe quelle classe du noyau sans inclure explicitement le fichier correspondant, grâce au
chargeur de classe de Yii.)
Composants et objets
--------------------
Yii 2.0 décompose la classe `CComponent` 1.1 en deux classes: [[yii\base\Object]] et [[yii\base\Component]].
Le classe [[yii\base\Object|Object]] est une classe de base légère qui permet de définir les
[Propriétés de l'objet](concept-properties.md) via des accesseurs. La classe [[yii\base\Component|Component]] est une
sous classe de [[yii\base\Object|Object]] et supporte les [Evénements] (concept events.md) et les
[Comportements](concept-behaviors.md).
Si votre classe n'a pas besoin des événements et des comportements, vous devriez envisager d'utiliser
[[yii\base\Object|Object]] comme classe de base. C'est généralement le cas pour les classes qui représentent
une structures de données basique.
Configuration d'Objet
---------------------
La classe [[yii\base\Object|Object]] introduit une manière uniforme pour configurer les objets. Toute sous classe
de [[yii\base\Object|Object]] doit déclarer son constructeur (si besoin) de la manière suivante afin qu'elle
puisse être configurée correctement:
```php
class MyClass extends \yii\base\Object
{
public function __construct($param1, $param2, $config = [])
{
// ... initialisation avant que la configuration soit appliquée
parent::__construct($config);
}
public function init()
{
parent::init();
// ... initialisation après que la configuration soit appliquée
}
}
```
Dans ce qui précède, le dernier paramètre du constructeur doit être un tableau de configuration
qui contient des entrées nom-valeur pour initialiser les propriétés à la fin du constructeur.
Vous pouvez remplacer la méthode [[yii\base\Object::init()|init()]] pour le travail d'initialisation qui doit être fait
après que la configuration ait été appliquée.
En suivant cette convention, vous serez en mesure de créer et de configurer de nouveaux objets en utilisant un tableau
de configuration :
```php
$object = Yii::createObject([
'class' => 'MyClass',
'property1' => 'abc',
'property2' => 'cde',
], [$param1, $param2]);
```
Plus de détails sur les configurations peuvent être trouvés dans la partie
[Configurations d'objet](concept-configurations.md).
Evénements
----------
Avec Yii 1, les événements étaient créés par la définition d'une méthode `on` (par exemple `onBeforeSave`). Avec Yii 2,
vous pouvez maintenant utiliser n'importe quel nom de l'événement. Vous déclenchez un événement en appelant
la méthode [[yii\base\Component::trigger()|trigger()]] :
```php
$event = new \yii\base\Event;
$component->trigger($eventName, $event);
```
Pour attacher un gestionnaire à un événement, utilisez la méthode [[yii\base\Component::on()|on()]]:
```php
$component->on($eventName, $handler);
// Pour détacher le gestionnaire, utilisez :
// $component->off($eventName, $handler);
```
Il y a de nombreuses améliorations dans la gestion des événements. Pour plus de détails, merci de lire la partie [Evénements](concept-events.md).
Alias
-----
Yii 2.0 étend l'utilisation des alias aux fichiers/répertoires et aux URL. Yii 2.0 impose maintenant
aux alias de commencer par le caractère `@`, pour différencier les alias de fichiers/répertoires ou URL.
Par exemple, l'alias `@yii` fait référence au répertoire d'installation de Yii. Les alias ??sont
supportés dans la plupart du code de Yii. Par exemple, [[yii\caching\FileCache::cachePath]] peut prendre
à la fois un alias et un chemin de répertoire normal.
Un alias est aussi étroitement liée aux espaces de noms des classes. Il est recommandé de définir
un alias pour chaque espace de nom racine, ce qui vous permet d'utiliser le chargeur automatique de classe de Yii sans
sans devoir en faire d'avantage. Par exemple, vu que `@yii` fait référence au dossier d'installation de Yii,
une classe comme `yii\web\Request` peut être chargée automatiquement. Si vous utilisez une librairie tierce,
telle que Zend Framework, vous pouvez définir un alias de chemin `@Zend` qui fera référence au dossier
d'installation de Zend Framework. Une fois que vous avez fait cela, Yii sera aussi en mesure de charger automatiquement une classe de ce framework.
Pour en savoir plus, consultez la partie [Alias](concept-aliases.md).
Vues
----
Le changement le plus significatif à propos des vues dans Yii 2 est que la variable spéciale `$this` dans une vue ne fait plus référence au
contrôleur ou widget. Au lieu de cela, `$this` correspond maintenant à un objet *vue*, un nouveau concept
introduit dans la version 2.0. L'objet *vue* est de type [[yii\web\View]], et représente la partie vue
du modèle MVC. Si vous souhaitez accéder au contrôleur ou widget dans une vue, vous pouvez utiliser `$this->context`.
Pour afficher une vue depuis une autre vue, utilisez `$this->render()`, et non `$this->renderPartial()`. Le résultat retourné par la méthode `render()` doit être explictement envoyé à la sortie, en effet `render()` retournera la vue au lieu de l'afficher. Par exemple :
```php
echo $this->render('_item', ['item' => $item]);
```
Outre l'utilisation de PHP comme langage principal de gabarit, Yii 2.0 supporte également
deux moteurs de gabarit populaires : Smarty et Twig. Le moteur de gabarit Prado n'est plus supporté.
Pour utiliser ces moteurs de gabarit, vous devez configurer le composant `view` de l'application en définissant la propriété
[[yii\base\View::$renderers|View::$renderers]]. Merci de lire la partie [Moteur de gabarit](tutorial-template-engines.md) pour en savoir plus.
Modèles
-------
Yii 2.0 utilise la classe [[yii\base\Model]] comme modèle de base, similaire à la classe `CModel` dans la version 1.1.
La classe `CFormModel` a été supprimée. Vous pouvez, à la place, étendre la classe [[yii\base\Model]] afin de créer une classe modèle pour un formulaire.
Yii 2.0 introduit une nouvelle méthode appelée [[yii\base\Model::scenarios()|scenarios()]] pour déclarer
les scénarios pris en charge, et indiquer dans quel scénario un attribut doit être validé, peut être considéré comme sûr ou non, etc. Par exemple:
```php
public function scenarios()
{
return [
'backend' => ['email', 'role'],
'frontend' => ['email', '!name'],
];
}
```
Dans ce qui précède, deux scénarios sont déclarés: `backend` et `frontend`. Pour le scénario `backend` les
propriétés `email` et `role` sont sûres et peuvent être affectées massivement. Pour le scénario `frontend`,
`email` peut être affectée massivement tandis que `role` ne peut pas. `email` et `rôle` doivent être validées en utilisant des règles.
La méthode [[yii\base\Model::rules()|rules()]] est toujours utilisée pour déclarer les règles de validation. Remarque : suite à l'introduction de la méthode [[yii\base\Model::scenarios()|scenarios()]], le validateur `unsafe` n'as plus de raison d'être.
Dans la plupart des cas, vous n'avez pas besoin de surcharger la méthode [[yii\base\Model::scenarios()|scenarios()]]
lorsque les scénarios existants sont déclarés via la méthode [[yii\base\Model::rules()|rules()]], et il n'y a pas besoin de déclarer de propriétés `unsafe`.
Pour en savoir plus sur les modèles, merci de lire la partie [Modèles](structure-models.md).
Contrôleurs
-----------
Yii 2.0 utilise la classe [[yii\web\Controller]] comme classe de base des contrôleurs, similaire à la classe `CWebController` dans la version Yii 1.1.
[[yii\base\Action]] est la classe de base pour les actions.
L'impact le plus évident de ces changements sur votre code est qu'une action de contrôleur doit retourner le contenu
que vous voulez afficher au lieu de l'envoyer vers la sortie :
```php
public function actionView($id)
{
$model = \app\models\Post::findOne($id);
if ($model) {
return $this->render('view', ['model' => $model]);
} else {
throw new \yii\web\NotFoundHttpException;
}
}
```
Merci de lire la partie [Contrôleurs](structure-controllers.md) pour plus de détails.
Widgets
-------
Yii 2.0 utilise la classe [[yii\base\Widget]] comme classe de base pour les widgets, similaire à la classe `CWidget` de Yii 1.1.
Pour avoir un meilleur support du framework dans les EDI, Yii2 introduit une nouvelle syntaxe pour utiliser les widgets. Les methodes statiques
[[yii\base\Widget::begin()|begin()]], [[yii\base\Widget::end()|end()]], et [[yii\base\Widget::widget()|widget()]]
ont été créées et sont utilisables comme suit :
```php
use yii\widgets\Menu;
use yii\widgets\ActiveForm;
// Remarque : vous devez utiliser echo pour afficher le résultat
echo Menu::widget(['items' => $items]);
// Utilisation d'un tableau pour initialiser les propriétés de l'objet
$form = ActiveForm::begin([
'options' => ['class' => 'form-horizontal'],
'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
]);
... champs du formulaire ici ...
ActiveForm::end();
```
Merci de lire la partie [Widgets](structure-widgets.md) pour en savoir plus.
Thèmes
------
Les thèmes fonctionnent tout à fait différemment dans la version 2.0. Ils sont maintenant basés sur un mécanisme de mappage de chemin qui mappe un chemin
de fichier de vue à un chemin de fichier de vue thématisée. Par exemple, si le mappage pour un thème est
`['/web/views' => '/web/themes/basic']`, alors la version thématisée du fichier de vue
`/web/views/site/index.php` sera `/web/themes/basic/site/index.php`. Pour cette raison, les thèmes peuvent maintenant
être appliqués à n'importe quel fichier de vue, même une vue utilisée en dehors du contexte d'un contrôleur ou d'un widget.
En outre, il n'y a plus de composant `CThemeManager`. A la place, `theme` est une propriété configurable du composant `view`
de l'application.
Merci de lire la partie [Thématisation](tutorial-theming.md) pour plus de détails.
Applications en ligne de commande
---------------------------------
Les applications en ligne de commande (console) sont désormais organisées en contrôleurs, comme les applications Web. ces contrôleurs
doivent étendre la classe [[yii\console\Controller]], similaire à la classe `CConsoleCommand` de la version 1.1.
Pour exécuter une commande console, utilisez `yii <route>`, où `<route>` correspond à une route vers un contrôleur
(par exemple `sitemap/index`). Les arguments anonymes supplémentaires sont passés comme paramètres à
l'action du contrôleur correspondant, alors que les arguments nommés sont analysés selon
les options déclarées dans la méthode [[yii\console\Controller::options()]].
Yii 2.0 prend en charge la génération automatique d'aide à partir des blocs de commentaire.
Merci de lire la partie [Commandes console](tutorial-console.md) pour plus de détails.
I18N
----
Yii 2.0 supprime les fonctionnalités internes de formattage de dates et nombres, en faveur du [module PHP PECL intl] (http://pecl.php.net/package/intl).
La traduction de message est désormais effectuée via le composant d'application `i18n`.
Ce composant gère un ensemble de sources de messages, ce qui vous permet d'utiliser différentes
sources de messages en fonction de catégories.
Merci de lire la partie [Internationalisation](tutorial-i18n.md) pour plus de détails.
Filtres d'action
----------------
Les filtres d'action sont maintenant implémentés comme des comportements. Pour définir un nouveau filtre personnalisé, étendez la classe [[yii\base\ActionFilter]]. Pour utiliser un filtre, déclarez le
comme un comportement du contrôleur. Par exemple, pour utilser le filtre [[yii\filters\AccessControl]], vous aurez le code suivant dans le contrôleur :
```php
public function behaviors()
{
return [
'access' => [
'class' => 'yii\filters\AccessControl',
'rules' => [
['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
],
],
];
}
```
Merci de lire la partie [Filtres](structure-filters.md) pour plus de détails.
Ressources
----------
Yii 2.0 introduit un nouveau concept de packet de ressources (*asset bundle*) qui remplace le concept de gestionnaire de ressources (*asset manager*) de la version 1.1.
Un packet de ressources est une collection de fichiers (par exemple : fichier JavaScript, CSS, image, etc.)
dans un dossier. Chaque paquet est représenté par une classe étendant [[yii\web\AssetBundle]].
En *enregistrant* un packet via [[yii\web\AssetBundle::register()]], vous rendez les ressources du packet accessibles via le Web. Contrairement à Yii 1.1, la page *enregistrant* le paquet
contiendra automatiquement les références vers les fichiers déclarés dans le paquet.
Merci de lire la partie [Assets](structure-assets.md) pour plus de détails.
Assistants
----------
Yii 2.0 introduit de nombreuses assistants couramment utilisés, sous la forme de classes statiques, y compris :
* [[yii\helpers\Html]]
* [[yii\helpers\ArrayHelper]]
* [[yii\helpers\StringHelper]]
* [[yii\helpers\FileHelper]]
* [[yii\helpers\Json]]
* [[yii\helpers\Security]]
Merci de lire la partie [Assistants](helper-overview.md) pour plus de détails.
Formulaires
-----------
Yii 2.0 introduit le concept de *champ* pour la construction d'un formulaire à l'aide de la classe [[yii\widgets\ActiveForm]]. Un champ
est un conteneur constitué d'une étiquette, d'une entrée, d'un message d'erreur, et/ou d'un texte d'aide.
Un champ est représenté comme un objet de la classe [[yii\widgets\ActiveField|ActiveField]].
En utilisant des champs, vous pouvez construire un formulaire plus proprement qu'avant:
```php
<?php $form = yii\widgets\ActiveForm::begin(); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<div class="form-group">
<?= Html::submitButton('Login') ?>
</div>
<?php yii\widgets\ActiveForm::end(); ?>
```
Merci de lire la partie [Créer des formulaires](input-forms.md) pour plus de détails.
Constructeur de requête
-----------------------
Dans la version 1.1, la construction des requêtes était dispersée dans plusieurs classes, y compris `CDbCommand`,
`CDbCriteria` et `CDbCommandBuilder`. Avec Yii 2.0, une requête de base de données est représentée par un objet de la classe [[yii\db\Query|Query]]
qui peut être transformé en une instruction SQL à l'aide de la classe [[yii\db\QueryBuilder|QueryBuilder]].
Par exemple:
```php
$query = new \yii\db\Query();
$query->select('id, name')
->from('user')
->limit(10);
$command = $query->createCommand();
$sql = $command->sql;
$rows = $command->queryAll();
```
De plus, ces méthodes de construction de requête peuvent également être utilisées lorsque vous travaillez avec [Active Record](db-active-record.md).
Merci de lire la partie [Constructeur de requête](db-query-builder.md) pour plus de détails.
Active Record
-------------
Yii 2.0 introduit beaucoup de modifications au modèle [Active Record](db-active-record.md). Les deux plus évidentes concernent la construction des requêtes et la manipulation de requêtes relationnelles.
La classe `CDbCriteria` en 1.1 est remplacée par [[yii\db\ActiveQuery]] dans Yii 2. Cette classe étend [[yii\db\Query]],
et hérite donc de toutes les méthodes de construction de requête. Pour commencer à construire une requête il suffit d'utiliser [[yii\db\ActiveRecord::find()]] :
```php
// Pour récupérer tous les clients *actifs* et les trier selon leur identifiant
$customers = Customer::find()
->where(['status' => $active])
->orderBy('id')
->all();
```
Pour déclarer une relation, il suffit de définir un accesseur qui renvoie un objet [[yii\db\ActiveQuery|ActiveQuery]].
Le nom de la propriété définie par l'accesseur représente le nom de la relation. Par exemple, le code suivant déclare
une relation `orders` (en 1.1, vous aviez à déclarer les relations dans la méthode `relations()`):
```php
class Customer extends \yii\db\ActiveRecord
{
public function getOrders()
{
return $this->hasMany('Order', ['customer_id' => 'id']);
}
}
```
Maintenant vous pouvez utiliser `$customer->orders` pour accéder aux commandes du client depuis la table liée.
Vous pouvez aussi utiliser le code suivant pour effectuer une requête relationnelle à la volée avec une condition
personnalisée :
```php
$orders = $customer->getOrders()->andWhere('status=1')->all();
```
Lors du chargement anticipé (*eager loading*) d'une relation, Yii 2.0 fonctionne différemment de la version 1.1.
En particulier avec Yii 1.1, une jointure était créée pour sélectionner à la fois l'enregistrement principal et les
enregistrements liés. Avec Yii 2.0, deux instructions SQL sont exécutées sans utiliser de jointure : la première
récupère les enregistrements principaux et la seconde récupère les enregistrements liés en filtrant selon les clés
primaires des enregistrements principaux.
Au lieu de retourner des objets [[yii\db\ActiveRecord|ActiveRecord]], vous pouvez utiliser la méthode
[[yii\db\ActiveQuery::asArray()|asArray()]] lors de la construction d'une requête pour renvoyer un grand nombre
d'enregistrements. Ainsi le résultat retourné sera sous forme de tableaux, ce qui peut réduire considérablement le temps de calcul nécessaire et la mémoire dans le cas d'un grand nombre d'enregistrements. Par exemple:
```php
$customers = Customer::find()->asArray()->all();
```
Un autre changement est que vous ne pouvez plus définir les valeurs par défaut des attributs en utilisant des propriétés
publiques. Si vous avez besoin, vous devez utiliser la méthode `init` de la classe de votre modèle.
```php
public function init()
{
parent::init();
$this->status = self::STATUS_NEW;
}
```
Il y avait des problèmes de surcharge du constructeur de la classe ActiveRecord 1.1. Ces problèmes n'existent plus dans
la version 2.0. Notez que lorsque vous ajoutez des paramètres au constructeur, vous avez éventuellement à surcharger
la méthode [[yii\db\ActiveRecord::instantiate()]].
Il y a beaucoup d'autres modifications et améliorations à Active Record.
Merci de lire la partie [Active Record](db-active-record.md) pour en savoir plus.
User et IdentityInterface
-------------------------
La classe `CWebUser` 1.1 est maintenant remplacé par [[yii\web\User]], et il n'y a plus de classe `CUserIdentity`.
Au lieu de cela, vous devez implémenter [[yii\web\IdentityInterface]] qui est beaucoup plus simple à utiliser.
Le modèle d'application avancé fournit un exemple.
Merci de lire les parties [Authentification](security-authentication.md), [Authorisation](security-authorization.md), et
[Modèle application avancée](tutorial-advanced-app.md) pour en savoir plus.
Gestion des URL
---------------
La gestion des URL dans Yii 2 est similaire à celle disponible dans la version 1.1. Une amélioration majeure est que la
gestion des URL supporte désormais les paramètres optionnels. Par exemple, si vous avez une règle déclarée comme suit,
cela fera correspondre `post/popular` et `post/1/popular`. Dans la version 1.1, il fallait utiliser deux règles pour
atteindre le même objectif.
```php
[
'pattern' => 'post/<page:\d+>/<tag>',
'route' => 'post/index',
'defaults' => ['page' => 1],
]
```
Merci de lire la partie [Gestion des URL](url.md) pour en savoir plus.
Utiliser Yii 1.1 et 2.x ensemble
--------------------------------
Si vous avez du code Yii 1.1 que vous souhaitez réutiliser avec Yii 2, merci de lire la partie [Utiliser Yii 1.1 et 2.0 ensemble](extend-using-v1-v2.md).
......@@ -11,7 +11,7 @@ Pour quel usage Yii est il optimal?
Yii est un framework Web générique, c'est à dire qu'il peut être utilisé pour développer tous types
d'applications Web basées sur PHP. De par son architecture à base de composants et son système de cache sophistiqué,
il est particulièrement adapté au développement d'applications a forte audience telles que des portails, des forums,
il est particulièrement adapté au développement d'applications à forte audience telles que des portails, des forums,
des systèmes de gestion de contenu (CMS), des sites e-commerce, services Web RESTFul, etc.
......
Приложения
==========
Приложения это объекты, которые управляют всей структурой и жизненным циклом прикладной системы Yii.
Каждая Yii прикладная система включает в себя один объект приложения, который создается в [входном скрипте](structure-entry-scripts.md)
и глобально доступен через `\Yii::$app`.
> Информация: В зависимости от контекста, когда мы говорим "приложение", это может означать как объект приложения так и
прикладную систему приложения в целом.
Существует два вида приложений: [[yii\web\Application|веб приложения]] и [[yii\console\Application|консольные приложения]].
Как можно догадаться по названию, первый тип в основном занимается обработкой веб запросов, в то время как последний - консольных команд.
## Конфигурации приложения <a name="application-configurations"></a>
Когда [входной скрипт](structure-entry-scripts.md создает приложение, он загрузит [конфигурацию](concept-configurations.md)
и применит ее к приложению, например:
```php
require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
// загрузка конфигурации приложения
$config = require(__DIR__ . '/../config/web.php');
// создание объекта приложения и его конфигурирование
(new yii\web\Application($config))->run();
```
Также как и обычные [конфигурации](concept-configurations.md), конфигурации приложения указывают как следует инициализировать
свойства объектов приложения. Из-за того, что конфигурации приложений часто являются сложными, они разбиваются на несколько
[конфигурационных файлов](concept-configurations.md#configuration-files), например, `web.php` файл в приведенном выше примере.
## Свойства приложений <a name="application-properties"></a>
Существует много важных свойств приложения, которые вы настраиваете в конфигурациях приложения. Эти свойства обычно
описывают окружение, в котором работает приложение. Например, приложение должно знать каким образом загружать [контроллеры](structure-controllers.md),
где хранить временные файлы, и т. д. Ниже мы рассмотрим данные свойства.
### Обязательные свойства <a name="required-properties"></a>
В любом приложении, вы должны настроить минимум два свойства: [[yii\base\Application::id|id]]
и [[yii\base\Application::basePath|basePath]].
#### [[yii\base\Application::id|id]] <a name="id"></a>
Свойство [[yii\base\Application::id|id]] это уникальный индекс приложения, который отличает его от других приложений.
В основном это используется внутрисистемно. Хоть это и не обязательно, но для лучшей совместимости рекомендуется использовать
буквенно-цифровые символы при указании индекса приложения.
#### [[yii\base\Application::basePath|basePath]] <a name="basePath"></a>
Свойство [[yii\base\Application::basePath|basePath]] указывает на корневую папку приложения. Это папка, которая содержит
весь код прикладной системы приложения. В данной папке обычно могут находится подпапки `models`, `views`, `controllers`, которые
содержат код, отвечающий шаблону проектирования MVC.
Вы можете настроить свойство [[yii\base\Application::basePath|basePath]] указав напрямую путь к каталогу через
[псевдонимы пути](concept-aliases.md). В обоих случаях, указанная папка должна существовать, иначе будет брошено исключение.
Путь будет нормализован с помощью вызова функции `realpath()`.
Свойство [[yii\base\Application::basePath|basePath]] часто используется для получения других важных путей, например, путь к
runtime папке, которая используется в процессе работы приложения. Именно по этой причине, псевдоним пути `@app` является
предопределенным и указывает на данную папку. Другие пути могут быть получены с помощью использования псевдонима пути, например,
`@app/runtime`.
### Важные свойства <a name="important-properties"></a>
Свойства, указанные в этом подразделе, часто должны быть настроены т. к. они могут отличаться от приложения к приложению.
#### [[yii\base\Application::aliases|aliases]] <a name="aliases"></a>
Это свойство позволяет настроить вам множество [псевдонимов](concept-aliases.md) в рамках массива.
Ключами массива являются имена псевдонимов, а ключами - соответствующие значение пути. Например,
```php
[
'aliases' => [
'@name1' => 'path/to/path1',
'@name2' => 'path/to/path2',
],
]
```
Это свойство доступно таким образом, чтобы вы могли указывать псевдонимы в рамках конфигураций приложения,
а не вызовов метода [[Yii::setAlias()]].
#### [[yii\base\Application::bootstrap|bootstrap]] <a name="bootstrap"></a>
Данное свойство является очень удобным, оно позволяет указать массив компонентов, которые должны быть загружены
в процессе [[yii\base\Application::bootstrap()|начальной загрузки]] приложения. Например, если вы хотите, чтобы
[модуль](structure-modules.md) производил тонкую настройку [URL правил](runtime-url-handling.md), вы можете указать его
ID в качестве элемента данного свойства.
Каждый из элементов данного свойства, может быть указан в одном из следующих форматов:
- ID, указанный в [компонентах](#components);
- ID модуля, указанный в [модулях](#modules);
- название класса;
- массив конфигурации.
Например,
```php
[
'bootstrap' => [
// ID компонента приложения или модуля
'demo',
// название класса
'app\components\TrafficMonitor',
// массив конфигурации
[
'class' => 'app\components\Profiler',
'level' => 3,
]
],
]
```
В процессе начальной загрузки, каждый компонент будет создан. Если класс компонента имеет интерфейс [[yii\base\BootstrapInterface]], то
также будет вызван метод [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]].
Еще одним практическим примером является конфигурация [базового шаблона приложения](start-installation.md), в котором
модули `debug` и `gii` указаны как `bootstrap` компоненты, когда приложение находится в отладочном режиме.
```php
if (YII_ENV_DEV) {
// настройка конфигурации для окружения 'dev'
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = 'yii\gii\Module';
}
```
> Примечание: Указывание слишком большого количества компонентов в `bootstrap` приведет к снижению производительности приложения,
потому что для каждого запроса одно и то же количество компонентов должно быть загружено. Таким образом вы должны использовать
начальную загрузку разумно.
#### [[yii\web\Application::catchAll|catchAll]] <a name="catchAll"></a>
Данное свойство поддерживается только [[yii\web\Application|веб приложениями]].Оно указывает [действие контроллера](structure-controllers.md),
которое должно обрабатывать все входящие запросы от пользователя. В основном это используется, когда приложения находится в
режиме обслуживания и должно обрабатывать все запросы через одно действие.
Конфигурация это массив, первый элемент которого, указывает маршрут действия. Остальные элементы в формате ключ-значение
указывают дополнительные параметры, которые должны быть переданы действию. Например,
```php
[
'catchAll' => [
'offline/notice',
'param1' => 'value1',
'param2' => 'value2',
],
]
```
#### [[yii\base\Application::components|components]] <a name="components"></a>
Данное свойство является наиболее важным. Оно позволяет вам указать список компонентов, которые называются [компоненты приложения](#structure-application-components.md),
которые вы можете использовать в других местах. Например,
```php
[
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
],
],
]
```
Каждый компонент приложения указан массивом в формате ключ-значение. Ключ представляет собой ID компонента приложения, в то время
как значение представляет собой название класса или [конфигурацию](concept-configurations.md).
Вы можете зарегистрировать любой компонент в приложении, позже этот компонент будет глобально доступен
через выражение `\Yii::$app->ComponentID`.
Более детальная информация приведена в разделе [Компоненты приложения](structure-application-components.md).
#### [[yii\base\Application::controllerMap|controllerMap]] <a name="controllerMap"></a>
Данное свойство позволяет вам устанавливать соответствия между ID контроллера и его классом. По-умолчанию, Yii устаналивает
соответствие между ID контроллера и его классом согласно данному [соглашению](#controllerNamespace) (таким образом,
ID `post` будет соответствовать `app\controllers\PostController` ). С помощью настройки этого свойства вы можете изменить
соглашение для нужных контроллеров. В приведенном ниже примере, `account` будет соответствовать `app\controllers\UserController`,
в то время как `article` будет соответствовать `app\controllers\PostController`.
```php
[
'controllerMap' => [
[
'account' => 'app\controllers\UserController',
'article' => [
'class' => 'app\controllers\PostController',
'enableCsrfValidation' => false,
],
],
],
]
```
Ключами данного свойства являются ID контроллеров, а значениями являются название
класса контроллера или [конфигурация](concept-configurations.md).
#### [[yii\base\Application::controllerNamespace|controllerNamespace]] <a name="controllerNamespace"></a>
Данное свойство указывает пространство имен, в котором по-умолчанию должны находится названия классов контроллеров.
По-умолчанию значение равно `app\controllers`. Если ID контроллера `post`, то согласно соглашению, соответствующий класс
контроллера (без пространства имен) будет равен `PostController`, а полное название класса будет равно `app\controllers\PostController`.
Класс контроллера может также находиться в подпапке папки, которая соответствует этому пространству имен.
Например, дан ID контроллера `admin/post`, соответствующие полное имя класса контроллера будет `app\controllers\admin\PostController`.
Очень важно, чтобы полное имя класса контроллера могло быть использовано [автозагрузкой](concept-autoloading.md) и соответсвующее
пространство имен вашего контроллера соответствовало данному свойству. Иначе, вы получите ошибку "Страница не найдена", когда
попытаетесь получить доступ к приложению.
В случае, если вы хотите изменить соглашение как описано выше, вы можете использовать свойство [controllerMap](#controllerMap).
#### [[yii\base\Application::language|language]] <a name="language"></a>
Данное свойство указывает язык приложения, на котором содержимое страницы должно быть отображно конечному пользователю.
По-умолчанию значение данного свойства равно `en`, что означает "Английский". Если ваше приложение должно поддерживать несколько
языков, вы должны настроить данное свойство.
Значение данного свойства определяется различными аспектами [интернационализации](tutorial-i18n.md), в том числе
переводом сообщений, форматированием дат, форматированием чисел, и т. д. Например, виджет [[yii\jui\DatePicker]]
использует данное свойство для определения по-умолчанию языка, на котором должен быть отображен календарь и формат данных
для календаря.
Рекомендуется что вы будете указывать язык в рамках стандарта [IETF](http://en.wikipedia.org/wiki/IETF_language_tag).
Например, для английского языка используется `en`, в то время как для английского в США - `en-US`.
Более детальная информация приведена в разделе [Интернационализация](tutorial-i18n.md).
#### [[yii\base\Application::modules|modules]] <a name="modules"></a>
Данное свойство указывает [модули](structure-modules.md), которые содержаться в приложении.
Значениями свойства могут быть массивы имен классов модулей или [конфигураций](concept-configurations.md), а ключами -
ID модулей. Например,
```php
[
'modules' => [
// a "booking" module specified with the module class
'booking' => 'app\modules\booking\BookingModule',
// a "comment" module specified with a configuration array
'comment' => [
'class' => 'app\modules\comment\CommentModule',
'db' => 'db',
],
],
]
```
Более детальная информация приведена в разделе [Модули](structure-modules.md).
#### [[yii\base\Application::name|name]] <a name="name"></a>
Свойство указывает название приложения, которое может быть показано конечным пользователям. В отличие от
свойства [[yii\base\Application::id|id]], которое должно быть уникальным, значение данного свойства нужно в
основном для отображения и не обязательно должно быть уникальным.
Если ваш код не использует данное свойство, то вы можете не настраивать его.
#### [[yii\base\Application::params|params]] <a name="params"></a>
Данное свойство указывает массив глобально доступных параметров приложения. Вместо того, чтобы использовать
жестко фиксированные числа и строки в вашем коде, лучше объявить их параметрами приложения в едином месте и
использовать в нужных вам местах кода. Например, вы можете определить размер превью для изображений следующим образом:
```php
[
'params' => [
'thumbnail.size' => [128, 128],
],
]
```
Затем, когда вам нужно использовать данные значения в вашем коде, вы делаете это как представлено ниже:
```php
$size = \Yii::$app->params['thumbnail.size'];
$width = \Yii::$app->params['thumbnail.size'][0];
```
Если позже вам понадобится изменить размер превью изображений, вам нужно только изменить это значение в настройке
приложения, не касаясь зависимого кода.
#### [[yii\base\Application::sourceLanguage|sourceLanguage]] <a name="sourceLanguage"></a>
Данное свойство указывает язык на котором написан код приложения. По-умолчанию значение равно `'en-US'`, что означает
"Английский" (США). Вы должны настроить данное свойство соответствующим образом, если содержимое в вашем коде является не
английским языком.
Аналогично свойству [language](#language), вы должны указать данное свойство в рамках стандарта [IETF](http://en.wikipedia.org/wiki/IETF_language_tag).
Например, для английского языка используется `en`, в то время как для английского в США - `en-US`.
Более детальная информация приведена в разделе [Интернационализация](tutorial-i18n.md).
#### [[yii\base\Application::timeZone|timeZone]] <a name="timeZone"></a>
Данное свойство предоставляет альтернативный способ установки временной зоны в процессе работы приложения.
Путем указания данного свойства, вы по существу вызываете PHP функцию
[date_default_timezone_set()](http://www.php.net/manual/ru/function.date-default-timezone-set.php). Например,
```php
[
// Europe/Moscow для России (прим. пер.)
'timeZone' => 'America/Los_Angeles',
]
```
#### [[yii\base\Application::version|version]] <a name="version"></a>
Данное свойство указывает версию приложения. По-умолчанию значение равно `'1.0'`. Вы можете не настраивать это свойство, если
ваш код не использует его.
### Полезные свойства <a name="useful-properties"></a>
Свойства, указанные в данном подразделе, не являются часто конфигруируемыми, т. к. их значения по-умолчанию
соответствуют общепринятым соглашениям. Однако, вы можете их настроить, если вам нужно использовать другие
соглашения.
#### [[yii\base\Application::charset|charset]] <a name="charset"></a>
Свойство указывает кодировку, которую использует приложение. По-умолчанию значение равно `'UTF-8'`, которое должно быть
оставлено как есть для большинства приложения, только если вы не работаете с устаревшим кодом, который использует большее
количество данных не юникода.
#### [[yii\base\Application::defaultRoute|defaultRoute]] <a name="defaultRoute"></a>
Свойство указывает [маршрут](runtime-routing.md), который должно использовать приложение, когда он не указан
во входящем запросе. Маршрут может состоять из ID модуля, ID контроллера и/или ID действия. Например, `help`,
`post/create`, `admin/post/create`. Если действие не указано, то будет использовано значение по-умолчанию
указанное в [[yii\base\Controller::defaultAction]].
Для [yii\web\Application|веб приложений], значение по-умолчанию для данного свойства равно `'site'`, что означет
контроллер `SiteController` и его действие по-умолчанию должно быть использовано. Таким образом, если вы попытаетесь
получить доступ к приложению не указав маршрут, оно покажет вам результат действия `app\controllers\SiteController::actionIndex()`.
Для [yii\console\Application|консольных приложений], значение по-умолчанию равно `'help'`, означающее, что встроенная
команда [[yii\console\controllers\HelpController::actionIndex()]] должна быть использована. Таким образом, если вы
выполнитек команду `yii` без аргументов, вам будет отображена справочная информация.
#### [[yii\base\Application::extensions|extensions]] <a name="extensions"></a>
Данное свойство указывает список [расширений](structure-extensions.md), которые установлены и используются приложением.
По-умолчанию, значением данного свойства будет массив, полученный из файла `@vendor/yiisoft/extensions.php`. Файл `extensions.php`
генерируется и обрабатывается автоматически, когда вы используете [Composer](http://getcomposer.org) для установки расширений.
Таким образом, в большинстве случаев вам не нужно настраивать данное свойство.
В особых случаях, когда вы хотите обрабатывать расширения в ручную, вы можете указать данное свойство следующим образом:
```php
[
'extensions' => [
[
'name' => 'extension name',
'version' => 'version number',
'bootstrap' => 'BootstrapClassName', // опционально, может быть также массив конфигурации
'alias' => [ // опционально
'@alias1' => 'to/path1',
'@alias2' => 'to/path2',
],
],
// ... аналогично для остальных расширений ...
],
]
```
Свойство является массивом спецификаций расширений. Каждое расширение указано массивом, состоящим из элементов `name` и `version`.
Если расширение должно быть выполнено в процессе [начальной загрузки](runtime-bootstrapping.md), то следует указать `bootstrap`
элемент, который может являться именем класса или [конфигурацией](concept-configurations.md).
Расширение также может определять несколько [псевдонимов](concept-aliases.md).
#### [[yii\base\Application::layout|layout]] <a name="layout"></a>
Данное свойство указываеть имя шаблона по-умолчанию, который должен быть использовать при формировании [представлений](structure-views.md).
Значение по-умолчанию равно `'main'`, означающее, что должен быть использован шаблон `main.php` в [папке шаблонов](#layoutPath).
Если оба свойства [папка шаблонов](#layoutPath) и [папка представлений](#viewPath) имееют значение по-умолчаниею,
то файл шаблона по-умолчанию может быть представлен псевдонимом пути как `@app/views/layouts/main.php`.
Для отключения использования шаблона, вы можете указать данное свойство как `false`, хотя это используется очень редко.
#### [[yii\base\Application::layoutPath|layoutPath]] <a name="layoutPath"></a>
Свойство указывает путь, по которому следует искать шаблоны. Значение по-умолчанию равно `layouts`, означающее подпапку
в [папке представлений](#viewPath). Если значение [папки представлений](#viewPath) является значением по-умолчанию, то
папка шаблонов по-умолчанию может быть представлена псевдонимом пути как `@app/views/layouts`.
Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md).
#### [[yii\base\Application::runtimePath|runtimePath]] <a name="runtimePath"></a>
Свойство указывает путь, по которому хранятся временные файлы, такие как: лог файлы, кэш файлы.
По-умолчанию значене равно папке, которая представлена псевдонимом пути `@app/runtime`.
Вы можете настроить данное свойство как папку или как [псевдоним](concept-aliases.md) пути. Обратите внимание,
что данная папка должна быть доступна для записи, процессом, который запускает приложение. Также папка должна быть
защищена от доступа конечными пользователями, хранимые в ней временные файлы могут содержать важную информацию.
Для упрощения работы с данной папкой, Yii предоставляет предопределенный псевдоним пути `@runtime`.
#### [[yii\base\Application::viewPath|viewPath]] <a name="viewPath"></a>
Данное свойство указывает базовую папку,где содержаться все файлы представлений. Значение по-умолчанию представляет
собой псевдоним `@app/views`. Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md).
#### [[yii\base\Application::vendorPath|vendorPath]] <a name="vendorPath"></a>
Свойство указывает папку сторонних библиотек, которые используются и управляются [Composer](http://getcomposer.org).
Она содержит все сторонние библиотеки используемые приложением, включая Yii фреймворк. Значение по-умолчанию
представляет собой псевдоним `@app/vendor`.
Вы можете настроить данное свойство как папку так и как [псевдоним](concept-aliases.md). При изменении данного свойства,
убедитесь что вы также изменили соответствующим образом настройки Composer.
Для упрощения работы с данной папкой, Yii предоставляет предопределенный псевдоним пути `@vendor`.
#### [[yii\console\Application::enableCoreCommands|enableCoreCommands]] <a name="enableCoreCommands"></a>
Данное свойство поддерживается только [[yii\console\Application|консольными приложениями]]. Оно указывает
нужно ли использовать встроенные в Yii консольные команды. Значение по-умолчанию равно `true`.
## События приложения <a name="application-events"></a>
В течение жизненного цикла приложения, возникает несолько событий. Вы можете назначать обработчики событий в
конфигурации приложения следующим образом:
```php
[
'on beforeRequest' => function ($event) {
// ...
},
]
```
Использование синтаксиса `on eventName` детально описано в разделе [Конфигурации](concept-configurations.md#configuration-format).
Также вы можете назначить обработчики событий в процессе начальной [загрузки приложения](runtime-bootstrapping.md), сразу после того
как приложение будет создано. Например,
```php
\Yii::$app->on(\yii\base\Application::EVENT_BEFORE_REQUEST, function ($event) {
// ...
});
```
### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] <a name="beforeRequest"></a>
Данное событие возникает *до* того как приложение начинает обрабатывать входящий запрос.
Настоящее имя события - `beforeRequest`.
На момент возникновения данного события, объект приложения уже создан и проинициализирован. Таким образом, это
является хорошим местом для вставки вашего кода с помощью событий, для перехвата управления обработкой запроса.
Например, обработчик события, может динамически подставлять язык приложения [[yii\base\Application::language]] в зависимости
от некоторых параметров.
### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_REQUEST]] <a name="afterRequest"></a>
Данное событие возникает *после* того как приложение заканчивает обработку запроса, но *до* того как произойдет
отправка ответа. Настоящее имя события - `afterRequest`.
На момент возникновения данного события, обработка запроса завершена и вы можете воспользоваться этим для произведения постобработки
запроса, с целью настройки ответа.
Обратите внимаени что в компоненте [[yii\web\Response|response]] также возникают события в процессе отправки данных
конечному пользователю. Эти события возникают *после* текущего события.
### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_ACTION]] <a name="beforeAction"></a>
Событие возникае *до* того как будет выполнено [действие контроллера](structure-controllers.md).
Настоящее имя события - `beforeAction`.
Событие является объектом [[yii\base\ActionEvent]]. Обработчик события может устанавливать
свойство [[yii\base\ActionEvent::isValid]] равным `false` для предотвращения выполнения действия.
Например,
```php
[
'on beforeAction' => function ($event) {
if (некоторое условие) {
$event->isValid = false;
} else {
}
},
]
```
Обратите внимание что то же самое событие `beforeAction` возникает в [модулях](structure-modules.md) и
[контроллерах](structure-controllers.md). Объекты приложения являются первыми, кто возбуждает данные события,
следуя за модулями (если таковые имеются) и в конце контроллерами. Если обработчик события устанавливает
свойство [[yii\base\ActionEvent::isValid]] равным `false`, все последующие события не возникнут.
### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_ACTION]] <a name="afterAction"></a>
Событие возникает *после* выполнения [действия контроллера](structure-controllers.md).
Настоящее имя события - `afterAction`.
Событие является объектом [[yii\base\ActionEvent]]. Через свойство [[yii\base\ActionEvent::result]] обработчик события
может получить доступ и изменить значение выполнения действия контроллера.
Например,
```php
[
'on afterAction' => function ($event) {
if (некоторое условие) {
// modify $event->result
} else {
}
},
]
```
Обратите внимание что то же самое событие `afterAction` возникает в [модулях](structure-modules.md) и
[контроллерах](structure-controllers.md). Эти объекты возбмуждают событие в обратном порядке, если сравнивать с `beforeAction`.
Таким образом, контроллеры являются первыми, где возникает данное событие, затем в модулях (если таковые имеются),
и наконец в приложениях.
## Жизненный цикл приложения <a name="application-lifecycle"></a>
Когда [входной скрипт](structure-entry-scripts.md) выполняется для обработки запроса, приложение
будет развиваться согласно следующему жизненному циклу:
1. Входной скрипт загружает конфигурацию приложения в качества массива;
2. Входной скрипт создает новый объект приложения:
* Вызывается метод [[yii\base\Application::preInit()|preInit()]], который настраивает некоторые
жизненно важные свойства приложения, такие как [[yii\base\Application::basePath|basePath]];
* Регистрируется [[yii\base\Application::errorHandler|обработчик ошибок]];
* Настраиваются свойства приложения;
* Вызывается метод [[yii\base\Application::init()|init()]], который затем вызывает метод
[[yii\base\Application::bootstrap()|bootstrap()]] для начальной загрузки компонентов.
3. Входной скрипт вызывает метод [[yii\base\Application::run()]] для запуска приложения:
* Возникает событие [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]];
* Обработка запроса: разбор информации запроса в [маршрут](runtime-routing.md) с соответствующими параметрами;
создание объектов модуля, контроллера и действия согласно указанному маршруту; запуск действия;
* Возникает событие [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]];
* Ответ отсылается конечному пользователю.
4. Входной скрипт получает значение статуса выхода от приложения и заканчивает обработку запроса.
Повний посібник до 2.0
======================
Даний посібник випущено відповідно до [положень про документацію Yii](http://www.yiiframework.com/doc/terms/).
All Rights Reserved.
2014 © Yii Software LLC.
Введення
--------
* [Про Yii](intro-yii.md)
* [Оновлення із версії 1.1](intro-upgrade-from-v1.md)
Перше знайомство
----------------
* [Встановлення Yii](start-installation.md)
* [Запуск додатка](start-workflow.md)
* [Говоримо «привіт»](start-hello.md)
* [Робота з формами](start-forms.md)
* [Робота з базами даних](start-databases.md)
* [Генерація коду за допомогою Gii](start-gii.md)
* [Що далі?](start-looking-head.md)
Структура додатка
-----------------
* [Огляд](structure-overview.md)
* [Вхідні скрипти](structure-entry-scripts.md)
* [Додатки](structure-applications.md)
* [Компоненти додатка](structure-application-components.md)
* [Контролери](structure-controllers.md)
* [Представлення](structure-views.md)
* [Моделі](structure-models.md)
* **TBD** [Фільтри](structure-filters.md)
* **TBD** [Віджети](structure-widgets.md)
* **TBD** [Модулі](structure-modules.md)
* [Ресурси](structure-assets.md)
* **TBD** [Розширення](structure-extensions.md)
Обробка запитів
---------------
* **TBD** [Bootstrapping](runtime-bootstrapping.md)
* **TBD** [Роутінг](runtime-routing.md)
* **TBD** [Запити](runtime-requests.md)
* **TBD** [Відповіді](runtime-responses.md)
* **TBD** [Сесії та кукі](runtime-sessions-cookies.md)
* [Розбір та генерація URL](runtime-url-handling.md)
* [Обробка помилок](runtime-handling-errors.md)
* [Логування](runtime-logging.md)
Основні поняття
---------------
* [Компоненти](concept-components.md)
* [Властивості](concept-properties.md)
* [Події](concept-events.md)
* [Поведінки](concept-behaviors.md)
* [Конфігурації](concept-configurations.md)
* [Псевдоніми](concept-aliases.md)
* [Автозавантаження класів](concept-autoloading.md)
* [Service Locator](concept-service-locator.md)
* [Dependency Injection Container](concept-di-container.md)
Робота з базами даних
---------------------
* [Обʼєкти доступу до даних (DAO)](db-dao.md) - Зʼєднання з базою даних, прості запити, транзакції і робота зі схемою.
* [Конструктор запитів](db-query-builder.md) - Запити до бази даних через простий шар абстракції.
* [Active Record](db-active-record.md) - Отримання обʼєктів AR, робота з ними та визначення звʼязків.
* [Міграції](db-migrations.md) - Контроль версій схеми даних при роботі в команді.
* **TBD** [Sphinx](db-sphinx.md)
* **TBD** [Redis](db-redis.md)
* **TBD** [MongoDB](db-mongodb.md)
* **TBD** [ElasticSearch](db-elastic-search.md)
Отримання даних від користувача
-------------------------------
* [Створення форм](input-forms.md)
* [Валідація](input-validation.md)
* **TBD** [Завантаження файлів](input-file-uploading.md)
* **TBD** [Робота з декількома моделями](input-multiple-models.md)
Відображення даних
------------------
* **TBD** [Форматування даних](output-formatting.md)
* **TBD** [Посторінкове розбиття](output-pagination.md)
* **TBD** [Сортування](output-sorting.md)
* [Провайдери даних](output-data-providers.md)
* [Віджети для даних](output-data-widgets.md)
* [Темізація](output-theming.md)
Безпека
-------
* [Аутентифікація](security-authentication.md)
* [Авторизація](security-authorization.md)
* [Робота з паролями](security-passwords.md)
* **TBD** [Клієнти авторизації](security-auth-clients.md)
* **TBD** [Кращі практики](security-best-practices.md)
Кешування
---------
* [Огляд](caching-overview.md)
* [Кешуванная даних](caching-data.md)
* [Кешуванная фрагментів](caching-fragment.md)
* [Кешуванная сторінок](caching-page.md)
* [HTTP кешуванная](caching-http.md)
Веб-сервіси REST
----------------
* [Швидкий старт](rest-quick-start.md)
* [Ресурси](rest-resources.md)
* [Контролери](rest-controllers.md)
* [Роутінг](rest-routing.md)
* [Форматування відповіді](rest-response-formatting.md)
* [Аутентифікація](rest-authentication.md)
* [Обмеження кількості запитів](rest-rate-limiting.md)
* [Версіонування](rest-versioning.md)
* [Обробка помилок](rest-error-handling.md)
Інструменти розробника
----------------------
* [Відладочна панель та відладчик](tool-debugger.md)
* [Генерація коду з Gii](tool-gii.md)
* **TBD** [Генератор документації API](tool-api-doc.md)
Тестування
----------
* [Огляд](test-overview.md)
* **TBD** [Модульні тести](test-unit.md)
* **TBD** [Функціональні тести](test-functional.md)
* **TBD** [Приймальні тести](test-acceptance.md)
* [Фікстури](test-fixtures.md)
Розширення Yii
--------------
* [Створення розширень](extend-creating-extensions.md)
* [Розширення коду фреймворку](extend-customizing-core.md)
* [Використання сторонніх бібліотек](extend-using-libs.md)
* **TBD** [Інтеграція Yii в сторонні системи](extend-embedding-in-others.md)
* **TBD** [Одночасне використання Yii 1.1 та 2.0](extend-using-v1-v2.md)
* [Використання Composer](extend-using-composer.md)
Спеціальні теми
---------------
* [Шаблон додатка advanced](tutorial-advanced-app.md)
* [Створення додатка з нуля](tutorial-start-from-scratch.md)
* [Консольні команди](tutorial-console.md)
* [Інтернаціонализація](tutorial-i18n.md)
* [Відправка пошти](tutorial-mailing.md)
* [Вдосконалення продуктивності](tutorial-performance-tuning.md)
* **TBD** [Робота на shared хостингу](tutorial-shared-hosting.md)
* [Шаблонізатори](tutorial-template-engines.md)
Віджети
-------
* GridView: link to demo page
* ListView: link to demo page
* DetailView: link to demo page
* ActiveForm: link to demo page
* Pjax: link to demo page
* Menu: link to demo page
* LinkPager: link to demo page
* LinkSorter: link to demo page
* [Віджети Bootstrap](bootstrap-widgets.md)
* **TBD** [Віджети Jquery UI](jui-widgets.md)
Хелпери
-------
* [Огляд](helper-overview.md)
* **TBD** [ArrayHelper](helper-array.md)
* **TBD** [Html](helper-html.md)
* **TBD** [Url](helper-url.md)
* **TBD** [Security](helper-security.md)
......@@ -193,7 +193,7 @@ Widgets
* LinkPager: link to demo page
* LinkSorter: link to demo page
* [Bootstrap Widgets](bootstrap-widgets.md)
* **TBD** [Jquery UI Widgets](jui-widgets.md)
* [Jquery UI Widgets](jui-widgets.md)
Helpers
......
......@@ -17,7 +17,7 @@ Installation
Yii 2.0 fully embraces [Composer](https://getcomposer.org/), the de facto PHP package manager. Installation
of the core framework, as well as extensions, are handled through Composer. Please refer to
the [Starting from Basic App](start-basic.md) section to learn how to install Yii 2.0. If you want to
the [Installing Yii](start-installation.md) section to learn how to install Yii 2.0. If you want to
create new extensions, or turn your existing 1.1 extensions into 2.0-compatible extensions, please refer to
the [Creating Extensions](extend-creating-extensions.md) section of the guide.
......@@ -203,7 +203,7 @@ In most cases, you do not need to override [[yii\base\Model::scenarios()|scenari
if the [[yii\base\Model::rules()|rules()]] method fully specifies the scenarios that will exist, and if there is no need to declare
`unsafe` attributes.
To learn more details about models, please refer to the [Models](basic-models.md) section.
To learn more details about models, please refer to the [Models](structure-models.md) section.
Controllers
......@@ -270,7 +270,7 @@ be applied to any view file, even a view rendered outside of the context of a co
Also, there is no more `CThemeManager` component. Instead, `theme` is a configurable property of the `view`
application component.
Please refer to the [Theming](tutorial-theming.md) section for more details.
Please refer to the [Theming](output-theming.md) section for more details.
Console Applications
......@@ -322,7 +322,7 @@ public function behaviors()
}
```
Please refer to the [Filtering](runtime-filtering.md) section for more details.
Please refer to the [Filtering](structure-filters.md) section for more details.
Assets
......@@ -336,7 +336,7 @@ By registering an asset bundle via [[yii\web\AssetBundle::register()]], you make
the assets in that bundle accessible via the Web. Unlike in Yii 1, the page registering the bundle will automatically
contain the references to the JavaScript and CSS files specified in that bundle.
Please refer to the [Managing Assets](output-assets.md) section for more details.
Please refer to the [Managing Assets](structure-assets.md) section for more details.
Helpers
......@@ -443,7 +443,7 @@ records by filtering with the primary keys of the primary records.
Instead of returning [[yii\db\ActiveRecord|ActiveRecord]] objects, you may chain the [[yii\db\ActiveQuery::asArray()|asArray()]]
method when building a query to return a large number of records. This will cause the query result to be returned
as arrays, which can significantly reduce the needed CPU time and memory if large number of records . For example,
as arrays, which can significantly reduce the needed CPU time and memory if large number of records . For example:
```php
$customers = Customer::find()->asArray()->all();
......@@ -493,7 +493,7 @@ the same goal.
]
```
Please refer to the [Url manager docs](url.md) section for more details.
Please refer to the [Url manager docs](runtime-url-handling.md) section for more details.
Using Yii 1.1 and 2.x together
------------------------------
......
Jquery UI Widgets
=================
> Note: This section is under development.
Out of the box, Yii includes support for the [jQuery UI](http://api.jqueryui.com/) library. jQuery UI is a curated set
of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.
Yii widgets
-----------
Most complex jQuery UI components are wrapped into Yii widgets to allow more robust syntax and integrate with
framework features. All widgets belong to `\yii\jui` namespace:
- [[yii\jui\Accordion|Accordion]]
- [[yii\jui\AutoComplete|AutoComplete]]
- [[yii\jui\DatePicker|DatePicker]]
- [[yii\jui\Dialog|Dialog]]
- [[yii\jui\Draggable|Draggable]]
- [[yii\jui\Droppable|Droppable]]
- [[yii\jui\Menu|Menu]]
- [[yii\jui\ProgressBar|ProgressBar]]
- [[yii\jui\Resizable|Resizable]]
- [[yii\jui\Selectable|Selectable]]
- [[yii\jui\Slider|Slider]]
- [[yii\jui\SliderInput|SliderInput]]
- [[yii\jui\Sortable|Sortable]]
- [[yii\jui\Spinner|Spinner]]
- [[yii\jui\Tabs|Tabs]]
\ No newline at end of file
......@@ -2,7 +2,7 @@ Installing Yii
==============
You can install Yii in two ways, using [Composer](http://getcomposer.org/) or by downloading an archive file.
The former is the preferred way, as it allows you to install new [extensions](structure-extensions.md) or update Yii by simply running a single command.
The former is the preferred way, as it allows you to install new [extensions](extend-creating-extensions.md) or update Yii by simply running a single command.
> Note: Unlike with Yii 1, standard installations of Yii 2 results in both the framework and an application skeleton being downloaded and installed.
......
Views
=====
> Note: This section is under development.
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.
......@@ -53,6 +51,8 @@ or other objects whose trigger the [view rendering](#rendering-views).
TODO: features in creating views
## Organizing Views
Like [controllers](structure-controllers.md) and [models](structure-models.md), there are conventions to organize views.
......@@ -73,35 +73,27 @@ method of controllers or widgets.
## Rendering Views
You can render views in [controllers](structure-controllers.md), [widgets](structure-widgets.md), or any
other places. There are different view rendering methods provided by different classes. However, they share the
similar method signature as follows,
other places by calling view rendering methods. These methods share a similar signature shown as follows,
```
/**
* @param string $view view name or file path, depending on the actual rendering method
* @param array $params the parameters to be pushed into the view
* @param array $params the data to be passed to the view
* @return string rendering result
*/
methodName($view, $params = [])
```
### Passing Data to Views
As you can see, the first parameter specifies which view to be rendered. We will describe more about it in the
[Named Views](#named-views) subsection. The second parameter specifies what data should be "pushed" into the view
and made accessible there. When the rendering method renders a view, it will "extract" the `$params` array so that each
keyed array element is turned into a variable of the same name in the view. For example, if `$params`
is `['a' => 1, 'b' => 2]`, in the view you will be able to access variable `$a` and `$b` whose values are 1 and 2,
respectively.
### Rendering in Controllers
Within [controllers](structure-controllers.md), you may call the following controller methods to render views.
Within [controllers](structure-controllers.md), you may call the following controller methods to render views:
* [[yii\base\Controller::render()|render()]]: renders a [named view](#named-views) and applies a [layout](#layouts)
to the rendering result.
* [[yii\base\Controller::renderPartial()|renderPartial()]]: renders a [named view](#named-views) without any layout.
* [[yii\web\Controller::renderAjax()|renderAjax()]]: renders a [named view](#named-views) without any layout,
and injects all registered JS/CSS scripts and files. It is usually used in response to AJAX Web requests.
* [[yii\base\Controller::renderFile()|renderFile()]]: renders a view specified in terms of a view file path or
[alias](concept-aliases.md).
......@@ -166,9 +158,12 @@ class ListWidget extends Widget
### Rendering in Other Places
In any place, you can render views by calling the following methods of the [[yii\base\View|view]] application component.
In any place, you can render views with the help of the [[yii\base\View|view]] application component by calling
its following methods:
* [[yii\base\View::render()|render()]]: renders a [named view](#named-views).
* [[yii\web\View::renderAjax()|renderAjax()]]: renders a [named view](#named-views) and injects all registered
JS/CSS scripts and files. It is usually used in response to AJAX Web requests.
* [[yii\base\View::renderFile()|renderFile()]]: renders a view specified in terms of a view file path or
[alias](concept-aliases.md).
......@@ -241,151 +236,239 @@ class PostController extends Controller
```
And the following code in the view `@app/views/post/view.php` is actually rendering the view file
`@app/views/post/overview.php`:
`@app/views/post/_overview.php`:
```php
<?= $this->render('overview', ['model' => $model]) ?>
<?= $this->render('_overview', ['model' => $model]) ?>
```
## Layouts
### Accessing Data in Views
### Nested Layouts
There are two approaches to access data within a view: push and pull.
By passing the data as the second parameter to the view rendering methods, you are using the push approach.
The data should be represented be an array of name-value pairs. When the view is being rendered, the PHP
`extract()` function will be called on this array so that the array is extracted into variables in the view.
For example, the following view rendering code in a controller will push two variables to the `report` view:
`$foo = 1` and `$bar = 2`.
## View Components
```php
echo $this->render('report', [
'foo' => 1,
'bar' => 2,
]);
```
## Creating Views
The pull approach actively retrieves data from the [[yii\base\View::context|view context object]]. Using the above
code as an example, within the view you can get the controller object by the expression `$this->context`.
As a result, it is possible for you to access any properties or methods of the controller in the `report` view.
For example, in the `report` view you may pull the `id` data like the following:
### Setting page title
### Adding meta tags
### Registering link tags
### Registering CSS
### Registering scripts
### Static Pages
### Assets
```php
The controller ID is: <?= $this->context->id ?>
?>
```
The pull approach is usually the preferred way of accessing data in views, because it makes views less dependent
on context objects. Its drawback is that you need to manually build the data array all the time, which could
becomes tedious and error prone if a view is shared and rendered in different places.
## Alternative Template Engines
## Layouts
Layouts are a special type of views that represent the common parts of multiple views. For example, the pages
for most Web applications share the same page header and footer. While you can repeat the same page header and footer
in every view, a better way is to do this once in a layout and embed the rendering result of a content view at
an appropriate place in the layout.
Basics
------
By default, Yii uses PHP in view templates to generate content and elements. A web application view typically contains
some combination of HTML, along with PHP `echo`, `foreach`, `if`, and other basic constructs.
Using complex PHP code in views is considered to be bad practice. When complex logic and functionality is needed,
such code should either be moved to a controller or a widget.
### Creating Layouts
The view is typically called from controller action using the [[yii\base\Controller::render()|render()]] method:
Because layouts are also views, they can be created in the similar way as normal views. The following example
shows how a layout looks like:
```php
public function actionIndex()
{
return $this->render('index', ['username' => 'samdark']);
}
<?php
use yii\helpers\Html;
/**
* @var yii\web\View $this
* @var string $content
*/
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="<?= Yii::$app->language ?>">
<head>
<meta charset="<?= Yii::$app->charset ?>"/>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
<div class="container">
<?= $content ?>
</div>
<footer class="footer">&copy; 2014 by me :)</footer>
<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>
```
The first argument to [[yii\base\Controller::render()|render()]] is the name of the view to display.
In the context of the controller, Yii will search for its views in `views/site/` where `site`
is the controller ID. For details on how the view name is resolved, refer to the [[yii\base\Controller::render()]] method.
The above layout is used to generate HTML pages. It generates HTML tags that are common to all pages. You may
also generate other common HTML tags in the layout, such as head tags, main menu, etc.
The second argument to [[yii\base\Controller::render()|render()]] is a data array of key-value pairs.
Through this array, data can be passed to the view, making the value available in the view as a variable
named the same as the corresponding key.
Within a layout, you have access to a special variable named `$content`. This is the only variable injected into
the layout by the controller when the [[yii\base\Controller::render()]] method is called to render a view.
The value of `$content` represents the rendering result of the view. As you can see in the above code,
`$content` is embedded within the body part of the layout.
The view for the action above would be `views/site/index.php` and can be something like:
Besides `$content`, you can also access the [[yii\base\View|view]] component via `$this`, like in normal views.
```php
<p>Hello, <?= $username ?>!</p>
```
Any data type can be passed to the view, including arrays or objects.
### Organizing Layouts
Besides the above [[yii\web\Controller::render()|render()]] method, the [[yii\web\Controller]] class also provides
several other rendering methods. Below is a summary of these methods:
* [[yii\web\Controller::render()|render()]]: renders a view and applies the layout to the rendering result.
This is most commonly used to render a complete page.
* [[yii\web\Controller::renderPartial()|renderPartial()]]: renders a view without applying any layout.
This is often used to render a fragment of a page.
* [[yii\web\Controller::renderAjax()|renderAjax()]]: renders a view without applying any layout, and injects all
registered JS/CSS scripts and files. It is most commonly used to render an HTML output to respond to an AJAX request.
* [[yii\web\Controller::renderFile()|renderFile()]]: renders a view file. This is similar to
[[yii\web\Controller::renderPartial()|renderPartial()]] except that it takes the file path
of the view instead of the view name.
Widgets
-------
### Using Layouts
Widgets are self-contained building blocks for your views, a way to combine complex logic, display, and functionality into a single component. A widget:
A layout is applied when you call the [[yii\base\Controller::render()|render()]] method in a controller. The method
will first render the view being requested; it will then render the layout specified by the [[yii\base\Controller::layout]]
property of the controller and push the rendering result of the view into the layout as a variable `$content`.
* May contain advanced PHP programming
* Is typically configurable
* Is often provided data to be displayed
* Returns HTML to be shown within the context of the view
There are a good number of widgets bundled with Yii, such as [active form](form.md),
breadcrumbs, menu, and [wrappers around bootstrap component framework](bootstrap-widgets.md). Additionally there are
extensions that provide more widgets, such as the official widget for [jQueryUI](http://www.jqueryui.com) components.
In order to use a widget, your view file would do the following:
### View Events
```php
// Note that you have to "echo" the result to display it
echo \yii\widgets\Menu::widget(['items' => $items]);
// Passing an array to initialize the object properties
$form = \yii\widgets\ActiveForm::begin([
'options' => ['class' => 'form-horizontal'],
'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
]);
... form inputs here ...
\yii\widgets\ActiveForm::end();
The [[yii\base\View|view]] component provides several *placeholder* methods, such as `head()` and `beginBody()`,
which generate placeholders which will be replaced later by
code shows a typical layout
A layout is a very convenient way to represent the part of the page that is common for all or at least for most pages
generated by your application. Typically it includes `<head>` section, footer, main menu and alike elements.
You can find a fine example of the layout in a [basic application template](apps-basic.md). Here we'll review the very
basic one without any widgets or extra markup.
In the markup above there's some code. First of all, `$content` is a variable that will contain result of views rendered
with controller's `$this->render()` method.
We are importing [[yii\helpers\Html|Html]] helper via standard PHP `use` statement. This helper is typically used for almost all views
where one need to escape outputted data.
Several special methods such as [[yii\web\View::beginPage()|beginPage()]]/[[yii\web\View::endPage()|endPage()]],
[[yii\web\View::head()|head()]], [[yii\web\View::beginBody()|beginBody()]]/[[yii\web\View::endBody()|endBody()]]
are triggering page rendering events that are used for registering scripts, links and process page in many other ways.
Always include these in your layout in order for the rendering to work correctly.
By default layout is loaded from `views/layouts/main.php`. You may change it at controller or module level by setting
different value to `layout` property.
In order to pass data from controller to layout, that you may need for breadcrumbs or similar elements, use view component
params property. In controller it can be set as:
```php
$this->view->params['breadcrumbs'][] = 'Contact';
```
In the first example in the code above, the [[yii\base\Widget::widget()|widget()]] method is used to invoke a widget
that just outputs content. In the second example, [[yii\base\Widget::begin()|begin()]] and [[yii\base\Widget::end()|end()]]
are used for a
widget that wraps content between method calls with its own output. In case of the form this output is the `<form>` tag
with some properties set.
In a view it will be:
```php
$this->params['breadcrumbs'][] = 'Contact';
```
Security
--------
In layout file the value can be used like the following:
One of the main security principles is to always escape output. If violated it leads to script execution and,
most probably, to cross-site scripting known as XSS leading to leaking of admin passwords, making a user to automatically
perform actions etc.
```php
<?= Breadcrumbs::widget([
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>
```
Yii provides a good tool set in order to help you escape your output. The very basic thing to escape is a text without any
markup. You can deal with it like the following:
You may also wrap the view render result into a layout using [[yii\base\View::beginContent()]], [[yii\base\View::endContent()]].
This approach can be used while applying nested layouts:
```php
<?php
use yii\helpers\Html;
?>
<?php $this->beginContent('//layouts/overall') ?>
<div class="content">
<?= $content ?>
<div>
<?php $this->endContent() ?>
```
<div class="username">
<?= Html::encode($user->name) ?>
</div>
### Nested Layouts
### Accessing Data in Layouts
## View Components
### Setting page title
### Adding meta tags
### Registering link tags
### Registering CSS
### Registering scripts
### Static Pages
### Assets
### Alternative Template Engines
### Rendering Static Pages
Static pages refer to those Web pages whose main content are mostly static without the need of accessing
dynamic data pushed from controllers.
You can generate static pages using the code like the following in a controller:
```php
public function actionAbout()
{
return $this->render('about');
}
```
When you want to render HTML it becomes complex so we're delegating the task to excellent
[HTMLPurifier](http://htmlpurifier.org/) library which is wrapped in Yii as a helper [[yii\helpers\HtmlPurifier]]:
If a Web site contains many static pages, it would be very tedious repeating the similar code many times.
To solve this problem, you may introduce a [standalone action](structure-controllers.md#standalone-actions)
called [[yii\web\ViewAction]] in a controller. For example,
```php
<?php
use yii\helpers\HtmlPurifier;
?>
namespace app\controllers;
<div class="post">
<?= HtmlPurifier::process($post->text) ?>
</div>
use yii\web\Controller;
class SiteController extends Controller
{
public function actions()
{
return [
'page' => [
'class' => 'yii\web\ViewAction',
],
];
}
}
```
Note that besides HTMLPurifier does excellent job making output safe it's not very fast so consider
[caching result](caching.md).
Now if you create a view named `about` under the directory `@app/views/site/pages`, you will be able to
display this view by the following URL:
```
http://localhost/index.php?r=site/page&view=about
```
The `GET` parameter `view` tells [[yii\web\ViewAction]] which view is requested. The action will then look
for this view under the directory `@app/views/site/pages`. You may configure [[yii\web\ViewAction::viewPrefix]]
to change the directory for searching these views.
## Best Practices
Alternative template languages
------------------------------
......@@ -684,59 +767,7 @@ the view file will be looked for under the view path of the currently active mod
will be looked for under the application view path.
### Accessing context
Views are generally used either by controller or by widget. In both cases the object that called view rendering is
available in the view as `$this->context`. For example if we need to print out the current internal request route in a
view rendered by controller we can use the following:
```php
echo $this->context->getRoute();
```
### Static Pages
If you need to render static pages you can use class `ViewAction`. It represents an action that displays a view according
to a user-specified parameter.
Usage of the class is simple. In your controller use the class via `actions` method:
```php
class SiteController extends Controller
{
public function actions()
{
return [
'static' => [
'class' => '\yii\web\ViewAction',
],
];
}
//...
}
```
Then create `index.php` in `@app/views/site/pages/`:
```php
//index.php
<h1>Hello, I am a static page!</h1>
```
That's it. Now you can try it using `/index.php?r=site/static`.
By default, the view being displayed is specified via the `view` GET parameter.
If you open `/index.php?r=site/static?&view=about` then `@app/views/site/pages/about.php` view file will be used.
If not changed or specified via GET defaults are the following:
- GET parameter name: `view`.
- View file used if parameter is missing: `index.php`.
- Directory where views are stored (`viewPrefix`): `pages`.
- Layout for the page rendered matches the one used in controller.
For more information see [[yii\web\ViewAction]].
### Caching blocks
......@@ -759,3 +790,40 @@ return [
],
];
```
Security
--------
One of the main security principles is to always escape output. If violated it leads to script execution and,
most probably, to cross-site scripting known as XSS leading to leaking of admin passwords, making a user to automatically
perform actions etc.
Yii provides a good tool set in order to help you escape your output. The very basic thing to escape is a text without any
markup. You can deal with it like the following:
```php
<?php
use yii\helpers\Html;
?>
<div class="username">
<?= Html::encode($user->name) ?>
</div>
```
When you want to render HTML it becomes complex so we're delegating the task to excellent
[HTMLPurifier](http://htmlpurifier.org/) library which is wrapped in Yii as a helper [[yii\helpers\HtmlPurifier]]:
```php
<?php
use yii\helpers\HtmlPurifier;
?>
<div class="post">
<?= HtmlPurifier::process($post->text) ?>
</div>
```
Note that besides HTMLPurifier does excellent job making output safe it's not very fast so consider
[caching result](caching.md).
Widgets
=======
> Note: This section is under development.
Widgets are self-contained building blocks for your views, a way to combine complex logic, display, and functionality into a single component. A widget:
* May contain advanced PHP programming
* Is typically configurable
* Is often provided data to be displayed
* Returns HTML to be shown within the context of the view
There are a good number of widgets bundled with Yii, such as [active form](form.md),
breadcrumbs, menu, and [wrappers around bootstrap component framework](bootstrap-widgets.md). Additionally there are
extensions that provide more widgets, such as the official widget for [jQueryUI](http://www.jqueryui.com) components.
In order to use a widget, your view file would do the following:
```php
// Note that you have to "echo" the result to display it
echo \yii\widgets\Menu::widget(['items' => $items]);
// Passing an array to initialize the object properties
$form = \yii\widgets\ActiveForm::begin([
'options' => ['class' => 'form-horizontal'],
'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
]);
... form inputs here ...
\yii\widgets\ActiveForm::end();
```
In the first example in the code above, the [[yii\base\Widget::widget()|widget()]] method is used to invoke a widget
that just outputs content. In the second example, [[yii\base\Widget::begin()|begin()]] and [[yii\base\Widget::end()|end()]]
are used for a
widget that wraps content between method calls with its own output. In case of the form this output is the `<form>` tag
with some properties set.
Yii version numbering
=====================
Релізи
------
A.B.C
A = Для Yii2 це завжди 2.
B = Основна версія. Не-BC (`BC`, від англ. Backward compatibility - зворотна сумісність) зміни із інструкціями щодо оновлення.
C = BC зміни та доповнення.
Реліз-кандидати
---------------
A.B.C-rc
A.B.C-rc2
Це коли ми хочемо зробити реліз-кандидат. Номер RC збільшується доки ми не отримаємо стабільний реліз без будь-яких
критичних помилок і звітів про звортню несумісність.
Альфи та бети
-------------
A.B.C-alpha
A.B.C-alpha2
Альфи це є нестабільні версії, де значні помилки можуть і, ймовірно, дійсно будуть.
API ще фіксується і може бути суттєво змінений.
`alpha2` і т.д. можуть або не можуть бути випущені на основі загальної стабільності коду та API.
A.B.C-beta
A.B.C-beta2
Бета більш-менш стабільна із меншою кількістю помилок та меншою нестабільністю API, ніж альфа.
Там все ще можуть бути зміни в API, але на це повинна бути вагома причина.
......@@ -22,4 +22,9 @@ Russian
Spanish
-------
- **Luciano Baraglia** [@lucianobaraglia](https://github.com/lucianobaraglia)
- Luciano Baraglia, [@lucianobaraglia](https://github.com/lucianobaraglia)
Ukrainian
---------
- Alexandr Bordun [@borales](https://github.com/Borales), admin@yiiframework.com.ua
\ No newline at end of file
......@@ -30,6 +30,7 @@ $this->beginPage();
<meta charset="<?= Yii::$app->charset ?>"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="language" content="en" />
<?= Html::csrfMetaTags() ?>
<?php $this->head() ?>
<title><?= Html::encode($this->context->pageTitle) ?></title>
</head>
......
......@@ -10,7 +10,7 @@ namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* Bootstrap 2 theme for Bootstrap 3.
* Asset bundle for the Twitter bootstrap default theme.
*
* @author Alexander Makarov <sam@rmcreative.ru>
* @since 2.0
......
......@@ -13,6 +13,7 @@ yii\debug\DebugAsset::register($this);
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
......
......@@ -15,6 +15,7 @@ $asset = yii\gii\GiiAsset::register($this);
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
......
......@@ -45,10 +45,11 @@ Yii Framework 2 Change Log
- Bug #3752: `QueryBuilder::batchInsert()` does not typecast input values (qiangxue)
- Bug #3756: Fix number formatting error for `\yii\base\Formatter` by converting strings to float (kartik-v)
- Bug #3817: `yii\rbac\PhpManager::getChildren()` returns null instead of expected empty array (qiangxue)
- Bug #3843: Fixed Menu bug when using `template` with `encodeLabel` => false (creocoder, umneeq)
- Bug #3863: Fixed incorrect js selector for `\yii\widgets\ActiveForm::errorSummaryCssClass` when it contains multiple classes (creocoder, umneeq)
- Bug: Fixed inconsistent return of `\yii\console\Application::runAction()` (samdark)
- Bug: URL encoding for the route parameter added to `\yii\web\UrlManager` (klimov-paul)
- Bug: Fixed the bug that requesting protected or private action methods would cause 500 error instead of 404 (qiangxue)
- Bug #3843: Fixed Menu bug when using `template` with `encodeLabel` => false (creocoder, umneeq)
- Enh #2264: `CookieCollection::has()` will return false for expired or removed cookies (qiangxue)
- Enh #2435: `yii\db\IntegrityException` is now thrown on database integrity errors instead of general `yii\db\Exception` (samdark)
- Enh #2837: Error page now shows arguments in stack trace method calls (samdark)
......@@ -101,6 +102,7 @@ Yii Framework 2 Change Log
- Chg #2913: RBAC `DbManager` is now initialized via migration (samdark)
- Chg #3036: Upgraded Twitter Bootstrap to 3.1.x (qiangxue)
- Chg #3175: InvalidCallException, InvalidParamException, UnknownMethodException are now extended from SPL BadMethodCallException (samdark)
- Chg #3358: Removed automatic CSRF meta tag generation by `View`. Added `Html::csrfMetaTags()` and its call to main layout files (qiangxue)
- Chg #3383: Added `$type` parameter to `IdentityInterface::findIdentityByAccessToken()` (qiangxue)
- Chg #3531: \yii\grid\GridView now allows any character (except ":") in the attribute part of the shorthand syntax for columns (rawtaz)
- Chg #3544: Added `$key` as a parameter to the callable specified via `yii\grid\DataColumn::value` (mdmunir)
......
......@@ -50,3 +50,6 @@ Upgrade from Yii 2.0 Beta
* The `fileinfo` PHP extension is now required by Yii. If you use `yii\helpers\FileHelper::getMimeType()`, make sure
you have enabled this extension. This extension is [builtin](http://www.php.net/manual/en/fileinfo.installation.php) in php above `5.3`.
* Please update your main layout file by adding this line in the `<head>` section: `<?= Html::csrfMetaTags() ?>`.
This change is needed because `yii\web\View` no longer automatically generates CSRF meta tags due to issue #3358.
......@@ -249,6 +249,22 @@ class BaseHtml
}
/**
* Generates the meta tags containing CSRF token information.
* @return string the generated meta tags
* @see Request::enableCsrfValidation
*/
public static function csrfMetaTags()
{
$request = Yii::$app->getRequest();
if ($request instanceof Request && $request->enableCsrfValidation) {
return static::tag('meta', '', ['name' => 'csrf-param', 'content' => $request->csrfParam]) . "\n "
. static::tag('meta', '', ['name' => 'csrf-token', 'content' => $request->getCsrfToken()]) . "\n";
} else {
return '';
}
}
/**
* Generates a form start tag.
* @param array|string $action the form action URL. This parameter will be processed by [[Url::to()]].
* @param string $method the form submission method, such as "post", "get", "put", "delete" (case-insensitive).
......
......@@ -104,6 +104,7 @@ class Request extends \yii\base\Request
*
* In JavaScript, you may get the values of [[csrfParam]] and [[csrfToken]] via `yii.getCsrfParam()` and
* `yii.getCsrfToken()`, respectively. The [[\yii\web\YiiAsset]] asset must be registered.
* You also need to include CSRF meta tags in your pages by using [[\yii\helpers\Html::csrfMetaTags()]].
*
* @see Controller::enableCsrfValidation
* @see http://en.wikipedia.org/wiki/Cross-site_request_forgery
......
......@@ -460,12 +460,6 @@ class View extends \yii\base\View
$lines[] = implode("\n", $this->metaTags);
}
$request = Yii::$app->getRequest();
if ($request instanceof \yii\web\Request && $request->enableCsrfValidation && !$request->getIsAjax()) {
$lines[] = Html::tag('meta', '', ['name' => 'csrf-param', 'content' => $request->csrfParam]);
$lines[] = Html::tag('meta', '', ['name' => 'csrf-token', 'content' => $request->getCsrfToken()]);
}
if (!empty($this->linkTags)) {
$lines[] = implode("\n", $this->linkTags);
}
......
......@@ -197,7 +197,7 @@ class ActiveForm extends Widget
protected function getClientOptions()
{
$options = [
'errorSummary' => '.' . $this->errorSummaryCssClass,
'errorSummary' => '.' . implode('.', preg_split('/\s+/', $this->errorSummaryCssClass, -1, PREG_SPLIT_NO_EMPTY)),
'validateOnSubmit' => $this->validateOnSubmit,
'errorCssClass' => $this->errorCssClass,
'successCssClass' => $this->successCssClass,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment