Skip to content

$ciphers throws exceptions on newly created objects

Bug Report

Q A
PHP version 7.3.16
Package version 2.0.0
Framework Laravel
Framework version 7.9.2

Actual Behaviour

When creating a new object with unspecified attributes (i.e. the column defaults to empty in the database migration) an exception is thrown if one of those unspecified attributes is in the $ciphers array:

Invalid property: "login_ip" {"userId":1,"exception":"[object] (Altek\\Accountant\\Exceptions\\AccountantException(code: 0): Invalid property: \"login_ip\" at /Users/mike/Sites/app/vendor/altek/accountant/src/Recordable.php:146)
[stacktrace]
#0 /Users/mike/Sites/app/vendor/altek/accountant/src/Drivers/Database.php(40): App\\User->collect('created')
#1 /Users/mike/Sites/app/vendor/altek/accountant/src/Accountant.php(81): Altek\\Accountant\\Drivers\\Database->record(Object(App\\User), 'created', NULL, Array)
#2 /Users/mike/Sites/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(261): Altek\\Accountant\\Accountant->record(Object(App\\User), 'created')
#3 /Users/mike/Sites/app/vendor/altek/accountant/src/RecordableObserver.php(54): Illuminate\\Support\\Facades\\Facade::__callStatic('record', Array)
#4 [internal function]: Altek\\Accountant\\RecordableObserver->created(Object(App\\User))

Steps to Reproduce

Assuming a typical Laravel User model, but:

Migration:

$table->binary("login_ip")->nullable();

Model:

$ciphers = ["login_ip" => Base64::class];

Controller:

# breaks
$u = User::create(['email'=>'foo@example.com', 'name'=>'Foo Bar']);
$u->save();

# works
$u = User::create(['email'=>'foo@example.com', 'name'=>'Foo Bar', 'login_ip'=>null]);
$u->save();

Possible Solutions

A call to $this->refresh() before $properties = $this->getAttributes() seems to do the trick. (Of course it should only be done on create events, if it's the answer.)

Edited by Michael Newton
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information