0

Edit: My question may perhaps been overly complex, let's simplify. How do I import/call tables from different controllers and tables. E.g. how would I call UsersTable from ProjectsController?

If I want to access and handle data for a table that uses composite keys to tie two different tables together how should I do this?

As an example I have Projects and Users and a table called ProjectsUsers that keeps track of the relationship of the two (which users have been assigned to which project and their role in that project). Using composite keys I was easily able to bake scaffold code for add and edit that let's me assign users to projects when creating them, however this does not give me access to the role variable that is in the table.

I am thinking that I should make a model for the ProjectsUsers (which I did do using bake) and then make functions inside the ProjectsUsersTable to check wether a given user has access rights to whatever they are trying to access.

The ProjectsTable method isOwnedBy (below) is working fine and so I tried replicating it for my composite table but with no luck.

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 (working fine):

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;
    }

}

But I am getting an error:

Call to a member function isModeratedBy() on boolean

Edit: My question may perhaps been overly complex, let's simplify. How do I import/call tables from different controllers and tables. E.g. how would I call UsersTable from ProjectsController?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
RusinaRange
  • 341
  • 1
  • 4
  • 18
  • Possible duplicate of [What means Call to a member function on boolean and how to fix](http://stackoverflow.com/questions/31813722/what-means-call-to-a-member-function-on-boolean-and-how-to-fix) – ndm Feb 07 '16 at 14:09

2 Answers2

0

I thought I tried this allready so I was baffled for a while but the correct way to do this is:

use Cake\ORM\TableRegistry;

$articles = TableRegistry::get('Articles');
RusinaRange
  • 341
  • 1
  • 4
  • 18
0

You should consider use CakePHP associations in your model:

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');
    }
    ....
}

If you follow CakePHP associations, you could query using the containable behavior. If you are using your 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

Note: There are other ways to approach that, but this is the way I would do it.

  • I have the default bake associations for my tables but I am now having a problem with a innerjoin of projects and project_tickets. projects_tickets is set to belong to projects with the jointype 'inner' and projects is set to belongtomany tickets with a jointable of 'projects_tickets' but I am still getting an error: "Projects is not associated with ProjectsTickets", would you have any insight on this? – RusinaRange Feb 08 '16 at 21:50