Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,21 @@
"url": "https://github.com/sponsors/yiisoft"
}
],
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
"ext-pdo": "*",
"php": "^8.1",
"yiisoft/db": "^1.2",
"yiisoft/db-migration": "^1.1",
"yiisoft/friendly-exception": "^1.1",
"yiisoft/rbac": "^2.0"
"yiisoft/rbac": "dev-item-type-yii2-compatibility"
},
"require-dev": {
"ext-pdo_sqlite": "*",
"ext-uopz": "*",
"maglnet/composer-require-checker": "^4.3",
"phpunit/phpunit": "^10.5.5",
"phpunit/phpunit": "10.5.5",
"rector/rector": "^1.0.0",
"roave/infection-static-analysis-plugin": "^1.25",
"slope-it/clock-mock": "0.4.0",
Expand Down
70 changes: 70 additions & 0 deletions migrations/M241008204900UpdateItemType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

use Yiisoft\Db\Migration\MigrationBuilder;
use Yiisoft\Db\Migration\TransactionalMigrationInterface;

final class M241008204900UpdateItemType implements TransactionalMigrationInterface
{
private const TABLE_PREFIX = 'yii_rbac_';
private const ITEMS_TABLE = self::TABLE_PREFIX . 'item';

public function up(MigrationBuilder $b): void
{
$b
->getDb()
->createCommand()
->update(table: self::ITEMS_TABLE, columns: ['type' => 1], condition: ['type' => 'role'])
->execute();
$b
->getDb()
->createCommand()
->update(table: self::ITEMS_TABLE, columns: ['type' => 2], condition: ['type' => 'permission'])
->execute();

if ($b->getDb()->getDriverName() !== 'sqlite') {
$b->alterColumn(self::ITEMS_TABLE, 'type', $b->smallInteger()->notNull());
} else {
$b->execute('PRAGMA foreign_keys=off;');
$b->dropIndex(self::ITEMS_TABLE, 'idx-' . self::ITEMS_TABLE . '-type');
$b->renameTable(self::ITEMS_TABLE, self::ITEMS_TABLE . '_old');
$b->createTable(
self::ITEMS_TABLE,
[
'name' => 'string(126) NOT NULL PRIMARY KEY',
'type' => 'smallint NOT NULL',
'description' => 'string(191)',
'rule_name' => 'string(64)',
'created_at' => 'integer NOT NULL',
'updated_at' => 'integer NOT NULL',
],
);
$b->createIndex(self::ITEMS_TABLE, 'idx-' . self::ITEMS_TABLE . '-type', 'type');
$newTableName = self::ITEMS_TABLE;
$oldTableName = self::ITEMS_TABLE . '_old';
$b->execute(
"INSERT INTO $newTableName (name, type, description, rule_name, created_at, updated_at)
SELECT name, type, description, rule_name, created_at, updated_at
FROM $oldTableName;"
);
$b->dropTable($oldTableName);
$b->execute('PRAGMA foreign_keys=on;');
}
}

// public function down(MigrationBuilder $b): void
// {
// $b->alterColumn(self::ITEMS_TABLE, 'type', $b->string(10)->notNull());
// $b
// ->getDb()
// ->createCommand()
// ->update(table: self::ITEMS_TABLE, columns: ['type' => 'permission'], condition: ['type' => 2])
// ->execute();
// $b
// ->getDb()
// ->createCommand()
// ->update(table: self::ITEMS_TABLE, columns: ['type' => 'role'], condition: ['type' => 1])
// ->execute();
// }
}
2 changes: 1 addition & 1 deletion migrations/items/M240118192500CreateItemsTables.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ private function createItemsTable(MigrationBuilder $b): void
self::ITEMS_TABLE,
[
'name' => 'string(126) NOT NULL PRIMARY KEY',
'type' => 'string(10) NOT NULL',
'type' => 'smallint NOT NULL',
'description' => 'string(191)',
'rule_name' => 'string(64)',
'created_at' => 'integer NOT NULL',
Expand Down
18 changes: 9 additions & 9 deletions src/ItemsStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -421,13 +421,13 @@ public function removeChildren(string $parentName): void
/**
* Gets either all existing roles or permissions, depending on a specified type.
*
* @param string $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @param int $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @psalm-param Item::TYPE_* $type
*
* @return array A list of roles / permissions.
* @psalm-return ($type is Item::TYPE_PERMISSION ? array<string, Permission> : array<string, Role>)
*/
private function getItemsByType(string $type): array
private function getItemsByType(int $type): array
{
/** @psalm-var RawPermission[] | RawRole[] $rawItems */
$rawItems = (new Query($this->database))
Expand All @@ -441,14 +441,14 @@ private function getItemsByType(string $type): array
/**
* Gets a single item by its type and name.
*
* @param string $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @param int $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 an 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
private function getItemByTypeAndName(int $type, string $name): Permission|Role|null
{
/**
* @psalm-var RawItem|null $row
Expand All @@ -473,7 +473,7 @@ private function getItemByTypeAndName(string $type, string $name): Permission|Ro
private function createItem(array $rawItem): Permission|Role
{
$item = $this
->createItemByTypeAndName($rawItem['type'], $rawItem['name'])
->createItemByTypeAndName((int) $rawItem['type'], $rawItem['name'])
->withCreatedAt((int) $rawItem['created_at'])
->withUpdatedAt((int) $rawItem['updated_at']);

Expand All @@ -491,13 +491,13 @@ private function createItem(array $rawItem): Permission|Role
/**
* A basic factory method for creating a single item with name only.
*
* @param string $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @param int $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 an initial type specified.
* @psalm-return ($type is Item::TYPE_PERMISSION ? Permission : Role)
*/
private function createItemByTypeAndName(string $type, string $name): Permission|Role
private function createItemByTypeAndName(int $type, string $name): Permission|Role
{
return $type === Item::TYPE_PERMISSION ? new Permission($name) : new Role($name);
}
Expand All @@ -519,10 +519,10 @@ private function removeRelatedItemsChildren(ConnectionInterface $database, strin
/**
* Removes all existing items of a specified type.
*
* @param string $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @param int $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @psalm-param Item::TYPE_* $type
*/
private function clearItemsByType(string $type): void
private function clearItemsByType(int $type): void
{
$itemsStorage = $this;
$this->database->transaction(static function (ConnectionInterface $database) use ($itemsStorage, $type): void {
Expand Down
4 changes: 2 additions & 2 deletions tests/Base/SchemaTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ private function checkItemsTable(): void

$this->assertArrayHasKey('type', $columns);
$type = $columns['type'];
$this->assertSame('string', $type->getType());
$this->assertSame(10, $type->getSize());
$this->assertSame('smallint', $type->getType());
$this->assertNull($type->getSize());
$this->assertFalse($type->isAllowNull());

$this->assertArrayHasKey('description', $columns);
Expand Down