Разрешаем пользователю административного интерфейса просмотр и редактирование только своих записей

Часто возникает задача ограничения списка редактируемых пользователем данных. В этом примере разберем ограничение на редактирование только своих записей, хотя условия предоставления прав могут быть различными.

Задача: разрешить определенной группе администраторов редактировать только свои записи. Готового решения в системе нет, но его не долго реализовать самостоятельно.

Создадим модуль статей по инструкции "Ссылки на объекты и списки объектов проще, чем вам кажется!".

Назначим группе администраторов права на доступ в этот модуль и полные права на редактирование (используя интерфейс управления пользователями).

Теперь необходимо ограничить список выводимых записей и права на редактирование.

Доработаем методы контроллера Backend_Article_Controller:

/**
 * (non-PHPdoc) Возвращает список записей в интерфейс
 * @see Backend_Controller_Crud_Vc::listAction()
 */
public function listAction()
{
   // получим фильтры приходящие из интерфейса
   $filter = Request::post('filter', 'array', array());
   // если интерфейс не осуществлял фильтрацию, инициализируем фильтр пустым массивом
   if(!is_array($filter))
     	$filter = array();
   // установим жесткий фильтр на автора записи author_id это системное поле которое
   // существует во всех объектах использующий версионный контроль данных
   // $this->_user это ссылка на объект авторизованного пользователя User
   $filter['author_id'] = $this->_user->getId();
 
   // переопределяем POST запрос
   Request::updatePost('filter', $filter);
 
   // вызываем обработку из родительского контроллера
   return parent::listAction();
}
                                           	
/**
 * Проверка на право работы с конкретной статьей, при отсутствии прав
 * сразу отправляет ошибку в интерфейс
 * @param integer $articleId
 */
protected function _checkOwner($articleId)
{
// не передан идентификатор
     	if (!$articleId) {
                Response::jsonError($this->_lang->get('WRONG_REQUEST'));
     	}
     	// проверяем свою ли статью хочет изменить пользователь
     	$articleData = Model::factory('Article')->getItem($articleId);
 
     	if (!$articleData || $articleData['author_id'] !== $this->_user->getId()){
               	Response::jsonError($this->_lang->get('CANT_VIEW'));
     	}
}

/**
 * (non-PHPdoc) Добавляем проверку владельца в операцию обновления
 * @see Backend_Controller_Crud::updateAction()
 */
public function updateAction()
{
   $id = Request::post('id' , 'integer' , false);
   $this->_checkOwner($id);
  parent::updateAction();
}

/**
 * (non-PHPdoc) Добавляем проверку владельца в операцию удаления
 * @see Backend_Controller_Crud_Vc::deleteAction()
 */
public function deleteAction()
{
   $id = Request::post('id' , 'integer' , false);
   $this->_checkOwner($id);
  parent::deleteAction();
}

/**
 * (non-PHPdoc) Добавляем проверку владельца в операцию публикации
 * @see Backend_Controller_Crud_Vc::publishAction()
 */
public function publishAction()
{
   $id = Request::post('id' , 'integer' , false);
   $this->_checkOwner($id);
  parent::publishAction();
}

/**
 * (non-PHPdoc) Добавляем проверку владельца в операцию снятия с публикации
 * @see Backend_Controller_Crud_Vc::unpublishAction()
 */
public function unpublishAction()
{
   $id = Request::post('id' , 'integer' , false);
   $this->_checkOwner($id);
  parent::unpublishAction();
}

Теперь интерфейс отображает записи только текущего пользователя и разрешает пользователю редактировать только свои записи.