phpcakephpcakephp-4.x

Aliases for table fields in CakePHP4


In my DB I have a table page_content with a column which is a reserved MySQL 8 word, row. Due to constraints mandated by my hosting system, I need to rename the column to something that isn't a reserved word (my idea is to rename it to sort_row).

This row field is however, exposed by an API that my software is implementing and exposing. This API serializes the CakePHP ORM objects as JSON to expose them, which means, if I change the name of a field in my model class it will then also change accordingly in the JSON output of my API. But I don't want to rename the field in the API, because this would mean having to check and update every system which uses it.

The project is implemented with PHP8 and CakePHP 4.4. I have an entity class for the table:

<?php

namespace App\Model\Entity;

class PageContent extends Entity
{
    protected $_accessible = [
        '*' => true,
        'id' => false
    ];

    protected $_virtual = ['content'];

    protected $_hidden = [
        'is_visible',
        'visible_from',
        'visible_to',
        'is_deleted',
        'created',
        'modified',
        'created_user',
        'modified_user',
    ];

    protected function _getContent()
    {
        // method logic here
    }

    // more stuff here....
}

Is there any way I can specify an "alias" or something similar for my CakePHP model, so that while the MySQL field is called sort_row, as far as CakePHP is concerned (in ORM queries and so on) the field is still called row? The documentation doesn't really mention anything like that. Can I use a virtual field to achieve what I need?

In other words, I know I can use $this->setTable() on a table class to customize the link between a class and a MySQL table if they don't match the naming convention. I was wondering if there was something similar for column names.


Solution

  • It sounds like you're in a good position to be able to change the name of the column everywhere except in the API, and that the API is read-only. Given that, I think you could:

    1. Add a virtual field called row with protected function _getRow(): int { return $this->sort_row; }
    2. Add 'row' to your $_virtual.
    3. Add 'sort_row' to your $_hidden.

    Together, this should keep the name of the field as "row" in your serialized JSON output.