Cakephp 4.4.15 User Permissions from database table dynamic way

I have done something similar without plugins. Here is what I did (which I think it has been discussed before, as this is a common feature)

  1. Create a database table called UserAccess, linked to Users. This will control which user has access to view, create, edit (in my example here, there is no delete feature as it is only kept for Admin) for each Kitchen-price, Kitchen-items, etc. Data is stored as (single digit) integer. I use unix access (e.g. 7 for full access).

  2. Link it in the Model codes

// In Model/Table/UsersTable.php
$this->hasOne('UserAccess', [
    'className' => 'UserAccesses',
    'propertyName' => 'UserAccess',
    'foreignKey' => 'user_id',
]);

// In Model/Table/UserAccessesTable.php
$this->belongsTo('Users', [
    'foreignKey' => 'user_id',
]);
  1. Create a simple form with check-boxes to select view/create/edit access.
  2. Create a virtual field, so one can easily check it in the Entity. Example : $userEntity->UserAccess->access_recipients_can_view which will return true/false.
// In Model/Entity/UserAccess.php
protected $_virtual = [
        'access_recipients_can_view', 'access_recipients_can_create', 'access_recipients_can_edit',
];

// Do your own logic here
protected function _getAccessRecipientsCanView() :bool
{
  // todo
}
protected function _getAccessRecipientsCanCreate() :bool
{
  // todo
}
protected function _getAccessRecipientsCanEdit() :bool
{
  // todo
}
  1. Update the Policy. This is important, as it controls users can view it.
// Example, in Policy/RecipientPolicy.php

// Admin will always have full access, thus return true all the time
public function before($user, $resource, $action) {
  // todo
  if( $isAdmin) return true;

  // return null, so cake will continue processing it by calling the functions below.
  return null;
}


public function canView(IdentityInterface $user, Recipient $recipient)
{
    /**
     * @var \App\Model\Entity\UserAccess $userAccessEntity
     */
      $userAccessEntity = $user->UserAccess;
      return $userAccessEntity->access_recipients_can_view;

}