-
-
Notifications
You must be signed in to change notification settings - Fork 635
Expand file tree
/
Copy pathCollectionTreeController.php
More file actions
114 lines (90 loc) · 3.58 KB
/
Copy pathCollectionTreeController.php
File metadata and controls
114 lines (90 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
namespace Statamic\Http\Controllers\CP\Collections;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Statamic\Contracts\Entries\Collection;
use Statamic\Facades\Entry;
use Statamic\Facades\Site;
use Statamic\Facades\User;
use Statamic\Http\Controllers\CP\CpController;
use Statamic\Structures\TreeBuilder;
use Statamic\Support\Arr;
use function Statamic\trans;
class CollectionTreeController extends CpController
{
public function index(Request $request, Collection $collection)
{
$this->authorize('view', $collection, trans('You are not authorized to view this collection.'));
$site = $request->site ?? Site::selected()->handle();
$pages = (new TreeBuilder)->buildForController([
'structure' => $collection->structure(),
'include_home' => true,
'site' => $site,
]);
return ['pages' => $pages];
}
public function update(Request $request, $collection)
{
$this->authorize('reorder', $collection);
$contents = $this->toTree($request->pages);
$structure = $collection->structure();
$tree = $structure->in($request->site);
// Clone the tree and add the submitted contents into it so we can
// validate URI uniqueness without affecting the real object in memory.
$this->validateUniqueUris((clone $tree)->disableUriCache()->tree($contents));
$this->deleteEntries($request);
// Validate the tree, which will add any missing entries or throw an exception
// if somehow the root would end up having child pages, which isn't allowed.
$contents = $structure->validateTree($contents, $request->site);
return [
'saved' => $tree->tree($contents)->save(),
];
}
private function toTree($items)
{
return collect($items)->map(function ($item) {
return Arr::removeNullValues([
'entry' => $ref = $item['id'] ?? null,
'title' => $ref ? null : ($item['title'] ?? null),
'url' => $ref ? null : ($item['url'] ?? null),
'children' => $this->toTree($item['children']),
]);
})->all();
}
private function validateUniqueUris($tree)
{
if (! $tree->collection()->route($tree->locale())) {
return;
}
foreach ($tree->diff()->moved() as $id) {
$page = $tree->find($id);
$parent = $page->parent();
$siblings = (! $parent || $parent->isRoot())
? $tree->pages()->all()->slice(1)
: $page->parent()->pages()->all();
$siblings = $siblings->reject(function ($sibling) use ($id) {
return $sibling->reference() === $id;
});
$uris = $siblings->map->uri();
if ($uris->contains($uri = $page->uri())) {
throw ValidationException::withMessages(['uri' => trans('statamic::validation.duplicate_uri', ['value' => $uri])]);
}
}
}
private function deleteEntries($request)
{
$deletedEntries = collect($request->deletedEntries ?? [])
->map(function ($id) {
return Entry::find($id);
})
->filter(function ($entry) {
return User::current()->can('delete', $entry);
});
if ($request->deleteLocalizationBehavior === 'copy') {
$deletedEntries->each->detachLocalizations();
} else {
$deletedEntries->each->deleteDescendants();
}
$deletedEntries->each->delete();
}
}