-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Expand file tree
/
Copy pathViewBlockPreferences.php
More file actions
96 lines (82 loc) · 3.01 KB
/
Copy pathViewBlockPreferences.php
File metadata and controls
96 lines (82 loc) · 3.01 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
<?php
namespace BookStack\View;
use Illuminate\Contracts\Container\BindingResolutionException;
class ViewBlockPreferences
{
/**
* From the request data of the layout editor, validate the request data to ensure the blocks
* and locations are valid and then store the layout data.
* The request data is expected to be in the format of:
* [
* 'position-1' => ['block-id-1', 'block-id-2'],
* 'position-2' => ['block-id-3'],
* ]
* @param array<string, string[]> $layoutData
* @param array<string, class-string<ViewBlockInterface>[]> $validBlocksByPosition
* @throws BindingResolutionException
*/
public function storeByIdPositionMap(
string $location,
array $layoutData,
array $validBlocksByPosition,
): void {
$validIds = $this->extractValidBlockIds($validBlocksByPosition);
$validPositions = array_keys($validBlocksByPosition);
$validPositions[] = 'unused';
// Ignore updates for invalid/unknown locations
if (empty($validBlocksByPosition)) {
return;
}
/** @var array<string, string[]> $validatedLayoutData */
$validatedLayoutData = [];
foreach ($layoutData as $position => $blockIds) {
// @phpstan-ignore-next-line
if (!in_array($position, $validPositions) || !is_array($blockIds)) {
continue;
}
$validatedLayoutData[$position] = array_filter($blockIds, function ($id) use ($validIds) {
// @phpstan-ignore function.alreadyNarrowedType
return is_string($id) && in_array($id, $validIds);
});
}
$settingKey = $this->getSettingKey($location);
setting()->putForCurrentUser($settingKey, json_encode($validatedLayoutData));
}
/**
* Clear the view block preferences for a given location for the current user.
*/
public function clearForLocation(string $location): void
{
$settingKey = $this->getSettingKey($location);
setting()->removeForCurrentUser($settingKey);
}
/**
* Get the layout data for a given location.
* Provides arrays of block ids keyed by position.
* @return array<string, string[]>
*/
public function getIdByPositionMap(string $location): array
{
$settingKey = $this->getSettingKey($location);
$layoutData = setting()->getForCurrentUser($settingKey, '{}');
return json_decode($layoutData, true) ?? [];
}
protected function getSettingKey(string $location): string
{
return 'view-layout#' . $location;
}
/**
* @param array<string, class-string<ViewBlockInterface>[]> $blocksByPosition
* @return string[]
*/
protected function extractValidBlockIds(array $blocksByPosition): array
{
$ids = [];
foreach ($blocksByPosition as $blocks) {
foreach ($blocks as $block) {
$ids[] = $block::getId();
}
}
return array_unique($ids);
}
}