Skip to content

Commit

Permalink
Sync with base package
Browse files Browse the repository at this point in the history
  • Loading branch information
arogachev committed Dec 6, 2023
1 parent cb61807 commit 6860c53
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 28 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
## 2.0.0 under development

- Chg #63: Raise PHP version to 8.0 (@arogachev)
- Enh #63: Improve perfomance (@arogachev)
- Enh #63: Improve performance (@arogachev)
- Enh #?: Implement `getByNames()` and `getAccessTree()` methods in `ItemsStorage` (@arogachev)
- Enh #?: Implement `filterUserItemNames()` method in `AssignmentsStorage` (@arogachev)
- Chg #?: Rename `$name` argument to `$names` and allow array type for it in `getAllChildren()`, `getAllChildRoles()`,
`getAllChildPermissions()` methods in `ItemsStorage` (@arogachev)

## 1.0.0 April 08, 2022

Expand Down
17 changes: 17 additions & 0 deletions src/AssignmentsStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,23 @@ public function userHasItem(string $userId, array $itemNames): bool
return false;
}

public function filterUserItemNames(string $userId, array $itemNames): array
{
$assignments = $this->getByUserId($userId);
if (empty($assignments)) {
return [];
}

$userItemNames = [];
foreach ($itemNames as $itemName) {
if (array_key_exists($itemName, $assignments)) {
$userItemNames[] = $itemName;
}
}

return $userItemNames;
}

public function add(Assignment $assignment): void
{
$this->assignments[$assignment->getUserId()][$assignment->getItemName()] = $assignment;
Expand Down
101 changes: 74 additions & 27 deletions src/ItemsStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* system).
*
* @psalm-import-type ItemsIndexedByName from ItemsStorageInterface
* @psalm-import-type AccessTree from ItemsStorageInterface
*/
final class ItemsStorage extends CommonStorage implements ItemsStorageInterface
{
Expand Down Expand Up @@ -51,15 +52,16 @@ public function __construct(string $directory, string $itemFile = 'items.php')
$this->load();
}

/**
* @return Item[]
* @psalm-return array<string, Item>
*/
public function getAll(): array
{
return $this->items;
}

public function getByNames(array $names): array
{
return array_filter($this->getAll(), static fn (Item $item): bool => in_array($item->getName(), $names));
}

public function get(string $name): Permission|Role|null
{
return $this->items[$name] ?? null;
Expand Down Expand Up @@ -129,31 +131,39 @@ public function getParents(string $name): array
return $result;
}

