CakePHP: заменить поле ввода другим элементом формы (например, lablel) в зависимости от роли пользователя
У меня 2 модели:
- книги
- пользователей
И у меня есть следующие правила:
- обычные пользователи могут создавать / редактировать только свои книги
- пользователи-администраторы могут создавать / редактировать книги для всех
Я создал модели пользователей и книг и определил принадлежность к / один ко многим. Я использовал торт для создания представлений и контроллеров CRUD. Мое действие контроллера редактирования для книг выглядит следующим образом:
public function edit($id = null) {
if (!$this->Book->exists($id)) {
throw new NotFoundException(__('Invalid book'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->Book->save($this->request->data)) {
$this->Session->setFlash(__('The book has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The book could not be saved. Please, try again.'));
}
} else {
$options = array('conditions' => array('Book.' . $this->Book->primaryKey => $id));
$book = $this->Book->find('first', $options);
if ($this->isUserCanAccessThisRecordActionEdit($book['BookUser']))
$this->request->data = $book;
else
$this->redirectNotAuthorized();
}
$bookUsers = $this->Book->BookUser->find('list');
$this->set(compact('bookUsers'));
}
когда отображается edit.ctp, он отображает пользователей в виде выпадающего меню, например:Проблема: по правилам, которые я определил, я не хочу, чтобы обычный пользователь мог выбрать book_user_id, и только администраторы могут иметь такой список, я хочу, чтобы обычный пользователь мог просматривать свои имена как BookUser в другом формате элементов управления, таких как метки. Я пытался получить доступ к данным запроса для непосредственного отображения имени пользователя, но не смог этого сделать (у меня нет проблем, чтобы различать пользователей и администраторов в моих представлениях, но я не знаю, как изменить пользовательский интерфейс и получить доступ к связанным данным для отображения информации)
Еще одна плохая новость: таким образом все пары имени пользователя и идентификатора передаются для просмотра, так что их может иметь обычный пользователь, что является плохой идеей безопасности, например, вот вариант для Пользователей на моей отрендеренной HTML-странице edit.ctp:
<div class="input select required"><label for="BookBookUserId">Book User</label>
<select name="data[Book][book_user_id]" disabled="disabled" id="BookBookUserId">
<option value="3">vhb</option>
<option value="5">vhb2</option>
<option value="6">vhb3</option>
<option value="7">vhb4</option>
<option value="8">vhb5</option>
<option value="9">vhb6</option>
<option value="10">vhb7</option>
<option value="11">vhb8</option>
<option value="12">vhb9</option>
<option value="13">vhb10</option>
<option value="14">vhb11</option>
<option value="15">vhb12</option>
<option value="16">vhb13</option>
<option value="17">vhb14</option>
<option value="18">vhb15</option>
<option value="19">vhb16</option>
<option value="20">vhb17</option>
<option value="21">root</option>
<option value="22">vhb19</option>
<option value="23">vhb20</option>
<option value="24">vhb21</option>
<option value="25">vhb1</option>
</select></div>
1 ответ
Я рекомендую использовать разные модели для администраторов и пользователей. Это легко работать и поддерживать.
Я также предлагаю сохранить ваши проверки уровня пользователя в AppController.
Для вашего текущего кода:
Предположим, вы используете поле с именем "is_admin", чтобы проверить, является ли пользователь администратором:
В вашем контроллере:
public function edit($id = null) {
if (!$this->Book->exists($id)) {
throw new NotFoundException(__('Invalid book'));
}
$isAdmin = ($this->Auth->user('is_admin') == true) ? true : false;
$this->set(compact('isAdmin'));
if ($this->request->is(array('post', 'put'))) {
if ($isAdmin != true) {
$this->request->data['Book']['book_user_id'] = $this->Auth->user('id');
}
if ($this->Book->save($this->request->data)) {
$this->Session->setFlash(__('The book has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The book could not be saved. Please, try again.'));
}
} else {
$options = array('conditions' => array('Book.' . $this->Book->primaryKey => $id));
$book = $this->Book->find('first', $options);
if ($this->isUserCanAccessThisRecordActionEdit($book['BookUser']))
$this->request->data = $book;
else
$this->redirectNotAuthorized();
}
if ($isAdmin == true) {
$bookUsers = $this->Book->BookUser->find('list');
$this->set(compact('bookUsers'));
}
}
При этом вы избегаете загрузки ненужных данных.
По вашему мнению:
if ($isAdmin == true) {
$this->Html->input('book_user_id');
} else {
echo AuthComponent::user('name');
}