0 follower

Final Class Yiisoft\Rbac\Cycle\ItemsStorage

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

Warning: Do not use directly! Use with {@see 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 mixed __construct ( \Cycle\Database\DatabaseInterface $database, string $tableName 'yii_rbac_item', string $childrenTableName 'yii_rbac_item_child', string $namesSeparator ',' )
$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 {@see $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 void add ( \Yiisoft\Rbac\Permission|\Yiisoft\Rbac\Role $item )
$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 void addChild ( string $parentName, string $childName )
$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 void clear ( )

                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 void clearPermissions ( )

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

            
clearRoles() public method

public void clearRoles ( )

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

            
exists() public method

public boolean exists ( string $name )
$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 \Yiisoft\Rbac\Permission|\Yiisoft\Rbac\Role|null get ( string $name )
$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 array getAll ( )

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

            
getAllChildPermissions() public method

public array getAllChildPermissions ( string|array $names )
$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 array getAllChildRoles ( string|array $names )
$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 array getAllChildren ( string|array $names )
$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 array getByNames ( array $names )
$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 array getDirectChildren ( string $name )
$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 array getHierarchy ( string $name )
$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 array getParents ( string $name )
$name string

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

            
getPermission() public method

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

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

            
getPermissions() public method

public array getPermissions ( )

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

            
getPermissionsByNames() public method

public array getPermissionsByNames ( array $names )
$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 \Yiisoft\Rbac\Role|null getRole ( string $name )
$name string

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

            
getRoles() public method

public array getRoles ( )

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

            
getRolesByNames() public method

public array getRolesByNames ( array $names )
$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 boolean hasChild ( string $parentName, string $childName )
$parentName string
$childName string

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

            
hasChildren() public method

public boolean hasChildren ( string $name )
$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 boolean hasDirectChild ( string $parentName, string $childName )
$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 void remove ( string $name )
$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 void removeChild ( string $parentName, string $childName )
$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 void removeChildren ( string $parentName )
$parentName string

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

            
roleExists() public method

public boolean roleExists ( string $name )
$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 void update ( string $name, \Yiisoft\Rbac\Permission|\Yiisoft\Rbac\Role $item )
$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();
            }
        });
}