$_accessible change?

We have a cake 5.1.x application working since 6 monhts.

All of a sudden we have found a lot of duplicate records while saving an associated table

eg:

Request (id, user_id, origin, destination)
--> User (id, name)

Every time we save request, All of a sudden user.id is not saved anymore (so we duplicate the user everytime) and we have discovered that we have to put it in the entity

    protected array $_accessible = [
        '*' => true,
    ];

When did this change? Was it in some updates of the ORM? Normally linked fields where saved even without “allowing” them in the accessible field. Is there a configuration somewhere that we missed?

Thanks

Massimo

That property is defined in the EntityTrait which has exactly that default value as you see here.

This has not changed in Cake 5.1 and is not planned to be changed any time soon. So your problem is related to something else.

Could you dump your entity’s state in here (redacting any data/fields, which of course should not be public). I guess your entity has the _new flag set to true, which therefore makes the ORM insert instead of update.

1 Like

The strange thing is that if I remove all the $_accessible from my entities, everything works again perfectly.

But the $avcessible properties (without the id field) have always been there, so I guess is some version change of something…

BTW: I really miss how this $_accessible field can be useful: If I put a field in the db i obvously want to set it, otherwise I would not put it … so when could this property be more than a nuisance?

Thanks a lot,

Massimo

{“id”:3877,“confirmed”:false,“lastminute”:false,“driver_id”:null,“passenger_id”:null,“proposer_id”:65252,“created”:“2025-12-06T16:08:35+01:00”,“modified”:“2025-12-16T14:34:06+01:00”,“direction_id”:77,“arrival_date”:null,“arrival_time”:null,“origin”:“ Bra”,“origin_lat”:null,“origin_lon”:null,“origin_date”:“2025-12-17”,“origin_time”:“06:00:00”,“origin_flex”:false,“destination”:“Via Tanaro, 7, Verduno”,“dest_lat”:null,“dest_lon”:null,“dest_date”:“2025-12-17”,“dest_time”:“06:30:00”,“dest_flex”:false,“user_number”:1,“state_id”:2,“trip_id”:null,“km_tariffa”:null,“km_real”:11.24,“costo_per_persona”:5,“pagamento”:0,“metodo_pagamento_id”:null,“tipo_pagamento”:null,“linked_request_id”:null,“repeat”:null,“repeat_until_date”:null,“requests_platforms”:[{“id”:542,“request_id”:3877,“platform_id”:“contrasporto”,“platform”:{“id”:“contrasporto”,“name”:“conTrasporto”,“description”:“Piattaforma principale di conTrasporto”}}],“persone_requests”:,“main_request”:null,“metodo_pagamento”:null,“state”:{“id”:2,“code”:2,“name”:“annullata”,“description”:“Richiesta annullata dall’utente”},“trip”:null,“persona”:{“id”:65252,“Nome”:“A”,“Cognome”:“C”,“EMail”:“xxx”,“Cellulare”:“xxx”,“tag_list”:“”,“nome_composto”:“xxx”},“direction”:{“id”:77,“name”:“nodir”,“description”:“no direction”,“default_direction”:true}}

Everytime I save I get a duplicate persona:, state, etc.

I’ve now solved putting “*” in accessible, but it worked until 3 days ago!

You misunderstand what accessible means. It allows you to provide a map of fields on whether or not they can be mass-assigned via e.g. ->patchEntity()

See Entities - 5.x

I have no idea what that invalid JSON you posted should mean.

Again - as I said above - please dump your entity’s state in here like so (only works in debug mode)

pr($entity);

If you didn’t perform CakePHP or composer updates in the last 3 days its not related to any update we made to CakePHP :wink:

What version did you upgrade to? What exact version?

This is our composer

  "require": {
        "php": ">=8.2",
        "cakephp/authentication": "^3.2",
        "cakephp/cakephp": "5.1.*",
        "cakephp/migrations": "^4.0.0",
        "cakephp/plugin-installer": "^2.0",
        "cboden/ratchet": "^0.4.4",
        "dereuromark/cakephp-tags": "^2.1",
        "firebase/php-jwt": "^6.11",
        "friendsofcake/crud": "^7.1",
        "friendsofcake/search": "^7.1",
        "impronta48/cakephp-email-queue": "dev-cakephp5",
        "irazasyed/telegram-bot-sdk": "^3.15",
        "mjaschen/phpgeo": "^6.0",
        "mobiledetect/mobiledetectlib": "^4.8.03",
        "phpoffice/phpspreadsheet": "^1.23",
        "phpoption/phpoption": "^1.9",
        "ratchet/pawl": "0.4.1",
        "react/socket": "^1.16",
        "saikiran/geohash": "^1.0",
        "satispay/gbusiness-api-php-sdk": "^1.3",
        "shakib/cakephp-encrypt-decrypt": "dev-master",
        "vlucas/phpdotenv": "^5.6"
    },

The version currently installed is

       {
            "name": "cakephp/cakephp",
            "version": "5.1.6",
...

Really a wierd behaviour … I’ve also checked friendsofcake/crud but they have not been upgrading since 6 months…

What was the versions before your change for relevant packages (that still “worked”)? This should give some insight on the changes relevant.

Also, your version is terrible outdated, you should be using latest 5.2 for a long time now.
There can also be tons of fixes already in there as well - for possible smaller regressions and this one.

I try to update, to 5.2 but honestly no major change in my composer.

Just composer update.

Thanks

Massimo

No way to reproduce, now I’ve put $_accessible=’*’ everywhere…

BTW: I really miss how this $_accessible field can be useful: If I put a field in the db i obvously want to set it, otherwise I would not put it … so when could this property be more than a nuisance?

Just do what I have been doing the last decade:

You can always manually add blacklisted fields into it, e.g. password or alike.

The usefulness is in securing your application against certain hacks. Suppose you have a group_id column in your users table, not an uncommon thing to do. A hacker signs up for an account, then goes to the user edit page. You will surely not just put group_id on that page to let someone make themselves an administrator, but suppose they use developer tools in the browser to add that field to what is going to be posted. If you allow that to get patched into the entity by having * in the _accessible array, boom, they’ve made themselves an admin!

Of course, there are other ways to protect against this, but they are going to require some code, where this is a very simple configuration thing, and therefore quite reliable.

Allowing hackers to change the ID of a record is similarly going to be problematic, hence why it’s excluded by default. Using that, they would be able to replace existing records with theirs, which could gain them access to things that have join tables in any way connected to permissions.

Thanks for your reply @Zuluru and @dereuromark !
Just one more question: if I put ‘id’ => false as suggested the problem is that I duplicate all associated record (since a few weeks), because id comes empty to the $model→save() and it becomes a new record…

I’m sure I’m missing something,

Regards

Massimo

You’ve shown hardly any of your code, so it’s nearly impossible to help with resolving your bug. My best guess is that you are creating new entity objects when what you want is to update existing ones. Otherwise why would you be needing to put the ID into these objects? That only makes sense if you know the IDs. But if you do, you should be loading those existing records and updating them, not making new entities, and if you’re updating them you don’t need the ID field to be accessible because it’s already correctly set.

Why did it suddenly change? No idea. Not seeing any of your code, it seems at least as likely to me that it was something else that changed in your code at the same time as the Cake upgrade happened.

1 Like