Створення та редагування записів
================================

Після того, як ми закінчили із моделлю `Post`, займемося контролером `PostController` 
і його відображеннями. У даному розділі ми налаштуємо правила доступу операцій CRUD.
Потім змінимо код, відповідальний за `створення` (`create`) та `оновлення` (`update`).

Налаштування правил доступу
---------------------------

Перше, що ми запланували - налаштування
[прав доступу](/doc/guide/uk/topics.auth#access-control-filter).
Код, згенерований за допомогою `gii`, нам не підійде.

Необхідно змінити метод `accessRules()` у файлі
`/wwwroot/blog/protected/controllers/PostController.php` наступним чином:

~~~
[php]
public function accessRules()
{
	return array(
		array('allow',  // дозволяє всім користувачам виконувати дії 'list' та 'show'
			'actions'=>array('index', 'view'),
			'users'=>array('*'),
		),
		array('allow', // дозволяє аутентифікованим користувачам виконувати будь-які дії
			'users'=>array('@'),
		),
		array('deny',  // забороняє всім користувачам
			'users'=>array('*'),
		),
	);
}
~~~

Описані вище правила дозволяють всім користувачам виконувати дії
`index` та `view`. Аутентифікованим - будь-які дії, включаючи `admin`.
Всім іншим користувачам заборонено все. Варто відзначити, що правила
застосовуються у порядку їх опису. Перше правило, що спрацювало, визначає,
давати доступ або не давати. Наприклад, якщо поточний користувач є
власником системи та намагається зайти на сторінку створення запису,
буде застосовано друге правило і доступ буде дозволений.

Правки у діях `create` та `update`
----------------------------------

Операції `create` та `update` досить схожі. 
У обох випадках необхідно вивести HTML форму для збору даних, що вводяться користувачем.
Також потрібна валідація та збереження даних у БД. 
Головна відмінність у тому, що при `update` форма буде заповнюватися даними запису,
що редагується. З цієї причини `gii` генерує вкладене відображення 
`/wwwroot/blog/protected/views/post/_form.php`, яке включається 
як у відображення 'create', так і відображення 'update' для виводу HTML форми.

Для початку змінимо файл `_form.php` таким чином, щоб форма збирала тільки
потрібні нам дані: `title`, `content`, `tags` та `status`. 
Для перших трьох атрибутів ми використовуємо текстові поля. 
Для `status` - випадаючий список з усіма можливими станами запису:

~~~
[php]
<?php echo $form->dropDownList($model,'status',Lookup::items('PostStatus')); ?>
~~~

У наведеному коді для отримання списку статусів використовується виклик `Lookup::items('PostStatus')`.

Далі змінимо клас `Post` таким чином, щоб він автоматично виставляв
деякі атрибути (такі, як `create_time` та `author_id`) безпосередньо перед
збереженням запису у БД. Перекриємо метод `beforeSave()`:

~~~
[php]
protected function beforeSave()
{
	if(parent::beforeSave())
	{
		if($this->isNewRecord)
		{
			$this->create_time=$this->update_time=time();
			$this->author_id=Yii::app()->user->id;
		}
		else
			$this->update_time=time();
		return true;
	}
	else
		return false;
}
~~~

При збереженні запису ми хочемо також оновити інформацію про частоту використання
тегів у таблиці `tbl_tag`. Ми можемо реалізувати це у методі `afterSave()`,
який автоматично викликається після успішного збереження запису у БД.

~~~
[php]
protected function afterSave()
{
	parent::afterSave();
	Tag::model()->updateFrequency($this->_oldTags, $this->tags);
}

private $_oldTags;

protected function afterFind()
{
	parent::afterFind();
	$this->_oldTags=$this->tags;
}
~~~

Так як необхідно визначити, чи змінював користувач теги при редагуванні запису, 
нам знадобляться старі теги. Для цього ми реалізуємо метод `afterFind()`, 
який записує старі теги у властивість `_oldTags`. Метод `afterFind()` викликається
автоматично при заповненні моделі AR даними, отриманими із БД.

Тут ми не будемо детально розглядати метод `Tag::updateFrequency()`.
Зацікавлені читачі можуть ознайомитися із ним у файлі
`/wwwroot/yii/demos/blog/protected/models/Tag.php`.
