Files
BookStack/app/View/ViewBlockPreferences.php
T

97 lines
3.0 KiB
PHP

<?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);
}
}