From c2e68a5ddbc3bad194ddfea2bff46f91443b860e Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Wed, 1 Jan 2014 12:01:02 +0100 Subject: [PATCH] Issue #2150407 by chx, bdone, eliza411, andypost: Migrate D6 roles and permissions. --- .../Plugin/migrate/destination/Entity.php | 84 ++++++++++ .../config/migrate.migration.d6_user_role.yml | 55 +++++++ .../migrate/process/d6/NodeUpdate7008.php | 34 +++++ .../migrate/process/d6/SystemUpdate7000.php | 43 ++++++ .../Plugin/migrate/source/d6/Role.php | 62 ++++++++ .../Tests/Dump/Drupal6UserRole.php | 123 +++++++++++++++ .../Tests/d6/MigrateUserRoleTest.php | 65 ++++++++ .../Tests/source/d6/RoleSourceTest.php | 144 ++++++++++++++++++ 8 files changed, 610 insertions(+) create mode 100644 core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/Entity.php create mode 100644 core/modules/migrate_drupal/config/migrate.migration.d6_user_role.yml create mode 100644 core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/process/d6/NodeUpdate7008.php create mode 100644 core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/process/d6/SystemUpdate7000.php create mode 100644 core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/source/d6/Role.php create mode 100644 core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UserRole.php create mode 100644 core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateUserRoleTest.php create mode 100644 core/modules/migrate_drupal/tests/Drupal/migrate_drupal/Tests/source/d6/RoleSourceTest.php diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/Entity.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/Entity.php new file mode 100644 index 00000000000..97e4121a223 --- /dev/null +++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/Entity.php @@ -0,0 +1,84 @@ +storageController = $storage_controller; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity.manager')->getStorageController($configuration['entity_type']) + ); + } + + /** + * {@inheritdoc} + */ + public function import(Row $row) { + // @TODO: add field handling. https://drupal.org/node/2164451 + // @TODO: add validation https://drupal.org/node/2164457 + $entity = $this->storageController->create($row->getDestination()); + $entity->save(); + return array($entity->id()); + } + + /** + * {@inheritdoc} + */ + public function getIdsSchema() { + // TODO: Implement getIdsSchema() method. + } + + /** + * {@inheritdoc} + */ + public function fields(Migration $migration = NULL) { + // TODO: Implement fields() method. + } + +} diff --git a/core/modules/migrate_drupal/config/migrate.migration.d6_user_role.yml b/core/modules/migrate_drupal/config/migrate.migration.d6_user_role.yml new file mode 100644 index 00000000000..3ee73348877 --- /dev/null +++ b/core/modules/migrate_drupal/config/migrate.migration.d6_user_role.yml @@ -0,0 +1,55 @@ +id: d6_user_role +sourceIds: + rid: + type: int + "not null": true + default: 0 +destinationIds: + id: + type: varchar + length: 255 +source: + plugin: drupal6_user_role +process: + id: + - + plugin: machine_name + source: name + - + plugin: dedupe_entity + entity_type: user_role + field: id + label: name +# permissions start as array(array('perm' => array('perm1', 'perm2'))), array('perm' => array('perm3', 'perm4'))) + permissions: + # extract gets array('perm' => array('perm1', 'perm2')) first + - + plugin: extract + source: permissions + index: + - perm + # the pipeline is now array(array('perm1', 'perm2')) + - plugin: flatten + # the pipeline is now array('perm1', 'perm2') + - + plugin: static_map + bypass: true + map: + 'use PHP for block visibility': 'use PHP for settings' + 'administer site-wide contact form': 'administer contact forms' + 'post comments without approval': 'skip comment approval' + 'edit own blog entries' : 'edit own blog content' + 'edit any blog entry' : 'edit any blog content' + 'delete own blog entries' : 'delete own blog content' + 'delete any blog entry' : 'delete any blog content' + 'create forum topics' : 'create forum content' + 'delete any forum topic' : 'delete any forum content' + 'delete own forum topics' : 'delete own forum content' + 'edit any forum topic' : 'edit any forum content' + 'edit own forum topics' : 'edit own forum content' + - plugin: system_update_7000 + - plugin: node_update_7008 + - plugin: flatten +destination: + plugin: entity + entity_type: user_role diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/process/d6/NodeUpdate7008.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/process/d6/NodeUpdate7008.php new file mode 100644 index 00000000000..06014c496f6 --- /dev/null +++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/process/d6/NodeUpdate7008.php @@ -0,0 +1,34 @@ +select('role', 'r') + ->fields('r', array('rid', 'name')) + ->orderBy('rid'); + return $query; + } + + /** + * {@inheritdoc} + */ + public function fields() { + return array( + 'rid' => t('Role ID.'), + 'name' => t('The name of the user role.'), + ); + } + + /** + * {@inheritdoc} + */ + function prepareRow(Row $row, $keep = TRUE) { + $permissions = array(); + $results = $this->database + ->select('permission', 'p', array('fetch' => \PDO::FETCH_ASSOC)) + ->fields('p', array('pid', 'rid', 'perm', 'tid')) + ->condition('rid', $row->getSourceProperty('rid')) + ->execute(); + foreach ($results as $perm) { + $permissions[] = array( + 'pid' => $perm['pid'], + 'rid' => $perm['rid'], + 'perm' => array_map('trim', explode(',', $perm['perm'])), + 'tid' => $perm['tid'], + ); + } + $row->setSourceProperty('permissions', $permissions); + return parent::prepareRow($row); + } + +} diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UserRole.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UserRole.php new file mode 100644 index 00000000000..934141edfd6 --- /dev/null +++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UserRole.php @@ -0,0 +1,123 @@ +schema()->createTable('permission', array( + 'description' => 'Stores permissions for users.', + 'fields' => array( + 'pid' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'description' => 'Primary Key: Unique permission ID.', + ), + 'rid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The {role}.rid to which the permissions are assigned.', + ), + 'perm' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + 'description' => 'List of permissions being assigned.', + ), + 'tid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Originally intended for taxonomy-based permissions, but never used.', + ), + ), + 'primary key' => array('pid'), + 'indexes' => array('rid' => array('rid')), + )); + $database->schema()->createTable('role', array( + 'description' => 'Stores user roles.', + 'fields' => array( + 'rid' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'Primary Key: Unique role id.', + ), + 'name' => array( + 'type' => 'varchar', + 'length' => 64, + 'not null' => TRUE, + 'default' => '', + 'description' => 'Unique role name.', + ), + ), + 'unique keys' => array('name' => array('name')), + 'primary key' => array('rid'), + )); + $database->schema()->createTable('users_roles', array( + 'description' => 'Maps users to roles.', + 'fields' => array( + 'uid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Primary Key: {users}.uid for user.', + ), + 'rid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Primary Key: {role}.rid for role.', + ), + ), + 'primary key' => array('uid', 'rid'), + 'indexes' => array( + 'rid' => array('rid'), + ), + )); + $database->insert('permission')->fields(array('pid', 'rid', 'perm')) + ->values(array('pid' => 3, 'rid' => 3, 'perm' => 'migrate test role 1 test permission')) + ->values(array('pid' => 4, 'rid' => 4, 'perm' => 'migrate test role 2 test permission')) + ->values(array('pid' => 5, 'rid' => 4, 'perm' => 'use PHP for settings')) + ->values(array('pid' => 6, 'rid' => 4, 'perm' => 'administer contact forms')) + ->values(array('pid' => 7, 'rid' => 4, 'perm' => 'skip comment approval')) + ->values(array('pid' => 8, 'rid' => 4, 'perm' => 'edit own blog content')) + ->values(array('pid' => 9, 'rid' => 4, 'perm' => 'edit any blog content')) + ->values(array('pid' => 10, 'rid' => 4, 'perm' => 'delete own blog content')) + ->values(array('pid' => 11, 'rid' => 4, 'perm' => 'delete any blog content')) + ->values(array('pid' => 12, 'rid' => 4, 'perm' => 'create forum content')) + ->values(array('pid' => 13, 'rid' => 4, 'perm' => 'delete any forum content')) + ->values(array('pid' => 14, 'rid' => 4, 'perm' => 'delete own forum content')) + ->values(array('pid' => 15, 'rid' => 4, 'perm' => 'edit any forum content')) + ->values(array('pid' => 16, 'rid' => 4, 'perm' => 'edit own forum content')) + ->values(array('pid' => 17, 'rid' => 4, 'perm' => 'administer nodes')) + ->execute(); + $database->insert('role')->fields(array('rid', 'name')) + ->values(array('rid' => 3, 'name' => 'migrate test role 1')) + ->values(array('rid' => 4, 'name' => 'migrate test role 2')) + ->values(array('rid' => 5, 'name' => 'migrate test role 3')) + ->execute(); + $database->insert('users_roles')->fields(array('uid', 'rid')) + ->values(array('uid' => 1, 'rid' => 3)) + ->values(array('uid' => 1, 'rid' => 4)) + ->execute(); + } + +} diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateUserRoleTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateUserRoleTest.php new file mode 100644 index 00000000000..5c6526b02d8 --- /dev/null +++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateUserRoleTest.php @@ -0,0 +1,65 @@ + 'Migrate user roles to user.role.*.yml', + 'description' => 'Upgrade user roles to user.role.*.yml', + 'group' => 'Migrate Drupal', + ); + } + + function testUserRole() { + /** @var \Drupal\migrate\entity\Migration $migration */ + $migration = entity_load('migration', 'd6_user_role'); + $dumps = array( + drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6UserRole.php', + ); + $this->prepare($migration, $dumps); + $executable = new MigrateExecutable($migration, new MigrateMessage()); + $executable->import(); + + $rid = 'migrate_test_role_1'; + $migrate_test_role_1 = entity_load('user_role', $rid); + $this->assertEqual($migrate_test_role_1->id(), $rid); + $this->assertEqual($migrate_test_role_1->getPermissions(), array(0 => 'migrate test role 1 test permission')); + $this->assertEqual(array($rid), $migration->getIdMap()->lookupDestinationID(array(3))); + $rid = 'migrate_test_role_2'; + $migrate_test_role_2 = entity_load('user_role', $rid); + $this->assertEqual($migrate_test_role_2->getPermissions(), array( + 'migrate test role 2 test permission', + 'use PHP for settings', + 'administer contact forms', + 'skip comment approval', + 'edit own blog content', + 'edit any blog content', + 'delete own blog content', + 'delete any blog content', + 'create forum content', + 'delete any forum content', + 'delete own forum content', + 'edit any forum content', + 'edit own forum content', + 'administer nodes', + 'access content overview', + )); + $this->assertEqual($migrate_test_role_2->id(), $rid); + $this->assertEqual(array($rid), $migration->getIdMap()->lookupDestinationID(array(4))); + } + +} diff --git a/core/modules/migrate_drupal/tests/Drupal/migrate_drupal/Tests/source/d6/RoleSourceTest.php b/core/modules/migrate_drupal/tests/Drupal/migrate_drupal/Tests/source/d6/RoleSourceTest.php new file mode 100644 index 00000000000..0e0bf9aab98 --- /dev/null +++ b/core/modules/migrate_drupal/tests/Drupal/migrate_drupal/Tests/source/d6/RoleSourceTest.php @@ -0,0 +1,144 @@ + 'test', + // Leave it empty for now. + 'idlist' => array(), + // This needs to be the identifier of the actual key: rid for comment, nid + // for node and so on. + 'source' => array( + 'plugin' => 'drupal6_user_role', + ), + 'sourceIds' => array( + 'rid' => array( + // This is where the field schema would go but for now we need to + // specify the table alias for the key. Most likely this will be the + // same as BASE_ALIAS. + 'alias' => 'r', + ), + ), + 'destinationIds' => array( + 'rid' => array( + // This is where the field schema would go. + ), + ), + ); + + protected $expectedResults = array( + array( + 'rid' => 1, + 'name' => 'anonymous user', + 'permissions' => array( + array( + 'pid' => 1, + 'rid' => 1, + 'perm' => array( + 'access content', + ), + 'tid' => 0, + ), + ), + ), + array( + 'rid' => 2, + 'name' => 'authenticated user', + 'permissions' => array( + array( + 'pid' => 2, + 'rid' => 2, + 'perm' => array( + 'access comments', + 'access content', + 'post comments', + 'post comments without approval', + ), + 'tid' => 0, + ), + ), + ), + array( + 'rid' => 3, + 'name' => 'administrator', + 'permissions' => array( + array( + 'pid' => 3, + 'rid' => 3, + 'perm' => array( + 'access comments', + 'administer comments', + 'post comments', + 'post comments without approval', + 'access content', + 'administer content types', + 'administer nodes', + ), + 'tid' => 0, + ), + ), + ), + ); + + /** + * {@inheritdoc} + */ + public static function getInfo() { + return array( + 'name' => 'D6 role source functionality', + 'description' => 'Tests D6 role source plugin.', + 'group' => 'Migrate Drupal', + ); + } + + /** + * {@inheritdoc} + */ + public function setUp() { + foreach ($this->expectedResults as $k => $row) { + foreach ($row['permissions'] as $perm) { + $this->databaseContents['permission'][$perm['pid']] = $perm; + $this->databaseContents['permission'][$perm['pid']]['perm'] = implode(',', $perm['perm']); + $this->databaseContents['permission'][$perm['pid']]['rid'] = $row['rid']; + } + unset($row['permissions']); + $this->databaseContents['role'][$k] = $row; + } + parent::setUp(); + } + +} + +use Drupal\Core\Database\Connection; +use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\migrate_drupal\Plugin\migrate\source\d6\Role; + +class TestRole extends Role { + function setDatabase(Connection $database) { + $this->database = $database; + } + function setModuleHandler(ModuleHandlerInterface $module_handler) { + $this->moduleHandler = $module_handler; + } +}