0 follower

Final Class Yiisoft\Rbac\Cycle\ItemTreeTraversal\SqlServerCteItemTreeTraversal

InheritanceYiisoft\Rbac\Cycle\ItemTreeTraversal\SqlServerCteItemTreeTraversal » Yiisoft\Rbac\Cycle\ItemTreeTraversal\CteItemTreeTraversal
ImplementsYiisoft\Rbac\Cycle\ItemTreeTraversal\ItemTreeTraversalInterface

An RBAC item tree traversal strategy based on CTE (common table expression) for SQL Server.

Method Details

Hide inherited methods

__construct() public method
public mixed __construct ( \Cycle\Database\DatabaseInterface $database, string $tableName, string $childrenTableName, 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.

$namesSeparator string

Separator used for joining item names.

                public function __construct(
    protected DatabaseInterface $database,
    protected string $tableName,
    protected string $childrenTableName,
    protected string $namesSeparator,
) {
}

            
getChildPermissionRows() public method
public array getChildPermissionRows ( string|array $names )
$names string|array

                public function getChildPermissionRows(string|array $names): array
{
    $baseOuterQuery = $this->getChildrenBaseOuterQuery($names)->andWhere(['item.type' => Item::TYPE_PERMISSION]);
    /** @psalm-var RawItem[] */
    return $this->getRowsStatement($names, baseOuterQuery: $baseOuterQuery, areParents: false)->fetchAll();
}

            
getChildRoleRows() public method
public array getChildRoleRows ( string|array $names )
$names string|array

                public function getChildRoleRows(string|array $names): array
{
    $baseOuterQuery = $this->getChildrenBaseOuterQuery($names)->andWhere(['item.type' => Item::TYPE_ROLE]);
    /** @psalm-var RawItem[] */
    return $this->getRowsStatement($names, baseOuterQuery: $baseOuterQuery, areParents: false)->fetchAll();
}

            
getChildrenRows() public method
public array getChildrenRows ( string|array $names )
$names string|array

                public function getChildrenRows(string|array $names): array
{
    $baseOuterQuery = $this->getChildrenBaseOuterQuery($names);
    /** @psalm-var RawItem[] */
    return $this->getRowsStatement($names, baseOuterQuery: $baseOuterQuery, areParents: false)->fetchAll();
}

            
getEmptyChildrenExpression() protected method

protected string getEmptyChildrenExpression ( )

                protected function getEmptyChildrenExpression(): string
{
    return "CAST('' AS NVARCHAR(MAX))";
}

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

                public function getHierarchy(string $name): array
{
    $baseOuterQuery = $this->database->select(['item.*', 'parent_of.children']);
    $cteSelectItemQuery = $this
        ->database
        ->select(['name', new Fragment($this->getEmptyChildrenExpression())])
        ->from($this->tableName)
        ->where(['name' => $name]);
    $cteSelectRelationQuery = $this
        ->database
        ->select(['parent', new Fragment($this->getTrimConcatChildrenExpression())])
        ->from("$this->childrenTableName AS item_child_recursive")
        ->innerJoin('parent_of')
        ->on('item_child_recursive.child', 'parent_of.child_name');
    $outerQuery = $baseOuterQuery
        ->from('parent_of')
        ->leftJoin($this->tableName, 'item')
        ->on('item.name', 'parent_of.child_name');
    $sql = "{$this->getWithExpression()} parent_of(child_name, children) AS (
        $cteSelectItemQuery
        UNION ALL
        $cteSelectRelationQuery
    )
    $outerQuery";
    /** @psalm-var Hierarchy */
    return $this->database->query($sql)->fetchAll();
}

            
getParentRows() public method
public array getParentRows ( string $name )
$name string

                public function getParentRows(string $name): array
{
    $baseOuterQuery = $this->database->select('item.*')->where('item.name', '!=', $name);
    /** @psalm-var RawItem[] */
    return $this->getRowsStatement($name, baseOuterQuery: $baseOuterQuery)->fetchAll();
}

            
getTrimConcatChildrenExpression() protected method
protected string getTrimConcatChildrenExpression ( )

                protected function getTrimConcatChildrenExpression(): string
{
    return "TRIM('$this->namesSeparator' FROM CONCAT(children, '$this->namesSeparator', " .
        'item_child_recursive.child))';
}

            
getWithExpression() protected method

protected string getWithExpression ( )

                protected function getWithExpression(): string
{
    return 'WITH';
}

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

                public function hasChild(string $parentName, string $childName): bool
{
    /**
     * @infection-ignore-all
     * - ArrayItemRemoval, select.
     */
    $baseOuterQuery = $this
        ->database
        ->select([new Fragment('1 AS item_child_exists')])
        ->andWhere(['item.name' => $childName]);
    /** @psalm-var array<0, 1>|false $result */
    $result = $this->getRowsStatement($parentName, baseOuterQuery: $baseOuterQuery, areParents: false)->fetch();
    return $result !== false;
}