0 follower

Final Class Yiisoft\Rbac\Cycle\ItemsStorage

InheritanceYiisoft\Rbac\Cycle\ItemsStorage
ImplementsYiisoft\Rbac\ItemsStorageInterface

Warning: Do not use directly! Use with Manager instead.

Storage for RBAC items (roles and permissions) and their relations in the form of database tables. Operations are performed using Cycle ORM.

Psalm Types

Name Value
RawItem array{type: \Yiisoft\Rbac\Item::TYPE_*, name: string, description: string|null, rule_name: string|null, created_at: integer|string, updated_at: integer|string}
RawRole array{type: \Yiisoft\Rbac\Item::TYPE_ROLE, name: string, description: string|null, rule_name: string|null, created_at: integer|string, updated_at: integer|string}
RawPermission array{type: \Yiisoft\Rbac\Item::TYPE_PERMISSION, name: string, description: string|null, rule_name: string|null, created_at: integer|string, updated_at: integer|string}

Method Details

Hide inherited methods

__construct() public method

public __construct( \Cycle\Database\DatabaseInterface $database, string $tableName 'yii_rbac_item', string $childrenTableName 'yii_rbac_item_child', string $namesSeparator ',' ): mixed
$database \Cycle\Database\DatabaseInterface

Cycle database instance.

$tableName string

A name of the table for storing RBAC items.

$childrenTableName string

A name of the table for storing relations between RBAC items. When set to null, it will be automatically generated using $tableName.

$namesSeparator string

Separator used for joining and splitting item names.

                public function __construct(
    private readonly DatabaseInterface $database,
    private readonly string $tableName = 'yii_rbac_item',
    private readonly string $childrenTableName = 'yii_rbac_item_child',
    string $namesSeparator = ',',
) {
    $this->assertNamesSeparator($namesSeparator);
    $this->namesSeparator = $namesSeparator;
}

            
add() public method

public add( \Yiisoft\Rbac\Permission|\Yiisoft\Rbac\Role $item ): void
$item \Yiisoft\Rbac\Permission|\Yiisoft\Rbac\Role

                public function add(Permission|Role $item): void
{
    $this
        ->database
        ->insert($this->tableName)
        ->values($item->getAttributes())
        ->run();
}

            
addChild() public method

public addChild( string $parentName, string $childName ): void
$parentName string
$childName string

                public function addChild(string $parentName, string $childName): void
{
    $this
        ->database
        ->insert($this->childrenTableName)
        ->values(['parent' => $parentName, 'child' => $childName])
        ->run();
}

            
clear() public method

public clear( ): void

                public function clear(): void
{
    $itemsStorage = $this;
    $this
        ->database
        ->transaction(static function (Database $database) use ($itemsStorage): void {
            $database
                ->delete($itemsStorage->childrenTableName)
                ->run();
            $database
                ->delete($itemsStorage->tableName)
                ->run();
        });
}

            
clearPermissions() public method

public clearPermissions( ): void

                public function clearPermissions(): void
{
    $this->clearItemsByType(Item::TYPE_PERMISSION);
}

            
clearRoles() public method

public clearRoles( ): void

                public function clearRoles(): void
{
    $this->clearItemsByType(Item::TYPE_ROLE);
}

            
exists() public method

public exists( string $name ): boolean
$name string

                public function exists(string $name): bool
{
    /**
     * @psalm-var array<0, 1>|false $result
     * @infection-ignore-all
     * - ArrayItemRemoval, select.
     */
    $result = $this
        ->database
        ->select([new Fragment('1 AS item_exists')])
        ->from($this->tableName)
        ->where(['name' => $name])
        ->run()
        ->fetch();
    return $result !== false;
}

            
get() public method

public get( string $name ): \Yiisoft\Rbac\Permission|\Yiisoft\Rbac\Role|null
$name string

                public function get(string $name): Permission|Role|null
{
    /** @psalm-var RawItem|null $row */
    $row = $this
        ->database
        ->select()
        ->from($this->tableName)
        ->where(['name' => $name])
        ->run()
        ->fetch();
    return empty($row) ? null : $this->createItem($row);
}

            
getAll() public method

public getAll( ): array

                public function getAll(): array
{
    /** @psalm-var RawItem[] $rows */
    $rows = $this
        ->database
        ->select()
        ->from($this->tableName)
        ->fetchAll();
    return $this->getItemsIndexedByName($rows);
}

            
getAllChildPermissions() public method

