• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Entity fields not saving when using 'business logic' method.

#1
Some help / advice requested, please.

Using the 'UserModel' model and 'User' entity examples duplicated from the CodeIgniter4 docs, I have encountered a problem. The saving of the user entity to the the database works as expected until I add a 'business logic' method to the User entity class, the field involved - in this case it's the password hash example from the docs - is no longer included in the insert query when using save or insert. As follows: (The queries are copied from the CodeIgniter diagnostics panel and the I have included a var_dump of the user entity after using the fill method on the posted data from my three field form. If any other information is required, please let me know. )

PHP Code:
<?php namespace App\Entities;
  use CodeIgniter\Entity;
  class User extends Entity{    
   
// without a method
   

Code:
User
[color=#000000][size=small]array(0) { } ["dates":protected]=> array(3) { [0]=> string(10) "created_at" [1]=> string(10) "updated_at" [2]=> string(10) "deleted_at" } ["casts":protected]=> array(0) { } ["attributes":protected]=> array(5) { ["username"]=> string(11) "usertest101" ["password"]=> string(8) "12121212" ["pass_confirm"]=> string(8) "12121212" ["email"]=> string(18) "usertest101@me.com" ["registerform"]=> string(8) "Register" } ["original":protected]=> array(0) { } ["_cast":"CodeIgniter\Entity":private]=> bool(true) }[/size][/color]

Code:
Database
SELECT 1 FROM `users` WHERE `username` = 'usertest101' LIMIT 1

INSERT INTO `users` (`username`, `password`, `email`, `created`, `updated`) VALUES ('usertest101', '12121212', 'usertest101@me.com', '2020-01-20 10:38:19', '2020-01-20 10:38:19')

Correct query with password included.

But when a method is added to hash the password, the password is no longer included in the query.
PHP Code:
<?php namespace App\Entities;

  use CodeIgniter\Entity;

  class User extends Entity{    
    
protected function setPassword(string $pass)
    {
        $this->password password_hash($passPASSWORD_BCRYPT);
        return $this;
    }        
  


User
Code:
array(0) { } ["dates":protected]=> array(3) { [0]=> string(10) "created_at" [1]=> string(10) "updated_at" [2]=> string(10) "deleted_at" } ["casts":protected]=> array(0) { } ["attributes":protected]=> array(4) { ["username"]=> string(11) "usertest102" ["pass_confirm"]=> string(8) "12121212" ["email"]=> string(18) "usertest102@me.com" ["registerform"]=> string(8) "Register" } ["original":protected]=> array(0) { } ["_cast":"CodeIgniter\Entity":private]=> bool(true) ["password"]=> string(60) "$2y$10$y/K7qeUIilBrZeeDaCr6b.t2UZZy/CoHPFShNTNz3sSdzKPR/iop2" }

Code:
Database
SELECT 1 FROM `users` WHERE `username` = 'usertest102' LIMIT 1

INSERT INTO `users` (`username`, `email`, `created`, `updated`) VALUES ('usertest102', 'usertest102@me.com', '2020-01-20 10:57:26', '2020-01-20 10:57:26')

The password field is no longer included in the query. Does anyone have any suggestions? The hashed password can be read OK from the entity object but why is it no longer included in the INSERT statement when using the entity save or insert methods? Am I misunderstanding something fundamental here? Your advice would be much appreciated.

Thank you.
Reply

#2
Hello,

at this moment I am playing around with entities as well. I had the same issue, maybe documentation is not complete yet.

Look at source of myth-auth here: https://github.com/lonnieezell/myth-auth...er.php#L70


PHP Code:
$this->attributes['password'] = password_hash($passPASSWORD_BCRYPT); 
Reply

#3
Thanks. The documentation makes it seem straightforward but I've had to abandon the entity business rules approach until I get more information. I've moved my latest project from 3 to 4 with very few problems until encountering the entity class. Still not sure if moving was the right decision.
Reply

#4
I'm afraid that part of the userguide are incorrect. You can see a working example in @janroz post. Or setCreatedAt() in the userguide. It have been fixed and the userguide will be updated, in around a months time. When we aim to have the stable version out. Until then, please report all inconsistencies with the manual as you get kind of blind reading them yourself.

I haven't debugged this, so take as a grain of salt; The reason it's not working are that $this->password will call the magic __set function. And that function will go into setPassword() and the attribute will be emptied. $this->password sets the property of class itself (so that's why it's visible), but Codeigniter 4 queries are done based on the $this->attributes array.
Reply

#5
Hi, using the suggestion in janroz's post results in the following error when saving.

ErrorException Can't use method return value in write context

Not quite there yet... but thank you for explaining the situation.
Reply

#6
Can you post what line etc that you got that error message in/from. And what system file generated it.
Reply

#7
ErrorException #64
Can't use method return value in write context

Error line: $this->attributes('password') = password_hash($pass, PASSWORD_BCRYPT);

Backtrace: {PHP internal code} — CodeIgniter\Debug\Exceptions->shutdownHandler ()
Reply

#8
Hi,

You should use [] and not ().

Not working:
Code:
$this->attributes('password') = password_hash($pass, PASSWORD_BCRYPT);

Working
Code:
$this->attributes['password'] = password_hash($pass, PASSWORD_BCRYPT);
Reply

#9
Apologies, that was careless of me. I have corrected it, and it's working correctly now. The password is encrypted and saved when saving the entity. Thank you both for your help.
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.