From 60f3db722a817d90bafe055ae052ea52e72da285 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 16 Mar 2021 10:52:39 +0100 Subject: [PATCH 01/10] Fix getMediaModel with nested flexible Layout Instanceof Layout without import return always false and getMediaModel must be public. --- src/Concerns/HasMediaLibrary.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Concerns/HasMediaLibrary.php b/src/Concerns/HasMediaLibrary.php index 9f5284ab..1c0f1016 100644 --- a/src/Concerns/HasMediaLibrary.php +++ b/src/Concerns/HasMediaLibrary.php @@ -16,6 +16,7 @@ use Illuminate\Support\Str; use Ebess\AdvancedNovaMediaLibrary\Fields\Media; use Whitecube\NovaFlexibleContent\Http\ScopedRequest; +use Whitecube\NovaFlexibleContent\Layouts\Layout; trait HasMediaLibrary { @@ -26,7 +27,7 @@ trait HasMediaLibrary { * * @return \Spatie\MediaLibrary\HasMedia */ - protected function getMediaModel() : HasMedia + public function getMediaModel() : HasMedia { $model = Flexible::getOriginModel() ?? $this->model; From a0efb3a8e0556dc364be2b80b5829f53ae235a35 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 16 Mar 2021 11:23:22 +0100 Subject: [PATCH 02/10] Fix HasMediaLibrary was required for all the Layouts With this fix you can implement HasMediaLibrary only on Layouts that have media. --- src/Concerns/HasMediaLibrary.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Concerns/HasMediaLibrary.php b/src/Concerns/HasMediaLibrary.php index 1c0f1016..b49c7c7d 100644 --- a/src/Concerns/HasMediaLibrary.php +++ b/src/Concerns/HasMediaLibrary.php @@ -32,7 +32,11 @@ public function getMediaModel() : HasMedia $model = Flexible::getOriginModel() ?? $this->model; while ($model instanceof Layout) { - $model = $model->getMediaModel(); + if(method_exists($model,'getMediaModel')) { + $model = $model->getMediaModel(); + } else { + $model = $model->model; + } } if(is_null($model) || !($model instanceof HasMedia)) { From a3ede3a101a3346b648fbbaa280fa5a9ad0e27b0 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 25 May 2021 12:59:03 +0200 Subject: [PATCH 03/10] Fix translatable validation inside flexible layouts --- src/Http/ParsesFlexibleAttributes.php | 116 ++++++++++++++++---------- 1 file changed, 73 insertions(+), 43 deletions(-) diff --git a/src/Http/ParsesFlexibleAttributes.php b/src/Http/ParsesFlexibleAttributes.php index c6341fd6..1e1f89fd 100644 --- a/src/Http/ParsesFlexibleAttributes.php +++ b/src/Http/ParsesFlexibleAttributes.php @@ -17,61 +17,72 @@ trait ParsesFlexibleAttributes /** * Check if given request should be handled by the middleware * - * @param \Illuminate\Http\Request $request + * @param \Illuminate\Http\Request $request * @return bool */ protected function requestHasParsableFlexibleInputs(Request $request) { - return (in_array($request->method(), ['POST','PUT']) && - is_string($request->input(FlexibleAttribute::REGISTER))); + return (in_array($request->method(), ['POST', 'PUT']) && + is_string($request->input(FlexibleAttribute::REGISTER))); } /** * Transform the request's flexible values * - * @param \Illuminate\Http\Request $request + * @param \Illuminate\Http\Request $request * @return array */ protected function getParsedFlexibleInputs(Request $request) { $this->registerFlexibleFields($request->input(FlexibleAttribute::REGISTER)); - return array_reduce(array_keys($request->all()), function($carry, $attribute) use ($request) { - $value = $request->input($attribute); + return array_reduce( + array_keys($request->all()), + function ($carry, $attribute) use ($request) { + $value = $request->input($attribute); - if(!$this->isFlexibleAttribute($attribute, $value)) return $carry; + if (!$this->isFlexibleAttribute($attribute, $value)) { + return $carry; + } - $carry[$attribute] = $this->getParsedFlexibleValue($value); + $carry[$attribute] = $this->getParsedFlexibleValue($value); - return $carry; - }, []); + return $carry; + }, + [] + ); } /** * Apply JSON decode and recursively check for nested values * - * @param mixed $value + * @param mixed $value * @return array */ protected function getParsedFlexibleValue($value) { - if(is_string($value)) { + if (is_string($value)) { $raw = json_decode($value, true); } else { $raw = $value; } - if(!is_array($raw)) return $value; + if (!is_array($raw)) { + return $value; + } - return array_map(function($group) { - return $this->getParsedFlexibleGroup($group); - }, $raw); + return array_map( + function ($group) { + return $this->getParsedFlexibleGroup($group); + }, + $raw + ); } /** * Cleans & prepares a filled group * - * @param array $group + * @param array $group * @return array */ protected function getParsedFlexibleGroup($group) @@ -85,29 +96,34 @@ protected function getParsedFlexibleGroup($group) foreach ($group['attributes'] ?? [] as $attribute => $value) { $this->fillFlexibleAttributes($clean['attributes'], $clean['key'], $attribute, $value); } - foreach ($clean['attributes'] as $attribute => $value) { - if(!$this->isFlexibleAttribute($attribute, $value)) continue; - $clean['attributes'][$attribute] = $this->getParsedFlexibleValue($value); + if ($this->isFlexibleAttribute($attribute, $value)) { + $clean['attributes'][$attribute] = $this->getParsedFlexibleValue($value); + } else { + $jsonDecoded = json_decode($value, true); + if (json_last_error() == JSON_ERROR_NONE) { + if ($this->isTranslatableAttribute($jsonDecoded)) { + $clean['attributes'][$attribute] = $jsonDecoded; + } + } + } } - return $clean; } /** * Fill a flexible group's attributes with cleaned attributes & values * - * @param array $attributes - * @param string $group - * @param string $attribute - * @param string $value + * @param array $attributes + * @param string $group + * @param string $attribute + * @param string $value * @return void */ protected function fillFlexibleAttributes(&$attributes, $group, $attribute, $value) { $attribute = $this->parseAttribute($attribute, $group); - - if($attribute->isFlexibleFieldsRegister()) { + if ($attribute->isFlexibleFieldsRegister()) { $this->registerFlexibleFields($value, $group); return; } @@ -118,8 +134,8 @@ protected function fillFlexibleAttributes(&$attributes, $group, $attribute, $val /** * Analyse and clean up the raw attribute * - * @param string $attribute - * @param string $group + * @param string $attribute + * @param string $group * @return \Whitecube\NovaFlexibleContent\Http\FlexibleAttribute */ protected function parseAttribute($attribute, $group) @@ -130,17 +146,17 @@ protected function parseAttribute($attribute, $group) /** * Add flexible attributes to the register * - * @param null|string $value - * @param null|string $group + * @param null|string $value + * @param null|string $group * @return void */ protected function registerFlexibleFields($value, $group = null) { - if(!$value) { + if (!$value) { return; } - if(!is_array($value)) { + if (!is_array($value)) { $value = json_decode($value); } @@ -152,8 +168,8 @@ protected function registerFlexibleFields($value, $group = null) /** * Add an attribute to the register * - * @param mixed $attribute - * @param null|string $group + * @param mixed $attribute + * @param null|string $group * @return void */ protected function registerFlexibleField($attribute, $group = null) @@ -164,20 +180,20 @@ protected function registerFlexibleField($attribute, $group = null) } /** - * Check if given attribute is a registered and usable + * Check if given attribute is a registered and usable * flexible attribute * - * @param string $attribute - * @param mixed $value + * @param string $attribute + * @param mixed $value * @return bool */ protected function isFlexibleAttribute($attribute, $value) { - if(!$this->getFlexibleAttribute($attribute)) { + if (!$this->getFlexibleAttribute($attribute)) { return false; } - - if(!$value || !is_string($value)) { + + if (!$value || !is_string($value)) { return false; } @@ -187,13 +203,27 @@ protected function isFlexibleAttribute($attribute, $value) /** * Retrieve a registered flexible attribute * - * @param string $attribute + * @param string $attribute * @return \Whitecube\NovaFlexibleContent\Http\FlexibleAttribute */ protected function getFlexibleAttribute($attribute) { foreach ($this->registered as $registered) { - if($registered->name === $attribute) return $registered; + if ($registered->name === $attribute) { + return $registered; + } + } + } + + protected function isTranslatableAttribute(array $attribute): bool + { + if (config()->has('nova-translatable.locales')) { + foreach (array_keys(config('nova-translatable.locales')) as $locale) { + if (isset($attribute[$locale])) { + return true; + } + } } + return false; } } From 351d83de209a00134e4206d3a5b6c5a1fbfc5be2 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 25 May 2021 15:26:46 +0200 Subject: [PATCH 04/10] fix not array attribute --- src/Http/ParsesFlexibleAttributes.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Http/ParsesFlexibleAttributes.php b/src/Http/ParsesFlexibleAttributes.php index 1e1f89fd..52699832 100644 --- a/src/Http/ParsesFlexibleAttributes.php +++ b/src/Http/ParsesFlexibleAttributes.php @@ -215,11 +215,11 @@ protected function getFlexibleAttribute($attribute) } } - protected function isTranslatableAttribute(array $attribute): bool + protected function isTranslatableAttribute($attribute): bool { if (config()->has('nova-translatable.locales')) { foreach (array_keys(config('nova-translatable.locales')) as $locale) { - if (isset($attribute[$locale])) { + if (is_array($attribute) && isset($attribute[$locale])) { return true; } } From 8263f8422b88c6a5c17248a6c066e9001f35116c Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 25 May 2021 18:31:44 +0200 Subject: [PATCH 05/10] fix for medialibrary --- src/Http/ParsesFlexibleAttributes.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Http/ParsesFlexibleAttributes.php b/src/Http/ParsesFlexibleAttributes.php index 52699832..5449ebb3 100644 --- a/src/Http/ParsesFlexibleAttributes.php +++ b/src/Http/ParsesFlexibleAttributes.php @@ -100,10 +100,12 @@ protected function getParsedFlexibleGroup($group) if ($this->isFlexibleAttribute($attribute, $value)) { $clean['attributes'][$attribute] = $this->getParsedFlexibleValue($value); } else { - $jsonDecoded = json_decode($value, true); - if (json_last_error() == JSON_ERROR_NONE) { - if ($this->isTranslatableAttribute($jsonDecoded)) { - $clean['attributes'][$attribute] = $jsonDecoded; + if(is_string($value)) { + $jsonDecoded = json_decode($value, true); + if (json_last_error() == JSON_ERROR_NONE) { + if ($this->isTranslatableAttribute($jsonDecoded)) { + $clean['attributes'][$attribute] = $jsonDecoded; + } } } } From 900eb7c868c177d149246bfdeb6b3b54f3078d4d Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 18 Aug 2021 17:18:30 +0200 Subject: [PATCH 06/10] Docblock and refactoring --- src/Http/ParsesFlexibleAttributes.php | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Http/ParsesFlexibleAttributes.php b/src/Http/ParsesFlexibleAttributes.php index 5449ebb3..b6a551fc 100644 --- a/src/Http/ParsesFlexibleAttributes.php +++ b/src/Http/ParsesFlexibleAttributes.php @@ -99,14 +99,12 @@ protected function getParsedFlexibleGroup($group) foreach ($clean['attributes'] as $attribute => $value) { if ($this->isFlexibleAttribute($attribute, $value)) { $clean['attributes'][$attribute] = $this->getParsedFlexibleValue($value); - } else { - if(is_string($value)) { - $jsonDecoded = json_decode($value, true); - if (json_last_error() == JSON_ERROR_NONE) { - if ($this->isTranslatableAttribute($jsonDecoded)) { - $clean['attributes'][$attribute] = $jsonDecoded; - } - } + } elseif(is_string($value)) { + $jsonDecoded = json_decode($value, true); + if (json_last_error() === JSON_ERROR_NONE && + $this->isTranslatableAttribute($jsonDecoded) + ) { + $clean['attributes'][$attribute] = $jsonDecoded; } } } @@ -217,11 +215,17 @@ protected function getFlexibleAttribute($attribute) } } - protected function isTranslatableAttribute($attribute): bool + /** + * Check if an attribute is a translatable + * + * @param array $attribute + * @return bool + */ + protected function isTranslatableAttribute(array $attribute): bool { if (config()->has('nova-translatable.locales')) { foreach (array_keys(config('nova-translatable.locales')) as $locale) { - if (is_array($attribute) && isset($attribute[$locale])) { + if (isset($attribute[$locale])) { return true; } } From fc6e2daf6ff4ee72112cf5d1b52985aa21302ac7 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 26 Aug 2021 18:18:27 +0200 Subject: [PATCH 07/10] fix no Array strings --- src/Http/ParsesFlexibleAttributes.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Http/ParsesFlexibleAttributes.php b/src/Http/ParsesFlexibleAttributes.php index b6a551fc..00fb69f7 100644 --- a/src/Http/ParsesFlexibleAttributes.php +++ b/src/Http/ParsesFlexibleAttributes.php @@ -102,6 +102,7 @@ protected function getParsedFlexibleGroup($group) } elseif(is_string($value)) { $jsonDecoded = json_decode($value, true); if (json_last_error() === JSON_ERROR_NONE && + is_array($jsonDecoded) && $this->isTranslatableAttribute($jsonDecoded) ) { $clean['attributes'][$attribute] = $jsonDecoded; From 4ee97fedfea3296680dcc3b9b087c87e30babdec Mon Sep 17 00:00:00 2001 From: Alberto Peripolli Date: Fri, 21 Oct 2022 09:52:12 +0200 Subject: [PATCH 08/10] Update Layout.php --- src/Layouts/Layout.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Layouts/Layout.php b/src/Layouts/Layout.php index 4e98a572..ec3407b6 100644 --- a/src/Layouts/Layout.php +++ b/src/Layouts/Layout.php @@ -83,6 +83,20 @@ class Layout implements LayoutInterface, JsonSerializable, ArrayAccess, Arrayabl * @var Illuminate\Database\Eloquent\Model */ protected $model; + + /** + * Define that Layout is a model, when in fact it is not. + * + * @var bool + */ + protected $exists = false; + + /** + * Define that Layout is a model, when in fact it is not. + * + * @var bool + */ + protected $wasRecentlyCreated = false; /** * Create a new base Layout instance From f8f2aa41bc386ac5bbd232387e66a33febe9ea98 Mon Sep 17 00:00:00 2001 From: Alberto Peripolli Date: Wed, 19 Apr 2023 17:34:10 +0200 Subject: [PATCH 09/10] Update Layout.php --- src/Layouts/Layout.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Layouts/Layout.php b/src/Layouts/Layout.php index ec3407b6..507a280b 100644 --- a/src/Layouts/Layout.php +++ b/src/Layouts/Layout.php @@ -97,6 +97,20 @@ class Layout implements LayoutInterface, JsonSerializable, ArrayAccess, Arrayabl * @var bool */ protected $wasRecentlyCreated = false; + + /** + * The relation resolver callbacks for the Layout. + * + * @var array + */ + protected $relationResolvers = []; + + /** + * The loaded relationships for the Layout. + * + * @var array + */ + protected $relations = []; /** * Create a new base Layout instance From 3fcec286892d267fd246555da1864bf0d8c2c085 Mon Sep 17 00:00:00 2001 From: Alberto Peripolli Date: Wed, 19 Apr 2023 17:51:15 +0200 Subject: [PATCH 10/10] Update Layout.php --- src/Layouts/Layout.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Layouts/Layout.php b/src/Layouts/Layout.php index 507a280b..897311e7 100644 --- a/src/Layouts/Layout.php +++ b/src/Layouts/Layout.php @@ -601,6 +601,20 @@ protected function relationLoaded() { return false; } + + /** + * Get the dynamic relation resolver if defined or inherited, or return null. + * Since it is not possible to define a relation on a layout, this method + * returns null + * + * @param string $class + * @param string $key + * @return mixed + */ + public function relationResolver($class, $key) + { + return null; + } /** * Transform layout for serialization