Yii - Modèles

Les modèles sont des objets représentant la logique métier et les règles. Pour créer un modèle, vous devez étendre leyii\base\Model classe ou ses sous-classes.

Les attributs

Les attributs représentent les données commerciales. Ils sont accessibles comme des éléments de tableau ou des propriétés d'objet. Chaque attribut est une propriété accessible au public d'un modèle. Pour spécifier les attributs d'un modèle, vous devez remplacer leyii\base\Model::attributes() méthode.

Jetons un œil à la ContactForm modèle du modèle d'application de base.

<?php
   namespace app\models;
   use Yii;
   use yii\base\Model;
   /**
   * ContactForm is the model behind the contact form.
   */
   class ContactForm extends Model {
      public $name; public $email;
      public $subject; public $body;
      public $verifyCode; /** * @return array the validation rules. */ public function rules() { return [ // name, email, subject and body are required [['name', 'email', 'subject', 'body'], 'required'], // email has to be a valid email address ['email', 'email'], // verifyCode needs to be entered correctly ['verifyCode', 'captcha'], ]; } /** * @return array customized attribute labels */ public function attributeLabels() { return [ 'verifyCode' => 'Verification Code', ]; } /** * Sends an email to the specified email address using the information collected by this model. * @param string $email the target email address
      * @return boolean whether the model passes validation
      */
      public function contact($email) { if ($this->validate()) {
            Yii::$app->mailer->compose() ->setTo($email)
               ->setFrom([$this->email => $this->name])
               ->setSubject($this->subject) ->setTextBody($this->body)
               ->send();
            return true;
         }
         return false;
      }
   }
?>

Step 1 - Créez une fonction appelée actionShowContactModel dans le SiteController avec le code suivant.

public function actionShowContactModel() { 
   $mContactForm = new \app\models\ContactForm(); $mContactForm->name = "contactForm"; 
   $mContactForm->email = "[email protected]"; $mContactForm->subject = "subject"; 
   $mContactForm->body = "body"; var_dump($mContactForm); 
}

Dans le code ci-dessus, nous définissons le ContactForm modèle, définissez les attributs et affichez le modèle à l'écran.

Step 2 - Maintenant, si vous tapez http://localhost:8080/index.php?r=site/show-contact-model dans la barre d'adresse du navigateur Web, vous verrez ce qui suit.

Si votre modèle s'étend de yii\base\Model, alors toutes ses variables membres (publiques et non statiques) sont des attributs. Il y a cinq attributs dans leContactForm modèle - nom, e-mail, sujet, corps, verifyCode et vous pouvez facilement en ajouter de nouveaux.

Étiquettes d'attribut

Vous devez souvent afficher les étiquettes associées aux attributs. Par défaut, les étiquettes d'attribut sont automatiquement générées par leyii\base\Model::generateAttributeLabel()méthode. Pour déclarer manuellement les étiquettes d'attribut, vous pouvez remplacer leyii\base\Model::attributeLabels() méthode.

Step 1 - Si vous ouvrez http://localhost:8080/index.php?r=site/contact, vous verrez la page suivante.

Notez que les étiquettes d'attribut sont les mêmes que leurs noms.

Step 2 - Maintenant, modifiez le attributeLabels fonction dans le ContactForm modèle de la manière suivante.

public function attributeLabels() {
   return [
      'name' => 'name overridden',
      'email' => 'email overridden',
      'subject' => 'subject overridden',
      'body' => 'body overridden',
      'verifyCode' => 'verifyCode overridden',
   ];
}

Step 3 - Si vous ouvrez http://localhost:8080/index.php?r=site/contact à nouveau, vous remarquerez que les étiquettes ont changé comme indiqué dans l'image suivante.

Scénarios

Vous pouvez utiliser un modèle dans différents scénarios. Par exemple, lorsqu'un invité souhaite envoyer un formulaire de contact, nous avons besoin de tous les attributs du modèle. Lorsqu'un utilisateur veut faire la même chose, il est déjà connecté, nous n'avons donc pas besoin de son nom, car nous pouvons facilement le prendre dans la base de données.

Pour déclarer des scénarios, nous devons remplacer le scenarios()fonction. Il renvoie un tableau dont les clés sont les noms de scénario et les valeurs sontactive attributes. Les attributs actifs sont ceux à valider. Ils peuvent aussi êtremassively assigned.

Step 1 - Modifier le ContactForm modèle de la manière suivante.

<?php
   namespace app\models;
   use Yii;
   use yii\base\Model;
   /**
   * ContactForm is the model behind the contact form.
   */
   class ContactForm extends Model {
      public $name; public $email;
      public $subject; public $body;
      public $verifyCode; const SCENARIO_EMAIL_FROM_GUEST = 'EMAIL_FROM_GUEST'; const SCENARIO_EMAIL_FROM_USER = 'EMAIL_FROM_USER'; public function scenarios() { return [ self::SCENARIO_EMAIL_FROM_GUEST => ['name', 'email', 'subject', 'body', 'verifyCode'], self::SCENARIO_EMAIL_FROM_USER => ['email' ,'subject', 'body', 'verifyCode'], ]; } /** * @return array the validation rules. */ public function rules() { return [ // name, email, subject and body are required [['name', 'email', 'subject', 'body'], 'required'], // email has to be a valid email address ['email', 'email'], // verifyCode needs to be entered correctly ['verifyCode', 'captcha'], ]; } /** * @return array customized attribute labels */ public function attributeLabels() { return [ 'name' => 'name overridden', 'email' => 'email overridden', 'subject' => 'subject overridden', 'body' => 'body overridden', 'verifyCode' => 'verifyCode overridden', ]; } /** * Sends an email to the specified email address using the information collected by this model. * @param string $email the target email address
      * @return boolean whether the model passes validation
      */
      public function contact($email) { if ($this -> validate()) {
            Yii::$app->mailer->compose() ->setTo($email)
               ->setFrom([$this->email => $this->name]) 
               ->setSubject($this->subject) ->setTextBody($this->body)
               ->send();
            return true;
         }
         return false;
      }
   }
?>

Nous avons ajouté deux scénarios. Un pour l'invité et un autre pour l'utilisateur authentifié. Lorsque l'utilisateur est authentifié, nous n'avons pas besoin de son nom.

Step 2 - Maintenant, modifiez le actionContact fonction de la SiteController.

public function actionContact() {
   $model = new ContactForm(); $model->scenario = ContactForm::SCENARIO_EMAIL_FROM_GUEST;
   if ($model->load(Yii::$app->request->post()) && $model-> contact(Yii::$app->params ['adminEmail'])) {
         Yii::$app->session->setFlash('contactFormSubmitted'); return $this->refresh();
   }
   return $this->render('contact', [ 'model' => $model,
   ]);
}

Step 3 - Type http://localhost:8080/index.php?r=site/contactdans le navigateur Web. Vous remarquerez qu'actuellement, tous les attributs du modèle sont obligatoires.

Step 4 - Si vous modifiez le scénario du modèle dans le actionContact, comme indiqué dans le code suivant, vous constaterez que l'attribut name n'est plus nécessaire.

$model->scenario = ContactForm::SCENARIO_EMAIL_FROM_USER;

Affectation massive

L'affectation massive est un moyen pratique de créer un modèle à partir de plusieurs attributs d'entrée via une seule ligne de code.

Les lignes de code sont -

$mContactForm = new \app\models\ContactForm; 
$mContactForm->attributes = \Yii::$app->request->post('ContactForm');

Les lignes de code données ci-dessus sont équivalentes à -

$mContactForm = new \app\models\ContactForm; $postData = \Yii::$app->request->post('ContactForm', []); $mContactForm->name = isset($postData['name']) ? $postData['name'] : null; 
$mContactForm->email = isset($postData['email']) ? $postData['email'] : null; $mContactForm->subject = isset($postData['subject']) ? $postData['subject'] : null; 
$mContactForm->body = isset($postData['body']) ? $postData['body'] : null;

Le premier est beaucoup plus propre. Remarquerez quemassive assignment s'applique uniquement au safe attributes. Ce ne sont que les attributs de scénario actuels répertoriés dans lescenario() fonction.

Export de données

Les modèles doivent souvent être exportés dans différents formats. Pour convertir le modèle en tableau, modifiez leactionShowContactModel fonction de la SiteController -

public function actionShowContactModel() {
   $mContactForm = new \app\models\ContactForm();
   $mContactForm->name = "contactForm"; $mContactForm->email = "[email protected]";
   $mContactForm->subject = "subject"; $mContactForm->body = "body";
   var_dump($mContactForm->attributes);
}

Type http://localhost:8080/index.php?r=site/show-contact-model dans la barre d'adresse et vous verrez ce qui suit -

Pour convertir le modèle en JSON format, modifiez le actionShowContactModel fonctionne de la manière suivante -

public function actionShowContactModel() {
   $mContactForm = new \app\models\ContactForm();
   $mContactForm->name = "contactForm"; $mContactForm->email = "[email protected]";
   $mContactForm->subject = "subject"; $mContactForm->body = "body";
   return \yii\helpers\Json::encode($mContactForm);
}

Browser output -

{
   "name":"contactForm",
   "email":"[email protected]",
   "subject":"subject",
   "body":"body ",
   "verifyCode":null
}

Les points importants

Les modèles sont généralement beaucoup plus rapides que les contrôleurs dans une application bien conçue. Les modèles devraient -

  • Contient une logique métier.
  • Contiennent des règles de validation.
  • Contiennent des attributs.
  • Ne pas intégrer HTML.
  • Pas d'accès direct aux demandes.
  • N'ayez pas trop de scénarios.