From f6cea4e5f45873043bec1e45eb5dbbb0dd38aea8 Mon Sep 17 00:00:00 2001 From: Quentin Renard Date: Mon, 1 Apr 2019 02:04:02 -0400 Subject: [PATCH] Support multi-browsers in blocks --- src/Models/Behaviors/HasRelated.php | 6 ++- src/Models/Block.php | 3 +- src/Models/RelatedItem.php | 2 +- src/Repositories/Behaviors/HandleBlocks.php | 40 ++++++++++--------- src/Repositories/BlockRepository.php | 44 +++++++++++++++++++++ src/Repositories/ModuleRepository.php | 2 +- views/partials/form/_browser.blade.php | 12 +++++- 7 files changed, 85 insertions(+), 24 deletions(-) diff --git a/src/Models/Behaviors/HasRelated.php b/src/Models/Behaviors/HasRelated.php index a5218ffda..2f3778dbb 100644 --- a/src/Models/Behaviors/HasRelated.php +++ b/src/Models/Behaviors/HasRelated.php @@ -27,7 +27,9 @@ public function getRelated($browser_name) public function loadRelated($browser_name) { - $this->load('relatedItems'); + if (!isset($this->relatedItems)) { + $this->load('relatedItems'); + } return $this->relatedCache[$browser_name] = $this->relatedItems ->where('browser_name', $browser_name) @@ -36,7 +38,7 @@ public function loadRelated($browser_name) }); } - public function sync($items, $browser_name) + public function saveRelated($items, $browser_name) { RelatedItem::where([ 'browser_name' => $browser_name, diff --git a/src/Models/Block.php b/src/Models/Block.php index 3a65f3549..53ab97777 100644 --- a/src/Models/Block.php +++ b/src/Models/Block.php @@ -5,11 +5,12 @@ use A17\Twill\Models\Behaviors\HasFiles; use A17\Twill\Models\Behaviors\HasMedias; use A17\Twill\Models\Behaviors\HasPresenter; +use A17\Twill\Models\Behaviors\HasRelated; use Illuminate\Database\Eloquent\Model as BaseModel; class Block extends BaseModel { - use HasMedias, HasFiles, HasPresenter; + use HasMedias, HasFiles, HasPresenter, HasRelated; public $timestamps = false; diff --git a/src/Models/RelatedItem.php b/src/Models/RelatedItem.php index f19dd7b3c..08d1262c9 100644 --- a/src/Models/RelatedItem.php +++ b/src/Models/RelatedItem.php @@ -26,6 +26,6 @@ public function subject() public function getTable() { - return 'related'; + return config('twill.related_table', 'related'); } } diff --git a/src/Repositories/Behaviors/HandleBlocks.php b/src/Repositories/Behaviors/HandleBlocks.php index f2aa94e48..f51ebca68 100644 --- a/src/Repositories/Behaviors/HandleBlocks.php +++ b/src/Repositories/Behaviors/HandleBlocks.php @@ -5,6 +5,7 @@ use A17\Twill\Models\Behaviors\HasMedias; use A17\Twill\Repositories\BlockRepository; use Illuminate\Support\Collection; +use Schema; trait HandleBlocks { @@ -248,26 +249,29 @@ public function getFormFieldsHandleBlocks($object, $fields) protected function getBlockBrowsers($block) { return Collection::make($block['content']['browsers'])->mapWithKeys(function ($ids, $relation) use ($block) { - $relationRepository = $this->getModelRepository($relation); - $relatedItems = $relationRepository->get([], ['id' => $ids], [], -1); - $sortedRelatedItems = array_flip($ids); + if (Schema::hasTable(config('twill.related_table', 'related')) && $block->getRelated($relation)->isNotEmpty()) { + $items = $this->getFormFieldsForRelatedBrowser($block, $relation);; + } else { + $relationRepository = $this->getModelRepository($relation); + $relatedItems = $relationRepository->get([], ['id' => $ids], [], -1); + $sortedRelatedItems = array_flip($ids); + + foreach ($relatedItems as $item) { + $sortedRelatedItems[$item->id] = $item; + } - foreach ($relatedItems as $item) { - $sortedRelatedItems[$item->id] = $item; + $items = Collection::make(array_values($sortedRelatedItems))->filter(function ($value) { + return is_object($value); + })->map(function ($relatedElement) use ($relation) { + return [ + 'id' => $relatedElement->id, + 'name' => $relatedElement->titleInBrowser ?? $relatedElement->title, + 'edit' => moduleRoute($relation, config('twill.block_editor.browser_route_prefixes.' . $relation), 'edit', $relatedElement->id), + ] + (classHasTrait($relatedElement, HasMedias::class) ? [ + 'thumbnail' => $relatedElement->defaultCmsImage(['w' => 100, 'h' => 100]), + ] : []); + })->toArray(); } - - $items = Collection::make(array_values($sortedRelatedItems))->filter(function ($value) { - return is_object($value); - })->map(function ($relatedElement) use ($relation) { - return [ - 'id' => $relatedElement->id, - 'name' => $relatedElement->titleInBrowser ?? $relatedElement->title, - 'edit' => moduleRoute($relation, config('twill.block_editor.browser_route_prefixes.' . $relation), 'edit', $relatedElement->id), - ] + (classHasTrait($relatedElement, HasMedias::class) ? [ - 'thumbnail' => $relatedElement->defaultCmsImage(['w' => 100, 'h' => 100]), - ] : []); - })->toArray(); - return [ "blocks[$block->id][$relation]" => $items, ]; diff --git a/src/Repositories/BlockRepository.php b/src/Repositories/BlockRepository.php index 82c1da8ef..894799efc 100644 --- a/src/Repositories/BlockRepository.php +++ b/src/Repositories/BlockRepository.php @@ -9,6 +9,9 @@ use A17\Twill\Repositories\Behaviors\HandleMedias; use Illuminate\Config\Repository as Config; use Illuminate\Support\Collection; +use Log; +use ReflectionException; +use Schema; class BlockRepository extends ModuleRepository { @@ -37,14 +40,55 @@ public function getCrops($role) return $this->config->get('twill.block_editor.crops')[$role]; } + public function hydrate($object, $fields) + { + if (Schema::hasTable(config('twill.related_table', 'related'))) { + $relatedItems = Collection::make(); + + Collection::make($fields['browsers'])->each(function ($items, $browserName) use ($object, &$relatedItems) { + Collection::make($items)->each(function ($item) use ($browserName, &$relatedItems) { + try { + $repository = $this->getModelRepository($item['endpointType'] ?? $browserName); + $relatedItems->push((object) [ + 'related' => $repository->getById($item['id']), + 'browser_name' => $browserName, + ]); + + } catch (ReflectionException $e) { + Log::error($e); + } + }); + }); + + $object->setRelation('relatedItems', $relatedItems); + } + + return parent::hydrate($object, $fields); + } + /** * @param HasMedias|HasFiles $object * @return void */ + public function afterSave($object, $fields) + { + if (Schema::hasTable(config('twill.related_table', 'related'))) { + Collection::make($fields['browsers'])->each(function ($items, $browserName) use ($object) { + $object->saveRelated($items, $browserName); + }); + } + + parent::afterSave($object, $fields); + } + public function afterDelete($object) { $object->medias()->sync([]); $object->files()->sync([]); + + if (Schema::hasTable(config('twill.related_table', 'related'))) { + $object->relatedItems()->delete(); + } } /** diff --git a/src/Repositories/ModuleRepository.php b/src/Repositories/ModuleRepository.php index 357a284cd..e8c45e1de 100644 --- a/src/Repositories/ModuleRepository.php +++ b/src/Repositories/ModuleRepository.php @@ -769,7 +769,7 @@ public function updateBrowser($object, $fields, $relationship, $positionAttribut */ public function updateRelatedBrowser($object, $fields, $browserName) { - $object->sync($fields['browsers'][$browserName] ?? [], $browserName); + $object->saveRelated($fields['browsers'][$browserName] ?? [], $browserName); } /** diff --git a/views/partials/form/_browser.blade.php b/views/partials/form/_browser.blade.php index d02c3808b..b824331f7 100644 --- a/views/partials/form/_browser.blade.php +++ b/views/partials/form/_browser.blade.php @@ -1,8 +1,18 @@ @php $name = $name ?? $moduleName; $label = $label ?? 'Missing browser label'; - $endpoints = $endpoints ?? []; + + $endpointsFromModules = isset($modules) ? collect($modules)->map(function ($module) { + return [ + 'label' => $module['label'] ?? ucfirst($module['name']), + 'value' => moduleRoute($module['name'], $module['routePrefix'] ?? null, 'browser', $module['params'] ?? [], false) + ]; + })->toArray() : null; + + $endpoints = $endpoints ?? $endpointsFromModules ?? []; + $endpoint = $endpoint ?? (!empty($endpoints) ? null : moduleRoute($moduleName, $routePrefix ?? null, 'browser', $params ?? [], false)); + $max = $max ?? 1; $note = $note ?? 'Add' . ($max > 1 ? " up to $max ". strtolower($label) : ' one ' . str_singular(strtolower($label))); $itemLabel = $itemLabel ?? strtolower($label);