I've got a model:
class Product extends Model {
public $jsonable = ['links'];
public $translatable = ['links'];
public $implement = ['@RainLab.Translate.Behaviors.TranslatableModel'];
}
When I do this...
$p = Product::first();
$p->attributesToArray();
... everything works as expected. When I run...
$p = Product::first();
$p->lang('fr')->attributesToArray();
... i get:
PHP Warning: json_decode() expects parameter 1 to be string, array given in /(...)/vendor/october/rain/src/Database/Model.php on line 1115
It seems like the jsonable attributes are already turned into an array when loaded via the trans method. The subsequent call to json_decode in Model.php therefore fails.
https://github.com/octobercms/library/blob/master/src/Database/Model.php#L1115
Hmm, this is caused by loadTranslatableData() in behaviors/TranslatableModel.php, It's decoding the values before returning it.
Try commenting out the json_decode() call in there just to see if that fixes the problem.
I'm sure this code is needed, so we'll need to investigate deeper.
Maybe we should use a try/catch block in library/src/Database/Model.php, I am not sure how to prevent this double decoding.
This line seems to be the problem:
https://github.com/rainlab/translate-plugin/blob/master/classes/TranslatableBehavior.php#L165
Without it the attributesToArray() call works but obviously everything else is broken.
The simplest solution that comes to mind is to add a is_array check to the attributesToArray method:
foreach ($this->jsonable as $key) {
if (
!array_key_exists($key, $attributes) ||
in_array($key, $mutatedAttributes)
) {
continue;
}
// Prevent double decoding
if (is_array($attributes[$key])) {
continue;
}
$jsonValue = json_decode($attributes[$key], true);
if (json_last_error() === JSON_ERROR_NONE) {
$attributes[$key] = $jsonValue;
}
}
Yes, that would make the most sense.
Can you submit a PR for this @tobias-kuendig ?
@tobias-kuendig make it a !is_string check instead please
This fix is available in https://github.com/octobercms/library/pull/405
Most helpful comment
This line seems to be the problem:
https://github.com/rainlab/translate-plugin/blob/master/classes/TranslatableBehavior.php#L165
Without it the
attributesToArray()call works but obviously everything else is broken.The simplest solution that comes to mind is to add a
is_arraycheck to theattributesToArraymethod: