Models - uniqcle/Yii2 GitHub Wiki

Models реализует логику и работает с данными

Расширяемся от базового класса yii\base\Model

Attributes

Создаем frontend/models/Stuff.php

namespace frontend\models; 

//Подключаем базовый класс Model
use yii\base\Model; 

class Stuff extends Model 
{
	//Атрибуты - публичные св-ва
	public $firstName; 
	public $lastName; 
	public $middleName; 
	public $salary; 

}

Доступ к элементам объекта

Создаем frontend/controllers/StuffController.php

namespace frontend\controllers; 

use yii\web\Controller; 
use frontend\models\Stuff; 

class StuffController extends Controller
{

	public function actionIndex(){

		$stuff1 = new Stuff(); 

		$stuff1 -> firstName = 'Kirill'; 
		$stuff1 -> lastName = 'Anuchkin'; 
		$stuff1 -> middleName = 'Andreevich'; 
		$stuff1 -> salary = 120000; 

		//Если к единичному свойству
		echo $stuff1->firstName;  

		//1. Реализация интерфейса ArrayAccess.
		//Обеспечивает к объектам как к массиву. 
		echo $stuff1['firstName']; 
		echo $stuff1['lastName']; 
		echo $stuff1['middleName'];
		echo $stuff1['salary'];


		//2. Реализация интерфейса Traversable
		//Можно обходить с помощью чикла foreach
		foreach($stuff1 as $attribute => $value):
			echo "$attribute : $value";
		endforeach; 

		echo '<hr>'; 

		foreach($stuff1 as $value):
			echo $value;
		endforeach; 


		//3. Реализация интерфейса Arrayable
		//С помощью метода toArray() представление атрибутов stuff в ввиде массива
		$array = $stuff1->toArray(); 

		debug($array); 


		//4. Получить список всех атрибутов, обратившись к методу getAttributes()
		$attrArray1 = $stuff1->getAttributes(); 

		debug($attrArray1); 


		//5. Получить список всех аттрибутов из св-ва attributes
		$attrArray2 = $stuff1->attributes; 

		debug($attrArray2); 

		//6. Получить список все аттрибутов из метода attributes()
		$attrArray3 = $stuff1->attributes(); 

		debug($attrArray3); 
	}
}

Upload data. Validation

В Controller frontend/controllers/NewsletterController.php

namespace frontend\controllers; 

use yii\web\Controller; 

use Yii; 
use frontend\models\Newsletter; 

class NewsletterController extends Controller 
{	
	//Страница подписки
	public function actionSubscribe(){
		
		$formData = Yii::$app->request->post(); //Загружает данные из глобального массива POST

		$model = new Newsletter(); 

		if( Yii::$app->request->isPost ){ //isPost - переменная. Post запрос был  или нет. 

			//Загружаем данные в модель
			$model->email = $formData['email']; 

			//Процедура валидации по правилам и сохранение в БД
			if( $model->validate() && $model->save() ){

				//Устанавливаем Flash сообщение
				Yii::$app->session->setFlash('subscribeStatus', 'Вы успешно подписались!');
			} 	

		}

		return $this->render('subscribe', [
			'model' => $model 
		]);
	}
}

