diff --git a/src/app/Http/Controllers/Operations/ReorderOperation.php b/src/app/Http/Controllers/Operations/ReorderOperation.php index 3c400d4bde..0fe547f78a 100644 --- a/src/app/Http/Controllers/Operations/ReorderOperation.php +++ b/src/app/Http/Controllers/Operations/ReorderOperation.php @@ -38,6 +38,12 @@ protected function setupReorderDefaults() $this->crud->operation('reorder', function () { $this->crud->loadDefaultOperationSettingsFromConfig(); + $this->crud->setOperationSetting('reorderColumnNames', [ + 'parent_id' => 'parent_id', + 'lft' => 'lft', + 'rgt' => 'rgt', + 'depth' => 'depth', + ]); }); $this->crud->operation('list', function () { diff --git a/src/app/Library/CrudPanel/Traits/Reorder.php b/src/app/Library/CrudPanel/Traits/Reorder.php index 2b51bc86e6..962c536012 100644 --- a/src/app/Library/CrudPanel/Traits/Reorder.php +++ b/src/app/Library/CrudPanel/Traits/Reorder.php @@ -19,6 +19,8 @@ public function updateTreeOrder($request) { $primaryKey = $this->model->getKeyName(); + $columns = $this->getOperationSetting('reorderColumnNames'); + // we use the upsert method that should update the values of the matching ids. // it has the drawback of creating new entries when the id is not found // for that reason we get a list of all the ids and filter the ones @@ -28,14 +30,29 @@ public function updateTreeOrder($request) // filter the items that are not in the database and map the request $reorderItems = collect($request)->filter(function ($item) use ($itemKeys) { return $item['item_id'] !== '' && $item['item_id'] !== null && $itemKeys->contains($item['item_id']); - })->map(function ($item) use ($primaryKey) { + })->map(function ($item) use ($primaryKey, $columns) { $item[$primaryKey] = $item['item_id']; - $item['parent_id'] = empty($item['parent_id']) ? null : $item['parent_id']; - $item['depth'] = empty($item['depth']) ? null : (int) $item['depth']; - $item['lft'] = empty($item['left']) ? null : (int) $item['left']; - $item['rgt'] = empty($item['right']) ? null : (int) $item['right']; + $item[$columns['parent_id']] = empty($item['parent_id']) ? null : $item['parent_id']; + $item[$columns['depth']] = empty($item['depth']) ? null : (int) $item['depth']; + $item[$columns['lft']] = empty($item['left']) ? null : (int) $item['left']; + $item[$columns['rgt']] = empty($item['right']) ? null : (int) $item['right']; + // unset mapped items properties. - unset($item['item_id'], $item['left'], $item['right']); + if ($columns['parent_id'] !== 'parent_id') { + unset($item['parent_id']); + } + if ($columns['depth'] !== 'depth') { + unset($item['depth']); + } + if ($columns['lft'] !== 'left') { + unset($item['left']); + } + if ($columns['rgt'] !== 'right') { + unset($item['right']); + } + + // unset the item_id property + unset($item['item_id']); return $item; })->toArray(); @@ -47,13 +64,13 @@ public function updateTreeOrder($request) }); // wrap the queries in a transaction to avoid partial updates - DB::connection($this->model->getConnectionName())->transaction(function () use ($reorderItems, $primaryKey, $itemKeys) { + DB::connection($this->model->getConnectionName())->transaction(function () use ($reorderItems, $primaryKey, $itemKeys, $columns) { // create a string of ?,?,?,? to use as bind placeholders for item keys $reorderItemsBindString = implode(',', array_fill(0, count($reorderItems), '?')); // each of this properties will be updated using a single query with a CASE statement // this ensures that only 4 queries are run, no matter how many items are reordered - foreach (['parent_id', 'depth', 'lft', 'rgt'] as $column) { + foreach (array_values($columns) as $column) { $query = ''; $bindings = []; $query .= "UPDATE {$this->model->getTable()} SET {$column} = CASE "; diff --git a/src/resources/views/crud/reorder.blade.php b/src/resources/views/crud/reorder.blade.php index d97ca17aab..1fd8755d6d 100644 --- a/src/resources/views/crud/reorder.blade.php +++ b/src/resources/views/crud/reorder.blade.php @@ -7,6 +7,8 @@ trans('backpack::crud.reorder') => false, ]; + $columns = $crud->getOperationSetting('reorderColumnNames'); + // if breadcrumbs aren't defined in the CrudController, use the default breadcrumbs $breadcrumbs = $breadcrumbs ?? $defaultBreadcrumbs; @endphp @@ -24,9 +26,11 @@ @endsection @section('content') - getOperationSetting('reorderColumnNames'); + if (! isset($entry->tree_element_shown)) { // mark the element as shown $all_entries[$key]->tree_element_shown = true; @@ -39,12 +43,12 @@ function tree_element($entry, $key, $all_entries, $crud) // see if this element has any children $children = []; foreach ($all_entries as $key => $subentry) { - if ($subentry->parent_id == $entry->getKey()) { + if ($subentry->{$columns['parent_id']} == $entry->getKey()) { $children[] = $subentry; } } - $children = collect($children)->sortBy('lft'); + $children = collect($children)->sortBy($columns['lft']); // if it does have children, show them if (count($children)) { @@ -59,6 +63,7 @@ function tree_element($entry, $key, $all_entries, $crud) return $entry; } +} ?> @@ -68,15 +73,15 @@ function tree_element($entry, $key, $all_entries, $crud)
{{ trans('backpack::crud.reorder_text') }}