Yii - Modelos
Modelos são objetos que representam lógica e regras de negócios. Para criar um modelo, você deve estender oyii\base\Model classe ou suas subclasses.
Atributos
Os atributos representam os dados de negócios. Eles podem ser acessados como elementos de matriz ou propriedades de objeto. Cada atributo é uma propriedade acessível publicamente de um modelo. Para especificar quais atributos um modelo possui, você deve substituir oyii\base\Model::attributes() método.
Vamos dar uma olhada no ContactForm modelo do modelo básico de aplicativo.
<?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 - Crie uma função chamada actionShowContactModel no SiteController com o seguinte código.
public function actionShowContactModel() {
$mContactForm = new \app\models\ContactForm(); $mContactForm->name = "contactForm";
$mContactForm->email = "[email protected]"; $mContactForm->subject = "subject";
$mContactForm->body = "body"; var_dump($mContactForm);
}
No código acima, definimos o ContactForm modelo, definir atributos e exibir o modelo na tela.
Step 2 - Agora, se você digitar http://localhost:8080/index.php?r=site/show-contact-model na barra de endereço do navegador da web, você verá o seguinte.
Se o seu modelo se estende de yii\base\Model, então todas as suas variáveis de membro (públicas e não estáticas) são atributos. Existem cinco atributos noContactForm modelo - nome, e-mail, assunto, corpo, verifyCode e você pode facilmente adicionar novos.
Rótulos de atributos
Freqüentemente, você precisa exibir rótulos associados a atributos. Por padrão, rótulos de atributos são gerados automaticamente peloyii\base\Model::generateAttributeLabel()método. Para declarar manualmente rótulos de atributos, você pode substituir oyii\base\Model::attributeLabels() método.
Step 1 - Se você abrir http://localhost:8080/index.php?r=site/contact, você verá a página seguinte.
Observe que os rótulos dos atributos são iguais aos seus nomes.
Step 2 - Agora, modifique o attributeLabels função no ContactForm modelo da seguinte maneira.
public function attributeLabels() {
return [
'name' => 'name overridden',
'email' => 'email overridden',
'subject' => 'subject overridden',
'body' => 'body overridden',
'verifyCode' => 'verifyCode overridden',
];
}
Step 3 - Se você abrir http://localhost:8080/index.php?r=site/contact novamente, você notará que os rótulos foram alterados conforme mostrado na imagem a seguir.
Cenários
Você pode usar um modelo em diferentes cenários. Por exemplo, quando um convidado deseja enviar um formulário de contato, precisamos de todos os atributos do modelo. Quando um usuário deseja fazer a mesma coisa, ele já está logado, então não precisamos do seu nome, pois podemos retirá-lo facilmente do BD.
Para declarar cenários, devemos substituir o scenarios()função. Ele retorna uma matriz cujas chaves são os nomes dos cenários e os valores sãoactive attributes. Atributos ativos são aqueles a serem validados. Eles também podem sermassively assigned.
Step 1 - Modifique o ContactForm modelo da seguinte maneira.
<?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;
}
}
?>
Nós adicionamos dois cenários. Um para o convidado e outro para o usuário autenticado. Quando o usuário é autenticado, não precisamos do nome dele.
Step 2 - Agora, modifique o actionContact função do 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 - Tipo http://localhost:8080/index.php?r=site/contactno navegador da web. Você notará que, atualmente, todos os atributos do modelo são obrigatórios.
Step 4 - Se você alterar o cenário do modelo no actionContact, conforme fornecido no código a seguir, você descobrirá que o atributo name não é mais necessário.
$model->scenario = ContactForm::SCENARIO_EMAIL_FROM_USER;
Atribuição massiva
A atribuição massiva é uma maneira conveniente de criar um modelo a partir de vários atributos de entrada por meio de uma única linha de código.
As linhas de código são -
$mContactForm = new \app\models\ContactForm;
$mContactForm->attributes = \Yii::$app->request->post('ContactForm');
As linhas de código fornecidas acima são equivalentes a -
$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;
O primeiro é muito mais limpo. Notar quemassive assignment só se aplica ao safe attributes. Eles são apenas os atributos do cenário atual listados noscenario() função.
Exportação de Dados
Os modelos geralmente precisam ser exportados em formatos diferentes. Para converter o modelo em uma matriz, modifique oactionShowContactModel função do 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);
}
Tipo http://localhost:8080/index.php?r=site/show-contact-model na barra de endereço e você verá o seguinte -
Para converter o modelo para o JSON formato, modifique o actionShowContactModel funcionar da seguinte maneira -
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
}
Pontos importantes
Os modelos são geralmente muito mais rápidos do que os controladores em um aplicativo bem projetado. Os modelos deveriam -
- Conter lógica de negócios.
- Contém regras de validação.
- Contém atributos.
- Não incorporar HTML.
- Não acessa diretamente as solicitações.
- Não tem muitos cenários.