Як у Yii2 написати свій екшин (action) і повторно використовувати його у різних контролерах

Як у Yii2 написати свій екшин (action) і повторно використовувати його у різних контролерах

Перш ніж розробляти якийсь більш-менш великий продукт на фреймворку, я б порадив глибоко вивчити його можливості.

Сьогодні мова піде про екшени. Але не ті, що "жорстко" прописані в наших контролерах. А ті, які можна використовувати в різних контролерах, підключаючи через метод контролера actions():

public function actions()
{
	$actions = parent::actions();
	
	$actions['aj-avatar-upload'] = [
		'class' => 'commonactionuserAjaxAvatarUploadAction',
	];
	$actions['aj-avatar-delete'] = [
		'class' => 'commonactionuserAjaxAvatarDeleteAction',
	];
	
	return $actions;
}

З подібною «дією» ми стикаємось ще на самому початку свого шляху, відкриваючи файл конфігурації, де вказується action помилки:

'errorHandler' => [
	'errorAction' => 'site/error',
],

А тепер детальніше про використання. Велосипед я не створив, і, на жаль, раніше цього не зустрічав. Але подібні екшени дуже зручно використовувати як заготовки для типових дій (йдеться про адмінку):

  • список записів
  • створення
  • редагування
  • видалення (включно з файлом або файлами)
  • сортування

Нижче я наведу лише приклад двох екшенів — створення та видалення.

Action створення запису:

use Yii;
use yiibaseAction;

class AddAction extends Action
{
	public $Model;
	public $model_config = [];
	public $view = '@backend/actions/object/view/add';
	public $view_model = 'ModelForm';
	public $flash;
	public $text = [];
	
	public function init()
	{
		parent::init();
		
		if($this -> flash === NULL)
		{
			$this -> flash = Yii::t('app','Object created');
		}
		
		if(isset($this -> text['title']) == false)
		{
			$this -> text['title'] = Yii::t('app', 'Creating Object');
		}
	}
	
	/**
	 * Add
	 * @return mixed
	 */
	public function run()
    {
		$LocalModel = $this -> Model;
		
		$ModelForm = new $LocalModel($this -> model_config);

		if($ModelForm -> load(Yii::$app -> request -> post()) && $ModelForm -> save())
		{
			return $this -> controller -> setFlash(['edit', 'id' => $ModelForm -> id], $this -> flash);
		}

		//View
		$this -> controller -> setBreadcrumbs($this -> text['title']);
		$this -> controller -> setTitle($this -> text['title']);
		return $this -> controller -> render($this -> view, [
			$this-> view_model => $ModelForm,
		]);
	}
}

Конфігурування екшена виконується в методі actions() поточного контролера. Якщо представлення (view) використовується нестандартне, то за допомогою властивості view можна вказати шлях до свого шаблону. Під стандартним виглядом мається на увазі такий, який підходить у більшості випадків (без видалення або додавання полів форми). Наприклад — форма з одним полем Title для створення списків записів, таких як — категорії, регіони тощо.

Action видалення запису з БД:

use Yii;
use yiibaseAction;
use yiiwebNotFoundHttpException;

class DeleteAction extends Action
{
	public $Model;
	public $field_delete = NULL;
	public $flash = NULL;
	
	public function init()
	{
		parent::init();
		
		if($this -> flash === NULL)
		{
			$this -> flash = Yii::t('app','Object deleted');
		}
	}
	
	/**
	 * Delete row in DB
	 * @param int $id
	 * @return mixed
	 * @throws NotFoundHttpException
	 */
	public function run($id)
    {
		$LocalModel = $this -> Model;
		
		$Model = $LocalModel::findOne([
			'id' => (int) $id
		]);
		if($Model === NULL)
		{
			throw new NotFoundHttpException();
		}

		if(method_exists($Model, 'deleteFile'))
		{
			$field_delete_ar = (array) $this -> field_delete;
			foreach ($field_delete_ar as $field_delete)
			{
				$Model -> deleteFile($Model -> {$field_delete});
			}
		}
		$Model -> delete();
		
		return $this -> controller -> setFlash(['index'], $this -> flash);
	}
}

Якщо в моделі визначено метод deleteFile, то при виклику дії буде зроблена спроба видалення файлів за вказаними полями.

З вашим сайтом на фреймворку Yii2 проблеми? потрібний додатковий функціонал?
Тоді напишіть мені через форму зворотного зв'язку, і я постараюся вам допомогти.

Напишіть коментар

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *