Issue #2150407 by chx, bdone, eliza411, andypost: Migrate D6 roles and permissions.

8.0.x
Alex Pott 2014-01-01 12:01:02 +01:00
parent 814aed203d
commit c2e68a5ddb
8 changed files with 610 additions and 0 deletions

View File

@ -0,0 +1,84 @@
<?php
/**
* @file
* Contains \Drupal\migrate\Plugin\migrate\destination\Entity.
*/
namespace Drupal\migrate\Plugin\migrate\destination;
use Drupal\Core\Entity\EntityStorageControllerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\field\FieldInfo;
use Drupal\migrate\Entity\Migration;
use Drupal\migrate\Plugin\MigratePluginManager;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* @PluginId("entity")
*/
class Entity extends DestinationBase implements ContainerFactoryPluginInterface {
/**
* The entity storage controller.
*
* @var \Drupal\Core\Entity\EntityStorageControllerInterface
*/
protected $storageController;
/**
* Constructs an entity destination plugin.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param array $plugin_definition
* The plugin implementation definition.
* @param EntityStorageControllerInterface $storage_controller
* The storage controller for this entity type.
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityStorageControllerInterface $storage_controller) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->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.
}
}

View File

@ -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

View File

@ -0,0 +1,34 @@
<?php
/**
* @file
* Contains \Drupal\migrate_drupal\Plugin\migrate\Process\d6\NodeUpdate7008.
*/
namespace Drupal\migrate_drupal\Plugin\migrate\Process\d6;
use Drupal\migrate\MigrateExecutable;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* Split the 'administer nodes' permission from 'access content overview'.
*
* @MigrateProcessPlugin(
* id = "node_update_7008"
* )
*/
class NodeUpdate7008 extends ProcessPluginBase {
/**
* {@inheritdoc}
*
* Split the 'administer nodes' permission from 'access content overview'.
*/
public function transform($value, MigrateExecutable $migrate_executable, Row $row, $destination_property) {
if ($value === 'administer nodes') {
return array($value, 'access content overview');
}
return $value;
}
}

View File

@ -0,0 +1,43 @@
<?php
/**
* @file
* Contains \Drupal\migrate_drupal\Plugin\migrate\Process\d6\system_update_7000.
*/
namespace Drupal\migrate_drupal\Plugin\migrate\process\d6;
use Drupal\migrate\MigrateExecutable;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* Rename blog and forum permissions to be consistent with other content types.
*
* @MigrateProcessPlugin(
* id = "system_update_7000"
* )
*/
class SystemUpdate7000 extends ProcessPluginBase {
/**
* {@inheritdoc}
*
* Rename blog and forum permissions to be consistent with other content types.
*/
public function transform($value, MigrateExecutable $migrate_executable, Row $row, $destination_property) {
$value = preg_replace('/(?<=^|,\ )create\ blog\ entries(?=,|$)/', 'create blog content', $value);
$value = preg_replace('/(?<=^|,\ )edit\ own\ blog\ entries(?=,|$)/', 'edit own blog content', $value);
$value = preg_replace('/(?<=^|,\ )edit\ any\ blog\ entry(?=,|$)/', 'edit any blog content', $value);
$value = preg_replace('/(?<=^|,\ )delete\ own\ blog\ entries(?=,|$)/', 'delete own blog content', $value);
$value = preg_replace('/(?<=^|,\ )delete\ any\ blog\ entry(?=,|$)/', 'delete any blog content', $value);
$value = preg_replace('/(?<=^|,\ )create\ forum\ topics(?=,|$)/', 'create forum content', $value);
$value = preg_replace('/(?<=^|,\ )delete\ any\ forum\ topic(?=,|$)/', 'delete any forum content', $value);
$value = preg_replace('/(?<=^|,\ )delete\ own\ forum\ topics(?=,|$)/', 'delete own forum content', $value);
$value = preg_replace('/(?<=^|,\ )edit\ any\ forum\ topic(?=,|$)/', 'edit any forum content', $value);
$value = preg_replace('/(?<=^|,\ )edit\ own\ forum\ topics(?=,|$)/', 'edit own forum content', $value);
return $value;
}
}

View File

@ -0,0 +1,62 @@
<?php
/**
* @file
* Contains \Drupal\migrate\Plugin\migrate\source\d6\Role.
*/
namespace Drupal\migrate_drupal\Plugin\migrate\source\d6;
use Drupal\migrate\Row;
/**
* Drupal 6 role source from database.
*
* @PluginId("drupal6_user_role")
*/
class Role extends Drupal6SqlBase {
/**
* {@inheritdoc}
*/
public function query() {
$query = $this->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);
}
}

View File

@ -0,0 +1,123 @@
<?php
/**
* @file
* Contains \Drupal\migrate\Tests\Dump\Drupal6UserRole.
*/
namespace Drupal\migrate_drupal\Tests\Dump;
use Drupal\Core\Database\Connection;
/**
* Database dump for testing user role migration.
*/
class Drupal6UserRole {
/**
* @param \Drupal\Core\Database\Connection $database
*/
public static function load(Connection $database) {
$database->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();
}
}

View File

@ -0,0 +1,65 @@
<?php
/**
* @file
* Contains \Drupal\migrate_drupal\Tests\d6\MigrateUserRoleTest.
*/
namespace Drupal\migrate_drupal\Tests\d6;
use Drupal\migrate\MigrateExecutable;
use Drupal\migrate\MigrateMessage;
use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
class MigrateUserRoleTest extends MigrateDrupalTestBase {
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => '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)));
}
}

View File

@ -0,0 +1,144 @@
<?php
/**
* @file
* Contains \Drupal\migrate_drupal\Tests\source\d6\RoleSourceTest.
*/
namespace Drupal\migrate_drupal\Tests\source\d6;
use Drupal\migrate\Tests\MigrateSqlSourceTestCase;
/**
* Tests user role migration from D6 to D8.
*
* @group migrate_drupal
* @group Drupal
*/
class RoleSourceTest extends MigrateSqlSourceTestCase {
// The plugin system is not working during unit testing so the source plugin
// class needs to be manually specified.
const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\d6\Role';
// The fake Migration configuration entity.
protected $migrationConfiguration = array(
// The ID of the entity, can be any string.
'id' => '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;
}
}