Comments (4)
Hi Javier,
First off, I needed it fixes, so no better way then deep diving into it myself ;-). I've been able to fix it with our encryptable field by changing the setAttribute()
function a bit:
function setAttribute($key, $value)
{
if (Str::contains($key, '->')) {
[$key, $path] = explode('->', $key, 2);
}
if (!in_array($key, $this->getEncryptableFields())) {
return parent::setAttribute($key, $value);
}
if (isset($path)) {
$value = array_merge(
$this->{$key} ?? [],
["$path" => $value]
);
}
$value = isset($value) ? encrypt($value) : null;
return parent::setAttribute($key, $value);
}
This way nested values will be set correctly, while still be able to have literal null
on encrypted field instead of an encrypted version of null
. Only limit our trait now has for array values is "deep nesting", The explode limit of 2 will prevent setting a value like $user->info['extra']['data']
with the arrow notation $user->{"info->extra->data"} = 'something
. For our usecase not a problem, but for others might be an issue.
Anyway, I'll see if I find the time to completely test setting nested values without our encryptable trait, since I had some weird behaviour with that as well.
If I don't find anything, I'll close this issue, otherwise I'll keep you all up to date!
from nova-fields.
ok, after some more investigation I don't really know if the bug is with this package, or with Laravel itself or with Nova:
The problem seems to be the way the attributes are being converted in this package while storing. In short it looks something like this:
$this->model->{ $attribute . '->' . $field->attribute} = $value;
When value is null, instead of setting that sub attribute as null, it stores the whole attribute as null.
I can reproduce it here in tinker as well:
>>> $i = ReplyLive\Models\Invitee::find(8037)
=> ReplyLive\Models\Invitee {#4736
id: 8037,
info: ""eyJpdiI6InNPZ0IxUlFVMFBtekJMZzNlUjdjUUE9PSIsInZhbHVlIjoiUDd0KzB6MFZmR1JsSW0zY3RsZ0hWOTkxY25obUNsdVVqRHNJU2R3RjVubThpLzJoUUhZNTRpUWxPV1RrU3JwRTcyMmtOQ3NqSzhpNmYwRkk2cVVuREVQTWE4Q0M4SGtqNXgwSzFiLzZhYWV2ZVM3UVhzcmFrbTRPWkdaTkordEVTalBFOFFjdXRjV3lCMVdEVmpxZFFqYnBuaVBoMHQvckhnVkpkNWpibm9nODBXckVEUG0vYWNUdXB6a1FVbVh5ZUVMcSt5aFUrbVRCZmtyWjcwTldiZz09IiwibWFjIjoiZjZmZmQwZGEwNzFiMjZkMDJkMGYyNWExNzE0NGMxMjY4ZjZhZTBjYjQ3NTJjM2RlYTQ0MGE1NjNjZTNjMjY1ZSJ9"",
}
>>> $i->info
=> [
"function" => "aa",
"gender" => "female",
"diet" => [
"vegetarian",
],
"newsletter" => "yes",
"company" => "ffasd",
]
>>> $i->{"info->newsletter"} = "no"
=> "no"
>>> $i->info
=> [
"function" => "aa",
"gender" => "female",
"diet" => [
"vegetarian",
],
"newsletter" => "no",
"company" => "ffasd",
]
>>> $i->{"info->newsletter"} = null
=> null
>>> $i->info
=> null
Also weird: as you can see I've the info field encrypted. If I take the encryption off of this field, the arrow notation for setting the sub attribute does not work at all:
>>> $i = ReplyLive\Models\Invitee::withTrashed()->find(8037)
=> ReplyLive\Models\Invitee {#4734
id: 8037,
info: "{"value":"something"}",
}
>>> $i->info
=> [
"value" => "something",
]
>>> $i->{"info->value"} = "something else"
=> "something else"
>>> $i->info
=> "something else"
Field is casted as array by the way. casting as json seems to give the same result
from nova-fields.
Ok, 1 night of sleep later and I've found something in our Encryptable trait we use on our models, which breaks this.
<?php
namespace ReplyLive\Traits;
use Illuminate\Support\Str;
trait Encryptable
{
public function attributesToArray()
{
$attributes = parent::attributesToArray();
foreach ($this->getEncryptableFields() as $key) {
if (array_key_exists($key, $attributes) && isset($attributes[$key])) {
$attributes[$key] = decrypt($attributes[$key]);
}
}
return $attributes;
}
public function getAttribute($key)
{
$value = parent::getAttribute($key);
if (in_array($key, $this->getEncryptableFields()) && isset($value)) {
try {
$value = decrypt($value);
} catch (\Illuminate\Contracts\Encryption\DecryptException $e) {
return $value;
}
}
return $value;
}
public function setAttribute($key, $value)
{
if (Str::contains($key, '->')) {
[$key, $path] = explode('->', $key, 2);
}
if (in_array($key, $this->getEncryptableFields()) && isset($value)) {
if (isset($path)) {
$value = array_merge(
$this->{$key} ?? [],
["$path" => $value]
);
}
$value = encrypt($value);
}
return parent::setAttribute($key, $value);
}
public function getEncryptableFields(): array
{
return property_exists($this, 'encryptable') ? $this->encryptable : [];
}
}
On line 42 the check isset($value)
returns false
when $value === null
, therefore encryption is not being used and the whole field is set to null
.
This is more a blog on fixing my own stuff now than having an actual bug in this package, but I'll keep you up to date with my progress. Also, still doesn't explain why code also breaks when I've had encryption disabled for the given field.....
from nova-fields.
Thank you so much for all your time. We will keep an eye on this issue and see if we can help with anything
from nova-fields.
Related Issues (20)
- fieldClasses, inputClasses and wrapperClasses are not being added to the Field HOT 1
- quickCreate with parameters to populate values not working HOT 1
- readOnly attribute not working on Autocomplete field HOT 3
- quickCreate modal breaks if there are any fields forEach is not a function HOT 4
- Composer install failing?
- Row Sorting HOT 1
- Help Texts are not visible any more in JSON field HOT 5
- Row field is not hydrated in form view (undefined error thrown in console) HOT 3
- Panel title on JSON field grouping HOT 1
- JSON in JSON field does not work HOT 1
- production files are 640 kb
- Translation in this package
- Datepicker not open
- Support for alwaysShow() on row field type
- Documentation website is down
- Abandoned?
- Project status
- Nova 4 HOT 12
- TypeError: Cannot read properties of undefined (reading '_c') in nova-fields
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nova-fields.