Редактировать: мой вопрос, возможно, был слишком сложным, давайте упростим. Как импортировать / вызывать таблицы из разных контроллеров и таблиц. Например. как бы я вызвал UsersTable из ProjectsController?
Если я хочу получить доступ и обрабатывать данные для таблицы, которая использует составные ключи, чтобы связать две разные таблицы, как мне это сделать?
В качестве примера у меня есть Projects and Users и таблица ProjectsUsers, которая отслеживает отношения между ними (какие пользователи были назначены какому проекту и их роль в этом проекте). Используя составные ключи, я легко смог испечь код скаффолда для добавления и редактирования, который позволяет мне назначать пользователей проектам при их создании, однако это не дает мне доступ к переменной роли, которая находится в таблице.
Я думаю, что мне следует создать модель для ProjectsUsers (что я и сделал, используя bake), а затем создать функции внутри ProjectsUsersTable, чтобы проверить, есть ли у данного пользователя права доступа ко всему, к чему он пытается получить доступ.
Метод ProjectsTable isOwnedBy (ниже) работает нормально, поэтому я попытался воспроизвести его для составной таблицы, но безуспешно.
ProjectsController:
use App\Controller\AppController;
use App\Model\Table\ProjectsUsers;
class ProjectsController extends AppController
{
//Individual access rules to projects functions (projects/*).
public function isAuthorized($user)
{
// All registered users can add projects.
if ($this->request->action === 'add'){
return true;
}
// Check from the ProjectsUsers table if the person trying to access
// is a moderator of that project.
if ($this->request->action === 'edit'){
$projectId = (int)$this->request->params['pass'][0];
if ($this->ProjectsUsers->isModeratedBy($projectId, $user['id']))
{ return true;
}
}
// The owner of an article can edit and delete it.
if (in_array($this->request->action, ['edit', 'delete'])){
$projectId = (int)$this->request->params['pass'][0];
if ($this->Projects->isOwnedBy($projectId, $user['id'])){
return true;
}
}
return parent::isAuthorized($user);
}
}
ProjectsTable (работает нормально):
class ProjectsTable extends Table
{
public function isOwnedBy($projectId, $userId)
{
return $this->exists(['id' => $projectId, 'user_id' => $userId]);
}
}
ProjectsUsersTable:
class ProjectsUsersTable extends Table
{public function isModeratedBy($projectId, $userId)
{
return true;
}
}
Но я получаю ошибку:
Вызов функции-члена isModeratedBy () для логического значения
Редактировать: мой вопрос, возможно, был слишком сложным, давайте упростим. Как импортировать / вызывать таблицы из разных контроллеров и таблиц. Например. как бы я вызвал UsersTable из ProjectsController?
Я думал, что попробовал это уже, поэтому я был озадачен некоторое время, но правильный способ сделать это:
use Cake\ORM\TableRegistry;
$articles = TableRegistry::get('Articles');
Вы должны рассмотреть возможность использования ассоциаций CakePHP в вашей модели:
ProjectsTable:
class ProjectsTable extends Table
{
public function initialize(array $config)
{
$this->belongsToMany('Users', [
'through' => 'ProjectUsers',
]);
}
...
}
UsersTable:
class UsersTable extends Table
{
public function initialize(array $config)
{
$this->belongsToMany('Projects', [
'through' => 'ProjectUsers',
]);
}
...
}
ProjectsUsersTable:
class ProjectsUsersTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Projects');
$this->belongsTo('Users');
}
....
}
Если вы будете следовать ассоциациям CakePHP, вы можете делать запросы, используя сдерживаемое поведение. Если вы используете свой ProjectsController:
//Find all projects and it's related users.
$projects = $this->Projects->find('all')->contain(['Users']);
//Find all users and it's related projects.
$this->loadModel('Users');
$users = $this->Users->find('all')->contain(['Projects']);
//Find certain user and it's related projects.
$this->loadModel('Users');
$user = $this->Users->find('all')->contain(['Projects'])->where(['Users.id' => 1]);
//After this you can access the projects assigned to this user through $user->projects
Примечание. Есть и другие способы решения этой проблемы, но я бы так и сделал.