PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, February 13, 2022

[FIXED] CakePHP 3 - Two foreign keys linked to the same table - wrong foreign key being used

 February 13, 2022     cakephp, cakephp-3.0, mysql     No comments   

Issue

I have two tables, each with their own attributes and with two foreign keys linking them:

Sessions

  • id
  • staff_id (primary staff member) - foreign key linking to Staff table
  • assistant_id (secondary staff member) - foreign key linking to Staff table
  • date

Staff

  • id
  • user_id (foreign key linking to Users table)
  • name

When I attempt to do a Find query, to display a Session with its primary staff member, it shows the assistant staff member instead in Index.ctp.

For example, if Session with ID=1 has staff_id=3 and assistant_id=null, the Staff column in Index shows up as blank. If however, assistant_id=1, it shows the staff with ID=1 (the assistant staff) instead of ID=3 (the primary staff).

In my SessionsTable, I have the following:

$this->belongsTo('Staff', [
    'foreignKey' => 'staff_id'
]);
$this->belongsTo('Staff', [
    'foreignKey' => 'assistant_id'
]);

In my StaffTable, I have the following:

$this->hasMany('Sessions', [
    'foreignKey' => 'staff_id'
]);
$this->hasMany('Sessions', [
    'foreignKey' => 'assistant_id'
]);

In my SessionsController, the index function has the following find request assigned to a Cake variable:

$sessions = $this->Sessions->find('all', [
    'contain' => ['Staff']
    ]);

In the Index's ctp page, the table is as follows:

<table class="bookingsTables display" id="confirmedTable">
    <thead>
        <tr>
            <th scope="col"><?= $this->Paginator->sort('id', 'ID') ?></th>
            <th scope="col"><?= $this->Paginator->sort('staff_id', 'Primary Staff Member') ?></th>
            <th scope="col"><?= $this->Paginator->sort('date', 'Date') ?></th>
            <th scope="col" class="actions"><?= __('Actions') ?></th>
        </tr>
    </thead>
    <tbody>
    <?php foreach ($sessions as $session): ?>
        <tr>
            <td><?= h($session->id) ?></td>
            <td><?= $session->has('staff') ? h($session->staff->name) : '' ?></td>
            <td><?= h($session->date) ?></td>
            <td class="actions">
                <?= $this->Html->link(__('View'), ['action' => 'view', $session->id]) ?>

            </td>
        </tr>
    <?php endforeach; ?>
    </tbody>
</table>

Also with regards to the Find query, if I log in as a staff member and do a find of all Sessions where they are the primary staff member, it will not be able to find any.

$id = $this->Auth->user('id'); //gets the id of the logged in user
$sessions = $this->Sessions->find('all', [ 
        'contain' => ['Staff'],
        'conditions' => ['user_id' => $id]
        ]); //find Sessions where staff_id = staff member who's logged in

Or alternatively:

$id = $this->Auth->user('id'); //gets the id of the logged in user
$sessions = $this->Sessions->find('all', [
    'contain' => ['Staff', 'Staff.Users'],
    'conditions' => ['Users.id' => $id] 
]); //find Sessions where staff_id = staff member who's logged in

Solution

Cake will override first instance of Staff if second one exist. To avoid this your model should be like:

$this->belongsTo('Staff', [ 
    'className' => 'Staff', 
    'foreignKey' => 'staff_id', 
    'propertyName' => 'staff'
]);

$this->belongsTo('Assistant', [ 
   'className' => 'Staff', 
   'foreignKey' => 'assistant_id', 
   'propertyName' => 'assistant'
]);

And then in your view replace

<td><?= $session->has('staff') ? h($session->staff->name) : '' ?></td>

with:

<td><?= $session->has('staff') ? h($session->staff->name) : $session->has('assistant') ? h($session->assistant->name) : '' ?></td>


Answered By - Matteo Kovacic
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home
View mobile version

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing