Browse Source

Merge branch 'master' into 2.1

tags/3.0.0-alpha1
Alexander Makarov 8 years ago
parent
commit
653362e6f8
  1. 352
      docs/guide-fr/structure-filters.md
  2. 6
      docs/guide-fr/structure-views.md
  3. 179
      docs/guide-fr/structure-widgets.md
  4. 4
      docs/guide/concept-events.md
  5. 1
      framework/CHANGELOG.md
  6. 1
      framework/messages/zh-TW/yii.php
  7. 11
      framework/widgets/ActiveField.php

352
docs/guide-fr/structure-filters.md

@ -0,0 +1,352 @@
Filtres
=======
Les filtres sont des objets qui sont exécutés avant et/ou après les [actions de contrôleurs](structure-controllers.md#actions). Par exemple, un filtre de contrôle d'accès peut être exécuté avant les actions pour garantir qu'un utilisateur final particulier est autorisé à y accéder. Un filtre de compression de contenu peut être exécuté après les actions pour compresser la réponse avant de l'envoyer à l'utilisateur final.
Un filtre peut être constitué d''un pré-filtre (logique de filtrage appliquée *avant* les actions) et/ou un post-filtre (logique appliquée *après* les actions).
## Utilisation des filtres <span id="using-filters"></span>
Pour l'essentiel, les filtres sont des sortes de [comportements](concept-behaviors.md). Par conséquent, leur utilisation est identique à l' [utilisation des comportements](concept-behaviors.md#attaching-behaviors). Vous pouvez déclarer des filtres dans une classe de contrôleur en redéfinissant sa méthode [[yii\base\Controller::behaviors()|behaviors()]] de la manière suivante :
```php
public function behaviors()
{
return [
[
'class' => 'yii\filters\HttpCache',
'only' => ['index', 'view'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('user')->max('updated_at');
},
],
];
}
```
Par défaut, les filtres déclarés dans une classe de contrôleur sont appliqués à *toutes* les action de ce contrôleur. Vous pouvez cependant, spécifier explicitement à quelles actions ils s'appliquent en configurant la propriété [[yii\base\ActionFilter::only|only]]. Dans l'exemple précédent, le filtre `HttpCache` s'applique uniquement aux actions `index` et `view`. Vous pouvez également configurer la propriété [[yii\base\ActionFilter::except|except]] pour empêcher quelques actions d'être filtrées.
En plus des contrôleurs, vous pouvez également déclarer des filtres dans un [module](structure-modules.md) ou dans une [application](structure-applications.md). Lorsque vous faites cela, les filtres s'appliquent à *toutes* les actions de contrôleur qui appartiennent à ce module ou à cette application, sauf si vous configurez les propriétés des filtres [[yii\base\ActionFilter::only|only]] et [[yii\base\ActionFilter::except|except]] comme expliqué précédemment.
> Note: lorsque vous déclarez des filtres dans des modules ou des applications, vous devriez utiliser des [routes](structure-controllers.md#routes) plutôt que des identifiants d'action dans les propriétés [[yii\base\ActionFilter::only|only]] et [[yii\base\ActionFilter::except|except]]. Cela tient au fait qu'un identifiant d'action seul ne peut pas pleinement spécifier une action dans le cadre d'un module ou d'une application.
Lorsque plusieurs filtres sont configurés pour une même action, ils sont appliqués en respectant les règles et l'ordre qui suivent :
* Pré-filtrage
- Les filtres déclarés dans l'application sont appliqués dans l'ordre dans lequel ils sont listés dans la méthode `behaviors()`.
- Les filtres déclarés dans le module sont appliqués dans l'ordre dans lequel ils sont listés dans la méthode `behaviors()`.
- Les filtres déclarés dans le contrôleur sont appliqués dans l'ordre dans lequel ils sont listés dans la méthode `behaviors()`.
- Si l'un quelconque des filtres annule l'exécution de l'action, les filtres subséquents (à la fois de pré-filtrage et de post-fitrage) ne sont pas appliqués.
* L'action est exécutée si les filtres de pré-filtrage réussissent.
* Post-filtrage
- Les filtres déclarés dans le contrôleur sont appliqués dans l'ordre dans lequel ils sont listés dans la méthode `behaviors()`.
- Les filtres déclarés dans le module sont appliqués dans l'ordre dans lequel ils sont listés dans la méthode `behaviors()`.
- Les filtres déclarés dans l'application sont appliqués dans l'ordre dans lequel ils sont listés dans la méthode `behaviors()`.
## Création de filtres <span id="creating-filters"></span>
Pour créer un filtre d'action, vous devez étendre la classe [[yii\base\ActionFilter]] et redéfinir la méthode [[yii\base\ActionFilter::beforeAction()|beforeAction()]] et/ou la méthode [[yii\base\ActionFilter::afterAction()|afterAction()]]. La première est exécutée avant l'exécution de l'action, tandis que la seconde est exécutée après l'exécution de l'action. Le valeur de retour de la méthode [[yii\base\ActionFilter::beforeAction()|beforeAction()]] détermine si une action doit être exécutée ou pas. Si c'est `false` (faux), les filtres qui suivent sont ignorés et l'action n'est pas exécutée.
L'exemple qui suit montre un filtre qui enregistre dans un journal le temps d'exécution de l'action :
```php
namespace app\components;
use Yii;
use yii\base\ActionFilter;
class ActionTimeFilter extends ActionFilter
{
private $_startTime;
public function beforeAction($action)
{
$this->_startTime = microtime(true);
return parent::beforeAction($action);
}
public function afterAction($action, $result)
{
$time = microtime(true) - $this->_startTime;
Yii::trace("Action '{$action->uniqueId}' spent $time second.");
return parent::afterAction($action, $result);
}
}
```
## Filtres du noyau <span id="core-filters"></span>
Yii fournit un jeu de filtres couramment utilisés, que l'on trouve en premier lieu dans l'espace de noms `yii\filters`. Dans ce qui suit, nous introduisons brièvement ces filtres.
### [[yii\filters\AccessControl|AccessControl]] <span id="access-control"></span>
*AccessControl* (contrôle d'accès) fournit un contrôle d'accès simple basé sur un jeu de [[yii\filters\AccessControl::rules|règles]]. En particulier, avant qu'une action ne soit exécutée, *AccessControl* examine les règles listées et trouve la première qui correspond aux variables du contexte courant (comme l'adresse IP, l'état de connexion de l'utilisateur, etc.). La règle qui correspond détermine si l'exécution de l'action requise doit être autorisée ou refusée. Si aucune des règles ne correspond, l'accès est refusé.
L'exemple suivant montre comment autoriser les utilisateurs authentifiés à accéder aux actions `create` et `update` tout en refusant l'accès à ces actions aux autres utilisateurs.
```php
use yii\filters\AccessControl;
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['create', 'update'],
'rules' => [
// autoriser les utilisateurs authentifiés
[
'allow' => true,
'roles' => ['@'],
],
// tout autre chose est interdite d'accès par défaut
],
],
];
}
```
Pour plus de détails sur le contrôle d'accès en général, reportez-vous à la section [Authorization](security-authorization.md).
### Filtres de méthodes d'authentification <span id="auth-method-filters"></span>
Les filtres de méthodes d'authentification sont utilisés pour authentifier un utilisateur qui utilise des méthodes d'authentification variées comme
[HTTP Basic Auth](http://en.wikipedia.org/wiki/Basic_access_authentication) ou [OAuth 2](http://oauth.net/2/). Les classes de filtre sont dans l'espace de noms `yii\filters\auth`.
L'exemple qui suit montre comment vous pouvez utiliser [[yii\filters\auth\HttpBasicAuth]] pour authentifier un utilisateur qui utilise un jeton d'accès basé sur la méthode *HTTP Basic Auth*. Notez qu'afin que cela fonctionne, votre [[yii\web\User::identityClass|classe *identity* de l'utilisateur]] doit implémenter l'interface [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]].
```php
use yii\filters\auth\HttpBasicAuth;
public function behaviors()
{
return [
'basicAuth' => [
'class' => HttpBasicAuth::className(),
],
];
}
```
Les filtres de méthode d'authentification sont communément utilisés dans la mise en œuvre des API pleinement REST. Pour plus de détails, reportez-vous à la section [Authentification REST](rest-authentication.md).
### [[yii\filters\ContentNegotiator|ContentNegotiator]] <span id="content-negotiator"></span>
*ContentNegotiator* (négociateur de contenu) prend en charge la négociation des formats de réponse et la négociation de langue d'application. Il essaye de déterminer le format de la réponse et/ou la langue en examinant les paramètres de la méthode `GET` et ceux de l'entête HTTP `Accept`.
Dans l'exemple qui suit, le filtre *ContentNegotiator* est configuré pour prendre en charge JSON et XML en tant que formats de réponse, et anglais (États-Unis) et allemand en tant que langues.
```php
use yii\filters\ContentNegotiator;
use yii\web\Response;
public function behaviors()
{
return [
[
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
],
'languages' => [
'en-US',
'de',
],
],
];
}
```
Les formats de réponse et les langues nécessitent souvent d'être déterminés bien plus tôt durant le [cycle de vie de l'application](structure-applications.md#application-lifecycle). Pour cette raison, *ContentNegotiator* est conçu de manière à être également utilisé en tant que [composant du processus d'amorçage](structure-applications.md#bootstrap). Par exemple, vous pouvez le configurer dans la [configuration de l'application](structure-applications.md#application-configurations) de la manière suivante :
```php
use yii\filters\ContentNegotiator;
use yii\web\Response;
[
'bootstrap' => [
[
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
],
'languages' => [
'en-US',
'de',
],
],
],
];
```
> Info: dans le cas où le type de contenu et la langue préférés ne peuvent être déterminés à partir de la requête, le premier format et la première langue listés dans [[formats]] et[[languages]], respectivement, sont utilisés.
### [[yii\filters\HttpCache|HttpCache]] <span id="http-cache"></span>
*HttpCache* met en œuvre la mise en cache côté client en utilisant les entêtes HTTP `Last-Modified` (dernier modifié) et `Etag`.
Par exemple :
```php
use yii\filters\HttpCache;
public function behaviors()
{
return [
[
'class' => HttpCache::className(),
'only' => ['index'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('user')->max('updated_at');
},
],
];
}
```
Reportez-vous à la section [Mise en cache HTTP](caching-http.md) pour plus de détails sur l'utilisation de *HttpCache*.
### [[yii\filters\PageCache|PageCache]] <span id="page-cache"></span>
*PageCache* met en œuvre la mise en cache de pages entières côté serveur. Dans l'exemple qui suit, *PageCache0 est appliqué à l'action `index` pour mettre la page entière en cache pendant un maximum de 60 secondes ou jusqu'à un changement du nombre d'entrées dans la table `post`. Il stocke également différentes versions de la page en fonction de la langue choisie.
```php
use yii\filters\PageCache;
use yii\caching\DbDependency;
public function behaviors()
{
return [
'pageCache' => [
'class' => PageCache::className(),
'only' => ['index'],
'duration' => 60,
'dependency' => [
'class' => DbDependency::className(),
'sql' => 'SELECT COUNT(*) FROM post',
],
'variations' => [
\Yii::$app->language,
]
],
];
}
```
Reportez-vous à la section [Page Caching](caching-page.md) pour plus de détails sur l'utilisation de *PageCache*.
### [[yii\filters\RateLimiter|RateLimiter]] <span id="rate-limiter"></span>
*RateLimiter* met en œuvre un algorithme de limitation de débit basé sur l'[algorithme leaky bucket](http://en.wikipedia.org/wiki/Leaky_bucket). On l'utilise en premier lieu dans la mise en œuvre des API pleinement REST. Reportez-vous à la section [limitation de débit](rest-rate-limiting.md) pour plus de détails sur l'utilisation de ce filtre.
### [[yii\filters\VerbFilter|VerbFilter]] <span id="verb-filter"></span>
*VerbFilter* vérifie si les méthodes de requête HTTP sont autorisées par l'action requise. Si ce n'est pas le cas, une exception HTTP 405 est levée. Dans l'exemple suivant, *VerbFilter* est déclaré pour spécifier un jeu typique de méthodes de requête pour des actions CRUD — Create (créer), Read (lire), Update (mettre à jour), DELETE (supprimer).
```php
use yii\filters\VerbFilter;
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index' => ['get'],
'view' => ['get'],
'create' => ['get', 'post'],
'update' => ['get', 'put', 'post'],
'delete' => ['post', 'delete'],
],
],
];
}
```
### [[yii\filters\Cors|Cors]] <span id="cors"></span>
*Cross-origin resource sharing* [CORS](https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS) est un mécanisme qui permet à des ressource (e.g. fonts, JavaScript, etc.) d'être requises d'un autre domaine en dehors du domaine dont la ressource est originaire. En particulier, les appels AJAX de Javascript peuvent utiliser le mécanisme *XMLHttpRequest*. Autrement, de telles requêtes "cross-domain" (inter domaines) seraient interdites par les navigateurs, à cause de la politique de sécurité dite d'origine identique (*same origin*). *CORS* définit une manière par laquelle le navigateur et le serveur interagissent pour déterminer si, oui ou non, la requête *cross-origin* (inter-site) est autorisée.
Le [[yii\filters\Cors|filtre Cors]] doit être défini avant les filtres d'authentification et/ou d'autorisation pour garantir que les entêtes CORS sont toujours envoyés.
```php
use yii\filters\Cors;
use yii\helpers\ArrayHelper;
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => Cors::className(),
],
], parent::behaviors());
}
```
Consultez également la section sur les [contrôleurs REST](rest-controllers.md#cors) si vous voulez ajouter le filtre CORS à une classe
[[yii\rest\ActiveController]] dans votre API.
Les filtrages Cors peuvent être peaufinés via la propriété [[yii\filters\Cors::$cors|$cors]].
* `cors['Origin']`: un tableau utilisé pour définir les origines autorisées. Peut être `['*']` (tout le monde) ou `['http://www.myserver.net', 'http://www.myotherserver.com']`. Valeur par défaut  `['*']`.
* `cors['Access-Control-Request-Method']`: un tableau des verbes autorisés tel que `['GET', 'OPTIONS', 'HEAD']`. Valeur par défaut `['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']`.
* `cors['Access-Control-Request-Headers']`: un tableau des entêtes autorisés. Peut être`['*']` tous les entêtes ou certains spécifiquement `['X-Request-With']`. Valeur par défaut `['*']`.
* `cors['Access-Control-Allow-Credentials']`: définit si la requête courante peut être faite en utilisant des identifiants de connexion. Peut être `true` (vrai), `false` (faux) ou `null` (non défini). Valeur par défaut `null`.
* `cors['Access-Control-Max-Age']`: définit la durée de vie des requêtes de pré-vérification (*preflight requests*). Valeur par défaut `86400`.
Par exemple, autoriser CORS pour l'origine `http://www.myserver.net` avec les méthodes `GET`, `HEAD` et `OPTIONS` :
```php
use yii\filters\Cors;
use yii\helpers\ArrayHelper;
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => Cors::className(),
'cors' => [
'Origin' => ['http://www.myserver.net'],
'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
],
],
], parent::behaviors());
}
```
Vous pouvez peaufiner les entêtes CORS en redéfinissant les paramètres par défaut action par action. Par exemple, ajouter les `Access-Control-Allow-Credentials` (autoriser les identifiants de contrôle d'accès) pour l'action`login` pourrait être réalisé comme ceci :
```php
use yii\filters\Cors;
use yii\helpers\ArrayHelper;
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => Cors::className(),
'cors' => [
'Origin' => ['http://www.myserver.net'],
'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
],
'actions' => [
'login' => [
'Access-Control-Allow-Credentials' => true,
]
]
],
], parent::behaviors());
}
```

6
docs/guide-fr/structure-views.md

@ -76,7 +76,7 @@ use yii\helpers\HtmlPurifier;
Comme les [contrôleurs](structure-controllers.md) et les [modèles](structure-models.md), il existe certaines conventions pour organiser les vues. Comme les [contrôleurs](structure-controllers.md) et les [modèles](structure-models.md), il existe certaines conventions pour organiser les vues.
* Pour les vues rendues par un contrôleur, elles devraient être placées par défaut dans le dossier `@app/views/ControllerID``ControllerID` doit être remplacé par l'[identifiant du contrôleur](structure-controllers.md#routes). Par exemple, si la classe du contrôleur est `PostController`, le dossier est `@app/views/post`; si c'est `PostCommentController` le dossier est `@app/views/post-comment`. Dans le cas où le contrôleur appartient à un module, le dossier s'appelle `views/ControllerID` et se trouve dans le [[yii\base\Module::basePath|dossier racine du module]]. * Pour les vues rendues par un contrôleur, elles devraient être placées par défaut dans le dossier `@app/views/ControllerID``ControllerID` doit être remplacé par l'[identifiant du contrôleur](structure-controllers.md#routes). Par exemple, si la classe du contrôleur est `PostController`, le dossier est `@app/views/post`; si c'est `PostCommentController` le dossier est `@app/views/post-comment`. Dans le cas où le contrôleur appartient à un module, le dossier s'appelle `views/ControllerID` et se trouve dans le [[yii\base\Module::basePath|dossier de base du module]].
* Pour les vues rendues dans un [widget (objet graphique)](structure-widgets.md), elles devraient être placées par défaut dans le dossier `WidgetPath/views``WidgetPath` est le dossier contenant le fichier de la classe du widget. * Pour les vues rendues dans un [widget (objet graphique)](structure-widgets.md), elles devraient être placées par défaut dans le dossier `WidgetPath/views``WidgetPath` est le dossier contenant le fichier de la classe du widget.
* Pour les vues rendues par d'autres objets, il est recommandé d'adopter une convention similaire à celle utilisée pour les *widgets*. * Pour les vues rendues par d'autres objets, il est recommandé d'adopter une convention similaire à celle utilisée pour les *widgets*.
@ -254,7 +254,7 @@ Les dispositions (*layouts*) sont des types spéciaux de vues qui représentent
### Création de dispositions <span id="creating-layouts"></span> ### Création de dispositions <span id="creating-layouts"></span>
Parce que les dispositions sont aussi des vues, elles peuvent être créées de manière similaire aux vues ordinaires. Par défaut, les dispositions sont stockées dans le dossier `@app/views/layouts`. Les dispositions utilisées dans un [module](structure-modules.md) doivent être stockées dans le dossier `views/layouts` du [[yii\base\Module::basePath|dossier racine du module]]. Vous pouvez personnaliser le dossier par défaut des dispositions en configurant la propriété [[yii\base\Module::layoutPath]] de l'application ou du module. Parce que les dispositions sont aussi des vues, elles peuvent être créées de manière similaire aux vues ordinaires. Par défaut, les dispositions sont stockées dans le dossier `@app/views/layouts`. Les dispositions utilisées dans un [module](structure-modules.md) doivent être stockées dans le dossier `views/layouts` du [[yii\base\Module::basePath|dossier de base du module]]. Vous pouvez personnaliser le dossier par défaut des dispositions en configurant la propriété [[yii\base\Module::layoutPath]] de l'application ou du module.
L'exemple qui suit montre à quoi ressemble une disposition. Notez que dans un but illustratif, nous avons grandement simplifié le code à l'intérieur de cette disposition. En pratique, vous désirerez ajouter à ce code plus de contenu, comme des balises head, un menu principal, etc. L'exemple qui suit montre à quoi ressemble une disposition. Notez que dans un but illustratif, nous avons grandement simplifié le code à l'intérieur de cette disposition. En pratique, vous désirerez ajouter à ce code plus de contenu, comme des balises head, un menu principal, etc.
@ -334,7 +334,7 @@ Dans la seconde étape, il détermine le fichier de disposition réel en fonctio
- Un alias de chemin (p. ex. `@app/views/layouts/main`). - Un alias de chemin (p. ex. `@app/views/layouts/main`).
- Un chemin absolu (p. ex. `/main`): la valeur de disposition commence par une barre oblique de division. Le fichier réel de disposition est recherché dans le [[yii\base\Application::layoutPath|chemin des disposition (*layoutPath*)]] (par défaut `@app/views/layouts`). - Un chemin absolu (p. ex. `/main`): la valeur de disposition commence par une barre oblique de division. Le fichier réel de disposition est recherché dans le [[yii\base\Application::layoutPath|chemin des disposition (*layoutPath*)]] (par défaut `@app/views/layouts`).
- Un chemin relatif (p. ex. `main`): le fichier réel de disposition est recherché dans le [[yii\base\Module::layoutPath|chemin des dispositions (*layoutPath*)]] du module du contexte (par défaut`views/layouts`) dans le [[yii\base\Module::basePath|dossier racine du module]]. - Un chemin relatif (p. ex. `main`): le fichier réel de disposition est recherché dans le [[yii\base\Module::layoutPath|chemin des dispositions (*layoutPath*)]] du module du contexte (par défaut`views/layouts`) dans le [[yii\base\Module::basePath|dossier de base du module]].
- La valeur booléenne `false`: aucune disposition n'est appliquée. - La valeur booléenne `false`: aucune disposition n'est appliquée.
Si la valeur de disposition ne contient pas d'extension de fichier, l'extension par défaut `.php` est utilisée. Si la valeur de disposition ne contient pas d'extension de fichier, l'extension par défaut `.php` est utilisée.

179
docs/guide-fr/structure-widgets.md

@ -0,0 +1,179 @@
Objets d'interface graphique
==============================
Les objets d'interface graphique (*widgets*) sont des blocs de construction réutilisables dans des [vues](structure-views.md) pour créer des éléments d'interface utilisateur complexes et configurables d'une manière orientée objet. Par exemple, un composant d'interface graphique de sélection de date peut générer un sélecteur de date original qui permet aux utilisateurs de sélectionner une date en tant qu'entrée. Tout ce que vous avez besoin de faire, c'est d'insérer le code dans une vue comme indiqué ci-dessous :
```php
<?php
use yii\jui\DatePicker;
?>
<?= DatePicker::widget(['name' => 'date']) ?>
```
Il existe un grand nombre d'objets d'interface graphique fournis avec Yii, tels que les[[yii\widgets\ActiveForm|active form]], [[yii\widgets\Menu|menu]], [jQuery UI widgets](widget-jui.md), [Twitter Bootstrap widgets](widget-bootstrap.md). Dans ce qui suit, nous introduisons les connaissances de base sur les objets d'interface graphique. Reportez-vous à la documentation de la classe dans l'API si vous désirez en apprendre davantage sur un objet d'interface graphique particulier.
## Utilisation des objets d'interface graphique <span id="using-widgets"></span>
Les objets d'interface graphique sont utilisés en premier lieu dans des [vues](structure-views.md). Vous pouvez appeler la méthode [[yii\base\Widget::widget()]] pour utiliser un objet d'interface graphique dans une vue. Cette méthode accepte un tableau de [configuration](concept-configurations.md) pour initialiser l'objet graphique d'interface et retourne le résultat du rendu de cet objet. Par exemple, le code suivant insère un objet d'interface graphique de sélection de date qui est configuré dans la langue *russe* et conserve l'entrée dans l'attribut `from_date` du `$model`.
```php
<?php
use yii\jui\DatePicker;
?>
<?= DatePicker::widget([
'model' => $model,
'attribute' => 'from_date',
'language' => 'ru',
'clientOptions' => [
'dateFormat' => 'yy-mm-dd',
],
]) ?>
```
Quelques objets d'interface graphique peuvent accepter un bloc de contenu qui doit être compris entre l'appel des méthodes [[yii\base\Widget::begin()]] et [[yii\base\Widget::end()]]. Par exemple, le code suivant utilise l'objet d'interface graphique [[yii\widgets\ActiveForm]] pour générer une ouverture de balise `<form>` à l'endroit de l'appel de `begin()` et une fermeture de la même balise à l'endroit de l'appel de `end()`. Tout ce qui se trouve entre les deux est rendu tel quel.
```php
<?php
use yii\widgets\ActiveForm;
use yii\helpers\Html;
?>
<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<div class="form-group">
<?= Html::submitButton('Login') ?>
</div>
<?php ActiveForm::end(); ?>
```
Notez que contrairement à la méthode [[yii\base\Widget::widget()]] qui retourne le résultat du rendu d'un objet d'interface graphique, la méthode [[yii\base\Widget::begin()]] retourne une instance de l'objet d'interface graphique que vous pouvez utiliser pour construire le contenu de l'objet d'interface.
> Note: quelques objets d'interface graphique utilisent [la mise en tampon de sortie](http://php.net/manual/en/book.outcontrol.php)
> pour ajuster le contenu inclus quand la méthode [[yii\base\Widget::end()]] est appelée.
> Pour cette raison, l'appel des méthodes [[yii\base\Widget::begin()]] and
> [[yii\base\Widget::end()]] est attendu dans le même fichier de vue.
> Ne pas respecter cette règle peut conduire à des résultats inattendus.
### Configuration des variables globales par défaut
Les variables globales par défaut pour un objet d'interface graphique peuvent être configurées via le conteneur d'injection de dépendances (*DI container*) :
```php
\Yii::$container->set('yii\widgets\LinkPager', ['maxButtonCount' => 5]);
```
Voir la section ["Utilisation pratique " dans le Guide du conteneur d'injection de dépendances](concept-di-container.md#practical-usage) pour les détails.
## Création d'objets d'interface graphique <span id="creating-widgets"></span>
Pour créer un objet d'interface graphique, étendez la classe [[yii\base\Widget]] et redéfinissez sa méthode [[yii\base\Widget::init()]] et/ou sa méthode [[yii\base\Widget::run()]]. Ordinairement, la méthode `init()` devrait contenir le code qui normalise les propriétés de l'objet d'interface graphique, tandis que la méthode `run()` devrait contenir le code qui génère le résultat du rendu de cet objet d'interface graphique. Le résultat du rendu peut être "renvoyé en écho" directement ou retourné comme une chaîne de caractères par la méthode `run()`.
Dans l'exemple suivant, `HelloWidget` encode en HTML et affiche le contenu assigné à sa propriété `message`.
Si la propriété n'est pas définie, il affiche "Hello World" par defaut.
```php
namespace app\components;
use yii\base\Widget;
use yii\helpers\Html;
class HelloWidget extends Widget
{
public $message;
public function init()
{
parent::init();
if ($this->message === null) {
$this->message = 'Hello World';
}
}
public function run()
{
return Html::encode($this->message);
}
}
```
Pour utiliser cet objet d'interface graphique, contentez-vous d'insérer le code suivant dans une vue :
```php
<?php
use app\components\HelloWidget;
?>
<?= HelloWidget::widget(['message' => 'Good morning']) ?>
```
Ce-dessous, nous présentons une variante de `HelloWidget` qui prend le contenu inséré entre les appels des méthodes `begin()` et `end()`, l'encode en HTML et l'affiche.
```php
namespace app\components;
use yii\base\Widget;
use yii\helpers\Html;
class HelloWidget extends Widget
{
public function init()
{
parent::init();
ob_start();
}
public function run()
{
$content = ob_get_clean();
return Html::encode($content);
}
}
```
Comme vous pouvez le voir, le tampon de sortie de PHP est démarré dans `init()` de manière à ce que toute sortie entre les appels de `init()` et de `run()`
puisse être capturée, traitée et retournée dans `run()`.
> Info: lorsque vous appelez [[yii\base\Widget::begin()]], une nouvelle instance de l'objet d'interface graphique est créé et sa méthode `init()` est appelée à la fin de la construction de l'objet. Lorsque vous appelez [[yii\base\Widget::end()]], la méthode `run()` est appelée et sa valeur de retour est renvoyée en écho par `end()`.
Le code suivant montre comment utiliser cette nouvelle variante de `HelloWidget`:
```php
<?php
use app\components\HelloWidget;
?>
<?php HelloWidget::begin(); ?>
content that may contain <tag>'s
<?php HelloWidget::end(); ?>
```
Parfois, un objet d'interface graphique peut avoir à rendre un gros bloc de contenu. Bien que vous puissiez incorporer le contenu dans la méthode `run()`, une meilleure approche consiste à le mettre dans une [vue](structure-views.md) et à appeler la méthode [[yii\base\Widget::render()]] pour obtenir son rendu. Par exemple :
```php
public function run()
{
return $this->render('hello');
}
```
Par défaut, les vues pour un objet d'interface graphique doivent être stockées dans le dossier `WidgetPath/views`, où `WidgetPath` représente le dossier contenant la classe de l'objet d'interface graphique. Par conséquent, l'exemple ci-dessus rend le fichier de vue `@app/components/views/hello.php`, en supposant que la classe de l'objet d'interface graphique est située dans le dossier `@app/components`. Vous pouvez redéfinir la méthode [[yii\base\Widget::getViewPath()]] pour personnaliser le dossier qui contient les fichiers de vue des objets d'interface graphique.
## Meilleures pratiques <span id="best-practices"></span>
Les objets d'interface graphique sont une manière orientée objets de réutiliser du code de vues.
Lors de la création d'objets d'interface graphique, vous devriez continuer de suivre le modèle d'architecture MVC. En général, vous devriez conserver la logique dans les classes d'objets d'interface graphique et la présentation dans les [vues](structure-views.md).
Les objets d'interface graphique devraient également être conçus pour être auto-suffisants. Cela veut dire que, lors de l'utilisation d'un tel objet, vous devriez être en mesure de vous contenter de le placer dans une vue sans rien faire d'autre. Cela peut s'avérer délicat si un objet d'interface graphique requiert des ressources externes, comme du CSS, du Javascript, des images, etc. Heureusement, Yii fournit une prise en charge des [paquets de ressources](structure-assets.md) que vous pouvez utiliser pour résoudre le problème.
Quand un objet d'interface graphique contient du code de vue seulement, il est très similaire à une [vue](structure-views.md). En fait, dans ce cas, la seule différence est que l'objet d'interface graphique est une classe redistribuable, tandis qu'une vue est juste un simple script PHP que vous préférez conserver dans votre application.

4
docs/guide/concept-events.md

@ -129,7 +129,7 @@ With the above code, any calls to `bar()` will trigger an event named `hello`.
auto-completion support. Third, you can tell what events are supported in a class by simply checking its constant declarations. auto-completion support. Third, you can tell what events are supported in a class by simply checking its constant declarations.
Sometimes when triggering an event you may want to pass along additional information to the event handlers. Sometimes when triggering an event you may want to pass along additional information to the event handlers.
For example, a mailer may want pass the message information to the handlers of the `messageSent` event so that the handlers For example, a mailer may want to pass the message information to the handlers of the `messageSent` event so that the handlers
can know the particulars of the sent messages. To do so, you can provide an event object as the second parameter to can know the particulars of the sent messages. To do so, you can provide an event object as the second parameter to
the [[yii\base\Component::trigger()]] method. The event object must be an instance of the [[yii\base\Event]] class the [[yii\base\Component::trigger()]] method. The event object must be an instance of the [[yii\base\Event]] class
or a child class. For example: or a child class. For example:
@ -258,7 +258,7 @@ Events using interfaces <span id="interface-level-event-handlers"></span>
There is even more abstract way to deal with events. You can create a separated interface for the special event and There is even more abstract way to deal with events. You can create a separated interface for the special event and
implement it in classes, where you need it. implement it in classes, where you need it.
For example we can create the following interface: For example, we can create the following interface:
```php ```php
interface DanceEventInterface interface DanceEventInterface

1
framework/CHANGELOG.md

@ -12,6 +12,7 @@ Yii Framework 2 Change Log
2.0.10 under development 2.0.10 under development
------------------------ ------------------------
- Enh #12073: Added the ability to suppress the generation of input hint when it is specified through `Model::attributeHints()` (PowerGamer1)
- Bug #12068: Added missing 'LEVEL_PROFILE' for the syslog target (Mak-Di) - Bug #12068: Added missing 'LEVEL_PROFILE' for the syslog target (Mak-Di)
- Bug #11461: Fixed migration tool error when create migrate with comma in defaultValue (pana1990, s-o-f) - Bug #11461: Fixed migration tool error when create migrate with comma in defaultValue (pana1990, s-o-f)
- Bug #11912: Fixed PostgreSQL Schema to support negative default values for integer/float/decimal columns (nsknewbie) - Bug #11912: Fixed PostgreSQL Schema to support negative default values for integer/float/decimal columns (nsknewbie)

1
framework/messages/zh-TW/yii.php

@ -77,6 +77,7 @@ return [
'{attribute} must be an IP address with specified subnet.' => '{attribute} 必須指定一個IP地址和子網。', '{attribute} must be an IP address with specified subnet.' => '{attribute} 必須指定一個IP地址和子網。',
'{attribute} must be an integer.' => '{attribute} 必須為整數。', '{attribute} must be an integer.' => '{attribute} 必須為整數。',
'{attribute} must be either "{true}" or "{false}".' => '{attribute} 必須為 "{true}" 或 "{false}"。', '{attribute} must be either "{true}" or "{false}".' => '{attribute} 必須為 "{true}" 或 "{false}"。',
'{attribute} must be equal to "{compareValueOrAttribute}".' => '{attribute}必須等於"{compareValueOrAttribute}"。',
'{attribute} must be greater than "{compareValue}".' => '{attribute} 必須大於 "{compareValue}"。', '{attribute} must be greater than "{compareValue}".' => '{attribute} 必須大於 "{compareValue}"。',
'{attribute} must be greater than or equal to "{compareValue}".' => '{attribute} 必須大或等於 "{compareValue}"。', '{attribute} must be greater than or equal to "{compareValue}".' => '{attribute} 必須大或等於 "{compareValue}"。',
'{attribute} must be less than "{compareValue}".' => '{attribute} 必須小於 "{compareValue}"。', '{attribute} must be less than "{compareValue}".' => '{attribute} 必須小於 "{compareValue}"。',

11
framework/widgets/ActiveField.php

@ -304,7 +304,9 @@ class ActiveField extends Component
/** /**
* Renders the hint tag. * Renders the hint tag.
* @param string $content the hint content. It will NOT be HTML-encoded. * @param string|bool $content the hint content. If null, the hint will be generated via [[Model::getAttributeHint()]].
* If false, the generated field will not contain the hint part.
* Note that this will NOT be [[Html::encode()|encoded]].
* @param array $options the tag options in terms of name-value pairs. These will be rendered as * @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the hint tag. The values will be HTML-encoded using [[Html::encode()]]. * the attributes of the hint tag. The values will be HTML-encoded using [[Html::encode()]].
* *
@ -317,8 +319,15 @@ class ActiveField extends Component
*/ */
public function hint($content, $options = []) public function hint($content, $options = [])
{ {
if ($content === false) {
$this->parts['{hint}'] = '';
return $this;
}
$options = array_merge($this->hintOptions, $options); $options = array_merge($this->hintOptions, $options);
if ($content !== null) {
$options['hint'] = $content; $options['hint'] = $content;
}
$this->parts['{hint}'] = Html::activeHint($this->model, $this->attribute, $options); $this->parts['{hint}'] = Html::activeHint($this->model, $this->attribute, $options);
return $this; return $this;

Loading…
Cancel
Save