public getAllChildPermissions( string|array $names ): array
$names string|array

                public function getAllChildPermissions(string|array $names): array
{
    if (is_array($names) && empty($names)) {
        return [];
    }
    $rawItems = $this->getTreeTraversal()->getChildPermissionRows($names);
    /** @psalm-var array<string, Permission> */
    return $this->getItemsIndexedByName($rawItems);
}

            
getAllChildRoles() public method

public getAllChildRoles( string|array $names ): array
$names string|array

                public function getAllChildRoles(string|array $names): array
{
    if (is_array($names) && empty($names)) {
        return [];
    }
    $rawItems = $this->getTreeTraversal()->getChildRoleRows($names);
    /** @psalm-var array<string, Role> */
    return $this->getItemsIndexedByName($rawItems);
}

            
getAllChildren() public method

public getAllChildren( string|array $names ): array
$names string|array

                public function getAllChildren(string|array $names): array
{
    if (is_array($names) && empty($names)) {
        return [];
    }
    $rawItems = $this->getTreeTraversal()->getChildrenRows($names);
    return $this->getItemsIndexedByName($rawItems);
}

            
getByNames() public method

public getByNames( array $names ): array
$names array

                public function getByNames(array $names): array
{
    if (empty($names)) {
        return [];
    }
    /** @psalm-var RawItem[] $rawItems */
    $rawItems = $this
        ->database
        ->select()
        ->from($this->tableName)
        ->where('name', 'IN', $names)
        ->fetchAll();
    return $this->getItemsIndexedByName($rawItems);
}

            
getDirectChildren() public method

public getDirectChildren( string $name ): array
$name string

                public function getDirectChildren(string $name): array
{
    /** @psalm-var RawItem[] $rawItems */
    $rawItems = $this
        ->database
        ->select($this->tableName . '.*')
        ->from($this->tableName)
        ->leftJoin($this->childrenTableName)
        ->on($this->childrenTableName . '.child', $this->tableName . '.name')
        ->where(['parent' => $name])
        ->fetchAll();
    return $this->getItemsIndexedByName($rawItems);
}

            
getHierarchy() public method

public getHierarchy( string $name ): array
$name string

                public function getHierarchy(string $name): array
{
    $tree = [];
    $childrenNamesMap = [];
    foreach ($this->getTreeTraversal()->getHierarchy($name) as $data) {
        $childrenNamesMap[$data['name']] = $data['children'] !== ''
            ? explode($this->namesSeparator, $data['children'])
            : [];
        unset($data['children']);
        $tree[$data['name']] = ['item' => $this->createItem($data)];
    }
    foreach ($tree as $index => $_item) {
        $children = [];
        foreach ($childrenNamesMap[$index] as $childrenName) {
            if (!isset($tree[$childrenName])) {
                throw new SeparatorCollisionException();
            }
            $children[$childrenName] = $tree[$childrenName]['item'];
        }
        $tree[$index]['children'] = $children;
    }
    return $tree;
}

            
getParents() public method

public getParents( string $name ): array
$name string

                public function getParents(string $name): array
{
    $rawItems = $this->getTreeTraversal()->getParentRows($name);
    return $this->getItemsIndexedByName($rawItems);
}

            
getPermission() public method

public getPermission( string $name ): \Yiisoft\Rbac\Permission|null
$name string

                public function getPermission(string $name): ?Permission
{
    return $this->getItemByTypeAndName(Item::TYPE_PERMISSION, $name);
}

            
getPermissions() public method

public getPermissions( ): array

                public function getPermissions(): array
{
    return $this->getItemsByType(Item::TYPE_PERMISSION);
}

            
getPermissionsByNames() public method

public getPermissionsByNames( array $names ): array
$names array

                public function getPermissionsByNames(array $names): array
{
    if (empty($names)) {
        return [];
    }
    /** @psalm-var RawPermission[] $rawItems */
    $rawItems = $this
        ->database
        ->select()
        ->from($this->tableName)
        ->where(['type' => Item::TYPE_PERMISSION])
        ->andWhere('name', 'IN', $names)
        ->fetchAll();
    /** @psalm-var array<string, Permission> */
    return $this->getItemsIndexedByName($rawItems);
}

            
getRole() public method

public getRole( string $name ): \Yiisoft\Rbac\Role|null
$name string

                public function getRole(string $name): ?Role
{
    return $this->getItemByTypeAndName(Item::TYPE_ROLE, $name);
}

            
getRoles() public method

public getRoles( ): array

                public function getRoles(): array
{
    return $this->getItemsByType(Item::TYPE_ROLE);
}

            
getRolesByNames() public method

