CakePHP 3 - набор переключателей BuildRules
Я делаю приложение, в котором пользователи могут создавать действия, а другие пользователи могут подписаться на них. Новые действия должны быть одобрены через панель администратора, к которой имеют доступ только администраторы.
Действия, которые были одобрены, должны быть заблокированы, чтобы они не могли быть изменены их пользователем. Только через админ-панель одобренные действия должны быть доступны для редактирования.
Чтобы реализовать это, мы сделали это buildRule:
public function buildRules(RulesChecker $rules)
{
// Check if activity wasn't locked
$rules->add(function ($entity, $settings)
{
// Return false if already approved before
return !$entity->approved || $entity->isDirty('approved');
}, 'alreadySubscribed', ['errorField' => 'name', 'message' => 'Activity has been approved and is now locked']);
return $rules;
}
(BuildRule вместо правила проверки, потому что проверка должна также срабатывать, когда approved
поле не изменено и, следовательно, не является частью проверки.)
Приведенное выше правило не позволяет администраторам изменять действия, поэтому мой вопрос:
Можете ли вы переключаться между builRules в вашей таблице, как вы можете изменить метод проверки?
2 ответа
Не совсем, есть Model.buildRules
событие, которое можно использовать для добавления правил, но это все.
Я не уверен, что это слишком хорошая идея - смешивать несколько правил приложения в зависимости от состояния вне модели. То, чего вы пытаетесь достичь, звучит как контроль доступа, то есть авторизация, и я бы посоветовал реализовать соответствующие проверки.
Посмотрите на https://github.com/cakephp/authorization, это позволяет вам реализовать очень гибкие политики, которые могут справиться с такими случаями. В качестве альтернативы есть функция авторизации старой школы, предоставляемая компонентом auth или (недокументированным) плагином ACL.
Если ваша авторизация действительно очень проста, то есть "область администратора = редактирование разрешено" и "областьне администратор = редактирование НЕ разрешено", т. Е. В вашем приложении может быть только одна точка, где потребуется проверка, тогда вы, возможно, могли бы уйти с чем-то менее сложным, например, передать параметры в процессе сохранения. Опции будут переданы в правила, где вы можете проверить их соответственно, то есть что-то вроде этого:
$options = [
'updateApproved' => true
];
$Model->save($entity, $options);
function ($entity, $settings)
{
if (isset($settings['updateApproved']) &&
$settings['updateApproved'] === true
) {
return true;
}
// ...
return !$entity->approved || $entity->isDirty('approved');
}
Таким образом, сохранение утвержденных объектов будет работать только тогда, когда true
передается через updateApproved
вариант. Как уже упоминалось, это не слишком хорошее решение, в любом случае я бы посоветовал взглянуть на плагин авторизации и узнать, как правильно реализовать авторизацию.
Смотрите также
Я думаю, что решение @ ndm является более официальным. Я закончил с другим решением, которое я хотел бы сначала попробовать.
В основном я добавил флаг в модель деятельности:
class ActivitiesTable extends Table
{
/** @var bool Flag whether admin is modifying the table */
private $_admin = false;
// ...
И сделал построение правил зависимым от него:
if (!$this->_admin)
{
$rules->add(function ($entity, $settings)
{
// ...
В контроллере вы можете переключить модель в режим администратора и сохранить объект, который в противном случае потерпел бы неудачу:
$this->Activities->_admin = true;
$this->Activities->save($activity);