Cakephp 4 Identifers custom finder not containing blob resource data

I am using a custom finder for the ‘Authentication.Password’ Identifier so that the logged in user contains associated data.
One of the association is the profile which is an extra table. The profile has a blob field for the user picture.
When I try to get a user by $this->Users->get($id, [‘contain’ => ‘…’]) everything is fine. I can use the blob data and if i do a debug($user), the profile field for the avatar shows ‘‘avatar’ => (resource) Resource id #28’.

However, if I access the logged in users profile by ‘$this->Identity->get(‘profile’)’ and debug the entity, the field only shows '‘avatar’ => (int) 0) and I am not able to use the blob data (since it is simply not there)

So at the moment I need to get the id from the logged in user by ‘$this->Authentication->getIdentity()’ and then use the id with $this->Users->get($id, [‘contain’ => ‘…’]) to have the valid data.

But this seems kind of wrong since i would assume that the correct way is to load the association in the custom finder for the identifier…

Are you sure that your custom finder is being used, and returning the right thing?

Yes, as soon as I remove the profile from the finder, it is null.

When I set (in the finder):
$query = $query->contain([‘Profiles’]);
and do:
debug($this->Identity->get(‘profile’));
I get:
object(App\Model\Entity\Profile) id:0 {}

And when I set (in the finder):
$query = $query->contain([]);
and do:
debug($this->Identity->get(‘profile’));
I get:
null

I also stepped through the code in the debugger and see that when I login, the finder works and the avatar is declared as resource. But when I switch the page and the logged in user is retrieved via ‘$this->Identity->get()’ or by ‘$this->Authentication->getIdentity()’ the avatar appears as ‘‘avatar’ => (int) 0’

Ah, the Resource is presumably being destroyed at the end of the page load where it’s created. In future page loads, the session will then have an object that’s referring to something that no longer exists. I guess you’ll need to do something to force it to read the bytes from that resource, so they’re stored in the session instead of a dead reference.

Yes that sounds correct. What I did now is to set the avatar data in the afterIdentify Event as you suggested.

To be precise, I added something like the following to the bootstrap.php:

$this->getEventManager()->on(‘Authentication.afterIdentify’,
function (Event $event, $provider, $identity, $service) {
$identity->get(‘profile’)->avatar = stream_get_contents($identity->get(‘profile’)->avatar);
});

I will test if everything is working and if it is not working I will come back but I’m very confident that it will work.

Thanks for pointing me in the right direction :slight_smile:

1 Like