['block-id-1', 'block-id-2'], * 'position-2' => ['block-id-3'], * ] * @param array $layoutData * @param array[]> $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 $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 */ 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[]> $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); } }