public getRolesByNames( array $names ): array
$names array

                public function getRolesByNames(array $names): array
{
    if (empty($names)) {
        return [];
    }
    /** @psalm-var RawRole[] $rawItems */
    $rawItems = $this
        ->database
        ->select()
        ->from($this->tableName)
        ->where(['type' => Item::TYPE_ROLE])
        ->andWhere('name', 'IN', $names)
        ->fetchAll();
    /** @psalm-var array<string, Role> */
    return $this->getItemsIndexedByName($rawItems);
}

            
hasChild() public method

public hasChild( string $parentName, string $childName ): boolean
$parentName string
$childName string

                public function hasChild(string $parentName, string $childName): bool
{
    return $this->getTreeTraversal()->hasChild($parentName, $childName);
}

            
hasChildren() public method

public hasChildren( string $name ): boolean
$name string

                public function hasChildren(string $name): bool
{
    /**
     * @psalm-var array<0, 1>|false $result
     * @infection-ignore-all
     * - ArrayItemRemoval, select.
     */
    $result = $this
        ->database
        ->select([new Fragment('1 AS item_child_exists')])
        ->from($this->childrenTableName)
        ->where(['parent' => $name])
        ->run()
        ->fetch();
    return $result !== false;
}

            
hasDirectChild() public method

public hasDirectChild( string $parentName, string $childName ): boolean
$parentName string
$childName string

                public function hasDirectChild(string $parentName, string $childName): bool
{
    /**
     * @psalm-var array<0, 1>|false $result
     * @infection-ignore-all
     * - ArrayItemRemoval, select.
     */
    $result = $this
        ->database
        ->select([new Fragment('1 AS item_child_exists')])
        ->from($this->childrenTableName)
        ->where(['parent' => $parentName, 'child' => $childName])
        ->run()
        ->fetch();
    return $result !== false;
}

            
remove() public method

public remove( string $name ): void
$name string

                public function remove(string $name): void
{
    $itemsStorage = $this;
    $this
        ->database
        ->transaction(static function (Database $database) use ($itemsStorage, $name): void {
            $itemsStorage->removeRelatedItemsChildren($database, $name);
            $database
                ->delete($itemsStorage->tableName, ['name' => $name])
                ->run();
        });
}

            
removeChild() public method

public removeChild( string $parentName, string $childName ): void
$parentName string
$childName string

                public function removeChild(string $parentName, string $childName): void
{
    $this
        ->database
        ->delete($this->childrenTableName, ['parent' => $parentName, 'child' => $childName])
        ->run();
}

            
removeChildren() public method

public removeChildren( string $parentName ): void
$parentName string

                public function removeChildren(string $parentName): void
{
    $this
        ->database
        ->delete($this->childrenTableName, ['parent' => $parentName])
        ->run();
}

            
roleExists() public method

public roleExists( string $name ): boolean
$name string

                public function roleExists(string $name): bool
{
    /**
     * @psalm-var array<0, 1>|false $result
     * @infection-ignore-all
     * - ArrayItemRemoval, select.
     */
    $result = $this
        ->database
        ->select([new Fragment('1 AS role_exists')])
        ->from($this->tableName)
        ->where(['name' => $name, 'type' => Item::TYPE_ROLE])
        ->run()
        ->fetch();
    return $result !== false;
}

            
update() public method

public update( string $name, \Yiisoft\Rbac\Permission|\Yiisoft\Rbac\Role $item ): void
$name string
$item \Yiisoft\Rbac\Permission|\Yiisoft\Rbac\Role

                public function update(string $name, Permission|Role $item): void
{
    $itemsStorage = $this;
    $this
        ->database
        ->transaction(static function (Database $database) use ($itemsStorage, $name, $item): void {
            $itemsChildren = $database
                ->select()
                ->from($itemsStorage->childrenTableName)
                ->where(['parent' => $name])
                ->orWhere(['child' => $name])
                ->fetchAll();
            if ($itemsChildren !== []) {
                $itemsStorage->removeRelatedItemsChildren($database, $name);
            }
            $database
                ->update($itemsStorage->tableName, $item->getAttributes(), ['name' => $name])
                ->run();
            if ($itemsChildren !== []) {
                $itemsChildren = array_map(
                    static function (array $itemChild) use ($name, $item): array {
                        if ($itemChild['parent'] === $name) {
                            $itemChild['parent'] = $item->getName();
                        }
                        if ($itemChild['child'] === $name) {
                            $itemChild['child'] = $item->getName();
                        }
                        return [$itemChild['parent'], $itemChild['child']];
                    },
                    $itemsChildren,
                );
                $database
                    ->insert($itemsStorage->childrenTableName)
                    ->columns(['parent', 'child'])
                    ->values($itemsChildren)
                    ->run();
            }
        });
}