Search code examples
cakephp

Using uuid for edit/delete in CRUD


  • CakePHP 4.4.14
  • friendsofcake/crud: 6.2.0

For simply security reasons and also not to reveal the amount of rows in the table I want to use the uuid field for the edit/delete actions.

Usually it works like this /edit/123. This is exactly what I don't want to have. Therefore I want to change it to /edit/446a1a76-4eac-4b2d-8825-7e3a7e91f4a0.

Yep, and now I get the error message that it cannot be converted to number; this is correct, because uuid is not a number.

I checked the events but there is - also according to the CRUD documentation - the WHERE already set.

query A Query object from the Repository where $PrimaryKey => $IdFromRequest is already added to the conditions.

How can I set/change the field in the query to uuid. As I understand it, it must be done before beforeFind because the type for the parameter is already set to integer and uuid is not an integer.

    $this->Crud->on('beforeFind', function(\Cake\Event\EventInterface $event) {
        $event->getSubject()->query->where(['uuid' => "uuid-as-string]);
    });

Doesn't work because the condition is added and the id remains in the query.


To make it clear: Each table has the primary key id - according to the CakePHP rules - but each table has also the field uuid which is used for public access. Internally the project uses the id.


Solution

  • In AppController:

    public function edit()
    {
        ...
    
        $controllerName = $this->getName();
        $this->getTableLocator()->get($controllerName)->setPrimaryKey("uuid");
    
        ...
    }
    

    Then, in the beginning of the CRUD actions| edit | view handler the id field should be re-established as the primary key. This is for example then needed, when the rows of dependent tables are shown in the edit mode as well - implemented for example with register tabs.

    If id won't be set in the beginning then the dependent rows are not found because CakePHP thinks uuid is the primary key, which isn't.

    <ControllerInstance>->getTableLocator()->get(<ControllerName>)->setPrimaryKey("id");