Completed
Push — 2.1 ( c952e8...98ed49 )
by Carsten
10:00
created

m140506_102106_rbac_init   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 5
dl 0
loc 133
rs 10
c 0
b 0
f 0
ccs 0
cts 69
cp 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getAuthManager() 0 8 2
A isMSSQL() 0 4 3
B up() 0 88 6
A down() 0 14 2
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
use yii\base\InvalidConfigException;
9
use yii\rbac\DbManager;
10
11
/**
12
 * Initializes RBAC tables
13
 *
14
 * @author Alexander Kochetov <[email protected]>
15
 * @since 2.0
16
 */
17
class m140506_102106_rbac_init extends \yii\db\Migration
18
{
19
    /**
20
     * @throws yii\base\InvalidConfigException
21
     * @return DbManager
22
     */
23
    protected function getAuthManager()
24
    {
25
        $authManager = Yii::$app->getAuthManager();
26
        if (!$authManager instanceof DbManager) {
27
            throw new InvalidConfigException('You should configure "authManager" component to use database before executing this migration.');
28
        }
29
        return $authManager;
30
    }
31
32
    /**
33
     * @return bool
34
     */
35
    protected function isMSSQL()
36
    {
37
        return $this->db->driverName === 'mssql' || $this->db->driverName === 'sqlsrv' || $this->db->driverName === 'dblib';
38
    }
39
40
    /**
41
     * @inheritdoc
42
     */
43
    public function up()
44
    {
45
        $authManager = $this->getAuthManager();
46
        $this->db = $authManager->db;
47
48
        $tableOptions = null;
49
        if ($this->db->driverName === 'mysql') {
50
            // http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
51
            $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
52
        }
53
54
        $this->createTable($authManager->ruleTable, [
55
            'name' => $this->string(64)->notNull(),
56
            'data' => $this->text(),
57
            'created_at' => $this->integer(),
58
            'updated_at' => $this->integer(),
59
            'PRIMARY KEY (name)',
60
        ], $tableOptions);
61
62
        $this->createTable($authManager->itemTable, [
63
            'name' => $this->string(64)->notNull(),
64
            'type' => $this->integer()->notNull(),
65
            'description' => $this->text(),
66
            'rule_name' => $this->string(64),
67
            'data' => $this->text(),
68
            'created_at' => $this->integer(),
69
            'updated_at' => $this->integer(),
70
            'PRIMARY KEY (name)',
71
            'FOREIGN KEY (rule_name) REFERENCES ' . $authManager->ruleTable . ' (name)'.
72
                ($this->isMSSQL() ? '' : ' ON DELETE SET NULL ON UPDATE CASCADE'),
73
        ], $tableOptions);
74
        $this->createIndex('idx-auth_item-type', $authManager->itemTable, 'type');
75
76
        $this->createTable($authManager->itemChildTable, [
77
            'parent' => $this->string(64)->notNull(),
78
            'child' => $this->string(64)->notNull(),
79
            'PRIMARY KEY (parent, child)',
80
            'FOREIGN KEY (parent) REFERENCES ' . $authManager->itemTable . ' (name)'.
81
                ($this->isMSSQL() ? '' : ' ON DELETE CASCADE ON UPDATE CASCADE'),
82
            'FOREIGN KEY (child) REFERENCES ' . $authManager->itemTable . ' (name)'.
83
                ($this->isMSSQL() ? '' : ' ON DELETE CASCADE ON UPDATE CASCADE'),
84
        ], $tableOptions);
85
86
        $this->createTable($authManager->assignmentTable, [
87
            'item_name' => $this->string(64)->notNull(),
88
            'user_id' => $this->string(64)->notNull(),
89
            'created_at' => $this->integer(),
90
            'PRIMARY KEY (item_name, user_id)',
91
            'FOREIGN KEY (item_name) REFERENCES ' . $authManager->itemTable . ' (name) ON DELETE CASCADE ON UPDATE CASCADE',
92
        ], $tableOptions);
93
94
        if ($this->isMSSQL()) {
95
            $this->execute("CREATE TRIGGER dbo.trigger_auth_item_child
96
            ON dbo.{$authManager->itemTable}
97
            INSTEAD OF DELETE, UPDATE
98
            AS
99
            DECLARE @old_name VARCHAR (64) = (SELECT name FROM deleted)
100
            DECLARE @new_name VARCHAR (64) = (SELECT name FROM inserted)
101
            BEGIN
102
            IF COLUMNS_UPDATED() > 0
103
                BEGIN
104
                    IF @old_name <> @new_name
105
                    BEGIN
106
                        ALTER TABLE auth_item_child NOCHECK CONSTRAINT FK__auth_item__child;
107
                        UPDATE auth_item_child SET child = @new_name WHERE child = @old_name;
108
                    END
109
                UPDATE auth_item
110
                SET name = (SELECT name FROM inserted),
111
                type = (SELECT type FROM inserted),
112
                description = (SELECT description FROM inserted),
113
                rule_name = (SELECT rule_name FROM inserted),
114
                data = (SELECT data FROM inserted),
115
                created_at = (SELECT created_at FROM inserted),
116
                updated_at = (SELECT updated_at FROM inserted)
117
                WHERE name IN (SELECT name FROM deleted)
118
                IF @old_name <> @new_name
119
                    BEGIN
120
                        ALTER TABLE auth_item_child CHECK CONSTRAINT FK__auth_item__child;
121
                    END
122
                END
123
                ELSE
124
                    BEGIN
125
                        DELETE FROM dbo.{$authManager->itemChildTable} WHERE parent IN (SELECT name FROM deleted) OR child IN (SELECT name FROM deleted);
126
                        DELETE FROM dbo.{$authManager->itemTable} WHERE name IN (SELECT name FROM deleted);
127
                    END
128
            END;");
129
        }
130
    }
131
132
    /**
133
     * @inheritdoc
134
     */
135
    public function down()
136
    {
137
        $authManager = $this->getAuthManager();
138
        $this->db = $authManager->db;
139
140
        if ($this->isMSSQL()) {
141
            $this->execute('DROP dbo.trigger_auth_item_child;');
142
        }
143
144
        $this->dropTable($authManager->assignmentTable);
145
        $this->dropTable($authManager->itemChildTable);
146
        $this->dropTable($authManager->itemTable);
147
        $this->dropTable($authManager->ruleTable);
148
    }
149
}