Drupal investigation

m170719_192953_create_rbac_tables.php 6.3KB

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