|
@@ -8,9 +8,75 @@
|
|
|
* @license Licensed under the General Public License version 2 and later, and the CeCILL 2.0 license.
|
|
|
*/
|
|
|
|
|
|
-class UnfuddlePeopleMigration extends XMLMigration {
|
|
|
- protected function getFieldInfo() {
|
|
|
- $fields = array(
|
|
|
+abstract class UnfuddleMigration extends XMLMigration {
|
|
|
+ public $items_url;
|
|
|
+ public $item_ID_xpath = 'id';
|
|
|
+ public $unmigratedDestinations = array();
|
|
|
+ public $unmigratedSources = array();
|
|
|
+ protected static $fields = array();
|
|
|
+
|
|
|
+ public function __construct($group) {
|
|
|
+ parent::__construct($group);
|
|
|
+ $this->items_url = file_directory_path() . '/unfuddle/backup.xml';
|
|
|
+ }
|
|
|
+
|
|
|
+ public function afterConstruct() {
|
|
|
+ $this->addUnmigratedDestinations($this->unmigratedDestinations, t('White hole'));
|
|
|
+ $this->addUnmigratedSources($this->unmigratedSources, t('Black hole'));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Return a field-name-indexed hash of field descriptions.
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ protected static function getFieldInfo() {
|
|
|
+ return self::$fields;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function addXPathFieldMapping($destination_field, $source_field, $xpath = NULL) {
|
|
|
+ if (!isset($xpath)) {
|
|
|
+ $xpath = $source_field;
|
|
|
+ }
|
|
|
+ return $this->addFieldMapping($destination_field, $source_field)
|
|
|
+ ->xpath($xpath);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Import "people" data from the Unfuddle backup into Drupal users
|
|
|
+ */
|
|
|
+class UnfuddlePeopleMigration extends UnfuddleMigration {
|
|
|
+ public $unmigratedDestinations = array(
|
|
|
+ 'pass',
|
|
|
+ 'roles',
|
|
|
+ 'theme',
|
|
|
+ 'signature',
|
|
|
+ 'signature_format',
|
|
|
+ 'language',
|
|
|
+ 'picture',
|
|
|
+ );
|
|
|
+
|
|
|
+ public $unmigratedSources = array(
|
|
|
+ 'account-id',
|
|
|
+ 'first-name',
|
|
|
+ 'identity-url',
|
|
|
+ 'is-administrator',
|
|
|
+ 'last-name',
|
|
|
+ 'notification-frequency',
|
|
|
+ 'notification-ignore-self',
|
|
|
+ 'notification-last-sent',
|
|
|
+ 'notification-scope-messages',
|
|
|
+ 'notification-scope-milestones',
|
|
|
+ 'notification-scope-notebooks',
|
|
|
+ 'notification-scope-source',
|
|
|
+ 'notification-scope-tickets',
|
|
|
+ 'text-markup',
|
|
|
+ 'updated-at',
|
|
|
+ );
|
|
|
+
|
|
|
+ protected static function getFieldInfo() {
|
|
|
+ self::$fields = array(
|
|
|
'account-id' => t('Unfuddle account Id'),
|
|
|
'id' => t('User account ID'),
|
|
|
'created-at' => t('User account creation timestamp'),
|
|
@@ -35,18 +101,16 @@ class UnfuddlePeopleMigration extends XMLMigration {
|
|
|
'username' => t('The user account login name'),
|
|
|
);
|
|
|
|
|
|
- return $fields;
|
|
|
+ return parent::getFieldInfo();
|
|
|
}
|
|
|
|
|
|
public function __construct() {
|
|
|
parent::__construct(MigrateGroup::getInstance('Unfuddle'));
|
|
|
|
|
|
- $items_url = file_directory_path() . '/unfuddle/backup.xml';
|
|
|
$item_xpath = '/account/people/person';
|
|
|
- $item_ID_xpath = 'id';
|
|
|
- $items_class = new MigrateItemsXML($items_url, $item_xpath, $item_ID_xpath);
|
|
|
+ $items_class = new MigrateItemsXML($this->items_url, $item_xpath, $this->item_ID_xpath);
|
|
|
|
|
|
- $this->source = new MigrateSourceMultiItems($items_class, $this->getFieldInfo());
|
|
|
+ $this->source = new MigrateSourceMultiItems($items_class, self::getFieldInfo());
|
|
|
$source_key = array(
|
|
|
'id' => array(
|
|
|
'type' => 'int',
|
|
@@ -62,54 +126,21 @@ class UnfuddlePeopleMigration extends XMLMigration {
|
|
|
|
|
|
// Do not map uid: this prevents user_save from creating the accounts.
|
|
|
|
|
|
- $this->addFieldMapping('created', 'created-at')
|
|
|
- ->xpath('created-at');
|
|
|
- $this->addFieldMapping('mail', 'email')
|
|
|
- ->xpath('email');
|
|
|
- $this->addFieldMapping('init', 'email')
|
|
|
+ $this->addXPathFieldMapping('created', 'created-at');
|
|
|
+ $this->addXPathFieldMapping('mail', 'email');
|
|
|
+ $this->addXPathFieldMapping('init', 'email')
|
|
|
->defaultValue('support@osinet.fr')
|
|
|
->description(t('Unfuddle does not keep the original email address'));
|
|
|
- $this->addFieldMapping('status', 'is-removed')
|
|
|
- ->xpath('is-removed')
|
|
|
+ $this->addXPathFieldMapping('status', 'is-removed')
|
|
|
->description(t('Inverted when converting to user.status'));
|
|
|
- $this->addFieldMapping('login', 'last-signed-in')
|
|
|
- ->xpath('last-signed-in');
|
|
|
- $this->addFieldMapping('access', 'last-signed-in')
|
|
|
- ->xpath('last-signed-in')
|
|
|
+ $this->addXPathFieldMapping('login', 'last-signed-in');
|
|
|
+ $this->addXPathFieldMapping('access', 'last-signed-in')
|
|
|
->description(t('Unfuddle does not log access time, only sign in.'));
|
|
|
- $this->addFieldMapping('timezone', 'time-zone')
|
|
|
- ->xpath('time-zone')
|
|
|
+ $this->addXPathFieldMapping('timezone', 'time-zone')
|
|
|
->description(t('Only Paris and London currently supported, without DST'));
|
|
|
- $this->addFieldMapping('name', 'username')
|
|
|
- ->xpath('username');
|
|
|
-
|
|
|
- $this->addUnmigratedDestinations(array(
|
|
|
- 'pass',
|
|
|
- 'roles',
|
|
|
- 'theme',
|
|
|
- 'signature',
|
|
|
- 'signature_format',
|
|
|
- 'language',
|
|
|
- 'picture',
|
|
|
- ), t('White hole'));
|
|
|
-
|
|
|
- $this->addUnmigratedSources(array(
|
|
|
- 'account-id',
|
|
|
- 'first-name',
|
|
|
- 'identity-url',
|
|
|
- 'is-administrator',
|
|
|
- 'last-name',
|
|
|
- 'notification-frequency',
|
|
|
- 'notification-ignore-self',
|
|
|
- 'notification-last-sent',
|
|
|
- 'notification-scope-messages',
|
|
|
- 'notification-scope-milestones',
|
|
|
- 'notification-scope-notebooks',
|
|
|
- 'notification-scope-source',
|
|
|
- 'notification-scope-tickets',
|
|
|
- 'text-markup',
|
|
|
- 'updated-at',
|
|
|
- ), t('Black hole'));
|
|
|
+ $this->addXPathFieldMapping('name', 'username');
|
|
|
+
|
|
|
+ $this->afterConstruct();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -139,3 +170,115 @@ class UnfuddlePeopleMigration extends XMLMigration {
|
|
|
: $timezones[$timezone];
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Import "project" core data from Unfuddle into CaseTracker project nodes
|
|
|
+ */
|
|
|
+class UnfuddleProjectMigration extends UnfuddleMigration {
|
|
|
+ public $unmigratedDestinations = array(
|
|
|
+ 'promote',
|
|
|
+ 'sticky',
|
|
|
+ 'revision',
|
|
|
+ 'language',
|
|
|
+ );
|
|
|
+ public $unmigratedSources = array(
|
|
|
+ 'account-id',
|
|
|
+ 'assignee-on-resolve',
|
|
|
+ 'backup-frequency',
|
|
|
+ 'close-ticket-simultaneously-default',
|
|
|
+ 'default-ticket-report-id',
|
|
|
+ 'disk-usage',
|
|
|
+ 'enable-time-tracking',
|
|
|
+ 's3-access-key-id',
|
|
|
+ 's3-backup-enabled',
|
|
|
+ 's3-bucket-name',
|
|
|
+ 'theme',
|
|
|
+ 'categories', // @todo TODO Taxonomy ?
|
|
|
+ );
|
|
|
+
|
|
|
+ protected static function getFieldInfo() {
|
|
|
+ self::$fields = array(
|
|
|
+ 'account-id' => t('Unfuddle account Id'),
|
|
|
+ 'archived' => t('Unpublished'),
|
|
|
+ 'assignee-on-resolve' => t('The user being assigned a ticket once it is resolved'),
|
|
|
+ 'backup-frequency' => t('Current email address for the account'),
|
|
|
+ 'close-ticket-simultaneously-default' => t('Close tickets on Resolved status'),
|
|
|
+ 'created-at' => t('Project creation timestamp'),
|
|
|
+ 'default-ticket-report-id' => t('User reporting tickets by default'),
|
|
|
+ 'description' => t('Description'),
|
|
|
+ 'disk-usage' => t('Disk usage on Unfuddle, in bytes'),
|
|
|
+ 'enable-time-tracking' => t('Enable issue time tracking'),
|
|
|
+ 's3-access-key-id' => t('Amazon S3 key'),
|
|
|
+ 's3-backup-enabled' => t('Periodic backups sent to Amazon S3'),
|
|
|
+ 's3-bucket-name' => t('Amazon S3 destination bucket for backups'),
|
|
|
+ 'short-name' => t('Short project name (machine name)'),
|
|
|
+ 'theme' => t('Unfuddle main color for project theme'),
|
|
|
+ /**
|
|
|
+ * @todo TODO insert as CCK fields
|
|
|
+ *
|
|
|
+ 'ticket-fieldn-active' => (boolean),
|
|
|
+ 'ticket-fieldn-disposition' => 'list',
|
|
|
+ 'ticket-fieldn-title' => (label)
|
|
|
+ *
|
|
|
+ */
|
|
|
+ 'title' => t('Title'),
|
|
|
+ 'updated-at' => t('Timestamp of latest project change'),
|
|
|
+ 'categories' => t('Categories'),
|
|
|
+ /*
|
|
|
+ * Ignored:
|
|
|
+ components
|
|
|
+ custom-field-values
|
|
|
+ messages
|
|
|
+ milestones
|
|
|
+ notebooks
|
|
|
+ severities
|
|
|
+ tickets -> separate import
|
|
|
+ ticket-reports (views)
|
|
|
+ versions
|
|
|
+ *
|
|
|
+ */
|
|
|
+ );
|
|
|
+
|
|
|
+ return self::$fields;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function __construct() {
|
|
|
+ parent::__construct(MigrateGroup::getInstance('Unfuddle'));
|
|
|
+ $item_xpath = '/account/projects/project';
|
|
|
+ $items_class = new MigrateItemsXML($this->items_url, $item_xpath, $this->item_ID_xpath);
|
|
|
+ $this->source = new MigrateSourceMultiItems($items_class, self::getFieldInfo());
|
|
|
+ $source_key = array(
|
|
|
+ 'id' => array(
|
|
|
+ 'type' => 'int',
|
|
|
+ 'unsigned' => TRUE,
|
|
|
+ 'not null' => TRUE,
|
|
|
+ )
|
|
|
+ );
|
|
|
+
|
|
|
+ $this->destination = new MigrateDestinationNode('casetracker_basic_project');
|
|
|
+ $this->map = new MigrateSQLMap('unfuddle_project',
|
|
|
+ $source_key,
|
|
|
+ MigrateDestinationNode::getKeySchema());
|
|
|
+
|
|
|
+ $this->addXPathFieldMapping('created', 'created-at');
|
|
|
+ $this->addXPathFieldMapping('status', 'archived')
|
|
|
+ ->description(t('Inverted when converting to node.status'));
|
|
|
+ $this->afterConstruct();
|
|
|
+ $this->addXPathFieldMapping('body', 'description')
|
|
|
+ ->description(t('Applying site default input format: will often be wrong'));
|
|
|
+ $this->addXPathFieldMapping('teaser', node_teaser('description', FILTER_FORMAT_DEFAULT))
|
|
|
+ ->description(t('Applying site default input format: will often be wrong'));
|
|
|
+ $this->addXPathFieldMapping('changed', 'updated-at');
|
|
|
+ $this->addXPathFieldMapping('title', 'title');
|
|
|
+
|
|
|
+ $this->addXPathFieldMapping('uid', NULL)->defaultValue(1);
|
|
|
+ $this->addXPathFieldMapping('revision_uid', NULL)->defaultValue(1);
|
|
|
+ $this->addXPathFieldMapping('path', 'short-name')
|
|
|
+ ->description(t('Auto-aliased to project/(short-name)'));
|
|
|
+ }
|
|
|
+
|
|
|
+ public function preparerow(stdClass $row) {
|
|
|
+ $row->xml->{'archived'} = ((int) $row->xml->{'archived'}) ? 0 : 1;
|
|
|
+ $row->xml->{'short-name'} = 'project/'. $row->xml->{'short-name'};
|
|
|
+ }
|
|
|
+}
|