Для защиты подделки запроса Bad Request (#400). Необходимо внести изменения в файл frontend/config/main.php

'components' => [
        'request' => [
            'csrfParam' => '_csrf-frontend',
            'enableCsrfValidation' => false, //Отключить Csrf валидацию
        ],
...

В Model frontend/models/Newsletter.php

namespace frontend\models; 

use Yii; 
use yii\base\Model; 

class Newsletter extends Model
{
	public $email; 

    public function attributeLabels(){
        return [
                'name' => 'Ваше имя...',
                'email' => 'Ваш email: ',
                'text' => 'Напишите нам здесь...'
            ];
     }

	//Правила валидации
	public function rules(){

		return [
			//[['поле'], 'валидатор']
			[['email'], 'required'],
			[['email'], 'email']
		];
	}

	//Сохранение данных в БД
	public function save(){
		$sql = "INSERT INTO subscribers (id, name, email) VALUES (null, null, '{$this->email}'); "; 

		return Yii::$app->db->createCommand($sql)->execute();
	}

}

Во View frontend/views/newsletter/subscribe.php

//Если есть ошибки
if( $model->hasErrors() ){

//Если валидация не прошла. В модель записываются ошибки валидации
//Эти ошибки можно вызвать методом getErrors() это массив
$errors = $model->getErrors(); 

}


//Проверяем записано ли Flash сообщение
if( Yii::$app->session->hasFlash('subscribeStatus') ){

	echo Yii::$app->session->getFlash('subscribeStatus');
}

?>

<form method = "post">
  <div class="form-group row">
    <label for="inputName" class="col-sm-2 col-form-label">Your name</label>
    <div class="col-sm-10">
      <input type="name" name = "name" class="form-control" id="inputName" placeholder="John Doe">
    </div>
  </div>

    <div class="form-group row">
    <label for="inputEmail3" class="col-sm-2 col-form-label">Email</label>
    <div class="col-sm-10">
      <input type="email" name = "email" class="form-control" id="inputEmail3" placeholder="[email protected]">
    </div>
  </div>
 
  
  <div class="form-group row">
    <div class="col-sm-10">
      <button type="submit" class="btn btn-primary">Subscribe</button>
    </div>
  </div>
</form>

Scenarios()

В контроллере frontend/controllers/EmployeeController.php

namespace frontend\controllers; 

use Yii; 
use yii\web\Controller; 
use frontend\models\Employee; 

class EmployeeController extends Controller 
{
	// Регистрация сотрудника
	public function actionRegister(){

		$model = new Employee(); 

		$model->scenario = Employee::SCENARIO_EMPLOYEE_REGISTER; 

		$formData = Yii::$app->request->post();

		
		if( Yii::$app->request->isPost ){

		//Безопасное массовое присваивание. Согласно сценариям
		$model->attributes = $formData; 

			if( $model->validate() && $model->register() ){

				Yii::$app->session->setFlash('success', 'Вы успешно зарегестрированы');				

			}  
		}

		return $this->render('register', [
			'model' => $model
		]);
	}

	

	//Обновление информации по сотруднику
	public function actionUpdate(){

		$model = new Employee(); 

		$model->scenario = Employee::SCENARIO_EMPLOYEE_UPDATE; 

		$formData = Yii::$app->request->post(); 

		if( Yii::$app->request->isPost ){

			$model->attributes = $formData; 

			if( $model->validate() && $model->update() ){

				Yii::$app->session->setFlash('success', 'Вы успешно обновили информацию!');

			}

		}

		return $this->render('update', [
			'model' => $model
		]);
	}
}

В модели frontend/models/Employee.php

namespace frontend\models; 

use Yii; 
use yii\base\Model; 

class Employee extends Model 
{	
	//Имя сценариев - их лучше поместить в константы
	const SCENARIO_EMPLOYEE_REGISTER = 'employee_register'; 
	const SCENARIO_EMPLOYEE_UPDATE =   'employee_update'; 

	public $firstName; 
	public $lastName; 
	public $middleName; 
	public $salary; 
	public $email; 
	public $bday; 
	public $startday; 
	public $city; 
	public $position; 
	public $idcode; 

	//Возвращает массив, в котором перечислены сценарии и атрибуты, которые в них используются
	public function scenarios(){

		return [
			self::SCENARIO_EMPLOYEE_REGISTER => ['firstName', 'lastName', 'middleName', 'salary', 'email', 'bday', 'startday', 'city', 'position', 'idcode'], 
			self::SCENARIO_EMPLOYEE_UPDATE => ['firstName', 'lastName', 'middleName', 'salary']
		]; 
	}

	public function rules(){

		return [
			[['email'], 'email'], 
			[['firstName', 'lastName', 'salary', 'email', 'startday', 'position', 'idcode'], 'required'],
			['firstName', 'string', 'min' => 2], 
			[['lastName', 'middleName'], 'string', 'min' => 3], 
			[['salary'], 'number', 'min' => 20000, 'max' => 100000], 
			[['bday', 'startday'], 'date', 'format' => 'php:Y-m-d'],
			['middleName', 'required', 'on' => self::SCENARIO_EMPLOYEE_UPDATE]
		]; 
	}

	public function register(){

		$sql = "INSERT INTO employee (id, firstName, lastName, middleName, salary, email, bday, startday, city, position, idcode ) VALUES (null, '{$this->firstName}', '{$this->lastName}', '{$this->middleName}', '{$this->salary}', '{$this->email}', '{$this->bday}', '{$this->startday}', '{$this->city}', '{$this->position}', '{$this->idcode}'); ";

		return Yii::$app->db->createCommand($sql)->execute(); 
	}

	public function update(){

		return true; 
	}
}

Во вью frontend/views/employee/register.php

//Если есть ошибки
if( $model->hasErrors() ){

//Если валидация не прошла. В модель записываются ошибки валидации
//Эти ошибки можно вызвать методом getErrors() это массив
$errors = $model->getErrors(); 

foreach($errors as $error):
  foreach($error as $item):
    echo $item.'</br>'; 
  endforeach; 
endforeach; 

}

?>

<h3>Register employee</h3>

<form method = "POST">
  <div class="form-group row">
    <label for="firstName" class="col-sm-2 col-form-label">Your first name*</label>
    <div class="col-sm-10">
      <input type="text" name = "firstName" class="form-control" id="firstName" placeholder="min 2 symbols">
    </div>
  </div>

  <div class="form-group row">
    <label for="lastName" class="col-sm-2 col-form-label">Your last name*</label>
    <div class="col-sm-10">
      <input type="text" name = "lastName" class="form-control" id="lastName" placeholder="min 3 symbols">
    </div>
  </div>

    <div class="form-group row">
    <label for="middleName" class="col-sm-2 col-form-label">Your middle name*</label>
    <div class="col-sm-10">
      <input type="text" name = "middleName" class="form-control" id="middleName" placeholder="min 3 symbols">
    </div>
  </div>

        <div class="form-group row">
    <label for="email" class="col-sm-2 col-form-label">email*</label>
    <div class="col-sm-10">
      <input type="email" name = "email" class="form-control" id="email" placeholder="[email protected]">
    </div>
  </div>

      <div class="form-group row">
    <label for="salary" class="col-sm-2 col-form-label">Salary*</label>
    <div class="col-sm-10">
      <input type="number" name = "salary" class="form-control" id="salary" placeholder="от 20 000 до 10 0000">
    </div>
  </div>

        <div class="form-group row">
    <label for="salary" class="col-sm-2 col-form-label">Start Day*</label>
    <div class="col-sm-10">
      <input type="text" name = "startday" class="form-control" id="salary" placeholder="2019-03-28">
    </div>
  </div>

          <div class="form-group row">
    <label for="bday" class="col-sm-2 col-form-label">Birth Day *</label>
    <div class="col-sm-10">
      <input type="text" name = "bday" class="form-control" id="bday" placeholder="1984-05-27">
    </div>
  </div>

<div class="form-group row">
  <label for="city" class="col-sm-2 col-form-label">City </label>
  <div class="col-sm-10">
  <select class="form-control" name="city" id="city">
    <option>Выбрать город</option>
    <option value = "1">Москва</option>
    <option value = "2">Новосибирск</option>
    <option value = "3">Барнаул</option>
    <option value = "4">Омск</option>
  </select>
  </div>
</div>

          <div class="form-group row">
    <label for="position" class="col-sm-2 col-form-label">Position*</label>
    <div class="col-sm-10">
      <input type="text" name = "position" class="form-control" id="position" placeholder="manager">
    </div>
  </div>

           <div class="form-group row">
    <label for="position" class="col-sm-2 col-form-label">ID Code*</label>
    <div class="col-sm-10">
      <input type="text" name = "idcode" class="form-control" id="idcode" placeholder="74532">
    </div>
  </div>

    
  <div class="form-group row">
    <div class="col-sm-10">
      <button type="submit" class="btn btn-primary">Register</button>
    </div>
  </div>
</form>
⚠️ **GitHub.com Fallback** ⚠️