0 follower

Final Class Yiisoft\Rbac\Db\ItemsStorage

InheritanceYiisoft\Rbac\Db\ItemsStorage
ImplementsYiisoft\Rbac\ItemsStorageInterface

Warning: Do not use directly! Use with Manager from https://github.com/yiisoft/rbac package.

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

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( \Yiisoft\Db\Connection\ConnectionInterface $database, string $tableName 'yii_rbac_item', string $childrenTableName 'yii_rbac_item_child', string $namesSeparator ',' ): mixed
$database \Yiisoft\Db\Connection\ConnectionInterface

Yii database connection 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 ConnectionInterface $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\Item $item ): void
$item \Yiisoft\Rbac\Item

                public function add(Item $item): void
{
    $this
        ->database
        ->createCommand()
        ->insert(
            $this->tableName,
            $item->getAttributes(),
        )
        ->execute();
}

            
addChild() public method

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

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

            
clear() public method

public clear( ): void

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

            
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
{
    return (new Query($this->database))
        ->from($this->tableName)
        ->where(['name' => $name])
        ->exists();
}

            
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 = (new Query($this->database))
        ->from($this->tableName)
        ->where(['name' => $name])
        ->one();
    return $row === null ? null : $this->createItem($row);
}

            
getAll() public method

public getAll( ): array

                public function getAll(): array
{
    /** @psalm-var RawItem[] $rows */
    $rows = (new Query($this->database))
        ->from($this->tableName)
        ->all();
    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)) {
        /** @infection-ignore-all  */
        return [];
    }
    /** @psalm-var RawItem[] $rawItems */
    $rawItems = (new Query($this->database))
        ->from($this->tableName)
        ->where(['name' => $names])
        ->all();
    return $this->getItemsIndexedByName($rawItems);
}

            
getDirectChildren() public method

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

                public function getDirectChildren(string $name): array
{
    $quoter = $this->database->getQuoter();
    $quotedJoinColumn = $quoter->quoteTableName($this->tableName) . '.' . $quoter->quoteColumnName('name');
    /** @psalm-var RawItem[] $rawItems */
    $rawItems = (new Query($this->database))
        ->select($this->tableName . '.*')
        ->from($this->tableName)
        ->leftJoin(
            $this->childrenTableName,
            [$this->childrenTableName . '.child' => new Expression($quotedJoinColumn)],
        )
        ->where(['parent' => $name])
        ->all();
    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'] !== '' && $data['children'] !== null
            ? 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)) {
        /** @infection-ignore-all  */
        return [];
    }
    /** @psalm-var RawPermission[] $rawItems */
    $rawItems = (new Query($this->database))
        ->from($this->tableName)
        ->where(['type' => Item::TYPE_PERMISSION, 'name' => $names])
        ->all();
    /** @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)) {
        /** @infection-ignore-all  */
        return [];
    }
    /** @psalm-var RawRole[] $rawItems */
    $rawItems = (new Query($this->database))
        ->from($this->tableName)
        ->where(['type' => Item::TYPE_ROLE, 'name' => $names])
        ->all();
    /** @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
{
    return (new Query($this->database))
        ->from($this->childrenTableName)
        ->where(['parent' => $name])
        ->exists();
}

            
hasDirectChild() public method

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

                public function hasDirectChild(string $parentName, string $childName): bool
{
    return (new Query($this->database))
        ->from($this->childrenTableName)
        ->where(['parent' => $parentName, 'child' => $childName])
        ->exists();
}

            
remove() public method

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

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

            
removeChild() public method

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

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

            
removeChildren() public method

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

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

            
roleExists() public method

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

                public function roleExists(string $name): bool
{
    return (new Query($this->database))
        ->from($this->tableName)
        ->where(['name' => $name, 'type' => Item::TYPE_ROLE])
        ->exists();
}

            
update() public method

public update( string $name, \Yiisoft\Rbac\Item $item ): void
$name string
$item \Yiisoft\Rbac\Item

                public function update(string $name, Item $item): void
{
    $itemsStorage = $this;
    $this
        ->database
        ->transaction(static function (ConnectionInterface $database) use ($itemsStorage, $name, $item): void {
            /**
             * @var array[] $itemsChildren We assume that arrays are returned here, not objects.
             */
            $itemsChildren = (new Query($database))
                ->from($itemsStorage->childrenTableName)
                ->where(['parent' => $name])
                ->orWhere(['child' => $name])
                ->all();
            if ($itemsChildren !== []) {
                $itemsStorage->removeRelatedItemsChildren($database, $name);
            }
            $database
                ->createCommand()
                ->update($itemsStorage->tableName, $item->getAttributes(), ['name' => $name])
                ->execute();
            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
                    ->createCommand()
                    ->insertBatch($itemsStorage->childrenTableName, $itemsChildren, ['parent', 'child'])
                    ->execute();
            }
        });
}