Skip to content

Commit

Permalink
Add docs for ItemsStorage
Browse files Browse the repository at this point in the history
  • Loading branch information
arogachev committed Mar 9, 2023
1 parent d834072 commit afd01a9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 26 deletions.
82 changes: 57 additions & 25 deletions src/ItemsStorage.php
Expand Up @@ -5,7 +5,6 @@
namespace Yiisoft\Rbac\Cycle;

use Cycle\Database\DatabaseInterface;
use Cycle\Database\DatabaseProviderInterface;
use Cycle\Database\Injection\Expression;
use Cycle\Database\Injection\Fragment;
use Cycle\Database\Table;
Expand All @@ -15,6 +14,9 @@
use Yiisoft\Rbac\Role;

/**
* Storage for RBAC items (roles and permissions) and their relations in the form of database tables. Operations are
* performed using Cycle ORM.
*
* @psalm-type RawItem = array{
* type: Item::TYPE_*,
* name: string,
Expand All @@ -26,24 +28,24 @@
*/
final class ItemsStorage implements ItemsStorageInterface
{
private DatabaseInterface $database;
/**
* @psalm-var non-empty-string
* @psalm-var non-empty-string A name of the table for storing relations between RBAC items.
*/
private string $childrenTableName;

/**
* @param non-empty-string|null $childrenTableName
* @param string $tableName A name of the table for storing RBAC items.
* @psalm-param non-empty-string $tableName
* @param DatabaseInterface $database Cycle database instance.
* @param string|null $childrenTableName A name of the table for storing relations between RBAC items. When set to
* `null`, it will be automatically generated using {@see $tableName}.
* @psalm-param non-empty-string|null $childrenTableName
*/
public function __construct(
/**
* @psalm-var non-empty-string
*/
private string $tableName,
DatabaseProviderInterface $dbal,
?string $childrenTableName = null
private DatabaseInterface $database,
?string $childrenTableName = null,
) {
$this->database = $dbal->database();
$this->childrenTableName = $childrenTableName ?? $tableName . '_child';
}

Expand All @@ -62,7 +64,7 @@ public function getAll(): array
$rows = $this->database->select()->from($this->tableName)->fetchAll();

return array_map(
fn(array $row): Item => $this->createItem($row),
fn(array $row): Item => $this->createItem(...$row),
$rows
);
}
Expand All @@ -77,7 +79,7 @@ public function get(string $name): ?Item
->run()
->fetch();

return empty($row) ? null : $this->createItem($row);
return empty($row) ? null : $this->createItem(...$row);
}

public function exists(string $name): bool
Expand Down Expand Up @@ -173,7 +175,7 @@ public function getParents(string $name): array
return array_combine(
array_column($parentRows, 'name'),
array_map(
fn(array $row): Item => $this->createItem($row),
fn(array $row): Item => $this->createItem(...$row),
$parentRows
),
);
Expand All @@ -192,7 +194,7 @@ public function getChildren(string $name): array
return array_combine(
$keys,
array_map(
fn(array $row): Item => $this->createItem($row),
fn(array $row): Item => $this->createItem(...$row),
$childrenRows
)
);
Expand Down Expand Up @@ -241,8 +243,12 @@ public function removeChildren(string $parentName): void
}

/**
* Gets either all existing roles or permissions, depending on specified type.
*
* @param string $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @psalm-param Item::TYPE_* $type
* @psalm-return ($type is Item::TYPE_PERMISSION ? Permission[] : ($type is Item::TYPE_ROLE ? Role[] : Item[]))
* @return array A list of roles / permissions.
* @psalm-return ($type is Item::TYPE_PERMISSION ? Permission[] : Role[])
*/
private function getItemsByType(string $type): array
{
Expand All @@ -254,13 +260,18 @@ private function getItemsByType(string $type): array
->fetchAll();

return array_map(
fn(array $row): Item => $this->createItem($row),
$rows
fn(array $row): Item => $this->createItem(...$row),
$rows,
);
}

/**
* Gets single item by its type and name.
*
* @param string $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @psalm-param Item::TYPE_* $type
* @return Permission|Role|null Either role or permission, depending on initial type specified. `null` is returned
* when no item was found by given condition.
* @psalm-return ($type is Item::TYPE_PERMISSION ? Permission : Role)|null
*/
private function getItemByTypeAndName(string $type, string $name): Permission|Role|null
Expand All @@ -277,23 +288,44 @@ private function getItemByTypeAndName(string $type, string $name): Permission|Ro
->run()
->fetch();

return empty($row) ? null : $this->createItem($row);
return empty($row) ? null : $this->createItem(...$row);
}

/**
* @psalm-param RawItem $attributes
* A factory method for creating single item with all attributes filled.
*
* @param string $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @psalm-param Item::TYPE_* $type
* @param string $name Unique name.
* @param string|null $description Optional description.
* @param string|null $ruleName Optional associated rule name.
* @param int|string $createdAt UNIX timestamp for creation time.
* @param int|string $updatedAt UNIX timestamp for updating time.
* @return Permission|Role Either role or permission, depending on initial type specified.
* @psalm-return ($type is Item::TYPE_PERMISSION ? Permission : Role)
*/
private function createItem(array $attributes): Permission|Role
private function createItem(
string $type,
string $name,
string|null $description = null,
string|null $ruleName = null,
int|string $createdAt,
int|string $updatedAt,
): Permission|Role
{
return $this->createItemByTypeAndName($attributes['type'], $attributes['name'])
->withDescription($attributes['description'] ?? '')
->withRuleName($attributes['ruleName'] ?? null)
->withCreatedAt((int) $attributes['createdAt'])
->withUpdatedAt((int) $attributes['updatedAt']);
return $this->createItemByTypeAndName($type, $name)
->withDescription($description ?? '')
->withRuleName($ruleName ?? null)
->withCreatedAt((int) $createdAt)
->withUpdatedAt((int) $updatedAt);
}

/**
* A basic factory method for creating single item with name only.
*
* @param string $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @psalm-param Item::TYPE_* $type
* @return Permission|Role Either role or permission, depending on initial type specified.
* @psalm-return ($type is Item::TYPE_PERMISSION ? Permission : Role)
*/
private function createItemByTypeAndName(string $type, string $name): Permission|Role
Expand Down
2 changes: 1 addition & 1 deletion tests/ItemsStorageTest.php
Expand Up @@ -298,6 +298,6 @@ protected function populateDb(): void

private function getStorage(): ItemsStorage
{
return new ItemsStorage(self::ITEMS_TABLE, $this->getDbal());
return new ItemsStorage(self::ITEMS_TABLE, $this->getDbal()->database());
}
}

0 comments on commit afd01a9

Please sign in to comment.