public function getAccessTree(string $name): array
{
$result = [$name => ['item' => $this->items[$name], 'children' => []]];
$this->fillAccessTreeRecursive($name, $result);

Check failure on line 137 in src/ItemsStorage.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.0-ubuntu-latest

ArgumentTypeCoercion

src/ItemsStorage.php:137:47: ArgumentTypeCoercion: Argument 2 of Yiisoft\Rbac\Php\ItemsStorage::fillAccessTreeRecursive expects non-empty-array<non-empty-string, array{children: array<non-empty-string, Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}>, but parent type non-empty-array<string, array{children: array<empty, empty>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}> provided (see https://psalm.dev/193)

Check failure on line 137 in src/ItemsStorage.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

ArgumentTypeCoercion

src/ItemsStorage.php:137:47: ArgumentTypeCoercion: Argument 2 of Yiisoft\Rbac\Php\ItemsStorage::fillAccessTreeRecursive expects non-empty-array<non-empty-string, array{children: array<non-empty-string, Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}>, but parent type non-empty-array<string, array{children: array<empty, empty>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}> provided (see https://psalm.dev/193)

Check failure on line 137 in src/ItemsStorage.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

ArgumentTypeCoercion

src/ItemsStorage.php:137:47: ArgumentTypeCoercion: Argument 2 of Yiisoft\Rbac\Php\ItemsStorage::fillAccessTreeRecursive expects non-empty-array<non-empty-string, array{children: array<non-empty-string, Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}>, but parent type non-empty-array<string, array{children: array<empty, empty>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}> provided (see https://psalm.dev/193)

return $result;
}

public function getDirectChildren(string $name): array
{
return $this->children[$name] ?? [];
}

public function getAllChildren(string $name): array
public function getAllChildren(string|array $names): array
{
$result = [];
$this->fillChildrenRecursive($name, $result);
$this->getAllChildrenInternal($names, $result);

return $result;
}

public function getAllChildRoles(string $name): array
public function getAllChildRoles(string|array $names): array
{
$result = [];
$this->fillChildrenRecursive($name, $result);
$this->getAllChildrenInternal($names, $result);

return $this->filterRoles($result);
}

public function getAllChildPermissions(string $name): array
public function getAllChildPermissions(string|array $names): array
{
$result = [];
$this->fillChildrenRecursive($name, $result);
$this->getAllChildrenInternal($names, $result);

return $this->filterPermissions($result);
}
Expand Down Expand Up @@ -425,8 +435,52 @@ private function fillParentsRecursive(string $name, array &$result): void
}

/**
* @psalm-param array<string, Item> $result
* @psalm-param-out array<string, Item> $result
* @psalm-param AccessTree $result
* @psalm-param-out non-empty-array<non-empty-string, array{
* item: Permission|Role,
* children: array<non-empty-string, Permission|Role>
* }> $result
*/
private function fillAccessTreeRecursive(string $name, array &$result, array $addedChildItems = []): void
{
foreach ($this->children as $parentName => $childItems) {
foreach ($childItems as $childItem) {
if ($childItem->getName() !== $name) {
continue;
}

$parent = $this->get($parentName);
if ($parent !== null) {
$result[$parentName]['item'] = $this->items[$parentName];

$addedChildItems[$childItem->getName()] = $childItem;
$result[$parentName]['children'] = $addedChildItems;
}

$this->fillAccessTreeRecursive($parentName, $result, $addedChildItems);

Check failure on line 460 in src/ItemsStorage.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.0-ubuntu-latest

ArgumentTypeCoercion

src/ItemsStorage.php:460:61: ArgumentTypeCoercion: Argument 2 of Yiisoft\Rbac\Php\ItemsStorage::fillAccessTreeRecursive expects non-empty-array<non-empty-string, array{children: array<non-empty-string, Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}>, but parent type non-empty-array<string, array{children: array<array-key, Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role|mixed>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}> provided (see https://psalm.dev/193)

Check failure on line 460 in src/ItemsStorage.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

ArgumentTypeCoercion

src/ItemsStorage.php:460:61: ArgumentTypeCoercion: Argument 2 of Yiisoft\Rbac\Php\ItemsStorage::fillAccessTreeRecursive expects non-empty-array<non-empty-string, array{children: array<non-empty-string, Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}>, but parent type non-empty-array<string, array{children: array<array-key, Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role|mixed>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}> provided (see https://psalm.dev/193)

Check failure on line 460 in src/ItemsStorage.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

ArgumentTypeCoercion

src/ItemsStorage.php:460:61: ArgumentTypeCoercion: Argument 2 of Yiisoft\Rbac\Php\ItemsStorage::fillAccessTreeRecursive expects non-empty-array<non-empty-string, array{children: array<non-empty-string, Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}>, but parent type non-empty-array<string, array{children: array<array-key, Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role|mixed>, item: Yiisoft\Rbac\Permission|Yiisoft\Rbac\Role}> provided (see https://psalm.dev/193)

break;
}
}
}

/**
* @param string|string[] $names
*
* @psalm-param ItemsIndexedByName $result
* @psalm-param-out ItemsIndexedByName $result
*/
private function getAllChildrenInternal(string|array $names, array &$result): void
{
$names = (array) $names;
foreach ($names as $name) {
$this->fillChildrenRecursive($name, $result);
}
}

/**
* @psalm-param ItemsIndexedByName $result
* @psalm-param-out array<string, Permission|Role> $result
*/
private function fillChildrenRecursive(string $name, array &$result): void
{
Expand All @@ -442,37 +496,30 @@ private function fillChildrenRecursive(string $name, array &$result): void
}

/**
* @param Item[] $array
* @psalm-param array<string, Item> $array
* @psalm-param ItemsIndexedByName $items
*
* @return Role[]
* @psalm-return array<string, Role>
*/
private function filterRoles(array $array): array
private function filterRoles(array $items): array
{
return array_filter(
$this->getRoles(),
static fn (Role $roleItem): bool => array_key_exists($roleItem->getName(), $array),
static fn (Permission|Role $item): bool => array_key_exists($item->getName(), $items),
);
}

/**
* @param Item[] $items
* @psalm-param array<string, Item> $items
* @psalm-param ItemsIndexedByName $items
*
* @return Permission[]
* @psalm-return array<string, Permission>
*/
private function filterPermissions(array $items): array
{
$permissions = [];
foreach (array_keys($items) as $permissionName) {
$permission = $this->getPermission($permissionName);
if ($permission !== null) {
$permissions[$permissionName] = $permission;
}
}

return $permissions;
return array_filter(
$this->getPermissions(),
static fn (Permission|Role $permissionItem): bool => array_key_exists($permissionItem->getName(), $items),
);
}
}

0 comments on commit 6860c53

Please sign in to comment.