Я видел этот вопрос несколько раз.Из документа «Торт» написано:
Списки контроля доступа, или ACL, обрабатывают две основные вещи: вещи, которые нужны, и вещи, которые нужны.
Теория, вы можете обрабатывать все элементы в вашем приложении, используя ACL, но я вижу несколько проблем с этим:
- Допустим, у вас есть 10 тыс. элементов в магазине в вашей таблице элементов, ну, вы будетеиметь одинаковое количество элементов в вашей таблице ACO.Теперь, если вы добавляете пользователя, вам нужно будет предоставить ему доступ к элементам в таблице ARO_ACO (еще 10 000 элементов ДЛЯ КАЖДОГО ПОЛЬЗОВАТЕЛЯ!)
- ... хорошо, возможно, я преувеличил в первом примере.Потому что вы можете сгруппировать элементы и в таблице ACO, и установить только разрешения для группы в таблице ACO_ARO.Но теперь это может быть кошмаром для выполнения запросов в вашем приложении, представьте, если вы хотите создать отфильтрованный нумерованный список элементов.Вам нужно будет попросить ACO (который теперь находится в древовидной структуре) и таблицу ARO_ACO подсчитать и разбить элементы на страницы ... и даже если это будет сделано автоматически, у вас будет проблема с производительностью
По моему мнению, лучше использовать ACL, чтобы предоставлять разрешения только методам контроллеров (CRUD) и управлять разрешениями элементов в вашем коде, устанавливая условие в ваших запросах:
$this->Items->find('all',array('conditions'=>array('store_id'=>$this->Auth->user('store_id'))))
Но выВозможно, потребуется повторить это условие везде, чтобы вы могли создать Поведение, которое изменит запросы, чтобы добавить условие в предложение WHERE, чтобы вы всегда возвращали / редактировали элементы текущего хранилища.Например, создайте поведение, подобное этому:
/**
* Filter query conditions with the correct `type' field condition.
*/
function beforeFind(&$model, $query)
{
/**
* Condition for the paginators that uses joins
*/
if(isset($query['joins']) && !empty($query['joins'])){
foreach($query['joins'] as $key => $joinTable){
if(ClassRegistry::init($joinTable['alias'])->hasField('store_id')){
$query['joins'][$key]['conditions'][] = $joinTable['alias'].".store_id = '".$_SESSION['store_id']."'";
}
}
}
/**
* condition for the normal find queries
*/
if($model->hasField('store_id') && $model->name != "User"){
$query['conditions'][$model->name.'.store_id'] = $_SESSION['store_id'];
}
return $query;
}
В контроллере мне просто нужно вызвать метод find
как обычно
$this->Items->find('all');
Таким образом, у вас нетсделать больше запросов, чтобы увидеть, может ли пользователь получить доступ к элементу.Я использовал что-то подобное на веб-сайте, и он прекрасно работает для меня.