updated elysia_cron, elfinder, metatag, libraries, email_registration, migrate, nodeform_cols
This commit is contained in:
@@ -1,3 +1,29 @@
|
||||
Next release
|
||||
============
|
||||
|
||||
Features and enhancements
|
||||
- #2552189 - Return migration status from drush migrate-import.
|
||||
- #2550793 - Option to always use chunk IDs in MigrateContentParser.
|
||||
- #2505683 - Pass item ID to MigrateContentParser implementations.
|
||||
- #2532222 - Allow spreadsheet source data on a row different that 1.
|
||||
- #1406802 - Add callback() field mapping method, to pass additional arguments
|
||||
to callbacks.
|
||||
- #2516828 - Add mdreg alias for migrate-deregister.
|
||||
- #2504517 - Add timezone handling to timestamp().
|
||||
|
||||
Bug fixes
|
||||
- #2612110 - Notice when units omitted on --limit.
|
||||
- #2597606 - Escape MySQL database names.
|
||||
- #2577091 - Do strict type-check on XML ids.
|
||||
- #2537206 - copy() return not checked.
|
||||
- #2536616 - Improve message when sourceMigration not found.
|
||||
- #2578391 - Improve message when class not found.
|
||||
- #2565043 - Handle empty idlist in MigrateSourceMultiItems.
|
||||
- #2510010 - Stop stripping group name prefixes from migration names.
|
||||
- #2542520 - Fallback for missing source key description.
|
||||
- #2499861 - Properly save/disable/restore mail system.
|
||||
- #2541996 - Prevent NULL file_mask being passed to file_scan_directory().
|
||||
|
||||
Migrate 2.8
|
||||
===========
|
||||
|
||||
|
@@ -1,15 +1,17 @@
|
||||
|
||||
The Migrate module provides a flexible framework for migrating content into Drupal
|
||||
from other sources (e.g., when converting a web site from another CMS to Drupal).
|
||||
The Migrate module provides a flexible framework for migrating content into
|
||||
Drupal from other sources
|
||||
(e.g., when converting a web site from another CMS to Drupal).
|
||||
Out-of-the-box, support for creating Drupal nodes, taxonomy terms, comments, and
|
||||
users are included. Plugins permit migration of other types of content.
|
||||
|
||||
Usage
|
||||
-----
|
||||
Documentation is at http://drupal.org/migrate. To get started, enable the
|
||||
migrate_example module and browse to admin/content/migrate to see its dashboard.
|
||||
The code for this migration is in migrate_example/beer.inc (advanced examples are
|
||||
in wine.inc). Mimic that file in order to specify your own migrations.
|
||||
migrate_example module, enable migrate_ui, and then browse to
|
||||
admin/content/migrate to see its dashboard.
|
||||
The code for this migration is in migrate_example/beer.inc
|
||||
(advanced examples are in wine.inc). Mimic that file in order to specify your
|
||||
own migrations.
|
||||
|
||||
The Migrate module itself has support for migration into core objects. Support
|
||||
for migration involving contrib modules is in the migrate_extras module.
|
||||
@@ -17,8 +19,8 @@ for migration involving contrib modules is in the migrate_extras module.
|
||||
Known issues
|
||||
------------
|
||||
A user migration with systemOfRecord == DESTINATION will drop pictures from user
|
||||
records due to core bug http://drupal.org/node/935592 - the simpletests report an
|
||||
error reflecting this. We have not developed a work-around.
|
||||
records due to core bug http://drupal.org/node/935592 - the simpletests report
|
||||
an error reflecting this. We have not developed a work-around.
|
||||
|
||||
Upgrading
|
||||
---------
|
||||
@@ -30,9 +32,9 @@ projects.
|
||||
|
||||
Acknowledgements
|
||||
----------------
|
||||
Much of the Migrate module functionality was sponsored by Cyrve, for its clients GenomeWeb
|
||||
(http://www.genomeweb.com), The Economist (http://www.economist.com), and Examiner.com
|
||||
(http://www.examiner.com).
|
||||
Much of the Migrate module functionality was sponsored by Cyrve, for its clients
|
||||
GenomeWeb (http://www.genomeweb.com), The Economist (http://www.economist.com),
|
||||
and Examiner.com (http://www.examiner.com).
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
@@ -8,11 +8,12 @@
|
||||
/**
|
||||
* The base class for all objects representing distinct steps in a migration
|
||||
* process. Most commonly these will be Migration objects which actually import
|
||||
* data from a source into a Drupal destination, but by deriving classes directly
|
||||
* from MigrationBase one can have other sorts of tasks (e.g., enabling/disabling
|
||||
* of modules) occur during the migration process.
|
||||
* data from a source into a Drupal destination, but by deriving classes
|
||||
* directly from MigrationBase one can have other sorts of tasks (e.g.,
|
||||
* enabling/disabling of modules) occur during the migration process.
|
||||
*/
|
||||
abstract class MigrationBase {
|
||||
|
||||
/**
|
||||
* Track the migration currently running, so handlers can easily determine it
|
||||
* without having to pass a Migration object everywhere.
|
||||
@@ -20,18 +21,21 @@ abstract class MigrationBase {
|
||||
* @var Migration
|
||||
*/
|
||||
protected static $currentMigration;
|
||||
|
||||
public static function currentMigration() {
|
||||
return self::$currentMigration;
|
||||
}
|
||||
|
||||
/**
|
||||
* The machine name of this Migration object, derived by removing the 'Migration'
|
||||
* suffix from the class name. Used to construct default map/message table names,
|
||||
* displayed in drush migrate-status, key to migrate_status table...
|
||||
* The machine name of this Migration object, derived by removing the
|
||||
* 'Migration' suffix from the class name. Used to construct default
|
||||
* map/message table names, displayed in drush migrate-status, key to
|
||||
* migrate_status table...
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $machineName;
|
||||
|
||||
public function getMachineName() {
|
||||
return $this->machineName;
|
||||
}
|
||||
@@ -42,6 +46,7 @@ abstract class MigrationBase {
|
||||
* @var MigrateGroup
|
||||
*/
|
||||
protected $group;
|
||||
|
||||
public function getGroup() {
|
||||
return $this->group;
|
||||
}
|
||||
@@ -52,18 +57,22 @@ abstract class MigrationBase {
|
||||
* @var string
|
||||
*/
|
||||
protected $description;
|
||||
|
||||
public function getDescription() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription($description) {
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save options passed to current operation
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
public function getOption($option_name) {
|
||||
if (isset($this->options[$option_name])) {
|
||||
return $this->options[$option_name];
|
||||
@@ -72,18 +81,20 @@ abstract class MigrationBase {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public function getItemLimit() {
|
||||
if (isset($this->options['limit']) &&
|
||||
($this->options['limit']['unit'] == 'items' || $this->options['limit']['unit'] == 'item')) {
|
||||
($this->options['limit']['unit'] == 'items' || $this->options['limit']['unit'] == 'item')) {
|
||||
return $this->options['limit']['value'];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public function getTimeLimit() {
|
||||
if (isset($this->options['limit']) &&
|
||||
($this->options['limit']['unit'] == 'seconds' || $this->options['limit']['unit'] == 'second')) {
|
||||
($this->options['limit']['unit'] == 'seconds' || $this->options['limit']['unit'] == 'second')) {
|
||||
return $this->options['limit']['value'];
|
||||
}
|
||||
else {
|
||||
@@ -108,6 +119,7 @@ abstract class MigrationBase {
|
||||
|
||||
/**
|
||||
* When the current operation started.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $starttime;
|
||||
@@ -137,41 +149,51 @@ abstract class MigrationBase {
|
||||
|
||||
/**
|
||||
* List of other Migration classes which should be imported before this one.
|
||||
* E.g., a comment migration class would typically have node and user migrations
|
||||
* as dependencies.
|
||||
* E.g., a comment migration class would typically have node and user
|
||||
* migrations as dependencies.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dependencies = array(), $softDependencies = array();
|
||||
|
||||
public function getHardDependencies() {
|
||||
return $this->dependencies;
|
||||
}
|
||||
|
||||
public function setHardDependencies(array $dependencies) {
|
||||
$this->dependencies = $dependencies;
|
||||
}
|
||||
|
||||
public function addHardDependencies(array $dependencies) {
|
||||
$this->dependencies = array_merge($this->dependencies, $dependencies);
|
||||
}
|
||||
|
||||
public function getSoftDependencies() {
|
||||
return $this->softDependencies;
|
||||
}
|
||||
|
||||
public function setSoftDependencies(array $dependencies) {
|
||||
$this->softDependencies = $dependencies;
|
||||
}
|
||||
|
||||
public function addSoftDependencies(array $dependencies) {
|
||||
$this->softDependencies = array_merge($this->softDependencies, $dependencies);
|
||||
}
|
||||
|
||||
public function getDependencies() {
|
||||
return array_merge($this->dependencies, $this->softDependencies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of a function for displaying feedback. It must take the message to display
|
||||
* as its first argument, and a (string) message type as its second argument
|
||||
* Name of a function for displaying feedback. It must take the message to
|
||||
* display as its first argument, and a (string) message type as its second
|
||||
* argument
|
||||
* (see drush_log()).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $displayFunction;
|
||||
|
||||
public static function setDisplayFunction($display_function) {
|
||||
self::$displayFunction = $display_function;
|
||||
}
|
||||
@@ -230,9 +252,11 @@ abstract class MigrationBase {
|
||||
* @var array
|
||||
*/
|
||||
protected $team = array();
|
||||
|
||||
public function getTeam() {
|
||||
return $this->team;
|
||||
}
|
||||
|
||||
public function setTeam(array $team) {
|
||||
$this->team = $team;
|
||||
}
|
||||
@@ -244,9 +268,11 @@ abstract class MigrationBase {
|
||||
* @var string
|
||||
*/
|
||||
protected $issuePattern;
|
||||
|
||||
public function getIssuePattern() {
|
||||
return $this->issuePattern;
|
||||
}
|
||||
|
||||
public function setIssuePattern($issue_pattern) {
|
||||
$this->issuePattern = $issue_pattern;
|
||||
}
|
||||
@@ -265,12 +291,15 @@ abstract class MigrationBase {
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = array();
|
||||
|
||||
public function getArguments() {
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
public function setArguments(array $arguments) {
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
public function addArguments(array $arguments) {
|
||||
$this->arguments = array_merge($this->arguments, $arguments);
|
||||
}
|
||||
@@ -282,9 +311,11 @@ abstract class MigrationBase {
|
||||
* @var boolean
|
||||
*/
|
||||
protected $enabled = TRUE;
|
||||
|
||||
public function getEnabled() {
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
public function setEnabled($enabled) {
|
||||
$this->enabled = $enabled;
|
||||
}
|
||||
@@ -294,9 +325,11 @@ abstract class MigrationBase {
|
||||
*
|
||||
* @var array
|
||||
* Key: Hook name (e.g., 'node_insert')
|
||||
* Value: Array of modules for which to disable this hook (e.g., array('pathauto')).
|
||||
* Value: Array of modules for which to disable this hook (e.g.,
|
||||
* array('pathauto')).
|
||||
*/
|
||||
protected $disableHooks = array();
|
||||
|
||||
public function getDisableHooks() {
|
||||
return $this->disableHooks;
|
||||
}
|
||||
@@ -304,26 +337,33 @@ abstract class MigrationBase {
|
||||
/**
|
||||
* An array to track 'mail_system' variable if disabled.
|
||||
*/
|
||||
protected $mailSystem = array();
|
||||
protected $mailSystem;
|
||||
|
||||
/**
|
||||
* Have we already warned about obsolete constructor argumentss on this request?
|
||||
* Have we already warned about obsolete constructor argumentss on this
|
||||
* request?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
static protected $groupArgumentWarning = FALSE;
|
||||
|
||||
static protected $emptyArgumentsWarning = FALSE;
|
||||
|
||||
/**
|
||||
* Codes representing the result of a rollback or import process.
|
||||
*/
|
||||
const RESULT_COMPLETED = 1; // All records have been processed
|
||||
|
||||
const RESULT_INCOMPLETE = 2; // The process has interrupted itself (e.g., the
|
||||
// memory limit is approaching)
|
||||
|
||||
// memory limit is approaching)
|
||||
const RESULT_STOPPED = 3; // The process was stopped externally (e.g., via
|
||||
// drush migrate-stop)
|
||||
|
||||
// drush migrate-stop)
|
||||
const RESULT_FAILED = 4; // The process had a fatal error
|
||||
|
||||
const RESULT_SKIPPED = 5; // Dependencies are unfulfilled - skip the process
|
||||
|
||||
const RESULT_DISABLED = 6; // This migration is disabled, skipping
|
||||
|
||||
/**
|
||||
@@ -331,20 +371,27 @@ abstract class MigrationBase {
|
||||
* migrate_status table.
|
||||
*/
|
||||
const STATUS_IDLE = 0;
|
||||
|
||||
const STATUS_IMPORTING = 1;
|
||||
|
||||
const STATUS_ROLLING_BACK = 2;
|
||||
|
||||
const STATUS_STOPPING = 3;
|
||||
|
||||
const STATUS_DISABLED = 4;
|
||||
|
||||
/**
|
||||
* Message types to be passed to saveMessage() and saved in message tables.
|
||||
* MESSAGE_INFORMATIONAL represents a condition that did not prevent the operation
|
||||
* from succeeding - all others represent different severities of conditions
|
||||
* resulting in a source record not being imported.
|
||||
* MESSAGE_INFORMATIONAL represents a condition that did not prevent the
|
||||
* operation from succeeding - all others represent different severities of
|
||||
* conditions resulting in a source record not being imported.
|
||||
*/
|
||||
const MESSAGE_ERROR = 1;
|
||||
|
||||
const MESSAGE_WARNING = 2;
|
||||
|
||||
const MESSAGE_NOTICE = 3;
|
||||
|
||||
const MESSAGE_INFORMATIONAL = 4;
|
||||
|
||||
/**
|
||||
@@ -374,7 +421,7 @@ abstract class MigrationBase {
|
||||
$this->group = $arguments;
|
||||
$this->arguments['group_name'] = $arguments->getName();
|
||||
if (!self::$groupArgumentWarning &&
|
||||
variable_get('migrate_deprecation_warnings', 1)) {
|
||||
variable_get('migrate_deprecation_warnings', 1)) {
|
||||
self::displayMessage(t('Passing a group object to a migration constructor is now deprecated - pass through the arguments array passed to the leaf class instead.'));
|
||||
self::$groupArgumentWarning = TRUE;
|
||||
}
|
||||
@@ -383,7 +430,7 @@ abstract class MigrationBase {
|
||||
if (empty($arguments)) {
|
||||
$this->arguments = array();
|
||||
if (!self::$emptyArgumentsWarning &&
|
||||
variable_get('migrate_deprecation_warnings', 1)) {
|
||||
variable_get('migrate_deprecation_warnings', 1)) {
|
||||
self::displayMessage(t('Passing an empty first parameter to a migration constructor is now deprecated - pass through the arguments array passed to the leaf class instead.'));
|
||||
self::$emptyArgumentsWarning = TRUE;
|
||||
}
|
||||
@@ -417,7 +464,8 @@ abstract class MigrationBase {
|
||||
}
|
||||
else {
|
||||
if (!is_numeric($limit)) {
|
||||
$last = drupal_strtolower($limit[strlen($limit)-1]);
|
||||
$last = drupal_strtolower($limit[strlen($limit) - 1]);
|
||||
$limit = substr($limit, 0, -1);
|
||||
switch ($last) {
|
||||
case 'g':
|
||||
$limit *= 1024;
|
||||
@@ -437,18 +485,12 @@ abstract class MigrationBase {
|
||||
// Record the time limit
|
||||
$this->timeLimit = ini_get('max_execution_time');
|
||||
|
||||
// Save the current mail system, prior to disabling emails.
|
||||
$this->saveMailSystem();
|
||||
|
||||
// Prevent emails from being sent out during migrations.
|
||||
$this->disableMailSystem();
|
||||
|
||||
// Make sure we clear our semaphores in case of abrupt exit
|
||||
drupal_register_shutdown_function(array($this, 'endProcess'));
|
||||
|
||||
// Save any hook disablement information.
|
||||
if (isset($this->arguments['disable_hooks']) &&
|
||||
is_array($this->arguments['disable_hooks'])) {
|
||||
is_array($this->arguments['disable_hooks'])) {
|
||||
$this->disableHooks = $this->arguments['disable_hooks'];
|
||||
}
|
||||
}
|
||||
@@ -477,7 +519,7 @@ abstract class MigrationBase {
|
||||
* @param array $arguments
|
||||
*/
|
||||
static public function registerMigration($class_name, $machine_name = NULL,
|
||||
array $arguments = array()) {
|
||||
array $arguments = array()) {
|
||||
// Support for legacy migration code - in later releases, the machine_name
|
||||
// should always be explicit.
|
||||
if (!$machine_name) {
|
||||
@@ -486,7 +528,7 @@ abstract class MigrationBase {
|
||||
|
||||
if (!preg_match('|^[a-z0-9_]+$|i', $machine_name)) {
|
||||
throw new Exception(t('!name is not a valid Migration machine name. Use only alphanumeric or underscore characters.',
|
||||
array('!name' => $machine_name)));
|
||||
array('!name' => $machine_name)));
|
||||
}
|
||||
|
||||
// We no longer have any need to store the machine_name in the arguments.
|
||||
@@ -509,10 +551,10 @@ abstract class MigrationBase {
|
||||
db_merge('migrate_status')
|
||||
->key(array('machine_name' => $machine_name))
|
||||
->fields(array(
|
||||
'class_name' => $class_name,
|
||||
'group_name' => $group_name,
|
||||
'arguments' => serialize($arguments)
|
||||
))
|
||||
'class_name' => $class_name,
|
||||
'group_name' => $group_name,
|
||||
'arguments' => serialize($arguments),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
|
||||
@@ -524,8 +566,8 @@ abstract class MigrationBase {
|
||||
*/
|
||||
static public function deregisterMigration($machine_name) {
|
||||
$rows_deleted = db_delete('migrate_status')
|
||||
->condition('machine_name', $machine_name)
|
||||
->execute();
|
||||
->condition('machine_name', $machine_name)
|
||||
->execute();
|
||||
// Make sure the group gets deleted if we were the only member.
|
||||
MigrateGroup::deleteOrphans();
|
||||
}
|
||||
@@ -583,10 +625,10 @@ abstract class MigrationBase {
|
||||
if (!isset($migrations[$machine_name_key])) {
|
||||
// See if we know about this migration
|
||||
$row = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('class_name', 'group_name', 'arguments'))
|
||||
->condition('machine_name', $machine_name)
|
||||
->execute()
|
||||
->fetchObject();
|
||||
->fields('ms', array('class_name', 'group_name', 'arguments'))
|
||||
->condition('machine_name', $machine_name)
|
||||
->execute()
|
||||
->fetchObject();
|
||||
if ($row) {
|
||||
$class_name = $row->class_name;
|
||||
$arguments = unserialize($row->arguments);
|
||||
@@ -603,8 +645,7 @@ abstract class MigrationBase {
|
||||
if (class_exists($class_name)) {
|
||||
try {
|
||||
$migrations[$machine_name_key] = new $class_name($arguments);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
self::displayMessage(t('Migration !machine could not be constructed.',
|
||||
array('!machine' => $machine_name)));
|
||||
self::displayMessage($e->getMessage());
|
||||
@@ -665,12 +706,14 @@ abstract class MigrationBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the given message appropriately (drush_print/drupal_set_message/etc.)
|
||||
* Output the given message appropriately
|
||||
* (drush_print/drupal_set_message/etc.)
|
||||
*
|
||||
* @param string $message
|
||||
* The message to output.
|
||||
* @param int $level
|
||||
* Optional message severity as understood by drupal_set_message and drush_log
|
||||
* Optional message severity as understood by drupal_set_message and
|
||||
* drush_log
|
||||
* (defaults to 'error').
|
||||
*/
|
||||
static public function displayMessage($message, $level = 'error') {
|
||||
@@ -690,12 +733,13 @@ abstract class MigrationBase {
|
||||
* @param $line
|
||||
* The line number the error was raised at.
|
||||
* @param $context
|
||||
* An array that points to the active symbol table at the point the error occurred.
|
||||
* An array that points to the active symbol table at the point the error
|
||||
* occurred.
|
||||
*/
|
||||
public function errorHandler($error_level, $message, $filename, $line, $context) {
|
||||
if ($error_level & error_reporting()) {
|
||||
$message .= "\n" . t('File !file, line !line',
|
||||
array('!line' => $line, '!file' => $filename));
|
||||
array('!line' => $line, '!file' => $filename));
|
||||
// Record notices and continue
|
||||
if ($error_level == E_NOTICE || $error_level == E_USER_NOTICE) {
|
||||
$this->saveMessage($message . "(file: $filename, line $line)", MigrationBase::MESSAGE_INFORMATIONAL);
|
||||
@@ -703,20 +747,21 @@ abstract class MigrationBase {
|
||||
// Simply ignore strict and deprecated errors
|
||||
// Note DEPRECATED constants introduced in PHP 5.3
|
||||
elseif (!($error_level == E_STRICT || $error_level == 8192 ||
|
||||
$error_level == 16384)) {
|
||||
$error_level == 16384)) {
|
||||
throw new MigrateException($message, MigrationBase::MESSAGE_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an Exception object and both saves and displays it, pulling additional
|
||||
* information on the location triggering the exception.
|
||||
* Takes an Exception object and both saves and displays it, pulling
|
||||
* additional information on the location triggering the exception.
|
||||
*
|
||||
* @param Exception $exception
|
||||
* Object representing the exception.
|
||||
* @param boolean $save
|
||||
* Whether to save the message in the migration's mapping table. Set to FALSE
|
||||
* Whether to save the message in the migration's mapping table. Set to
|
||||
* FALSE
|
||||
* in contexts where this doesn't make sense.
|
||||
*/
|
||||
public function handleException($exception, $save = TRUE) {
|
||||
@@ -730,6 +775,7 @@ abstract class MigrationBase {
|
||||
|
||||
/**
|
||||
* Check the current status of a migration.
|
||||
*
|
||||
* @return int
|
||||
* One of the MigrationBase::STATUS_* constants
|
||||
*/
|
||||
@@ -738,10 +784,10 @@ abstract class MigrationBase {
|
||||
return MigrationBase::STATUS_DISABLED;
|
||||
}
|
||||
$status = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('status'))
|
||||
->condition('machine_name', $this->machineName)
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('ms', array('status'))
|
||||
->condition('machine_name', $this->machineName)
|
||||
->execute()
|
||||
->fetchField();
|
||||
if (!isset($status)) {
|
||||
$status = MigrationBase::STATUS_IDLE;
|
||||
}
|
||||
@@ -750,19 +796,20 @@ abstract class MigrationBase {
|
||||
|
||||
/**
|
||||
* Retrieve the last time an import operation completed successfully.
|
||||
*
|
||||
* @return string
|
||||
* Date/time string, formatted... How? Default DB server format?
|
||||
*/
|
||||
public function getLastImported() {
|
||||
$last_imported = db_select('migrate_log', 'ml')
|
||||
->fields('ml', array('endtime'))
|
||||
->condition('machine_name', $this->machineName)
|
||||
->isNotNull('endtime')
|
||||
->orderBy('endtime', 'DESC')
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('ml', array('endtime'))
|
||||
->condition('machine_name', $this->machineName)
|
||||
->isNotNull('endtime')
|
||||
->orderBy('endtime', 'DESC')
|
||||
->execute()
|
||||
->fetchField();
|
||||
if ($last_imported) {
|
||||
$last_imported = date('Y-m-d H:i:s', $last_imported/1000);
|
||||
$last_imported = date('Y-m-d H:i:s', $last_imported / 1000);
|
||||
}
|
||||
else {
|
||||
$last_imported = '';
|
||||
@@ -778,10 +825,10 @@ abstract class MigrationBase {
|
||||
*/
|
||||
public function getHighwater() {
|
||||
$highwater = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('highwater'))
|
||||
->condition('machine_name', $this->machineName)
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('ms', array('highwater'))
|
||||
->condition('machine_name', $this->machineName)
|
||||
->execute()
|
||||
->fetchField();
|
||||
return $highwater;
|
||||
}
|
||||
|
||||
@@ -796,8 +843,8 @@ abstract class MigrationBase {
|
||||
protected function saveHighwater($highwater, $force = FALSE) {
|
||||
if (!isset($this->options['idlist'])) {
|
||||
$query = db_update('migrate_status')
|
||||
->fields(array('highwater' => $highwater))
|
||||
->condition('machine_name', $this->machineName);
|
||||
->fields(array('highwater' => $highwater))
|
||||
->condition('machine_name', $this->machineName);
|
||||
if (!$force) {
|
||||
if (!empty($this->highwaterField['type']) && $this->highwaterField['type'] == 'int') {
|
||||
// If the highwater is an integer type, we need to force the DB server
|
||||
@@ -808,9 +855,8 @@ abstract class MigrationBase {
|
||||
$query->where('(CASE WHEN highwater=\'\' THEN 0 ELSE CAST(highwater AS INTEGER) END) < :highwater', array(':highwater' => intval($highwater)));
|
||||
break;
|
||||
default:
|
||||
// CAST(highwater AS INTEGER) would be ideal, but won't
|
||||
// work in MySQL. This hack is thought to be portable.
|
||||
$query->where('(highwater+0) < :highwater', array(':highwater' => $highwater));
|
||||
// MySQL casts as integers as SIGNED or UNSIGNED.
|
||||
$query->where('(CASE WHEN highwater=\'\' THEN 0 ELSE CAST(highwater AS SIGNED) END) < :highwater', array(':highwater' => intval($highwater)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -823,20 +869,21 @@ abstract class MigrationBase {
|
||||
|
||||
/**
|
||||
* Retrieve the last throughput for current Migration (items / minute).
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastThroughput() {
|
||||
$last_throughput = 0;
|
||||
$row = db_select('migrate_log', 'ml')
|
||||
->fields('ml', array('starttime', 'endtime', 'numprocessed'))
|
||||
->condition('machine_name', $this->machineName)
|
||||
->condition('process_type', 1)
|
||||
->isNotNull('endtime')
|
||||
->orderBy('starttime', 'DESC')
|
||||
->execute()
|
||||
->fetchObject();
|
||||
->fields('ml', array('starttime', 'endtime', 'numprocessed'))
|
||||
->condition('machine_name', $this->machineName)
|
||||
->condition('process_type', 1)
|
||||
->isNotNull('endtime')
|
||||
->orderBy('starttime', 'DESC')
|
||||
->execute()
|
||||
->fetchObject();
|
||||
if ($row) {
|
||||
$elapsed = ($row->endtime - $row->starttime)/1000;
|
||||
$elapsed = ($row->endtime - $row->starttime) / 1000;
|
||||
if ($elapsed > 0) {
|
||||
$last_throughput = round(($row->numprocessed / $elapsed) * 60);
|
||||
}
|
||||
@@ -846,8 +893,9 @@ abstract class MigrationBase {
|
||||
|
||||
/**
|
||||
* Reports whether this migration process is complete. For a Migration, for
|
||||
* example, this would be whether all available source rows have been processed.
|
||||
* Other MigrationBase classes will need to return TRUE/FALSE appropriately.
|
||||
* example, this would be whether all available source rows have been
|
||||
* processed. Other MigrationBase classes will need to return TRUE/FALSE
|
||||
* appropriately.
|
||||
*/
|
||||
abstract public function isComplete();
|
||||
|
||||
@@ -904,6 +952,12 @@ abstract class MigrationBase {
|
||||
// Try to make the semaphore handling atomic (depends on DB support)
|
||||
$transaction = db_transaction();
|
||||
|
||||
// Save the current mail system, prior to disabling emails.
|
||||
$this->saveMailSystem();
|
||||
|
||||
// Prevent emails from being sent out during migrations.
|
||||
$this->disableMailSystem();
|
||||
|
||||
$this->starttime = microtime(TRUE);
|
||||
|
||||
// Check to make sure there's no process already running for this migration
|
||||
@@ -922,19 +976,22 @@ abstract class MigrationBase {
|
||||
|
||||
// Set an error handler for imports
|
||||
if ($newStatus == MigrationBase::STATUS_IMPORTING) {
|
||||
$this->previousErrorHandler = set_error_handler(array($this, 'errorHandler'));
|
||||
$this->previousErrorHandler = set_error_handler(array(
|
||||
$this,
|
||||
'errorHandler',
|
||||
));
|
||||
}
|
||||
|
||||
// Save the initial history record
|
||||
if ($this->logHistory) {
|
||||
$this->logID = db_insert('migrate_log')
|
||||
->fields(array(
|
||||
'machine_name' => $this->machineName,
|
||||
'process_type' => $newStatus,
|
||||
'starttime' => round(microtime(TRUE) * 1000),
|
||||
'initialHighwater' => $this->getHighwater(),
|
||||
))
|
||||
->execute();
|
||||
->fields(array(
|
||||
'machine_name' => $this->machineName,
|
||||
'process_type' => $newStatus,
|
||||
'starttime' => round(microtime(TRUE) * 1000),
|
||||
'initialHighwater' => $this->getHighwater(),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
|
||||
// If we're disabling any hooks, reset the static module_implements cache so
|
||||
@@ -950,8 +1007,8 @@ abstract class MigrationBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* End a rollback or import process, releasing the semaphore. Note that it must
|
||||
* be public to be callable as the shutdown function.
|
||||
* End a rollback or import process, releasing the semaphore. Note that it
|
||||
* must be public to be callable as the shutdown function.
|
||||
*/
|
||||
public function endProcess() {
|
||||
if ($this->previousErrorHandler) {
|
||||
@@ -960,7 +1017,14 @@ abstract class MigrationBase {
|
||||
}
|
||||
if ($this->processing) {
|
||||
$this->status = MigrationBase::STATUS_IDLE;
|
||||
$fields = array('class_name' => get_class($this), 'status' => MigrationBase::STATUS_IDLE);
|
||||
|
||||
// Restore the previous mail handler.
|
||||
$this->restoreMailSystem();
|
||||
|
||||
$fields = array(
|
||||
'class_name' => get_class($this),
|
||||
'status' => MigrationBase::STATUS_IDLE,
|
||||
);
|
||||
db_merge('migrate_status')
|
||||
->key(array('machine_name' => $this->machineName))
|
||||
->fields($fields)
|
||||
@@ -977,10 +1041,9 @@ abstract class MigrationBase {
|
||||
'numprocessed' => $this->total_processed,
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
} catch (PDOException $e) {
|
||||
Migration::displayMessage(t('Could not log operation on migration !name - possibly MigrationBase::beginProcess() was not called',
|
||||
array('!name' => $this->machineName)));
|
||||
array('!name' => $this->machineName)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1035,8 +1098,7 @@ abstract class MigrationBase {
|
||||
$this->beginProcess(MigrationBase::STATUS_ROLLING_BACK);
|
||||
try {
|
||||
$return = $this->rollback();
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
} catch (Exception $exception) {
|
||||
// If something bad happened, make sure we clear the semaphore
|
||||
$this->endProcess();
|
||||
throw $exception;
|
||||
@@ -1071,8 +1133,7 @@ abstract class MigrationBase {
|
||||
$this->beginProcess(MigrationBase::STATUS_IMPORTING);
|
||||
try {
|
||||
$return = $this->import();
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
} catch (Exception $exception) {
|
||||
// If something bad happened, make sure we clear the semaphore
|
||||
$this->endProcess();
|
||||
throw $exception;
|
||||
@@ -1117,43 +1178,50 @@ abstract class MigrationBase {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test whether we've exceeded the desired memory threshold. If so, output a message.
|
||||
* Test whether we've exceeded the desired memory threshold. If so, output a
|
||||
* message.
|
||||
*
|
||||
* @return boolean
|
||||
* TRUE if the threshold is exceeded, FALSE if not.
|
||||
*/
|
||||
protected function memoryExceeded() {
|
||||
$usage = memory_get_usage();
|
||||
$pct_memory = $usage/$this->memoryLimit;
|
||||
$pct_memory = $usage / $this->memoryLimit;
|
||||
if ($pct_memory > $this->memoryThreshold) {
|
||||
self::displayMessage(
|
||||
t('Memory usage is !usage (!pct% of limit !limit), resetting statics',
|
||||
array('!pct' => round($pct_memory*100),
|
||||
'!usage' => format_size($usage),
|
||||
'!limit' => format_size($this->memoryLimit))),
|
||||
array(
|
||||
'!pct' => round($pct_memory * 100),
|
||||
'!usage' => format_size($usage),
|
||||
'!limit' => format_size($this->memoryLimit),
|
||||
)),
|
||||
'warning');
|
||||
// First, try resetting Drupal's static storage - this frequently releases
|
||||
// plenty of memory to continue
|
||||
drupal_static_reset();
|
||||
$usage = memory_get_usage();
|
||||
$pct_memory = $usage/$this->memoryLimit;
|
||||
$pct_memory = $usage / $this->memoryLimit;
|
||||
// Use a lower threshold - we don't want to be in a situation where we keep
|
||||
// coming back here and trimming a tiny amount
|
||||
if ($pct_memory > (.90 * $this->memoryThreshold)) {
|
||||
self::displayMessage(
|
||||
t('Memory usage is now !usage (!pct% of limit !limit), not enough reclaimed, starting new batch',
|
||||
array('!pct' => round($pct_memory*100),
|
||||
'!usage' => format_size($usage),
|
||||
'!limit' => format_size($this->memoryLimit))),
|
||||
array(
|
||||
'!pct' => round($pct_memory * 100),
|
||||
'!usage' => format_size($usage),
|
||||
'!limit' => format_size($this->memoryLimit),
|
||||
)),
|
||||
'warning');
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
self::displayMessage(
|
||||
t('Memory usage is now !usage (!pct% of limit !limit), reclaimed enough, continuing',
|
||||
array('!pct' => round($pct_memory*100),
|
||||
'!usage' => format_size($usage),
|
||||
'!limit' => format_size($this->memoryLimit))),
|
||||
array(
|
||||
'!pct' => round($pct_memory * 100),
|
||||
'!usage' => format_size($usage),
|
||||
'!limit' => format_size($this->memoryLimit),
|
||||
)),
|
||||
'warning');
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1204,37 +1272,23 @@ abstract class MigrationBase {
|
||||
|
||||
/**
|
||||
* Encrypt an incoming value. Detects for existence of the Drupal 'Encrypt'
|
||||
* module or the mcrypt PHP extension.
|
||||
* module.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return string The encrypted value.
|
||||
*/
|
||||
static public function encrypt($value) {
|
||||
if (module_exists('encrypt')) {
|
||||
$value = encrypt($value);
|
||||
}
|
||||
else if (extension_loaded('mcrypt')) {
|
||||
// Mimic encrypt module to ensure compatibility
|
||||
$key = drupal_substr(variable_get('drupal_private_key', 'no_key'), 0, 32);
|
||||
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
|
||||
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
|
||||
$value = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $value,
|
||||
MCRYPT_MODE_ECB, $iv);
|
||||
|
||||
$encryption_array['text'] = $value;
|
||||
// For forward compatibility with the encrypt module.
|
||||
$encryption_array['method'] = 'mcrypt_rij_256';
|
||||
$encryption_array['key_name'] = 'drupal_private_key';
|
||||
$value = serialize($encryption_array);
|
||||
}
|
||||
else {
|
||||
if (self::$showEncryptionWarning) {
|
||||
MigrationBase::displayMessage(t('Encryption of secure migration information is not supported. Ensure the <a href="@encrypt">Encrypt module</a> or <a href="mcrypt">mcrypt PHP extension</a> is installed for this functionality.',
|
||||
array(
|
||||
'@encrypt' => 'http://drupal.org/project/encrypt',
|
||||
'@mcrypt' => 'http://php.net/manual/en/book.mcrypt.php',
|
||||
)
|
||||
),
|
||||
MigrationBase::displayMessage(t('Encryption of secure migration information is not supported. Ensure the <a href="@encrypt">Encrypt module</a> is installed for this functionality.',
|
||||
array(
|
||||
'@encrypt' => 'http://drupal.org/project/encrypt',
|
||||
)
|
||||
),
|
||||
'warning');
|
||||
self::$showEncryptionWarning = FALSE;
|
||||
}
|
||||
@@ -1246,33 +1300,20 @@ abstract class MigrationBase {
|
||||
* Decrypt an incoming value.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return string The encrypted value
|
||||
*/
|
||||
static public function decrypt($value) {
|
||||
if (module_exists('encrypt')) {
|
||||
$value = decrypt($value);
|
||||
}
|
||||
else if (extension_loaded('mcrypt')) {
|
||||
// Mimic encrypt module to ensure compatibility
|
||||
$encryption_array = unserialize($value);
|
||||
$method = $encryption_array['method']; // Not used right now
|
||||
$text = $encryption_array['text'];
|
||||
$key_name = $encryption_array['key_name']; // Not used right now
|
||||
|
||||
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
|
||||
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
|
||||
$key = drupal_substr(variable_get('drupal_private_key', 'no_key'), 0, 32);
|
||||
$value = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $text,
|
||||
MCRYPT_MODE_ECB, $iv);
|
||||
}
|
||||
else {
|
||||
if (self::$showEncryptionWarning) {
|
||||
MigrationBase::displayMessage(t('Encryption of secure migration information is not supported. Ensure the <a href="@encrypt">Encrypt module</a> or <a href="mcrypt">mcrypt PHP extension</a> is installed for this functionality.',
|
||||
array(
|
||||
'@encrypt' => 'http://drupal.org/project/encrypt',
|
||||
'@mcrypt' => 'http://php.net/manual/en/book.mcrypt.php',
|
||||
)
|
||||
),
|
||||
MigrationBase::displayMessage(t('Encryption of secure migration information is not supported. Ensure the <a href="@encrypt">Encrypt module</a> is installed for this functionality.',
|
||||
array(
|
||||
'@encrypt' => 'http://drupal.org/project/encrypt',
|
||||
)
|
||||
),
|
||||
'warning');
|
||||
self::$showEncryptionWarning = FALSE;
|
||||
}
|
||||
@@ -1329,12 +1370,18 @@ abstract class MigrationBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an incoming string (which may be a UNIX timestamp, or an arbitrarily-formatted
|
||||
* date/time string) to a UNIX timestamp.
|
||||
* Convert an incoming string (which may be a UNIX timestamp, or an
|
||||
* arbitrarily-formatted date/time string) to a UNIX timestamp.
|
||||
*
|
||||
* @param string $value
|
||||
* The time string to convert.
|
||||
* @param string $timezone
|
||||
* Optional timezone for the time string. NULL to leave the timezone unset.
|
||||
*
|
||||
* @return string
|
||||
* The UNIX timestamp.
|
||||
*/
|
||||
static public function timestamp($value) {
|
||||
static public function timestamp($value, $timezone = NULL) {
|
||||
// Does it look like it's already a timestamp? Just return it
|
||||
if (is_numeric($value)) {
|
||||
return $value;
|
||||
@@ -1345,7 +1392,10 @@ abstract class MigrationBase {
|
||||
return time();
|
||||
}
|
||||
|
||||
$date = new DateTime($value);
|
||||
if (isset($timezone)) {
|
||||
$timezone = new DateTimeZone($timezone);
|
||||
}
|
||||
$date = new DateTime($value, $timezone);
|
||||
$time = $date->format('U');
|
||||
if ($time == FALSE) {
|
||||
// Handles form YYYY-MM-DD HH:MM:SS.garbage
|
||||
@@ -1359,14 +1409,9 @@ abstract class MigrationBase {
|
||||
/**
|
||||
* Saves the current mail system, or set a system default if there is none.
|
||||
*/
|
||||
protected function saveMailSystem() {
|
||||
public function saveMailSystem() {
|
||||
global $conf;
|
||||
if (empty($conf['mail_system'])) {
|
||||
$conf['mail_system']['default-system'] = 'MigrateMailIgnore';
|
||||
}
|
||||
else {
|
||||
$this->mailSystem = $conf['mail_system'];
|
||||
}
|
||||
$this->mailSystem = empty($conf['mail_system']) ? NULL : $conf['mail_system'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1379,6 +1424,9 @@ abstract class MigrationBase {
|
||||
$conf['mail_system'][$system] = 'MigrateMailIgnore';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$conf['mail_system'] = array('default-system' => 'MigrateMailIgnore');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -13,11 +13,12 @@
|
||||
* MigrateDestinationEntity for an example.
|
||||
*/
|
||||
abstract class MigrateDestination {
|
||||
|
||||
/**
|
||||
* To support MigrateSQLMap maps, derived destination classes should return
|
||||
* schema field definition(s) corresponding to the primary key of the destination
|
||||
* being implemented. These are used to construct the destination key fields
|
||||
* of the map table for a migration using this destination.
|
||||
* schema field definition(s) corresponding to the primary key of the
|
||||
* destination being implemented. These are used to construct the destination
|
||||
* key fields of the map table for a migration using this destination.
|
||||
*
|
||||
* abstract static public function getKeySchema()
|
||||
*/
|
||||
@@ -36,6 +37,7 @@ abstract class MigrateDestination {
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
@@ -43,9 +45,9 @@ abstract class MigrateDestination {
|
||||
abstract public function fields();
|
||||
|
||||
/**
|
||||
* Derived classes must implement either bulkRollback or rollback() according to
|
||||
* the signatures below, to rollback (usually by deletion) previously-migrated
|
||||
* items.
|
||||
* Derived classes must implement either bulkRollback or rollback() according
|
||||
* to the signatures below, to rollback (usually by deletion)
|
||||
* previously-migrated items.
|
||||
*
|
||||
* $ids is an array of single-field keys to be deleted
|
||||
* abstract public function bulkRollback(array $ids);
|
||||
@@ -55,9 +57,10 @@ abstract class MigrateDestination {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Derived classes must implement import(), to construct one new object (pre-pppulated
|
||||
* using field mappings in the Migration). It is expected to call prepare and
|
||||
* complete handlers, passing them $row (the raw data from the source).
|
||||
* Derived classes must implement import(), to construct one new object
|
||||
* (pre-pppulated using field mappings in the Migration). It is expected to
|
||||
* call prepare and complete handlers, passing them $row (the raw data from
|
||||
* the source).
|
||||
*/
|
||||
abstract public function import(stdClass $object, stdClass $row);
|
||||
|
||||
@@ -78,10 +81,13 @@ abstract class MigrateDestination {
|
||||
* @var int
|
||||
*/
|
||||
protected $numCreated = 0;
|
||||
|
||||
public function getCreated() {
|
||||
return $this->numCreated;
|
||||
}
|
||||
|
||||
protected $numUpdated = 0;
|
||||
|
||||
public function getUpdated() {
|
||||
return $this->numUpdated;
|
||||
}
|
||||
@@ -105,6 +111,7 @@ abstract class MigrateDestination {
|
||||
* All destination handlers should be derived from MigrateDestinationHandler
|
||||
*/
|
||||
abstract class MigrateDestinationHandler extends MigrateHandler {
|
||||
|
||||
// Any one or more of these methods may be implemented
|
||||
|
||||
/**
|
||||
@@ -116,6 +123,7 @@ abstract class MigrateDestinationHandler extends MigrateHandler {
|
||||
* The bundle (article, blog, etc.), if any, for which to list fields.
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration providing the context.
|
||||
*
|
||||
* @return array
|
||||
* An array keyed by field name, with field descriptions as values.
|
||||
*/
|
||||
|
@@ -6,11 +6,14 @@
|
||||
*/
|
||||
|
||||
class MigrateException extends Exception {
|
||||
|
||||
/**
|
||||
* The level of the error being reported (a Migration::MESSAGE_* constant)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $level;
|
||||
|
||||
public function getLevel() {
|
||||
return $this->level;
|
||||
}
|
||||
@@ -22,6 +25,7 @@ class MigrateException extends Exception {
|
||||
* @var int
|
||||
*/
|
||||
protected $status;
|
||||
|
||||
public function getStatus() {
|
||||
return $this->status;
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
class MigrateFieldMapping {
|
||||
|
||||
/**
|
||||
* Destination field name for the mapping. If empty, the mapping is just a
|
||||
* stub for annotating the source field.
|
||||
@@ -14,6 +15,7 @@ class MigrateFieldMapping {
|
||||
* @var string
|
||||
*/
|
||||
protected $destinationField;
|
||||
|
||||
public function getDestinationField() {
|
||||
return $this->destinationField;
|
||||
}
|
||||
@@ -25,6 +27,7 @@ class MigrateFieldMapping {
|
||||
* @var string
|
||||
*/
|
||||
protected $sourceField;
|
||||
|
||||
public function getSourceField() {
|
||||
return $this->sourceField;
|
||||
}
|
||||
@@ -33,11 +36,15 @@ class MigrateFieldMapping {
|
||||
* @var int
|
||||
*/
|
||||
const MAPPING_SOURCE_CODE = 1;
|
||||
|
||||
const MAPPING_SOURCE_DB = 2;
|
||||
|
||||
protected $mappingSource = self::MAPPING_SOURCE_CODE;
|
||||
|
||||
public function getMappingSource() {
|
||||
return $this->mappingSource;
|
||||
}
|
||||
|
||||
public function setMappingSource($mapping_source) {
|
||||
$this->mappingSource = $mapping_source;
|
||||
}
|
||||
@@ -50,6 +57,7 @@ class MigrateFieldMapping {
|
||||
* @var mixed
|
||||
*/
|
||||
protected $defaultValue;
|
||||
|
||||
public function getDefaultValue() {
|
||||
return $this->defaultValue;
|
||||
}
|
||||
@@ -61,6 +69,7 @@ class MigrateFieldMapping {
|
||||
* @var string
|
||||
*/
|
||||
protected $separator;
|
||||
|
||||
public function getSeparator() {
|
||||
return $this->separator;
|
||||
}
|
||||
@@ -74,6 +83,7 @@ class MigrateFieldMapping {
|
||||
* An array of source migrations, or string for a single migration.
|
||||
*/
|
||||
protected $sourceMigration;
|
||||
|
||||
public function getSourceMigration() {
|
||||
return $this->sourceMigration;
|
||||
}
|
||||
@@ -84,6 +94,7 @@ class MigrateFieldMapping {
|
||||
* @var string
|
||||
*/
|
||||
protected $callbacks = array();
|
||||
|
||||
public function getCallbacks() {
|
||||
return $this->callbacks;
|
||||
}
|
||||
@@ -99,6 +110,7 @@ class MigrateFieldMapping {
|
||||
* @var string
|
||||
*/
|
||||
protected $dedupe;
|
||||
|
||||
public function getDedupe() {
|
||||
return $this->dedupe;
|
||||
}
|
||||
@@ -106,41 +118,49 @@ class MigrateFieldMapping {
|
||||
/**
|
||||
* Argument overrides. If present this will be an array, keyed by
|
||||
* a field API array key, with one or both of these entries:
|
||||
* 'source_field' - Name of the source field in the incoming row containing the
|
||||
* value to be assigned
|
||||
* 'default_value' - A constant value to be assigned in the absence of source_field
|
||||
* Deprecated - subfield notation is now preferred.
|
||||
* 'source_field' - Name of the source field in the incoming row containing
|
||||
* the value to be assigned
|
||||
* 'default_value' - A constant value to be assigned in the absence of
|
||||
* source_field Deprecated - subfield notation is now preferred.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments;
|
||||
|
||||
public function getArguments() {
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
protected $description = '';
|
||||
|
||||
public function getDescription() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
protected $issueGroup;
|
||||
|
||||
public function getIssueGroup() {
|
||||
return $this->issueGroup;
|
||||
}
|
||||
|
||||
protected $issueNumber;
|
||||
|
||||
public function getIssueNumber() {
|
||||
return $this->issueNumber;
|
||||
}
|
||||
|
||||
protected $issuePriority = self::ISSUE_PRIORITY_OK;
|
||||
|
||||
public function getIssuePriority() {
|
||||
return $this->issuePriority;
|
||||
}
|
||||
|
||||
const ISSUE_PRIORITY_OK = 1;
|
||||
|
||||
const ISSUE_PRIORITY_LOW = 2;
|
||||
|
||||
const ISSUE_PRIORITY_MEDIUM = 3;
|
||||
|
||||
const ISSUE_PRIORITY_BLOCKER = 4;
|
||||
|
||||
public static $priorities = array();
|
||||
@@ -177,7 +197,17 @@ class MigrateFieldMapping {
|
||||
}
|
||||
|
||||
public function callbacks($callbacks) {
|
||||
$this->callbacks = func_get_args();
|
||||
foreach (func_get_args() as $callback) {
|
||||
$this->callback($callback);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function callback($callback) {
|
||||
$this->callbacks[] = array(
|
||||
'callback' => $callback,
|
||||
'params' => array_slice(func_get_args(), 1),
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@@ -6,12 +6,14 @@
|
||||
*/
|
||||
|
||||
class MigrateGroup {
|
||||
|
||||
/**
|
||||
* The machine name of the group - used to identify it in drush commands.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
@@ -22,6 +24,7 @@ class MigrateGroup {
|
||||
* @var string
|
||||
*/
|
||||
protected $title;
|
||||
|
||||
public function getTitle() {
|
||||
return $this->title;
|
||||
}
|
||||
@@ -33,6 +36,7 @@ class MigrateGroup {
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = array();
|
||||
|
||||
public function getArguments() {
|
||||
return $this->arguments;
|
||||
}
|
||||
@@ -43,6 +47,7 @@ class MigrateGroup {
|
||||
* @var array
|
||||
*/
|
||||
protected $dependencies = array();
|
||||
|
||||
public function getDependencies() {
|
||||
return $this->dependencies;
|
||||
}
|
||||
@@ -53,6 +58,7 @@ class MigrateGroup {
|
||||
* @var array
|
||||
*/
|
||||
static protected $groupList = array();
|
||||
|
||||
static public function groups() {
|
||||
$groups = array();
|
||||
$dependent_groups = array();
|
||||
@@ -110,10 +116,10 @@ class MigrateGroup {
|
||||
static public function getInstance($name, $dependencies = array()) {
|
||||
if (empty(self::$groupList[$name])) {
|
||||
$row = db_select('migrate_group', 'mg')
|
||||
->fields('mg')
|
||||
->condition('name', $name)
|
||||
->execute()
|
||||
->fetchObject();
|
||||
->fields('mg')
|
||||
->condition('name', $name)
|
||||
->execute()
|
||||
->fetchObject();
|
||||
if ($row) {
|
||||
$arguments = unserialize($row->arguments);
|
||||
$arguments = MigrationBase::decryptArguments($arguments);
|
||||
@@ -141,8 +147,8 @@ class MigrateGroup {
|
||||
* A user-visible title for the group. Defaults to the machine name.
|
||||
*
|
||||
* @param array $arguments
|
||||
* An array of group arguments - generally data that applies to all migrations
|
||||
* in the group.
|
||||
* An array of group arguments - generally data that applies to all
|
||||
* migrations in the group.
|
||||
*/
|
||||
static public function register($name, $title = NULL, array $arguments = array()) {
|
||||
if (!$title) {
|
||||
@@ -156,9 +162,9 @@ class MigrateGroup {
|
||||
db_merge('migrate_group')
|
||||
->key(array('name' => $name))
|
||||
->fields(array(
|
||||
'title' => $title,
|
||||
'arguments' => serialize($arguments)
|
||||
))
|
||||
'title' => $title,
|
||||
'arguments' => serialize($arguments),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
|
||||
@@ -172,9 +178,9 @@ class MigrateGroup {
|
||||
*/
|
||||
static public function deregister($name) {
|
||||
$result = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('machine_name'))
|
||||
->condition('group_name', $name)
|
||||
->execute();
|
||||
->fields('ms', array('machine_name'))
|
||||
->condition('group_name', $name)
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
Migration::deregisterMigration($row->machine_name);
|
||||
}
|
||||
|
@@ -10,12 +10,15 @@
|
||||
* to implement appropriate methods (e.g., prepare, complete, or fields).
|
||||
*/
|
||||
abstract class MigrateHandler {
|
||||
|
||||
/**
|
||||
* List of other handler classes which should be invoked before the current one.
|
||||
* List of other handler classes which should be invoked before the current
|
||||
* one.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dependencies = array();
|
||||
|
||||
public function getDependencies() {
|
||||
return $this->dependencies;
|
||||
}
|
||||
@@ -27,6 +30,7 @@ abstract class MigrateHandler {
|
||||
* @var array
|
||||
*/
|
||||
protected $typesHandled = array();
|
||||
|
||||
public function getTypesHandled() {
|
||||
return $this->typesHandled;
|
||||
}
|
||||
|
@@ -10,12 +10,16 @@
|
||||
* for the purpose of rollback.
|
||||
*/
|
||||
abstract class MigrateMap implements Iterator {
|
||||
|
||||
/**
|
||||
* Codes reflecting the current status of a map row.
|
||||
*/
|
||||
const STATUS_IMPORTED = 0;
|
||||
|
||||
const STATUS_NEEDS_UPDATE = 1;
|
||||
|
||||
const STATUS_IGNORED = 2;
|
||||
|
||||
const STATUS_FAILED = 3;
|
||||
|
||||
/**
|
||||
@@ -23,6 +27,7 @@ abstract class MigrateMap implements Iterator {
|
||||
*
|
||||
*/
|
||||
const ROLLBACK_DELETE = 0;
|
||||
|
||||
const ROLLBACK_PRESERVE = 1;
|
||||
|
||||
/**
|
||||
@@ -32,7 +37,9 @@ abstract class MigrateMap implements Iterator {
|
||||
* @var array
|
||||
*/
|
||||
protected $sourceKey, $destinationKey;
|
||||
|
||||
abstract public function getSourceKey();
|
||||
|
||||
abstract public function getDestinationKey();
|
||||
|
||||
/**
|
||||
@@ -56,9 +63,11 @@ abstract class MigrateMap implements Iterator {
|
||||
* @var boolean
|
||||
*/
|
||||
protected $trackLastImported = FALSE;
|
||||
|
||||
public function getTrackLastImported() {
|
||||
return $this->trackLastImported;
|
||||
}
|
||||
|
||||
public function setTrackLastImported($trackLastImported) {
|
||||
if (is_bool($trackLastImported)) {
|
||||
$this->trackLastImported = $trackLastImported;
|
||||
@@ -76,8 +85,8 @@ abstract class MigrateMap implements Iterator {
|
||||
* @param $hash
|
||||
*/
|
||||
abstract public function saveIDMapping(stdClass $source_row, array $dest_ids,
|
||||
$status = MigrateMap::STATUS_IMPORTED,
|
||||
$rollback_action = MigrateMap::ROLLBACK_DELETE, $hash = NULL);
|
||||
$status = MigrateMap::STATUS_IMPORTED,
|
||||
$rollback_action = MigrateMap::ROLLBACK_DELETE, $hash = NULL);
|
||||
|
||||
/**
|
||||
* Record a message related to a source record
|
||||
@@ -147,6 +156,7 @@ abstract class MigrateMap implements Iterator {
|
||||
* Retrieve map data for a given source or destination item
|
||||
*/
|
||||
abstract public function getRowBySource(array $source_id);
|
||||
|
||||
abstract public function getRowByDestination(array $destination_id);
|
||||
|
||||
/**
|
||||
@@ -155,29 +165,32 @@ abstract class MigrateMap implements Iterator {
|
||||
abstract public function getRowsNeedingUpdate($count);
|
||||
|
||||
/**
|
||||
* Given a (possibly multi-field) destination key, return the (possibly multi-field)
|
||||
* source key mapped to it.
|
||||
* Given a (possibly multi-field) destination key, return the (possibly
|
||||
* multi-field) source key mapped to it.
|
||||
*
|
||||
* @param array $destination_id
|
||||
* Array of destination key values.
|
||||
*
|
||||
* @return array
|
||||
* Array of source key values, or NULL on failure.
|
||||
*/
|
||||
abstract public function lookupSourceID(array $destination_id);
|
||||
|
||||
/**
|
||||
* Given a (possibly multi-field) source key, return the (possibly multi-field)
|
||||
* destination key it is mapped to.
|
||||
* Given a (possibly multi-field) source key, return the (possibly
|
||||
* multi-field) destination key it is mapped to.
|
||||
*
|
||||
* @param array $source_id
|
||||
* Array of source key values.
|
||||
*
|
||||
* @return array
|
||||
* Array of destination key values, or NULL on failure.
|
||||
*/
|
||||
abstract public function lookupDestinationID(array $source_id);
|
||||
|
||||
/**
|
||||
* Remove any persistent storage used by this map (e.g., map and message tables)
|
||||
* Remove any persistent storage used by this map (e.g., map and message
|
||||
* tables)
|
||||
*/
|
||||
abstract public function destroy();
|
||||
}
|
||||
|
@@ -8,20 +8,24 @@
|
||||
/**
|
||||
* The base class for all import objects. This is where most of the smarts
|
||||
* of the migrate module resides. Migrations are created by deriving from this
|
||||
* class, and in the constructor (after calling parent::__construct()) initializing
|
||||
* at a minimum the name, description, source, and destination properties. The constructor
|
||||
* will also usually make several calls to addFieldMapping().
|
||||
* class, and in the constructor (after calling parent::__construct())
|
||||
* initializing at a minimum the name, description, source, and destination
|
||||
* properties. The constructor will also usually make several calls to
|
||||
* addFieldMapping().
|
||||
*/
|
||||
abstract class Migration extends MigrationBase {
|
||||
|
||||
/**
|
||||
* Source object for the migration, derived from MigrateSource.
|
||||
*
|
||||
* @var MigrateSource
|
||||
*/
|
||||
protected $source;
|
||||
|
||||
public function getSource() {
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
public function setSource(MigrateSource $source) {
|
||||
$this->source = $source;
|
||||
}
|
||||
@@ -32,9 +36,11 @@ abstract class Migration extends MigrationBase {
|
||||
* @var MigrateDestination
|
||||
*/
|
||||
protected $destination;
|
||||
|
||||
public function getDestination() {
|
||||
return $this->destination;
|
||||
}
|
||||
|
||||
public function setDestination(MigrateDestination $destination) {
|
||||
$this->destination = $destination;
|
||||
}
|
||||
@@ -45,9 +51,11 @@ abstract class Migration extends MigrationBase {
|
||||
* @var MigrateMap
|
||||
*/
|
||||
protected $map;
|
||||
|
||||
public function getMap() {
|
||||
return $this->map;
|
||||
}
|
||||
|
||||
public function setMap(MigrateMap $map) {
|
||||
$this->map = $map;
|
||||
}
|
||||
@@ -63,11 +71,15 @@ abstract class Migration extends MigrationBase {
|
||||
* @var int
|
||||
*/
|
||||
const SOURCE = 1;
|
||||
|
||||
const DESTINATION = 2;
|
||||
|
||||
protected $systemOfRecord = Migration::SOURCE;
|
||||
|
||||
public function getSystemOfRecord() {
|
||||
return $this->systemOfRecord;
|
||||
}
|
||||
|
||||
public function setSystemOfRecord($system_of_record) {
|
||||
$this->systemOfRecord = $system_of_record;
|
||||
}
|
||||
@@ -87,9 +99,11 @@ abstract class Migration extends MigrationBase {
|
||||
* @var int
|
||||
*/
|
||||
protected $defaultRollbackAction = MigrateMap::ROLLBACK_DELETE;
|
||||
|
||||
public function getDefaultRollbackAction() {
|
||||
return $this->defaultRollbackAction;
|
||||
}
|
||||
|
||||
public function setDefaultRollbackAction($rollback_action) {
|
||||
$this->defaultRollbackAction = $rollback_action;
|
||||
}
|
||||
@@ -107,7 +121,9 @@ abstract class Migration extends MigrationBase {
|
||||
* @var array
|
||||
*/
|
||||
protected $storedFieldMappings = array();
|
||||
|
||||
protected $storedFieldMappingsRetrieved = FALSE;
|
||||
|
||||
public function getStoredFieldMappings() {
|
||||
if (!$this->storedFieldMappingsRetrieved) {
|
||||
$this->loadFieldMappings();
|
||||
@@ -122,6 +138,7 @@ abstract class Migration extends MigrationBase {
|
||||
* @var array
|
||||
*/
|
||||
protected $codedFieldMappings = array();
|
||||
|
||||
public function getCodedFieldMappings() {
|
||||
return $this->codedFieldMappings;
|
||||
}
|
||||
@@ -133,10 +150,11 @@ abstract class Migration extends MigrationBase {
|
||||
* @var array
|
||||
*/
|
||||
protected $allFieldMappings = array();
|
||||
|
||||
public function getFieldMappings() {
|
||||
if (empty($allFieldMappings)) {
|
||||
$this->allFieldMappings = array_merge($this->getCodedFieldMappings(),
|
||||
$this->getStoredFieldMappings());
|
||||
$this->getStoredFieldMappings());
|
||||
// If there are multiple mappings of a given source field to no
|
||||
// destination field, keep only the last (so the UI can override a source
|
||||
// field DNM that was defined in code).
|
||||
@@ -193,21 +211,25 @@ abstract class Migration extends MigrationBase {
|
||||
* @var array
|
||||
*/
|
||||
protected $highwaterField = array();
|
||||
|
||||
public function getHighwaterField() {
|
||||
return $this->highwaterField;
|
||||
}
|
||||
|
||||
public function setHighwaterField(array $highwater_field) {
|
||||
$this->highwaterField = $highwater_field;
|
||||
}
|
||||
|
||||
/**
|
||||
* The object currently being constructed
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
protected $destinationValues;
|
||||
|
||||
/**
|
||||
* The current data row retrieved from the source.
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
protected $sourceValues;
|
||||
@@ -238,7 +260,7 @@ abstract class Migration extends MigrationBase {
|
||||
* @param array $arguments
|
||||
*/
|
||||
static public function registerMigration($class_name, $machine_name = NULL,
|
||||
array $arguments = array()) {
|
||||
array $arguments = array()) {
|
||||
// Record any field mappings provided via arguments.
|
||||
if (isset($arguments['field_mappings'])) {
|
||||
self::saveFieldMappings($machine_name, $arguments['field_mappings']);
|
||||
@@ -270,14 +292,13 @@ abstract class Migration extends MigrationBase {
|
||||
|
||||
// Remove stored field mappings for this migration
|
||||
$rows_deleted = db_delete('migrate_field_mapping')
|
||||
->condition('machine_name', $machine_name)
|
||||
->execute();
|
||||
->condition('machine_name', $machine_name)
|
||||
->execute();
|
||||
|
||||
// Call the parent deregistration (which clears migrate_status) last, the
|
||||
// above will reference it.
|
||||
parent::deregisterMigration($machine_name);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// Fail silently if it's already gone
|
||||
}
|
||||
}
|
||||
@@ -298,11 +319,11 @@ abstract class Migration extends MigrationBase {
|
||||
$source_field = $field_mapping->getSourceField();
|
||||
db_insert('migrate_field_mapping')
|
||||
->fields(array(
|
||||
'machine_name' => $machine_name,
|
||||
'destination_field' => is_null($destination_field) ? '' : $destination_field,
|
||||
'source_field' => is_null($source_field) ? '' : $source_field,
|
||||
'options' => serialize($field_mapping)
|
||||
))
|
||||
'machine_name' => $machine_name,
|
||||
'destination_field' => is_null($destination_field) ? '' : $destination_field,
|
||||
'source_field' => is_null($source_field) ? '' : $source_field,
|
||||
'options' => serialize($field_mapping),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
@@ -312,9 +333,9 @@ abstract class Migration extends MigrationBase {
|
||||
*/
|
||||
public function loadFieldMappings() {
|
||||
$result = db_select('migrate_field_mapping', 'mfm')
|
||||
->fields('mfm', array('destination_field', 'source_field', 'options'))
|
||||
->condition('machine_name', $this->machineName)
|
||||
->execute();
|
||||
->fields('mfm', array('destination_field', 'source_field', 'options'))
|
||||
->condition('machine_name', $this->machineName)
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
$field_mapping = unserialize($row->options);
|
||||
$field_mapping->setMappingSource(MigrateFieldMapping::MAPPING_SOURCE_DB);
|
||||
@@ -346,11 +367,14 @@ abstract class Migration extends MigrationBase {
|
||||
$warn_on_override = TRUE) {
|
||||
// Warn of duplicate mappings
|
||||
if ($warn_on_override && !is_null($destination_field) &&
|
||||
isset($this->codedFieldMappings[$destination_field])) {
|
||||
isset($this->codedFieldMappings[$destination_field])) {
|
||||
self::displayMessage(
|
||||
t('!name addFieldMapping: !dest was previously mapped from !source, overridden',
|
||||
array('!name' => $this->machineName, '!dest' => $destination_field,
|
||||
'!source' => $this->codedFieldMappings[$destination_field]->getSourceField())),
|
||||
array(
|
||||
'!name' => $this->machineName,
|
||||
'!dest' => $destination_field,
|
||||
'!source' => $this->codedFieldMappings[$destination_field]->getSourceField(),
|
||||
)),
|
||||
'warning');
|
||||
}
|
||||
$mapping = new MigrateFieldMapping($destination_field, $source_field);
|
||||
@@ -413,7 +437,7 @@ abstract class Migration extends MigrationBase {
|
||||
}
|
||||
foreach ($fields as $field) {
|
||||
$this->addFieldMapping($field, NULL, $warn_on_override)
|
||||
->issueGroup($issue_group);
|
||||
->issueGroup($issue_group);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,7 +457,7 @@ abstract class Migration extends MigrationBase {
|
||||
}
|
||||
foreach ($fields as $field) {
|
||||
$this->addFieldMapping(NULL, $field, $warn_on_override)
|
||||
->issueGroup($issue_group);
|
||||
->issueGroup($issue_group);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,7 +488,7 @@ abstract class Migration extends MigrationBase {
|
||||
|
||||
// Do some standard setup
|
||||
if (isset($this->options['feedback']) && isset($this->options['feedback']['value']) &&
|
||||
isset($this->options['feedback']['unit'])) {
|
||||
isset($this->options['feedback']['unit'])) {
|
||||
$this->feedback = $this->options['feedback']['value'];
|
||||
$this->feedback_unit = $this->options['feedback']['unit'];
|
||||
if ($this->feedback_unit == 'item') {
|
||||
@@ -477,7 +501,7 @@ abstract class Migration extends MigrationBase {
|
||||
$this->lastfeedback = $this->starttime;
|
||||
|
||||
$this->total_processed = $this->total_successes =
|
||||
$this->processed_since_feedback = $this->successes_since_feedback = 0;
|
||||
$this->processed_since_feedback = $this->successes_since_feedback = 0;
|
||||
|
||||
// Call pre-process methods
|
||||
if ($this->status == Migration::STATUS_IMPORTING) {
|
||||
@@ -572,7 +596,7 @@ abstract class Migration extends MigrationBase {
|
||||
// Note that bulk rollback is only supported for single-column keys
|
||||
$sourceids[] = $current_source_key;
|
||||
if (!empty($destination_key->destid1)) {
|
||||
$map_row = $this->map->getRowByDestination((array)$destination_key);
|
||||
$map_row = $this->map->getRowByDestination((array) $destination_key);
|
||||
if ($map_row['rollback_action'] == MigrateMap::ROLLBACK_DELETE) {
|
||||
$destids[] = $destination_key->destid1;
|
||||
}
|
||||
@@ -594,8 +618,7 @@ abstract class Migration extends MigrationBase {
|
||||
migrate_instrument_stop('rollback map/message update');
|
||||
$this->total_successes += $batch_count;
|
||||
$this->successes_since_feedback += $batch_count;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$this->handleException($e, FALSE);
|
||||
migrate_instrument_stop('bulkRollback');
|
||||
migrate_instrument_stop('rollback map/message update');
|
||||
@@ -656,10 +679,10 @@ abstract class Migration extends MigrationBase {
|
||||
}
|
||||
}
|
||||
if (!$skip) {
|
||||
$map_row = $this->map->getRowByDestination((array)$destination_key);
|
||||
$map_row = $this->map->getRowByDestination((array) $destination_key);
|
||||
if ($map_row['rollback_action'] == MigrateMap::ROLLBACK_DELETE) {
|
||||
migrate_instrument_start('destination rollback');
|
||||
$this->destination->rollback((array)$destination_key);
|
||||
$this->destination->rollback((array) $destination_key);
|
||||
migrate_instrument_stop('destination rollback');
|
||||
}
|
||||
}
|
||||
@@ -670,8 +693,7 @@ abstract class Migration extends MigrationBase {
|
||||
migrate_instrument_stop('rollback map/message update');
|
||||
$this->total_successes++;
|
||||
$this->successes_since_feedback++;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// TODO: At least count failures
|
||||
continue;
|
||||
}
|
||||
@@ -701,11 +723,15 @@ abstract class Migration extends MigrationBase {
|
||||
|
||||
try {
|
||||
$this->source->rewind();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
self::displayMessage(
|
||||
t('Migration failed with source plugin exception: %e, in %file:%line',
|
||||
array('%e' => $e->getMessage(), '%file' => $e->getFile(), '%line' => $e->getLine())));
|
||||
t('Migration for %class failed with source plugin exception: %e, in %file:%line',
|
||||
array(
|
||||
'%class' => get_class($this),
|
||||
'%e' => $e->getMessage(),
|
||||
'%file' => $e->getFile(),
|
||||
'%line' => $e->getLine(),
|
||||
)));
|
||||
return MigrationBase::RESULT_FAILED;
|
||||
}
|
||||
while ($this->source->valid()) {
|
||||
@@ -732,24 +758,22 @@ abstract class Migration extends MigrationBase {
|
||||
else {
|
||||
$this->map->saveIDMapping($this->sourceValues, array(),
|
||||
MigrateMap::STATUS_FAILED, $this->rollbackAction,
|
||||
$data_row->migrate_map_hash);
|
||||
NULL);
|
||||
if ($this->map->messageCount() == 0) {
|
||||
$message = t('New object was not saved, no error provided');
|
||||
$this->saveMessage($message);
|
||||
self::displayMessage($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
$this->map->saveIDMapping($this->sourceValues, array(),
|
||||
$e->getStatus(), $this->rollbackAction, $data_row->migrate_map_hash);
|
||||
$this->saveMessage($e->getMessage(), $e->getLevel());
|
||||
self::displayMessage($e->getMessage());
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$this->map->saveIDMapping($this->sourceValues, array(),
|
||||
MigrateMap::STATUS_FAILED, $this->rollbackAction,
|
||||
$data_row->migrate_map_hash);
|
||||
NULL);
|
||||
$this->handleException($e);
|
||||
}
|
||||
$this->total_processed++;
|
||||
@@ -779,11 +803,15 @@ abstract class Migration extends MigrationBase {
|
||||
}
|
||||
try {
|
||||
$this->source->next();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
self::displayMessage(
|
||||
t('Migration failed with source plugin exception: %e, in %file:%line',
|
||||
array('%e' => $e->getMessage(), '%file' => $e->getFile(), '%line' => $e->getLine())));
|
||||
t('Migration for %class failed with source plugin exception: %e, in %file:%line',
|
||||
array(
|
||||
'%class' => get_class($this),
|
||||
'%e' => $e->getMessage(),
|
||||
'%file' => $e->getFile(),
|
||||
'%line' => $e->getLine(),
|
||||
)));
|
||||
return MigrationBase::RESULT_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -805,8 +833,7 @@ abstract class Migration extends MigrationBase {
|
||||
self::$currentMigration = $this;
|
||||
try {
|
||||
$this->source->rewind();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
self::displayMessage(
|
||||
t('Migration analysis failed with source plugin exception: !e',
|
||||
array('!e' => $e->getMessage())));
|
||||
@@ -901,8 +928,7 @@ abstract class Migration extends MigrationBase {
|
||||
|
||||
try {
|
||||
$this->source->next();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
self::displayMessage(
|
||||
t('Migration analysis failed with source plugin exception: !e. Partial results follow:',
|
||||
array('!e' => $e->getMessage())));
|
||||
@@ -940,17 +966,18 @@ abstract class Migration extends MigrationBase {
|
||||
public function prepareKey($source_key, $row) {
|
||||
$key = array();
|
||||
foreach ($source_key as $field_name => $field_schema) {
|
||||
$key[$field_name] = $row->$field_name;
|
||||
$key[$field_name] = $row->{$field_name};
|
||||
}
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of prepareRow(). This method is called from the source
|
||||
* plugin upon first pulling the raw data from the source.
|
||||
* Default implementation of prepareRow(). This method is called from the
|
||||
* source plugin upon first pulling the raw data from the source.
|
||||
*
|
||||
* @param $row
|
||||
* Object containing raw source data.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE to process this row, FALSE to have the source skip it.
|
||||
*/
|
||||
@@ -971,8 +998,7 @@ abstract class Migration extends MigrationBase {
|
||||
public function sourceCount($refresh = FALSE) {
|
||||
try {
|
||||
$count = $this->source->count($refresh);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$count = t('N/A');
|
||||
self::displayMessage($e->getMessage());
|
||||
}
|
||||
@@ -981,14 +1007,14 @@ abstract class Migration extends MigrationBase {
|
||||
|
||||
/**
|
||||
* Get the number of source records processed.
|
||||
*
|
||||
* @return int
|
||||
* Number of processed records.
|
||||
*/
|
||||
public function processedCount() {
|
||||
try {
|
||||
$count = $this->map->processedCount();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$count = t('N/A');
|
||||
self::displayMessage($e->getMessage());
|
||||
}
|
||||
@@ -997,14 +1023,14 @@ abstract class Migration extends MigrationBase {
|
||||
|
||||
/**
|
||||
* Get the number of records successfully imported.
|
||||
*
|
||||
* @return int
|
||||
* Number of imported records.
|
||||
*/
|
||||
public function importedCount() {
|
||||
try {
|
||||
$count = $this->map->importedCount();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$count = t('N/A');
|
||||
self::displayMessage($e->getMessage());
|
||||
}
|
||||
@@ -1013,13 +1039,13 @@ abstract class Migration extends MigrationBase {
|
||||
|
||||
/**
|
||||
* Get the number of records marked as needing update.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function updateCount() {
|
||||
try {
|
||||
$count = $this->map->updateCount();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$count = t('N/A');
|
||||
self::displayMessage($e->getMessage());
|
||||
}
|
||||
@@ -1072,15 +1098,17 @@ abstract class Migration extends MigrationBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a progress message, reflecting the current status of a migration process.
|
||||
* Outputs a progress message, reflecting the current status of a migration
|
||||
* process.
|
||||
*
|
||||
* @param int $result
|
||||
* Status of the process, represented by one of the Migration::RESULT_* constants.
|
||||
* Status of the process, represented by one of the Migration::RESULT_*
|
||||
* constants.
|
||||
*/
|
||||
protected function progressMessage($result) {
|
||||
$time = microtime(TRUE) - $this->lastfeedback;
|
||||
if ($time > 0) {
|
||||
$perminute = round(60*$this->processed_since_feedback/$time);
|
||||
$perminute = round(60 * $this->processed_since_feedback / $time);
|
||||
$time = round($time, 1);
|
||||
}
|
||||
else {
|
||||
@@ -1129,31 +1157,37 @@ abstract class Migration extends MigrationBase {
|
||||
}
|
||||
$numitems = $this->processed_since_feedback + $this->source->getIgnored();
|
||||
$message = t($basetext,
|
||||
array('!numitems' => $numitems,
|
||||
'!successes' => $this->successes_since_feedback,
|
||||
'!failed' => $this->processed_since_feedback - $this->successes_since_feedback,
|
||||
'!created' => $this->destination->getCreated(),
|
||||
'!updated' => $this->destination->getUpdated(),
|
||||
'!ignored' => $this->source->getIgnored(),
|
||||
'!time' => $time,
|
||||
'!perminute' => $perminute,
|
||||
'!name' => $this->machineName));
|
||||
array(
|
||||
'!numitems' => $numitems,
|
||||
'!successes' => $this->successes_since_feedback,
|
||||
'!failed' => $this->processed_since_feedback - $this->successes_since_feedback,
|
||||
'!created' => $this->destination->getCreated(),
|
||||
'!updated' => $this->destination->getUpdated(),
|
||||
'!ignored' => $this->source->getIgnored(),
|
||||
'!time' => $time,
|
||||
'!perminute' => $perminute,
|
||||
'!name' => $this->machineName,
|
||||
));
|
||||
self::displayMessage($message, $type);
|
||||
|
||||
// Report on lookup_cache hit rate. Only visible at 'debug' level.
|
||||
if ($result != Migration::RESULT_INCOMPLETE && !empty($this->counts['lookup_cache'])) {
|
||||
foreach ($this->counts['lookup_cache'] as $name => $tallies) {
|
||||
$tallies += array('hit' => 0, 'miss_hit' => 0, 'miss_miss' => 0); // Set defaults to avoid NOTICE.
|
||||
$sum = $tallies['hit']+$tallies['miss_hit']+$tallies['miss_miss'];
|
||||
$tallies += array(
|
||||
'hit' => 0,
|
||||
'miss_hit' => 0,
|
||||
'miss_miss' => 0,
|
||||
); // Set defaults to avoid NOTICE.
|
||||
$sum = $tallies['hit'] + $tallies['miss_hit'] + $tallies['miss_miss'];
|
||||
self::displayMessage(
|
||||
t('Lookup cache: !mn SM=!name !hit hit, !miss_hit miss_hit, !miss_miss miss_miss (!total total).', array(
|
||||
'!mn' => $this->machineName,
|
||||
'!name' => $name,
|
||||
'!hit' => round((100*$tallies['hit'])/$sum) . '%',
|
||||
'!miss_hit' => round((100*$tallies['miss_hit'])/$sum) . '%',
|
||||
'!miss_miss' => round((100*$tallies['miss_miss'])/$sum) . '%',
|
||||
'!total' => $sum
|
||||
)), 'debug');
|
||||
'!mn' => $this->machineName,
|
||||
'!name' => $name,
|
||||
'!hit' => round((100 * $tallies['hit']) / $sum) . '%',
|
||||
'!miss_hit' => round((100 * $tallies['miss_hit']) / $sum) . '%',
|
||||
'!miss_miss' => round((100 * $tallies['miss_miss']) / $sum) . '%',
|
||||
'!total' => $sum,
|
||||
)), 'debug');
|
||||
}
|
||||
$this->counts['lookup_cache'] = array();
|
||||
}
|
||||
@@ -1182,7 +1216,7 @@ abstract class Migration extends MigrationBase {
|
||||
// If feedback is requested, produce a progress message at the proper time
|
||||
if (isset($this->feedback)) {
|
||||
if (($this->feedback_unit == 'seconds' && time() - $this->lastfeedback >= $this->feedback) ||
|
||||
($this->feedback_unit == 'items' && $this->processed_since_feedback >= $this->feedback)) {
|
||||
($this->feedback_unit == 'items' && $this->processed_since_feedback >= $this->feedback)) {
|
||||
$this->progressMessage(MigrationBase::RESULT_INCOMPLETE);
|
||||
}
|
||||
}
|
||||
@@ -1214,7 +1248,7 @@ abstract class Migration extends MigrationBase {
|
||||
// If there's a source mapping, and a source value in the data row, copy
|
||||
// to the destination
|
||||
if ($source && isset($this->sourceValues->{$source})) {
|
||||
$destination_values = $this->sourceValues->$source;
|
||||
$destination_values = $this->sourceValues->{$source};
|
||||
}
|
||||
// Otherwise, apply the default value (if any)
|
||||
elseif (!is_null($default)) {
|
||||
@@ -1225,7 +1259,25 @@ abstract class Migration extends MigrationBase {
|
||||
// will be populated as an array exploded from the source value
|
||||
$separator = $mapping->getSeparator();
|
||||
if ($separator && isset($destination_values)) {
|
||||
$destination_values = explode($separator, $destination_values);
|
||||
if (is_array($separator)) {
|
||||
if (isset($separator['group separator'])) {
|
||||
$destination_values = explode($separator['group separator'], $destination_values);
|
||||
}
|
||||
else {
|
||||
$destination_values = array($destination_values);
|
||||
}
|
||||
foreach ($destination_values as $group => $value) {
|
||||
if (isset($separator['key separator'])) {
|
||||
$destination_values[$group] = explode($separator['key separator'], $value);
|
||||
}
|
||||
else {
|
||||
$destination_values[$group] = array($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$destination_values = explode($separator, $destination_values);
|
||||
}
|
||||
}
|
||||
|
||||
// If a source migration is supplied, use the current value for this field
|
||||
@@ -1239,7 +1291,7 @@ abstract class Migration extends MigrationBase {
|
||||
$callbacks = $mapping->getCallbacks();
|
||||
foreach ($callbacks as $callback) {
|
||||
if (isset($destination_values)) {
|
||||
$destination_values = call_user_func($callback, $destination_values);
|
||||
$destination_values = call_user_func_array($callback['callback'], array_merge(array($destination_values), $callback['params']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1262,7 +1314,7 @@ abstract class Migration extends MigrationBase {
|
||||
$destination_values['arguments'] = array();
|
||||
foreach ($arguments as $argname => $destarg) {
|
||||
if (is_array($destarg) && isset($destarg['source_field']) && property_exists($this->sourceValues, $destarg['source_field'])) {
|
||||
$destination_values['arguments'][$argname] = $this->sourceValues->$destarg['source_field'];
|
||||
$destination_values['arguments'][$argname] = $this->sourceValues->{$destarg['source_field']};
|
||||
}
|
||||
elseif (is_array($destarg) && isset($destarg['default_value'])) {
|
||||
$destination_values['arguments'][$argname] = $destarg['default_value'];
|
||||
@@ -1281,47 +1333,47 @@ abstract class Migration extends MigrationBase {
|
||||
// last one.
|
||||
$destination_count = count($destination);
|
||||
$destination_field = $destination[0];
|
||||
if ($destination_count == 2) {
|
||||
if ($destination_count == 2) {
|
||||
$subfield = $destination[1];
|
||||
// We're processing the subfield before the primary value, initialize it
|
||||
if (!property_exists($this->destinationValues, $destination_field)) {
|
||||
$this->destinationValues->$destination_field = array();
|
||||
$this->destinationValues->{$destination_field} = array();
|
||||
}
|
||||
// We have a value, and need to convert to an array so we can add
|
||||
// arguments.
|
||||
elseif (!is_array($this->destinationValues->$destination_field)) {
|
||||
$this->destinationValues->$destination_field = array($this->destinationValues->$destination_field);
|
||||
elseif (!is_array($this->destinationValues->{$destination_field})) {
|
||||
$this->destinationValues->{$destination_field} = array($this->destinationValues->{$destination_field});
|
||||
}
|
||||
// Add the subfield value to the arguments array.
|
||||
$this->destinationValues->{$destination_field}['arguments'][$subfield] = $destination_values;
|
||||
}
|
||||
elseif ($destination_count == 3) {
|
||||
$subfield2 = $destination[2];
|
||||
// We're processing the subfield before the primary value, initialize it
|
||||
if (!property_exists($this->destinationValues, $destination_field)) {
|
||||
$this->destinationValues->$destination_field = array();
|
||||
}
|
||||
// We have a value, and need to convert to an array so we can add
|
||||
// arguments.
|
||||
elseif (!is_array($this->destinationValues->$destination_field)) {
|
||||
$this->destinationValues->$destination_field = array($this->destinationValues->$destination_field);
|
||||
}
|
||||
if (!is_array($this->destinationValues->{$destination_field}['arguments'][$destination[1]])) {
|
||||
// Convert first subfield level to an array so we can add to it.
|
||||
$this->destinationValues->{$destination_field}['arguments'][$destination[1]] = array( $this->destinationValues->{$destination_field}['arguments'][$destination[1]] );
|
||||
}
|
||||
// Add the subfield value to the arguments array.
|
||||
$this->destinationValues->{$destination_field}['arguments'][$destination[1]]['arguments'][$subfield2] = $destination_values;
|
||||
$subfield2 = $destination[2];
|
||||
// We're processing the subfield before the primary value, initialize it
|
||||
if (!property_exists($this->destinationValues, $destination_field)) {
|
||||
$this->destinationValues->{$destination_field} = array();
|
||||
}
|
||||
// We have a value, and need to convert to an array so we can add
|
||||
// arguments.
|
||||
elseif (!is_array($this->destinationValues->{$destination_field})) {
|
||||
$this->destinationValues->{$destination_field} = array($this->destinationValues->{$destination_field});
|
||||
}
|
||||
if (!is_array($this->destinationValues->{$destination_field}['arguments'][$destination[1]])) {
|
||||
// Convert first subfield level to an array so we can add to it.
|
||||
$this->destinationValues->{$destination_field}['arguments'][$destination[1]] = array($this->destinationValues->{$destination_field}['arguments'][$destination[1]]);
|
||||
}
|
||||
// Add the subfield value to the arguments array.
|
||||
$this->destinationValues->{$destination_field}['arguments'][$destination[1]]['arguments'][$subfield2] = $destination_values;
|
||||
}
|
||||
// Just the primary value, the first time through for this field, simply
|
||||
// set it.
|
||||
elseif (!property_exists($this->destinationValues, $destination_field)) {
|
||||
$this->destinationValues->$destination_field = $destination_values;
|
||||
$this->destinationValues->{$destination_field} = $destination_values;
|
||||
}
|
||||
// We've seen a subfield, so add as an array value.
|
||||
else {
|
||||
$this->destinationValues->{$destination_field} = array_merge(
|
||||
(array)$destination_values, $this->destinationValues->{$destination_field});
|
||||
(array) $destination_values, $this->destinationValues->{$destination_field});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1333,14 +1385,15 @@ abstract class Migration extends MigrationBase {
|
||||
* @param mixed $source_migrations
|
||||
* An array of source migrations, or string for a single migration.
|
||||
* @param mixed $source_keys
|
||||
* Key(s) to be looked up against the source migration(s). This may be a simple
|
||||
* value (one single-field key), an array of values (multiple single-field keys
|
||||
* to each be looked up), or an array of arrays (multiple multi-field keys to
|
||||
* each be looked up).
|
||||
* Key(s) to be looked up against the source migration(s). This may be a
|
||||
* simple value (one single-field key), an array of values (multiple
|
||||
* single-field keys to each be looked up), or an array of arrays (multiple
|
||||
* multi-field keys to each be looked up).
|
||||
* @param mixed $default
|
||||
* The default value, if no ID was found.
|
||||
* @param $migration
|
||||
* The implementing migration.
|
||||
*
|
||||
* @return
|
||||
* Destination value(s) from the source migration(s), as a single value if
|
||||
* a single key was passed in, or an array of values if there were multiple
|
||||
@@ -1377,6 +1430,11 @@ abstract class Migration extends MigrationBase {
|
||||
// Instantiate each migration, and store back in the array.
|
||||
foreach ($source_migrations as $key => $source_migration) {
|
||||
$source_migrations[$key] = Migration::getInstance($source_migration);
|
||||
if (!isset($source_migrations[$key])) {
|
||||
MigrationBase::displayMessage(t('The @source cannot be resolved to a migration instance.',
|
||||
array('@source' => $source_migration)));
|
||||
unset($source_migrations[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$results = array();
|
||||
@@ -1398,7 +1456,8 @@ abstract class Migration extends MigrationBase {
|
||||
// Loop through each source migration, checking for an existing dest ID.
|
||||
foreach ($source_migrations as $source_migration) {
|
||||
// Break out of the loop as soon as a destination ID is found.
|
||||
if ($destids = $source_migration->getMap()->lookupDestinationID($source_key)) {
|
||||
if ($destids = $source_migration->getMap()
|
||||
->lookupDestinationID($source_key)) {
|
||||
if (!empty($destids['destid1'])) {
|
||||
break;
|
||||
}
|
||||
@@ -1448,16 +1507,18 @@ abstract class Migration extends MigrationBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* For fields which require uniqueness, assign a new unique value if necessary.
|
||||
* For fields which require uniqueness, assign a new unique value if
|
||||
* necessary.
|
||||
*
|
||||
* @param array $dedupe
|
||||
* An array with two keys, 'table' the name of the Drupal table and 'column'
|
||||
* the column within that table where uniqueness must be maintained.
|
||||
* @param $original
|
||||
* The value coming in, which must be checked for uniqueness.
|
||||
*
|
||||
* @return string
|
||||
* The value to use - either the original, or a variation created by appending
|
||||
* a sequence number.
|
||||
* The value to use - either the original, or a variation created by
|
||||
* appending a sequence number.
|
||||
*/
|
||||
protected function handleDedupe($dedupe, $original) {
|
||||
// If we're remigrating a previously-existing value, simply running through
|
||||
@@ -1468,11 +1529,11 @@ abstract class Migration extends MigrationBase {
|
||||
if (isset($this->sourceValues->migrate_map_destid1)) {
|
||||
$key_field = key($this->destination->getKeySchema());
|
||||
$existing_value = db_select($dedupe['table'], 't')
|
||||
->fields('t', array($dedupe['column']))
|
||||
->range(0, 1)
|
||||
->condition($key_field, $this->sourceValues->migrate_map_destid1)
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('t', array($dedupe['column']))
|
||||
->range(0, 1)
|
||||
->condition($key_field, $this->sourceValues->migrate_map_destid1)
|
||||
->execute()
|
||||
->fetchField();
|
||||
// Note that if, for some reason, we don't find a value, fall through
|
||||
// to the normal deduping process
|
||||
if ($existing_value) {
|
||||
@@ -1481,12 +1542,12 @@ abstract class Migration extends MigrationBase {
|
||||
}
|
||||
$i = 1;
|
||||
$candidate = $original;
|
||||
while ($candidate_found = db_select($dedupe['table'], 't')
|
||||
->fields('t', array($dedupe['column']))
|
||||
->range(0, 1)
|
||||
->condition('t.' . $dedupe['column'], $candidate)
|
||||
->execute()
|
||||
->fetchField()) {
|
||||
while (db_select($dedupe['table'], 't')
|
||||
->fields('t', array($dedupe['column']))
|
||||
->range(0, 1)
|
||||
->condition('t.' . $dedupe['column'], $candidate)
|
||||
->execute()
|
||||
->rowCount() > 0) {
|
||||
// We already have the candidate value. Find a non-existing value.
|
||||
$i++;
|
||||
// @TODO: support custom replacement pattern instead of just append.
|
||||
@@ -1494,9 +1555,11 @@ abstract class Migration extends MigrationBase {
|
||||
}
|
||||
if ($i > 1) {
|
||||
$message = t('Replacing !column !original with !candidate',
|
||||
array('!column' => $dedupe['column'],
|
||||
'!original' => $original,
|
||||
'!candidate' => $candidate));
|
||||
array(
|
||||
'!column' => $dedupe['column'],
|
||||
'!original' => $original,
|
||||
'!candidate' => $candidate,
|
||||
));
|
||||
$migration = Migration::currentMigration();
|
||||
$migration->saveMessage($message, Migration::MESSAGE_INFORMATIONAL);
|
||||
}
|
||||
@@ -1515,7 +1578,7 @@ abstract class Migration extends MigrationBase {
|
||||
$data_row = new stdClass;
|
||||
$i = 0;
|
||||
foreach ($map_source_key as $key => $definition) {
|
||||
$data_row->$key = $source_key[$i++];
|
||||
$data_row->{$key} = $source_key[$i++];
|
||||
}
|
||||
$this->map->saveIDMapping($data_row, $destids,
|
||||
MigrateMap::STATUS_NEEDS_UPDATE, $this->defaultRollbackAction);
|
||||
@@ -1577,15 +1640,18 @@ abstract class Migration extends MigrationBase {
|
||||
* Migration instead.
|
||||
*/
|
||||
abstract class DynamicMigration extends Migration {
|
||||
|
||||
static $deprecationWarning = FALSE;
|
||||
|
||||
public function __construct($arguments) {
|
||||
parent::__construct($arguments);
|
||||
if (variable_get('migrate_deprecation_warnings', 1) &&
|
||||
!self::$deprecationWarning) {
|
||||
!self::$deprecationWarning) {
|
||||
self::displayMessage(t('The DynamicMigration class is no longer necessary and is now deprecated - please derive your migration classes directly from Migration.'));
|
||||
self::$deprecationWarning = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides default of FALSE
|
||||
*/
|
||||
|
@@ -13,6 +13,7 @@
|
||||
* MigrateSourceSQL for an example.
|
||||
*/
|
||||
abstract class MigrateSource implements Iterator {
|
||||
|
||||
/**
|
||||
* The current row from the quey
|
||||
*
|
||||
@@ -26,6 +27,7 @@ abstract class MigrateSource implements Iterator {
|
||||
* @var array
|
||||
*/
|
||||
protected $currentKey;
|
||||
|
||||
public function getCurrentKey() {
|
||||
return $this->currentKey;
|
||||
}
|
||||
@@ -50,6 +52,7 @@ abstract class MigrateSource implements Iterator {
|
||||
* @var int
|
||||
*/
|
||||
protected $numIgnored = 0;
|
||||
|
||||
public function getIgnored() {
|
||||
return $this->numIgnored;
|
||||
}
|
||||
@@ -60,6 +63,7 @@ abstract class MigrateSource implements Iterator {
|
||||
* @var int
|
||||
*/
|
||||
protected $numProcessed = 0;
|
||||
|
||||
public function getProcessed() {
|
||||
return $this->numProcessed;
|
||||
}
|
||||
@@ -160,7 +164,7 @@ abstract class MigrateSource implements Iterator {
|
||||
}
|
||||
|
||||
if (!isset($this->cacheKey)) {
|
||||
$this->cacheKey = md5((string)$this);
|
||||
$this->cacheKey = md5((string) $this);
|
||||
}
|
||||
|
||||
// If a refresh is requested, or we're not caching counts, ask the derived
|
||||
@@ -227,17 +231,18 @@ abstract class MigrateSource implements Iterator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of Iterator::key - called when entering a loop iteration, returning
|
||||
* the key of the current row. It must be a scalar - we will serialize
|
||||
* to fulfill the requirement, but using getCurrentKey() is preferable.
|
||||
* Implementation of Iterator::key - called when entering a loop iteration,
|
||||
* returning the key of the current row. It must be a scalar - we will
|
||||
* serialize to fulfill the requirement, but using getCurrentKey() is
|
||||
* preferable.
|
||||
*/
|
||||
public function key() {
|
||||
return serialize($this->currentKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of Iterator::valid() - called at the top of the loop, returning
|
||||
* TRUE to process the loop and FALSE to terminate it
|
||||
* Implementation of Iterator::valid() - called at the top of the loop,
|
||||
* returning TRUE to process the loop and FALSE to terminate it
|
||||
*/
|
||||
public function valid() {
|
||||
return !is_null($this->currentRow);
|
||||
@@ -292,7 +297,7 @@ abstract class MigrateSource implements Iterator {
|
||||
if ($map_row) {
|
||||
foreach ($map_row as $field => $value) {
|
||||
$field = 'migrate_map_' . $field;
|
||||
$row->$field = $value;
|
||||
$row->{$field} = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -422,12 +427,12 @@ abstract class MigrateSource implements Iterator {
|
||||
// so we need to provide them with the necessary information (before and
|
||||
// after hashes).
|
||||
if ($this->trackChanges) {
|
||||
$unhashed_row = clone ($row);
|
||||
$unhashed_row = clone $row;
|
||||
// Remove all map data, otherwise we'll have a false positive on the
|
||||
// second import (attempt) on a row.
|
||||
foreach ($unhashed_row as $field => $data) {
|
||||
if (strpos($field, 'migrate_map_') === 0) {
|
||||
unset($unhashed_row->$field);
|
||||
unset($unhashed_row->{$field});
|
||||
}
|
||||
}
|
||||
$row->migrate_map_original_hash = isset($row->migrate_map_hash) ?
|
||||
|
@@ -7,17 +7,21 @@
|
||||
*/
|
||||
|
||||
class MigrateTeamMember {
|
||||
|
||||
protected $name;
|
||||
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
protected $emailAddress;
|
||||
|
||||
public function getEmailAddress() {
|
||||
return $this->emailAddress;
|
||||
}
|
||||
|
||||
protected $group;
|
||||
|
||||
public function getGroup() {
|
||||
return $this->group;
|
||||
}
|
||||
|
@@ -6,7 +6,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Registers your module as an implementor of Migrate-based classes and provides
|
||||
* Registers your module as an implementor of Migrate-based classes and
|
||||
* provides
|
||||
* default configuration for migration processes.
|
||||
*
|
||||
* @return
|
||||
@@ -14,14 +15,16 @@
|
||||
* required):
|
||||
* - api: Always 2 for any module implementing the Migrate 2 API.
|
||||
* - groups: An associative array, keyed by group machine name, defining one
|
||||
* or more migration groups. Each value is an associative array - the 'title'
|
||||
* key defines a user-visible name for the group; any other values are
|
||||
* passed as arguments to all migrations in the group.
|
||||
* or more migration groups. Each value is an associative array - the
|
||||
* 'title' key defines a user-visible name for the group; any other values
|
||||
* are passed as arguments to all migrations in the group.
|
||||
* - migrations: An associative array, keyed by migration machine name,
|
||||
* defining one or more migrations. Each value is an associative array - any
|
||||
* defining one or more migrations. Each value is an associative array -
|
||||
* any
|
||||
* keys other than the following are passed as arguments to the migration
|
||||
* constructor:
|
||||
* - class_name (required): The name of the class implementing the migration.
|
||||
* - class_name (required): The name of the class implementing the
|
||||
* migration.
|
||||
* - group_name: The machine name of the group containing the migration.
|
||||
* - disable_hooks: An associative array, keyed by hook name, listing hook
|
||||
* implementations to be disabled during migration. Each value is an
|
||||
|
@@ -175,8 +175,10 @@ function migrate_drush_command() {
|
||||
);
|
||||
$items['migrate-stop'] = array(
|
||||
'description' => 'Stop an active migration operation',
|
||||
'options' => array('all' => 'Stop all active migration operations',
|
||||
'group' => 'Name of a specific migration group to stop'),
|
||||
'options' => array(
|
||||
'all' => 'Stop all active migration operations',
|
||||
'group' => 'Name of a specific migration group to stop',
|
||||
),
|
||||
'arguments' => array(
|
||||
'migration' => 'Name of migration to stop',
|
||||
),
|
||||
@@ -215,6 +217,7 @@ function migrate_drush_command() {
|
||||
'migrate-deregister --group=myblog' => 'Deregister the myblog group and all migrations within it',
|
||||
),
|
||||
'drupal dependencies' => array('migrate'),
|
||||
'aliases' => array('mdreg'),
|
||||
);
|
||||
$items['migrate-auto-register'] = array(
|
||||
'description' => 'Register any newly defined migration classes',
|
||||
@@ -229,7 +232,7 @@ function migrate_drush_command() {
|
||||
$items['migrate-wipe'] = array(
|
||||
'description' => 'Delete all nodes from specified content types.',
|
||||
'examples' => array(
|
||||
"migrate-wipe story article" => 'Delete all story and article nodes.',
|
||||
"migrate-wipe story article" => 'Delete all story and article nodes.',
|
||||
),
|
||||
'arguments' => array(
|
||||
'type' => 'A space delimited list of content type machine readable Ids.',
|
||||
@@ -328,13 +331,21 @@ function drush_migrate_status($name = NULL) {
|
||||
// An empty line and the headers.
|
||||
$table[] = array('');
|
||||
if ($names_only) {
|
||||
$table[] = array(dt('Group: !name',
|
||||
array('!name' => $group->getName())));
|
||||
$table[] = array(
|
||||
dt('Group: !name',
|
||||
array('!name' => $group->getName())),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$table[] = array(dt('Group: !name',
|
||||
array('!name' => $group->getName())), dt('Total'), dt('Imported'),
|
||||
dt('Unprocessed'), dt('Status'), dt('Last imported'));
|
||||
$table[] = array(
|
||||
dt('Group: !name',
|
||||
array('!name' => $group->getName())),
|
||||
dt('Total'),
|
||||
dt('Imported'),
|
||||
dt('Unprocessed'),
|
||||
dt('Status'),
|
||||
dt('Last imported'),
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!$names_only) {
|
||||
@@ -385,7 +396,14 @@ function drush_migrate_status($name = NULL) {
|
||||
$status = dt('Unknown');
|
||||
break;
|
||||
}
|
||||
$table[] = array($migration->getMachineName(), $total, $imported, $unimported, $status, $migration->getLastImported());
|
||||
$table[] = array(
|
||||
$migration->getMachineName(),
|
||||
$total,
|
||||
$imported,
|
||||
$unimported,
|
||||
$status,
|
||||
$migration->getLastImported(),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$table[] = array($migration->getMachineName());
|
||||
@@ -393,8 +411,7 @@ function drush_migrate_status($name = NULL) {
|
||||
}
|
||||
}
|
||||
drush_print_table($table);
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -419,8 +436,7 @@ function drush_migrate_fields_destination($args = NULL) {
|
||||
drush_print(dt('No fields were found.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -444,8 +460,7 @@ function drush_migrate_fields_source($args = NULL) {
|
||||
drush_print(dt('No fields were found.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -509,12 +524,22 @@ function drush_migrate_mappings($args = NULL) {
|
||||
// Put out each group header
|
||||
$table = array();
|
||||
if ($full) {
|
||||
$table[] = array(dt('Destination'), dt(''), dt('Source'), dt(''), dt('Default'),
|
||||
dt('Description'));
|
||||
$table[] = array(
|
||||
dt('Destination'),
|
||||
dt(''),
|
||||
dt('Source'),
|
||||
dt(''),
|
||||
dt('Default'),
|
||||
dt('Description'),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$table[] = array(dt('Destination'), dt('Source'), dt('Default'),
|
||||
dt('Description'));
|
||||
$table[] = array(
|
||||
dt('Destination'),
|
||||
dt('Source'),
|
||||
dt('Default'),
|
||||
dt('Description'),
|
||||
);
|
||||
}
|
||||
$first = TRUE;
|
||||
|
||||
@@ -550,12 +575,22 @@ function drush_migrate_mappings($args = NULL) {
|
||||
else {
|
||||
$src_description = '';
|
||||
}
|
||||
$table[] = array($destination, $dest_description, $source, $src_description,
|
||||
$default, $mapping->getDescription());
|
||||
$table[] = array(
|
||||
$destination,
|
||||
$dest_description,
|
||||
$source,
|
||||
$src_description,
|
||||
$default,
|
||||
$mapping->getDescription(),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$table[] = array($destination, $source,
|
||||
$default, $mapping->getDescription());
|
||||
$table[] = array(
|
||||
$destination,
|
||||
$source,
|
||||
$default,
|
||||
$mapping->getDescription(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -569,8 +604,7 @@ function drush_migrate_mappings($args = NULL) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -590,8 +624,8 @@ function drush_migrate_messages($migration_name) {
|
||||
$map = $migration->getMap();
|
||||
$message_table = $map->getMessageTable();
|
||||
$result = db_select($message_table, 'msg', array('fetch' => PDO::FETCH_ASSOC))
|
||||
->fields('msg')
|
||||
->execute();
|
||||
->fields('msg')
|
||||
->execute();
|
||||
$first = TRUE;
|
||||
$table = array();
|
||||
foreach ($result as $row) {
|
||||
@@ -621,8 +655,7 @@ function drush_migrate_messages($migration_name) {
|
||||
drush_print_table($table, TRUE, $widths);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -641,8 +674,10 @@ function drush_migrate_analyze($args = NULL) {
|
||||
if (!empty($analysis)) {
|
||||
foreach ($analysis as $field_name => $details) {
|
||||
if (!empty($details['description'])) {
|
||||
drush_print(dt('@name (@description):', array('@name' => $field_name,
|
||||
'@description' => $details['description'])));
|
||||
drush_print(dt('@name (@description):', array(
|
||||
'@name' => $field_name,
|
||||
'@description' => $details['description'],
|
||||
)));
|
||||
}
|
||||
else {
|
||||
drush_print(dt('@name:', array('@name' => $field_name)));
|
||||
@@ -655,17 +690,23 @@ function drush_migrate_analyze($args = NULL) {
|
||||
}
|
||||
else {
|
||||
drush_print(' ' . dt('Only one value present: @value',
|
||||
array('@value' => $value)));
|
||||
array('@value' => $value)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($details['is_numeric']) {
|
||||
drush_print(' ' . dt('Numeric field with a range of @min to @max',
|
||||
array('@min' => $details['min_numeric'], '@max' => $details['max_numeric'])));
|
||||
array(
|
||||
'@min' => $details['min_numeric'],
|
||||
'@max' => $details['max_numeric'],
|
||||
)));
|
||||
}
|
||||
else {
|
||||
drush_print(' ' . dt('String field with a length ranging from @min to @max',
|
||||
array('@min' => $details['min_strlen'], '@max' => $details['max_strlen'])));
|
||||
array(
|
||||
'@min' => $details['min_strlen'],
|
||||
'@max' => $details['max_strlen'],
|
||||
)));
|
||||
}
|
||||
$values = array();
|
||||
$header = NULL;
|
||||
@@ -781,10 +822,16 @@ function drush_migrate_audit($args = NULL) {
|
||||
}
|
||||
|
||||
foreach (array_diff_key($source_fields, $used_sources) as $name => $description) {
|
||||
$problems['sources_unmapped'][] = array('Field' => $name, 'Description' => $description);
|
||||
$problems['sources_unmapped'][] = array(
|
||||
'Field' => $name,
|
||||
'Description' => $description,
|
||||
);
|
||||
}
|
||||
foreach (array_diff_key($destination_fields, $used_destinations) as $name => $description) {
|
||||
$problems['destinations_unmapped'][] = array('Field' => $name, 'Description' => $description);
|
||||
$problems['destinations_unmapped'][] = array(
|
||||
'Field' => $name,
|
||||
'Description' => $description,
|
||||
);
|
||||
}
|
||||
|
||||
$problems = array_filter($problems);
|
||||
@@ -810,8 +857,7 @@ function drush_migrate_audit($args = NULL) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -849,9 +895,9 @@ function drush_migrate_rollback($args = NULL) {
|
||||
$options['limit']['unit'] = 'items';
|
||||
}
|
||||
elseif ($options['limit']['unit'] != 'seconds' &&
|
||||
$options['limit']['unit'] != 'second' &&
|
||||
$options['limit']['unit'] != 'items' &&
|
||||
$options['limit']['unit'] != 'item') {
|
||||
$options['limit']['unit'] != 'second' &&
|
||||
$options['limit']['unit'] != 'items' &&
|
||||
$options['limit']['unit'] != 'item') {
|
||||
drush_set_error(NULL, dt("Invalid limit unit '!unit'",
|
||||
array('!unit' => $options['limit']['unit'])));
|
||||
return;
|
||||
@@ -864,9 +910,9 @@ function drush_migrate_rollback($args = NULL) {
|
||||
$options['feedback']['value'] = $parts[0];
|
||||
$options['feedback']['unit'] = $parts[1];
|
||||
if ($options['feedback']['unit'] != 'seconds' &&
|
||||
$options['feedback']['unit'] != 'second' &&
|
||||
$options['feedback']['unit'] != 'items' &&
|
||||
$options['feedback']['unit'] != 'item') {
|
||||
$options['feedback']['unit'] != 'second' &&
|
||||
$options['feedback']['unit'] != 'items' &&
|
||||
$options['feedback']['unit'] != 'item') {
|
||||
drush_set_error(NULL, dt("Invalid feedback frequency unit '!unit'",
|
||||
array('!unit' => $options['feedback']['unit'])));
|
||||
return;
|
||||
@@ -907,8 +953,7 @@ function drush_migrate_rollback($args = NULL) {
|
||||
'warning');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -966,8 +1011,8 @@ function drush_migrate_get_migrations($args) {
|
||||
elseif ($group = drush_get_option('group')) {
|
||||
foreach ($migration_objects as $name => $migration) {
|
||||
if (drupal_strtolower($group) !=
|
||||
drupal_strtolower($migration->getGroup()->getName()) ||
|
||||
!$migration->getEnabled()) {
|
||||
drupal_strtolower($migration->getGroup()->getName()) ||
|
||||
!$migration->getEnabled()) {
|
||||
unset($migration_objects[$name]);
|
||||
}
|
||||
}
|
||||
@@ -1075,10 +1120,10 @@ function drush_migrate_validate_common($args) {
|
||||
foreach ($machine_names as $machine_name) {
|
||||
$machine_name = trim($machine_name);
|
||||
$class_name = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('class_name'))
|
||||
->condition('machine_name', $machine_name)
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('ms', array('class_name'))
|
||||
->condition('machine_name', $machine_name)
|
||||
->execute()
|
||||
->fetchField();
|
||||
if (!$class_name || !class_exists($class_name)) {
|
||||
drush_set_error(dt('Unrecognized migration: !name', array('!name' => $machine_name)));
|
||||
}
|
||||
@@ -1091,9 +1136,9 @@ function drush_migrate_validate_common($args) {
|
||||
$options['feedback']['value'] = $parts[0];
|
||||
$options['feedback']['unit'] = $parts[1];
|
||||
if ($options['feedback']['unit'] != 'seconds' &&
|
||||
$options['feedback']['unit'] != 'second' &&
|
||||
$options['feedback']['unit'] != 'items' &&
|
||||
$options['feedback']['unit'] != 'item') {
|
||||
$options['feedback']['unit'] != 'second' &&
|
||||
$options['feedback']['unit'] != 'items' &&
|
||||
$options['feedback']['unit'] != 'item') {
|
||||
drush_set_error(NULL, dt("Invalid feedback frequency unit '!unit'",
|
||||
array('!unit' => $options['feedback']['unit'])));
|
||||
return;
|
||||
@@ -1114,19 +1159,18 @@ function drush_migrate_pre_migrate_import($args = NULL) {
|
||||
foreach ($migrations as $migration) {
|
||||
$status = $migration->getStatus();
|
||||
if ($status == MigrationBase::STATUS_IMPORTING ||
|
||||
$status == MigrationBase::STATUS_ROLLING_BACK) {
|
||||
$status == MigrationBase::STATUS_ROLLING_BACK) {
|
||||
drush_log(dt("Stopping '!description' migration", array('!description' => $migration->getMachineName())));
|
||||
$migration->stopProcess();
|
||||
// Give the process a chance to stop.
|
||||
$count = 0;
|
||||
while ($migration->getStatus() != MigrationBase::STATUS_IDLE
|
||||
&& $count++ < 5) {
|
||||
&& $count++ < 5) {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -1144,6 +1188,8 @@ function drush_migrate_pre_migrate_import($args = NULL) {
|
||||
* A comma delimited list of machine names, or the special name 'all'
|
||||
*/
|
||||
function drush_migrate_import($args = NULL) {
|
||||
$status = NULL;
|
||||
|
||||
try {
|
||||
if (drush_get_option('notify', FALSE)) {
|
||||
// Capture non-informational output for mailing
|
||||
@@ -1165,14 +1211,18 @@ function drush_migrate_import($args = NULL) {
|
||||
if ($limit) {
|
||||
$parts = explode(' ', $limit);
|
||||
$options['limit']['value'] = $parts[0];
|
||||
$options['limit']['unit'] = $parts[1];
|
||||
if (!$options['limit']['unit']) {
|
||||
$options['limit']['unit'] = 'items';
|
||||
// Default unit.
|
||||
if (!isset($parts[1])) {
|
||||
$parts[1] = 'items';
|
||||
}
|
||||
elseif ($options['limit']['unit'] != 'seconds' &&
|
||||
$options['limit']['unit'] != 'second' &&
|
||||
$options['limit']['unit'] != 'items' &&
|
||||
$options['limit']['unit'] != 'item') {
|
||||
$options['limit']['unit'] = $parts[1];
|
||||
// Validation.
|
||||
if (!in_array($options['limit']['unit'], array(
|
||||
'seconds',
|
||||
'second',
|
||||
'items',
|
||||
'item',
|
||||
))) {
|
||||
drush_set_error(NULL, dt("Invalid limit unit '!unit'",
|
||||
array('!unit' => $options['limit']['unit'])));
|
||||
return;
|
||||
@@ -1184,9 +1234,9 @@ function drush_migrate_import($args = NULL) {
|
||||
$options['feedback']['value'] = $parts[0];
|
||||
$options['feedback']['unit'] = $parts[1];
|
||||
if ($options['feedback']['unit'] != 'seconds' &&
|
||||
$options['feedback']['unit'] != 'second' &&
|
||||
$options['feedback']['unit'] != 'items' &&
|
||||
$options['feedback']['unit'] != 'item') {
|
||||
$options['feedback']['unit'] != 'second' &&
|
||||
$options['feedback']['unit'] != 'items' &&
|
||||
$options['feedback']['unit'] != 'item') {
|
||||
drush_set_error(NULL, dt("Invalid feedback frequency unit '!unit'",
|
||||
array('!unit' => $options['feedback']['unit'])));
|
||||
return;
|
||||
@@ -1282,8 +1332,10 @@ function drush_migrate_import($args = NULL) {
|
||||
elseif ($status == MigrationBase::RESULT_INCOMPLETE) {
|
||||
$stop = TRUE;
|
||||
}
|
||||
drush_backend_set_result(array('status' => $status,
|
||||
'migrations' => implode(',', array_keys($migrations))));
|
||||
drush_backend_set_result(array(
|
||||
'status' => $status,
|
||||
'migrations' => implode(',', array_keys($migrations)),
|
||||
));
|
||||
}
|
||||
|
||||
if ($stop) {
|
||||
@@ -1291,8 +1343,7 @@ function drush_migrate_import($args = NULL) {
|
||||
}
|
||||
unset($migrations[$machine_name]);
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -1309,6 +1360,8 @@ function drush_migrate_import($args = NULL) {
|
||||
if (drush_get_option('notify')) {
|
||||
_drush_migrate_notify();
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1324,8 +1377,7 @@ function drush_migrate_stop($args = NULL) {
|
||||
drush_log(dt("Stopping '!description' migration", array('!description' => $migration->getMachineName())));
|
||||
$migration->stopProcess();
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -1342,8 +1394,7 @@ function drush_migrate_reset_status($args = NULL) {
|
||||
array('!description' => $migration->getMachineName())));
|
||||
$migration->resetStatus();
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -1368,8 +1419,8 @@ function drush_migrate_deregister($args = NULL) {
|
||||
if ($orphans) {
|
||||
$migrations = array();
|
||||
$result = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('class_name', 'machine_name'))
|
||||
->execute();
|
||||
->fields('ms', array('class_name', 'machine_name'))
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
if (!class_exists($row->class_name)) {
|
||||
$migrations[] = $row->machine_name;
|
||||
@@ -1385,8 +1436,7 @@ function drush_migrate_deregister($args = NULL) {
|
||||
array('!description' => $machine_name)), 'success');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
drush_print($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
@@ -1435,10 +1485,10 @@ function drush_migrate_register($args = NULL) {
|
||||
function drush_migrate_wipe() {
|
||||
$types = func_get_args();
|
||||
$nids = db_select('node', 'n')
|
||||
->fields('n', array('nid'))
|
||||
->condition('type', $types, 'IN')
|
||||
->execute()
|
||||
->fetchCol();
|
||||
->fields('n', array('nid'))
|
||||
->condition('type', $types, 'IN')
|
||||
->execute()
|
||||
->fetchCol();
|
||||
$chunks = array_chunk($nids, 50);
|
||||
foreach ($chunks as $chunk) {
|
||||
node_delete_multiple($chunk);
|
||||
@@ -1450,7 +1500,7 @@ function drush_migrate_wipe() {
|
||||
function drush_migrate_print_memory() {
|
||||
global $_migrate_memory;
|
||||
$temparray = array();
|
||||
foreach ((array)$_migrate_memory as $name => $memoryrec) {
|
||||
foreach ((array) $_migrate_memory as $name => $memoryrec) {
|
||||
// We have to use timer_read() for active timers, and check the record for others
|
||||
if (isset($memoryrec['start'])) {
|
||||
$temparray[$name] = migrate_memory_read($name);
|
||||
@@ -1468,7 +1518,7 @@ function drush_migrate_print_memory() {
|
||||
foreach ($temparray as $name => $memory) {
|
||||
$count = $_migrate_memory[$name]['count'];
|
||||
if ($count > 0) {
|
||||
$avg = round($memory/$count, 0);
|
||||
$avg = round($memory / $count, 0);
|
||||
}
|
||||
else {
|
||||
$avg = 'N/A';
|
||||
|
@@ -51,9 +51,8 @@ files[] = tests/plugins/destinations/term.test
|
||||
files[] = tests/plugins/destinations/user.test
|
||||
files[] = tests/plugins/sources/xml.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-07-01
|
||||
version = "7.x-2.8"
|
||||
; Information added by Drupal.org packaging script on 2018-06-10
|
||||
version = "7.x-2.11"
|
||||
core = "7.x"
|
||||
project = "migrate"
|
||||
datestamp = "1435760949"
|
||||
|
||||
datestamp = "1528674486"
|
||||
|
@@ -226,12 +226,12 @@ function migrate_uninstall() {
|
||||
function migrate_update_7001() {
|
||||
if (!db_field_exists('migrate_status', 'highwater')) {
|
||||
db_add_field('migrate_status', 'highwater', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'Highwater mark for detecting updated content',
|
||||
)
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'Highwater mark for detecting updated content',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -293,8 +293,8 @@ function migrate_update_7004() {
|
||||
|
||||
if (db_field_exists('migrate_status', 'lastimported')) {
|
||||
$result = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('machine_name', 'lastimported'))
|
||||
->execute();
|
||||
->fields('ms', array('machine_name', 'lastimported'))
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
$lastimportedtime = strtotime($row->lastimported);
|
||||
db_update('migrate_status')
|
||||
@@ -334,12 +334,12 @@ function migrate_update_7006() {
|
||||
$ret = '';
|
||||
if (!db_field_exists('migrate_status', 'class_name')) {
|
||||
db_add_field('migrate_status', 'class_name', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'Name of class to instantiate for this migration',
|
||||
)
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'Name of class to instantiate for this migration',
|
||||
)
|
||||
);
|
||||
|
||||
db_query("UPDATE {migrate_status}
|
||||
@@ -357,12 +357,12 @@ function migrate_update_7007() {
|
||||
$ret = '';
|
||||
if (!db_field_exists('migrate_status', 'arguments')) {
|
||||
db_add_field('migrate_status', 'arguments', array(
|
||||
'type' => 'blob',
|
||||
'not null' => FALSE,
|
||||
'size' => 'big',
|
||||
'serialize' => TRUE,
|
||||
'description' => 'A serialized array of arguments to the migration constructor',
|
||||
)
|
||||
'type' => 'blob',
|
||||
'not null' => FALSE,
|
||||
'size' => 'big',
|
||||
'serialize' => TRUE,
|
||||
'description' => 'A serialized array of arguments to the migration constructor',
|
||||
)
|
||||
|
||||
);
|
||||
$ret = t('Added arguments column to migrate_status table');
|
||||
@@ -394,18 +394,18 @@ function migrate_update_7008() {
|
||||
$field = 'destid' . $index++;
|
||||
$field_schema['not null'] = FALSE;
|
||||
$map_connection->schema()->changeField($map_table, $field, $field,
|
||||
$field_schema);
|
||||
$field_schema);
|
||||
$ret .= "\n" . t('Changed !table.!field to be non-null',
|
||||
array('!table' => $map_table, '!field' => $field));
|
||||
array('!table' => $map_table, '!field' => $field));
|
||||
}
|
||||
|
||||
// Add any existing failures to the map table
|
||||
$msg_table = $map->getMessageTable();
|
||||
$msg_marked = FALSE;
|
||||
$result = $map_connection->select($msg_table, 'msg')
|
||||
->fields('msg')
|
||||
->condition('level', Migration::MESSAGE_INFORMATIONAL, '<>')
|
||||
->execute();
|
||||
->fields('msg')
|
||||
->condition('level', Migration::MESSAGE_INFORMATIONAL, '<>')
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
$keys = array();
|
||||
$index = 1;
|
||||
@@ -415,9 +415,9 @@ function migrate_update_7008() {
|
||||
}
|
||||
}
|
||||
$map_connection->merge($map_table)
|
||||
->key($keys)
|
||||
->fields(array('needs_update' => MigrateMap::STATUS_FAILED))
|
||||
->execute();
|
||||
->key($keys)
|
||||
->fields(array('needs_update' => MigrateMap::STATUS_FAILED))
|
||||
->execute();
|
||||
$msg_marked = TRUE;
|
||||
}
|
||||
if ($msg_marked) {
|
||||
@@ -472,14 +472,14 @@ function migrate_update_7203() {
|
||||
db_create_table('migrate_group', migrate_schema_group());
|
||||
}
|
||||
if (!db_field_exists('migrate_status', 'group_name')) {
|
||||
$ret .= t('Add group relationship to migrate_status table'). "\n";
|
||||
$ret .= t('Add group relationship to migrate_status table') . "\n";
|
||||
db_add_field('migrate_status', 'group_name', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => 'default',
|
||||
'description' => 'Name of group containing migration',
|
||||
)
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => 'default',
|
||||
'description' => 'Name of group containing migration',
|
||||
)
|
||||
);
|
||||
// Populate each migration's group_name field
|
||||
$groups = array();
|
||||
@@ -497,17 +497,17 @@ function migrate_update_7203() {
|
||||
// Populate the migrate_group table
|
||||
foreach ($groups as $group_name) {
|
||||
$title = db_select('migrate_group', 'mg')
|
||||
->fields('mg', array('title'))
|
||||
->condition('name', $group_name)
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('mg', array('title'))
|
||||
->condition('name', $group_name)
|
||||
->execute()
|
||||
->fetchField();
|
||||
if (!$title) {
|
||||
db_insert('migrate_group')
|
||||
->fields(array(
|
||||
'name' => $group_name,
|
||||
'title' => $group_name,
|
||||
'arguments' => serialize(array()),
|
||||
))
|
||||
'name' => $group_name,
|
||||
'title' => $group_name,
|
||||
'arguments' => serialize(array()),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
@@ -559,20 +559,20 @@ function migrate_update_7206() {
|
||||
*/
|
||||
function migrate_update_7207() {
|
||||
$rows = db_select('migrate_group', 'mg')
|
||||
->fields('mg', array('name'))
|
||||
->condition('name', 'default')
|
||||
->execute()
|
||||
->rowCount();
|
||||
->fields('mg', array('name'))
|
||||
->condition('name', 'default')
|
||||
->execute()
|
||||
->rowCount();
|
||||
if ($rows > 0) {
|
||||
$rows = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('machine_name'))
|
||||
->condition('group_name', 'default')
|
||||
->execute()
|
||||
->rowCount();
|
||||
->fields('ms', array('machine_name'))
|
||||
->condition('group_name', 'default')
|
||||
->execute()
|
||||
->rowCount();
|
||||
if ($rows == 0) {
|
||||
db_delete('migrate_group')
|
||||
->condition('name', 'default')
|
||||
->execute();
|
||||
->condition('name', 'default')
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
class MigrateMailIgnore extends DefaultMailSystem {
|
||||
|
||||
/**
|
||||
* On an email request, do nothing and say we did.
|
||||
*
|
||||
@@ -14,6 +15,7 @@ class MigrateMailIgnore extends DefaultMailSystem {
|
||||
*
|
||||
* @param $message
|
||||
* A message array, as described in hook_mail_alter().
|
||||
*
|
||||
* @return
|
||||
* TRUE if the mail was successfully accepted, otherwise FALSE.
|
||||
*/
|
||||
|
@@ -18,6 +18,28 @@ define('MIGRATE_API_VERSION', 2);
|
||||
define('MIGRATE_ACCESS_BASIC', 'migration information');
|
||||
define('MIGRATE_ACCESS_ADVANCED', 'advanced migration information');
|
||||
|
||||
/**
|
||||
* Implements hook_help().
|
||||
*/
|
||||
function migrate_help($path, $arg) {
|
||||
switch ($path) {
|
||||
case 'admin/help#migrate':
|
||||
$output = '';
|
||||
$output .= '<h3>' . t('About') . '</h3>';
|
||||
$output .= '<p>' . t('The Migrate module provides a flexible framework for migrating content into Drupal from other sources (e.g., when converting a web site from another CMS to Drupal). Out-of-the-box, support for creating Drupal nodes, taxonomy terms, comments, and users are included. Plugins permit migration of other types of content. For more information, see the online documentation for the <a href="@handbook">Migrate module</a>.', array('@handbook' => 'http://drupal.org/migrate')) . '</p>';
|
||||
$output .= '<h3>' . t('Uses') . '</h3>';
|
||||
$output .= '<dl>';
|
||||
$output .= '<dt>' . t('Getting Started') . '</dt>';
|
||||
$output .= '<dd>' . t('To get started, enable the migrate_example module and browse to admin/content/migrate to see its dashboard. The code for this migration is in migrate_example/beer.inc (advanced examples are in wine.inc). Mimic that file in order to specify your own migrations.') . '</dd>';
|
||||
$output .= '<dt>' . t('Migrate Support') . '</dt>';
|
||||
$output .= '<dd>' . t('The Migrate module itself has support for migration into core objects. Some built-in support for migration involving contrib modules is in the migrate_extras module.') . '</dd>';
|
||||
$output .= '<dt>' . t('Migrate Extended Support') . '</dt>';
|
||||
$output .= '<dd>' . t('The best place to implement migration support for a contributed module is in that module, not in the Migrate or Migrate Extras modules. That way, the migration support is always self-consistent with the current module implementation - it is not practical for the migrate modules to keep up with changes to all other contrib modules.') . '</dd>';
|
||||
$output .= '</dl>';
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of all active migrations, ordered by dependencies. To be
|
||||
* recognized, a class must be non-abstract, and derived from MigrationBase.
|
||||
@@ -45,8 +67,8 @@ function migrate_migrations($reset = NULL) {
|
||||
$required_migrations = array();
|
||||
|
||||
$result = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('machine_name', 'class_name'))
|
||||
->execute();
|
||||
->fields('ms', array('machine_name', 'class_name'))
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
if (class_exists($row->class_name)) {
|
||||
$reflect = new ReflectionClass($row->class_name);
|
||||
@@ -68,12 +90,12 @@ function migrate_migrations($reset = NULL) {
|
||||
}
|
||||
else {
|
||||
MigrationBase::displayMessage(t('Class !class is no longer a valid concrete migration class',
|
||||
array('!class' => $row->class_name)));
|
||||
array('!class' => $row->class_name)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
MigrationBase::displayMessage(t('Class !class no longer exists',
|
||||
array('!class' => $row->class_name)));
|
||||
MigrationBase::displayMessage(t('Class !class could not be found',
|
||||
array('!class' => $row->class_name)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +123,8 @@ function migrate_migrations($reset = NULL) {
|
||||
)));
|
||||
}
|
||||
else {
|
||||
$final_migrations[$migration->getGroup()->getName()][$machine_name] = $migration;
|
||||
$final_migrations[$migration->getGroup()
|
||||
->getName()][$machine_name] = $migration;
|
||||
}
|
||||
}
|
||||
// Flatten the grouped list.
|
||||
@@ -124,8 +147,8 @@ function migrate_migrations($reset = NULL) {
|
||||
* Destination type ('Node', 'User', etc.) - generally the same string as
|
||||
* the destination class name without the MigrateDestination prefix.
|
||||
* @param $method
|
||||
* Method name such as 'prepare' (called at the beginning of an import operation)
|
||||
* or 'complete' (called at the end of an import operation).
|
||||
* Method name such as 'prepare' (called at the beginning of an import
|
||||
* operation) or 'complete' (called at the end of an import operation).
|
||||
* @param ...
|
||||
* Parameters to be passed to the handler.
|
||||
*/
|
||||
@@ -138,7 +161,7 @@ function migrate_handler_invoke_all($destination, $method) {
|
||||
$disabled = unserialize(variable_get('migrate_disabled_handlers', serialize(array())));
|
||||
foreach ($class_list as $class_name => $handler) {
|
||||
if (!in_array($class_name, $disabled) && $handler->handlesType($destination)
|
||||
&& method_exists($handler, $method)) {
|
||||
&& method_exists($handler, $method)) {
|
||||
migrate_instrument_start($class_name . '->' . $method);
|
||||
$result = call_user_func_array(array($handler, $method), $args);
|
||||
migrate_instrument_stop($class_name . '->' . $method);
|
||||
@@ -169,16 +192,16 @@ function migrate_handler_invoke_all($destination, $method) {
|
||||
* Handler method to call (defaults to prepare()).
|
||||
*/
|
||||
function migrate_field_handler_invoke_all($entity, array $field_info,
|
||||
array $instance, array $values, $method = 'prepare') {
|
||||
array $instance, array $values, $method = 'prepare') {
|
||||
$return = array();
|
||||
$type = $field_info['type'];
|
||||
$class_list = _migrate_class_list('MigrateFieldHandler');
|
||||
$disabled = unserialize(variable_get('migrate_disabled_handlers',
|
||||
serialize(array())));
|
||||
serialize(array())));
|
||||
$handler_called = FALSE;
|
||||
foreach ($class_list as $class_name => $handler) {
|
||||
if (!in_array($class_name, $disabled) && $handler->handlesType($type)
|
||||
&& method_exists($handler, $method)) {
|
||||
&& method_exists($handler, $method)) {
|
||||
migrate_instrument_start($class_name . '->' . $method);
|
||||
$result = call_user_func_array(array($handler, $method),
|
||||
array($entity, $field_info, $instance, $values));
|
||||
@@ -210,13 +233,15 @@ function migrate_field_handler_invoke_all($entity, array $field_info,
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given parent class, identify and instantiate objects for any non-abstract
|
||||
* classes derived from the parent, returning an array of the objects indexed by
|
||||
* class name. The array will be ordered such that any classes with dependencies
|
||||
* are listed after the classes they are dependent on.
|
||||
* For a given parent class, identify and instantiate objects for any
|
||||
* non-abstract classes derived from the parent, returning an array of the
|
||||
* objects indexed by class name. The array will be ordered such that any
|
||||
* classes with dependencies are listed after the classes they are dependent
|
||||
* on.
|
||||
*
|
||||
* @param $parent_class
|
||||
* Name of a class from which results will be derived.
|
||||
*
|
||||
* @return
|
||||
* Array of objects, keyed by the class name.
|
||||
*/
|
||||
@@ -295,8 +320,11 @@ function migrate_get_module_apis($reset = FALSE) {
|
||||
else {
|
||||
drupal_set_message(t('%function supports Migrate API version %modversion,
|
||||
Migrate module API version is %version - migration support not loaded.',
|
||||
array('%function' => $function, '%modversion' => $info['api'],
|
||||
'%version' => MIGRATE_API_VERSION)));
|
||||
array(
|
||||
'%function' => $function,
|
||||
'%modversion' => $info['api'],
|
||||
'%version' => MIGRATE_API_VERSION,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,6 +476,7 @@ function migrate_memory_start($name) {
|
||||
*
|
||||
* @param name
|
||||
* The name of the memory measurement.
|
||||
*
|
||||
* @return
|
||||
* The change in bytes since the last start.
|
||||
*/
|
||||
@@ -471,9 +500,11 @@ function migrate_memory_read($name) {
|
||||
*
|
||||
* @param name
|
||||
* The name of the memory measurement.
|
||||
*
|
||||
* @return
|
||||
* A memory array. The array contains the number of times the memory has been
|
||||
* started and stopped (count) and the accumulated memory difference value in bytes.
|
||||
* started and stopped (count) and the accumulated memory difference value in
|
||||
* bytes.
|
||||
*/
|
||||
function migrate_memory_stop($name) {
|
||||
global $_migrate_memory;
|
||||
@@ -496,9 +527,9 @@ function migrate_memory_stop($name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start measuring time and (optionally) memory consumption over a section of code.
|
||||
* Note that the memory consumption measurement is generally not useful in
|
||||
* lower areas of the code, where data is being generated that will be freed
|
||||
* Start measuring time and (optionally) memory consumption over a section of
|
||||
* code. Note that the memory consumption measurement is generally not useful
|
||||
* in lower areas of the code, where data is being generated that will be freed
|
||||
* by the next call to the same area. For example, measuring the memory
|
||||
* consumption of db_query is not going to be helpful.
|
||||
*
|
||||
@@ -534,7 +565,8 @@ function migrate_instrument_stop($name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Call hook_migrate_overview for overall documentation on implemented migrations.
|
||||
* Call hook_migrate_overview for overall documentation on implemented
|
||||
* migrations.
|
||||
*/
|
||||
function migrate_overview() {
|
||||
$overview = '';
|
||||
|
@@ -34,10 +34,12 @@
|
||||
*
|
||||
* In any serious migration project, you will find there are some options
|
||||
* which are common to the individual migrations you're implementing. You can
|
||||
* define an abstract intermediate class derived from Migration, then derive your
|
||||
* individual migrations from that, to share settings, utility functions, etc.
|
||||
* define an abstract intermediate class derived from Migration, then derive
|
||||
* your individual migrations from that, to share settings, utility functions,
|
||||
* etc.
|
||||
*/
|
||||
abstract class BasicExampleMigration extends Migration {
|
||||
|
||||
// A Migration constructor takes an array of arguments as its first parameter.
|
||||
// The arguments must be passed through to the parent constructor.
|
||||
public function __construct($arguments) {
|
||||
@@ -48,9 +50,9 @@ abstract class BasicExampleMigration extends Migration {
|
||||
// list in the shared class; it can be overridden for specific migrations.
|
||||
$this->team = array(
|
||||
new MigrateTeamMember('Liz Taster', 'ltaster@example.com',
|
||||
t('Product Owner')),
|
||||
t('Product Owner')),
|
||||
new MigrateTeamMember('Larry Brewer', 'lbrewer@example.com',
|
||||
t('Implementor')),
|
||||
t('Implementor')),
|
||||
);
|
||||
|
||||
// Individual mappings in a migration can be linked to a ticket or issue
|
||||
@@ -76,6 +78,7 @@ abstract class BasicExampleMigration extends Migration {
|
||||
* information associated with the mappings.
|
||||
*/
|
||||
class BeerTermMigration extends BasicExampleMigration {
|
||||
|
||||
public function __construct($arguments) {
|
||||
parent::__construct($arguments);
|
||||
// Human-friendly description of your migration process. Be as detailed as
|
||||
@@ -91,10 +94,15 @@ class BeerTermMigration extends BasicExampleMigration {
|
||||
// style_parent, we guarantee root terms are migrated first, so the
|
||||
// parent_name mapping below will find that the parent exists.
|
||||
$query = db_select('migrate_example_beer_topic', 'met')
|
||||
->fields('met', array('style', 'details', 'style_parent', 'region',
|
||||
'hoppiness'))
|
||||
// This sort assures that parents are saved before children.
|
||||
->orderBy('style_parent', 'ASC');
|
||||
->fields('met', array(
|
||||
'style',
|
||||
'details',
|
||||
'style_parent',
|
||||
'region',
|
||||
'hoppiness',
|
||||
))
|
||||
// This sort assures that parents are saved before children.
|
||||
->orderBy('style_parent', 'ASC');
|
||||
|
||||
// Create a MigrateSource object, which manages retrieving the input data.
|
||||
$this->source = new MigrateSourceSQL($query);
|
||||
@@ -112,15 +120,16 @@ class BeerTermMigration extends BasicExampleMigration {
|
||||
// destination - we need to be explicit for our source, but the destination
|
||||
// class knows its schema already.
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array(
|
||||
'style' => array('type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Topic ID',
|
||||
)
|
||||
array(
|
||||
'style' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Topic ID',
|
||||
),
|
||||
MigrateDestinationTerm::getKeySchema()
|
||||
);
|
||||
),
|
||||
MigrateDestinationTerm::getKeySchema()
|
||||
);
|
||||
|
||||
// Assign mappings TO destination fields FROM source fields. To discover
|
||||
// the names used in these calls, use the drush commands
|
||||
@@ -133,7 +142,7 @@ class BeerTermMigration extends BasicExampleMigration {
|
||||
// Documenting your mappings makes it easier for the whole team to see
|
||||
// exactly what the status is when developing a migration process.
|
||||
$this->addFieldMapping('parent_name', 'style_parent')
|
||||
->description(t('The incoming style_parent field is the name of the term parent'));
|
||||
->description(t('The incoming style_parent field is the name of the term parent'));
|
||||
|
||||
// Mappings are assigned issue groups, by which they are grouped on the
|
||||
// migration info page when the migrate_ui module is enabled. The default
|
||||
@@ -147,8 +156,8 @@ class BeerTermMigration extends BasicExampleMigration {
|
||||
// necessary information, and now the implementor needs to complete the
|
||||
// work.
|
||||
$this->addFieldMapping(NULL, 'hoppiness')
|
||||
->description(t('This info will not be maintained in Drupal'))
|
||||
->issueGroup(t('DNM'));
|
||||
->description(t('This info will not be maintained in Drupal'))
|
||||
->issueGroup(t('DNM'));
|
||||
|
||||
// Open mapping issues can be assigned priorities (the default is
|
||||
// MigrateFieldMapping::ISSUE_PRIORITY_OK). If you're using an issue
|
||||
@@ -156,11 +165,11 @@ class BeerTermMigration extends BasicExampleMigration {
|
||||
// above), you can specify a ticket/issue number in the system on the
|
||||
// mapping and migrate_ui will link directly to it.
|
||||
$this->addFieldMapping(NULL, 'region')
|
||||
->description('Will a field be added to the vocabulary for this?')
|
||||
->issueGroup(t('Client Issues'))
|
||||
// This priority wil cause the mapping to be highlighted in the UI.
|
||||
->issuePriority(MigrateFieldMapping::ISSUE_PRIORITY_MEDIUM)
|
||||
->issueNumber(770064);
|
||||
->description('Will a field be added to the vocabulary for this?')
|
||||
->issueGroup(t('Client Issues'))
|
||||
// This priority wil cause the mapping to be highlighted in the UI.
|
||||
->issuePriority(MigrateFieldMapping::ISSUE_PRIORITY_MEDIUM)
|
||||
->issueNumber(770064);
|
||||
|
||||
// It is good practice to account for all source and destination fields
|
||||
// explicitly - this makes sure that everyone understands exactly what is
|
||||
@@ -170,21 +179,21 @@ class BeerTermMigration extends BasicExampleMigration {
|
||||
// immediately visible, and you can decide if anything needs to be
|
||||
// migrated into it.
|
||||
$this->addFieldMapping('format')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
$this->addFieldMapping('weight')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
$this->addFieldMapping('parent')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
|
||||
// We conditionally DNM these fields, so your field mappings will be clean
|
||||
// whether or not you have path and/or pathauto enabled.
|
||||
$destination_fields = $this->destination->fields();
|
||||
if (isset($destination_fields['path'])) {
|
||||
$this->addFieldMapping('path')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
if (isset($destination_fields['pathauto'])) {
|
||||
$this->addFieldMapping('pathauto')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,23 +210,34 @@ class BeerTermMigration extends BasicExampleMigration {
|
||||
* transformations of the data.
|
||||
*/
|
||||
class BeerUserMigration extends BasicExampleMigration {
|
||||
|
||||
public function __construct($arguments) {
|
||||
// The basic setup is similar to BeerTermMigraiton
|
||||
parent::__construct($arguments);
|
||||
$this->description = t('Beer Drinkers of the world');
|
||||
$query = db_select('migrate_example_beer_account', 'mea')
|
||||
->fields('mea', array('aid', 'status', 'posted', 'name',
|
||||
'nickname', 'password', 'mail', 'sex', 'beers'));
|
||||
->fields('mea', array(
|
||||
'aid',
|
||||
'status',
|
||||
'posted',
|
||||
'name',
|
||||
'nickname',
|
||||
'password',
|
||||
'mail',
|
||||
'sex',
|
||||
'beers',
|
||||
));
|
||||
$this->source = new MigrateSourceSQL($query);
|
||||
$this->destination = new MigrateDestinationUser();
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array('aid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Account ID.'
|
||||
)
|
||||
array(
|
||||
'aid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Account ID.',
|
||||
),
|
||||
MigrateDestinationUser::getKeySchema()
|
||||
),
|
||||
MigrateDestinationUser::getKeySchema()
|
||||
);
|
||||
|
||||
// One good way to organize your mappings in the constructor is in three
|
||||
@@ -239,7 +259,7 @@ class BeerUserMigration extends BasicExampleMigration {
|
||||
// 'test_1'.
|
||||
// dedupe() takes the Drupal table and column for determining uniqueness.
|
||||
$this->addFieldMapping('name', 'name')
|
||||
->dedupe('users', 'name');
|
||||
->dedupe('users', 'name');
|
||||
|
||||
// The migrate module automatically converts date/time strings to UNIX
|
||||
// timestamps.
|
||||
@@ -252,7 +272,7 @@ class BeerUserMigration extends BasicExampleMigration {
|
||||
// value is provided in addition to a source field, the default value will
|
||||
// be applied to any rows where the source field is empty or NULL.
|
||||
$this->addFieldMapping('roles')
|
||||
->defaultValue(DRUPAL_AUTHENTICATED_RID);
|
||||
->defaultValue(DRUPAL_AUTHENTICATED_RID);
|
||||
|
||||
$this->addFieldMapping('field_migrate_example_gender', 'sex');
|
||||
|
||||
@@ -262,16 +282,16 @@ class BeerUserMigration extends BasicExampleMigration {
|
||||
// user.
|
||||
if (module_exists('node_reference')) {
|
||||
$this->addFieldMapping('field_migrate_example_favbeers', 'beers')
|
||||
->separator('|');
|
||||
->separator('|');
|
||||
}
|
||||
else {
|
||||
$this->addFieldMapping(NULL, 'beers')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
}
|
||||
|
||||
// Unmapped source fields
|
||||
$this->addFieldMapping(NULL, 'nickname')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
|
||||
// Unmapped destination fields
|
||||
|
||||
@@ -297,15 +317,15 @@ class BeerUserMigration extends BasicExampleMigration {
|
||||
// list of destination fields", and also lists "1 unmapped" under Destination,
|
||||
// where it highlights "init" as unmapped.
|
||||
$this->addFieldMapping('int')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
|
||||
$destination_fields = $this->destination->fields();
|
||||
if (isset($destination_fields['path'])) {
|
||||
$this->addFieldMapping('path')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
if (isset($destination_fields['pathauto'])) {
|
||||
$this->addFieldMapping('pathauto')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,6 +336,7 @@ class BeerUserMigration extends BasicExampleMigration {
|
||||
* and creates Drupal nodes of type 'Beer' as destination.
|
||||
*/
|
||||
class BeerNodeMigration extends BasicExampleMigration {
|
||||
|
||||
public function __construct($arguments) {
|
||||
parent::__construct($arguments);
|
||||
$this->description = t('Beers of the world');
|
||||
@@ -326,9 +347,18 @@ class BeerNodeMigration extends BasicExampleMigration {
|
||||
// each node? One way (valid for MySQL only) is to pull them into a single
|
||||
// comma-separated list.
|
||||
$query = db_select('migrate_example_beer_node', 'b')
|
||||
->fields('b', array('bid', 'name', 'body', 'excerpt', 'aid',
|
||||
'countries', 'image', 'image_alt', 'image_title',
|
||||
'image_description'));
|
||||
->fields('b', array(
|
||||
'bid',
|
||||
'name',
|
||||
'body',
|
||||
'excerpt',
|
||||
'aid',
|
||||
'countries',
|
||||
'image',
|
||||
'image_alt',
|
||||
'image_title',
|
||||
'image_description',
|
||||
));
|
||||
$query->leftJoin('migrate_example_beer_topic_node', 'tb', 'b.bid = tb.bid');
|
||||
// Gives a single comma-separated list of related terms
|
||||
$query->groupBy('tb.bid');
|
||||
@@ -355,19 +385,19 @@ class BeerNodeMigration extends BasicExampleMigration {
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID.',
|
||||
'alias' => 'b',
|
||||
)
|
||||
),
|
||||
),
|
||||
MigrateDestinationNode::getKeySchema()
|
||||
);
|
||||
|
||||
// Mapped fields
|
||||
$this->addFieldMapping('title', 'name')
|
||||
->description(t('Mapping beer name in source to node title'));
|
||||
->description(t('Mapping beer name in source to node title'));
|
||||
$this->addFieldMapping('sticky')
|
||||
->description(t('Should we default this to 0 or 1?'))
|
||||
->issueGroup(t('Client questions'))
|
||||
->issueNumber(765736)
|
||||
->issuePriority(MigrateFieldMapping::ISSUE_PRIORITY_LOW);
|
||||
->description(t('Should we default this to 0 or 1?'))
|
||||
->issueGroup(t('Client questions'))
|
||||
->issueNumber(765736)
|
||||
->issuePriority(MigrateFieldMapping::ISSUE_PRIORITY_LOW);
|
||||
|
||||
// References to related objects (such as the author of the content) are
|
||||
// most likely going to be identifiers from the source data, not Drupal
|
||||
@@ -377,17 +407,17 @@ class BeerNodeMigration extends BasicExampleMigration {
|
||||
// find a corresponding uid for the aid, the owner will be the administrative
|
||||
// account.
|
||||
$this->addFieldMapping('uid', 'aid')
|
||||
// Note this is the machine name of the user migration.
|
||||
->sourceMigration('BeerUser')
|
||||
->defaultValue(1);
|
||||
// Note this is the machine name of the user migration.
|
||||
->sourceMigration('BeerUser')
|
||||
->defaultValue(1);
|
||||
|
||||
// This is a multi-value text field - in the source data the values are
|
||||
// separated by |, so we tell migrate to split it by that character.
|
||||
$this->addFieldMapping('field_migrate_example_country', 'countries')
|
||||
->separator('|');
|
||||
->separator('|');
|
||||
// These are related terms, which by default will be looked up by name.
|
||||
$this->addFieldMapping('migrate_example_beer_styles', 'terms')
|
||||
->separator(',');
|
||||
->separator(',');
|
||||
|
||||
// Some fields may have subfields such as text formats or summaries. These
|
||||
// can be individually mapped as we see here.
|
||||
@@ -407,10 +437,10 @@ class BeerNodeMigration extends BasicExampleMigration {
|
||||
// other options are available. In this case, MigrateFileUri indicates that
|
||||
// the 'image' value is a URI.
|
||||
$this->addFieldMapping('field_migrate_example_image:file_class')
|
||||
->defaultValue('MigrateFileUri');
|
||||
->defaultValue('MigrateFileUri');
|
||||
// Here we specify the directory containing the source files.
|
||||
$this->addFieldMapping('field_migrate_example_image:source_dir')
|
||||
->defaultValue(drupal_get_path('module', 'migrate_example'));
|
||||
->defaultValue(drupal_get_path('module', 'migrate_example'));
|
||||
// And we map the alt and title values in the database to those on the image.
|
||||
$this->addFieldMapping('field_migrate_example_image:alt', 'image_alt');
|
||||
$this->addFieldMapping('field_migrate_example_image:title', 'image_title');
|
||||
@@ -424,20 +454,20 @@ class BeerNodeMigration extends BasicExampleMigration {
|
||||
// subfields of the same field may be grouped on the same line), and indent
|
||||
// subfields to distinguish them from top-level fields.
|
||||
$this->addUnmigratedDestinations(array(
|
||||
'body:format',
|
||||
'body:format',
|
||||
'changed',
|
||||
'comment',
|
||||
'created',
|
||||
'field_migrate_example_image:destination_dir',
|
||||
'field_migrate_example_image:destination_file',
|
||||
'field_migrate_example_image:file_replace',
|
||||
'field_migrate_example_image:preserve_files',
|
||||
'field_migrate_example_image:urlencode',
|
||||
'field_migrate_example_image:destination_dir',
|
||||
'field_migrate_example_image:destination_file',
|
||||
'field_migrate_example_image:file_replace',
|
||||
'field_migrate_example_image:preserve_files',
|
||||
'field_migrate_example_image:urlencode',
|
||||
'is_new',
|
||||
'language',
|
||||
'log',
|
||||
'migrate_example_beer_styles:source_type',
|
||||
'migrate_example_beer_styles:create_term',
|
||||
'migrate_example_beer_styles:source_type',
|
||||
'migrate_example_beer_styles:create_term',
|
||||
'promote',
|
||||
'revision',
|
||||
'revision_uid',
|
||||
@@ -448,10 +478,10 @@ class BeerNodeMigration extends BasicExampleMigration {
|
||||
$destination_fields = $this->destination->fields();
|
||||
if (isset($destination_fields['path'])) {
|
||||
$this->addFieldMapping('path')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
if (isset($destination_fields['pathauto'])) {
|
||||
$this->addFieldMapping('pathauto')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
}
|
||||
}
|
||||
if (module_exists('statistics')) {
|
||||
@@ -466,14 +496,23 @@ class BeerNodeMigration extends BasicExampleMigration {
|
||||
* Drupal comment objects.
|
||||
*/
|
||||
class BeerCommentMigration extends BasicExampleMigration {
|
||||
|
||||
public function __construct($arguments) {
|
||||
parent::__construct($arguments);
|
||||
$this->description = 'Comments about beers';
|
||||
|
||||
$query = db_select('migrate_example_beer_comment', 'mec')
|
||||
->fields('mec', array('cid', 'cid_parent', 'name', 'mail', 'aid',
|
||||
'body', 'bid', 'subject'))
|
||||
->orderBy('cid_parent', 'ASC');
|
||||
->fields('mec', array(
|
||||
'cid',
|
||||
'cid_parent',
|
||||
'name',
|
||||
'mail',
|
||||
'aid',
|
||||
'body',
|
||||
'bid',
|
||||
'subject',
|
||||
))
|
||||
->orderBy('cid_parent', 'ASC');
|
||||
$this->source = new MigrateSourceSQL($query);
|
||||
// Note that the machine name passed for comment migrations is
|
||||
// 'comment_node_' followed by the machine name of the node type these
|
||||
@@ -482,29 +521,30 @@ class BeerCommentMigration extends BasicExampleMigration {
|
||||
new MigrateDestinationComment('comment_node_migrate_example_beer');
|
||||
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array('cid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
)
|
||||
),
|
||||
array(
|
||||
'cid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
),
|
||||
MigrateDestinationComment::getKeySchema()
|
||||
);
|
||||
|
||||
// Mapped fields
|
||||
$this->addSimpleMappings(array('name', 'subject', 'mail'));
|
||||
$this->addFieldMapping('status')
|
||||
->defaultValue(COMMENT_PUBLISHED);
|
||||
->defaultValue(COMMENT_PUBLISHED);
|
||||
|
||||
$this->addFieldMapping('nid', 'bid')
|
||||
->sourceMigration('BeerNode');
|
||||
->sourceMigration('BeerNode');
|
||||
|
||||
$this->addFieldMapping('uid', 'aid')
|
||||
->sourceMigration('BeerUser')
|
||||
->defaultValue(0);
|
||||
->sourceMigration('BeerUser')
|
||||
->defaultValue(0);
|
||||
|
||||
$this->addFieldMapping('pid', 'cid_parent')
|
||||
->sourceMigration('BeerComment')
|
||||
->description('Parent comment.');
|
||||
->sourceMigration('BeerComment')
|
||||
->description('Parent comment.');
|
||||
|
||||
$this->addFieldMapping('comment_body', 'body');
|
||||
|
||||
@@ -513,7 +553,7 @@ class BeerCommentMigration extends BasicExampleMigration {
|
||||
// Unmapped destination fields
|
||||
$this->addUnmigratedDestinations(array(
|
||||
'changed',
|
||||
'comment_body:format',
|
||||
'comment_body:format',
|
||||
'created',
|
||||
'homepage',
|
||||
'hostname',
|
||||
@@ -524,10 +564,10 @@ class BeerCommentMigration extends BasicExampleMigration {
|
||||
$destination_fields = $this->destination->fields();
|
||||
if (isset($destination_fields['path'])) {
|
||||
$this->addFieldMapping('path')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
if (isset($destination_fields['pathauto'])) {
|
||||
$this->addFieldMapping('pathauto')
|
||||
->issueGroup(t('DNM'));
|
||||
->issueGroup(t('DNM'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -54,12 +54,12 @@ function migrate_example_beer_schema_node() {
|
||||
return array(
|
||||
'description' => 'Beers of the world.',
|
||||
'fields' => array(
|
||||
'bid' => array(
|
||||
'bid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID.',
|
||||
),
|
||||
'name' => array(
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
@@ -120,7 +120,7 @@ function migrate_example_beer_schema_topic() {
|
||||
return array(
|
||||
'description' => 'Categories',
|
||||
'fields' => array(
|
||||
'style' => array(
|
||||
'style' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
@@ -157,12 +157,12 @@ function migrate_example_beer_schema_topic_node() {
|
||||
return array(
|
||||
'description' => 'Beers topic pairs.',
|
||||
'fields' => array(
|
||||
'bid' => array(
|
||||
'bid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID.',
|
||||
),
|
||||
'style' => array(
|
||||
'style' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
@@ -177,12 +177,12 @@ function migrate_example_beer_schema_comment() {
|
||||
return array(
|
||||
'description' => 'Beers comments.',
|
||||
'fields' => array(
|
||||
'cid' => array(
|
||||
'cid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Comment ID.',
|
||||
),
|
||||
'bid' => array(
|
||||
'bid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID that is being commented upon',
|
||||
@@ -230,12 +230,12 @@ function migrate_example_beer_schema_account() {
|
||||
return array(
|
||||
'description' => 'Beers accounts.',
|
||||
'fields' => array(
|
||||
'aid' => array(
|
||||
'aid' => array(
|
||||
'type' => 'serial',
|
||||
//'not null' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Account ID',
|
||||
),
|
||||
'status' => array(
|
||||
'status' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Blocked_Allowed',
|
||||
@@ -290,7 +290,7 @@ function migrate_example_beer_schema_legacy_urls() {
|
||||
return array(
|
||||
'description' => 'Stores legacy paths and destination ids for redirection.',
|
||||
'fields' => array(
|
||||
'id' => array(
|
||||
'id' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Primary Key: ID.',
|
||||
@@ -475,8 +475,8 @@ function migrate_example_beer_image() {
|
||||
function migrate_example_beer_favs() {
|
||||
if (!field_info_field('field_migrate_example_favbeers')) {
|
||||
$field = array(
|
||||
'field_name' => 'field_migrate_example_favbeers',
|
||||
'type' => 'node_reference',
|
||||
'field_name' => 'field_migrate_example_favbeers',
|
||||
'type' => 'node_reference',
|
||||
'cardinality' => -1,
|
||||
'settings' => array(
|
||||
'referenceable_types' => array('migrate_example_beer'),
|
||||
@@ -506,9 +506,10 @@ function migrate_example_beer_gender() {
|
||||
'field_name' => 'field_migrate_example_gender',
|
||||
'type' => 'list_integer',
|
||||
'settings' => array(
|
||||
'allowed_values' =>
|
||||
"0|Male\n" .
|
||||
"1|Female\n",
|
||||
'allowed_values' => array(
|
||||
0 => 'Male',
|
||||
1 => 'Female'
|
||||
),
|
||||
),
|
||||
);
|
||||
field_create_field($field);
|
||||
@@ -557,7 +558,11 @@ function migrate_example_beer_country() {
|
||||
|
||||
function migrate_example_beer_content_type_delete() {
|
||||
$bundle = 'migrate_example_beer';
|
||||
$field_names = array('migrate_example_beer_styles', 'field_migrate_example_image', 'field_migrate_example_country');
|
||||
$field_names = array(
|
||||
'migrate_example_beer_styles',
|
||||
'field_migrate_example_image',
|
||||
'field_migrate_example_country',
|
||||
);
|
||||
foreach ($field_names as $field_name) {
|
||||
$instance = field_info_instance('node', $field_name, $bundle);
|
||||
field_delete_instance($instance);
|
||||
@@ -578,15 +583,58 @@ function migrate_example_beer_content_type_delete() {
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_node() {
|
||||
$fields = array('bid', 'name', 'body', 'excerpt', 'countries', 'aid', 'image',
|
||||
'image_alt', 'image_title', 'image_description');
|
||||
$fields = array(
|
||||
'bid',
|
||||
'name',
|
||||
'body',
|
||||
'excerpt',
|
||||
'countries',
|
||||
'aid',
|
||||
'image',
|
||||
'image_alt',
|
||||
'image_title',
|
||||
'image_description',
|
||||
);
|
||||
$query = db_insert('migrate_example_beer_node')
|
||||
->fields($fields);
|
||||
->fields($fields);
|
||||
// Use high bid numbers to avoid overwriting an existing node id.
|
||||
$data = array(
|
||||
array(99999999, 'Heineken', 'Blab Blah Blah Green', 'Green', 'Netherlands|Belgium', 0, 'heineken.jpg', 'Heinekin alt', 'Heinekin title', 'Heinekin description'), // comes with migrate_example project.
|
||||
array(99999998, 'Miller Lite', 'We love Miller Brewing', 'Tasteless', 'USA|Canada', 1, NULL, NULL, NULL, NULL),
|
||||
array(99999997, 'Boddington', 'English occassionally get something right', 'A treat', 'United Kingdom', 1, NULL, NULL, NULL, NULL),
|
||||
array(
|
||||
99999999,
|
||||
'Heineken',
|
||||
'Blab Blah Blah Green',
|
||||
'Green',
|
||||
'Netherlands|Belgium',
|
||||
0,
|
||||
'heineken.jpg',
|
||||
'Heinekin alt',
|
||||
'Heinekin title',
|
||||
'Heinekin description',
|
||||
), // comes with migrate_example project.
|
||||
array(
|
||||
99999998,
|
||||
'Miller Lite',
|
||||
'We love Miller Brewing',
|
||||
'Tasteless',
|
||||
'USA|Canada',
|
||||
1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
),
|
||||
array(
|
||||
99999997,
|
||||
'Boddington',
|
||||
'English occassionally get something right',
|
||||
'A treat',
|
||||
'United Kingdom',
|
||||
1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
@@ -597,14 +645,59 @@ function migrate_example_beer_data_node() {
|
||||
// Note that alice has duplicate username. Exercies dedupe() method.
|
||||
// @TODO duplicate email also.
|
||||
function migrate_example_beer_data_account() {
|
||||
$fields = array('status', 'posted', 'name', 'nickname', 'password', 'mail', 'sex', 'beers');
|
||||
$fields = array(
|
||||
'status',
|
||||
'posted',
|
||||
'name',
|
||||
'nickname',
|
||||
'password',
|
||||
'mail',
|
||||
'sex',
|
||||
'beers',
|
||||
);
|
||||
$query = db_insert('migrate_example_beer_account')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, '2010-03-30 10:31:05', 'alice', 'alice hot pants', 'alicepass', 'alice@example.com', '1', '99999999|99999998|99999997'),
|
||||
array(1, '2010-04-04 10:31:05', 'alice', 'alice dupe pants', 'alicepass', 'alice2@example.com', '1', '99999999|99999998|99999997'),
|
||||
array(0, '2007-03-15 10:31:05', 'bob', 'rebob', 'bobpass', 'bob@example.com', '1', '99999999|99999997'),
|
||||
array(1, '2004-02-29 10:31:05', 'charlie', 'charlie chocolate', 'mykids', 'charlie@example.com', '0', '99999999|99999998'),
|
||||
array(
|
||||
1,
|
||||
'2010-03-30 10:31:05',
|
||||
'alice',
|
||||
'alice hot pants',
|
||||
'alicepass',
|
||||
'alice@example.com',
|
||||
'1',
|
||||
'99999999|99999998|99999997',
|
||||
),
|
||||
array(
|
||||
1,
|
||||
'2010-04-04 10:31:05',
|
||||
'alice',
|
||||
'alice dupe pants',
|
||||
'alicepass',
|
||||
'alice2@example.com',
|
||||
'1',
|
||||
'99999999|99999998|99999997',
|
||||
),
|
||||
array(
|
||||
0,
|
||||
'2007-03-15 10:31:05',
|
||||
'bob',
|
||||
'rebob',
|
||||
'bobpass',
|
||||
'bob@example.com',
|
||||
'1',
|
||||
'99999999|99999997',
|
||||
),
|
||||
array(
|
||||
1,
|
||||
'2004-02-29 10:31:05',
|
||||
'charlie',
|
||||
'charlie chocolate',
|
||||
'mykids',
|
||||
'charlie@example.com',
|
||||
'0',
|
||||
'99999999|99999998',
|
||||
),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
@@ -613,15 +706,55 @@ function migrate_example_beer_data_account() {
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_comment() {
|
||||
$fields = array('bid', 'cid_parent', 'subject', 'body', 'name', 'mail', 'aid');
|
||||
$fields = array(
|
||||
'bid',
|
||||
'cid_parent',
|
||||
'subject',
|
||||
'body',
|
||||
'name',
|
||||
'mail',
|
||||
'aid',
|
||||
);
|
||||
$query = db_insert('migrate_example_beer_comment')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(99999998, NULL, 'im first', 'hot body', 'alice', 'alice@example.com', 0),
|
||||
array(99999998, NULL, 'im second', 'hot body', 'alice', 'alice@example.com', 0),
|
||||
array(99999999, NULL, 'im parent', 'hot body', 'alice', 'alice@example.com', 0),
|
||||
array(
|
||||
99999998,
|
||||
NULL,
|
||||
'im first',
|
||||
'hot body',
|
||||
'alice',
|
||||
'alice@example.com',
|
||||
0,
|
||||
),
|
||||
array(
|
||||
99999998,
|
||||
NULL,
|
||||
'im second',
|
||||
'hot body',
|
||||
'alice',
|
||||
'alice@example.com',
|
||||
0,
|
||||
),
|
||||
array(
|
||||
99999999,
|
||||
NULL,
|
||||
'im parent',
|
||||
'hot body',
|
||||
'alice',
|
||||
'alice@example.com',
|
||||
0,
|
||||
),
|
||||
array(99999999, 1, 'im child', 'cold body', 'bob', NULL, 1),
|
||||
array(99999999, 2, 'im grandchild', 'bitter body', 'charlie@example.com', NULL, 1),
|
||||
array(
|
||||
99999999,
|
||||
2,
|
||||
'im grandchild',
|
||||
'bitter body',
|
||||
'charlie@example.com',
|
||||
NULL,
|
||||
1,
|
||||
),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
@@ -636,7 +769,13 @@ function migrate_example_beer_data_topic() {
|
||||
$data = array(
|
||||
array('ale', 'traditional', NULL, 'Medieval British Isles', 'Medium'),
|
||||
array('red ale', 'colorful', 'ale', NULL, NULL),
|
||||
array('pilsner', 'refreshing', NULL, 'Pilsen, Bohemia (now Czech Republic)', 'Low'),
|
||||
array(
|
||||
'pilsner',
|
||||
'refreshing',
|
||||
NULL,
|
||||
'Pilsen, Bohemia (now Czech Republic)',
|
||||
'Low',
|
||||
),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
@@ -660,13 +799,37 @@ function migrate_example_beer_data_topic_node() {
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_urls() {
|
||||
$fields = array('id', 'migration_name', 'source_id', 'source_uri', 'modificationdatetime');
|
||||
$fields = array(
|
||||
'id',
|
||||
'migration_name',
|
||||
'source_id',
|
||||
'source_uri',
|
||||
'modificationdatetime',
|
||||
);
|
||||
$query = db_insert('migrate_example_beer_legacy_urls')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'BeerNode', 99999997, 'the_boddington/main', strtotime('2010-04-12 08:32:06')),
|
||||
array(2, 'BeerNode', 99999998, 'Miller Lite taste', strtotime('2010-04-12 08:32:05')),
|
||||
array(3, 'BeerNode', 99999999, 'green wonder', strtotime('2010-04-12 08:32:03')),
|
||||
array(
|
||||
1,
|
||||
'BeerNode',
|
||||
99999997,
|
||||
'the_boddington/main',
|
||||
strtotime('2010-04-12 08:32:06'),
|
||||
),
|
||||
array(
|
||||
2,
|
||||
'BeerNode',
|
||||
99999998,
|
||||
'Miller Lite taste',
|
||||
strtotime('2010-04-12 08:32:05'),
|
||||
),
|
||||
array(
|
||||
3,
|
||||
'BeerNode',
|
||||
99999999,
|
||||
'green wonder',
|
||||
strtotime('2010-04-12 08:32:03'),
|
||||
),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
|
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
class RoleTableMigration extends Migration {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->dependencies = array();
|
||||
@@ -23,14 +24,15 @@ class RoleTableMigration extends Migration {
|
||||
$this->destination = new MigrateDestinationTableCopy('role_copy', $destination_key);
|
||||
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array('rid' => array(
|
||||
array(
|
||||
'rid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'alias' => 'r',
|
||||
)
|
||||
),
|
||||
$destination_key
|
||||
),
|
||||
),
|
||||
$destination_key
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -18,9 +18,8 @@ files[] = wine.inc
|
||||
; For testing table_copy plugin. Since is infrequently used, we comment it out.
|
||||
; files[] = example.table_copy.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-07-01
|
||||
version = "7.x-2.8"
|
||||
; Information added by Drupal.org packaging script on 2018-06-10
|
||||
version = "7.x-2.11"
|
||||
core = "7.x"
|
||||
project = "migrate"
|
||||
datestamp = "1435760949"
|
||||
|
||||
datestamp = "1528674486"
|
||||
|
@@ -63,8 +63,8 @@ function migrate_example_update_7001() {
|
||||
);
|
||||
|
||||
$result = db_select('migrate_example_beer_legacy_urls', 'ms')
|
||||
->fields('ms', array('machine_name', 'modificationdate'))
|
||||
->execute();
|
||||
->fields('ms', array('machine_name', 'modificationdate'))
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
$modificationdatetime = strtotime($row->modificationdate);
|
||||
db_update('migrate_example_beer_legacy_urls')
|
||||
@@ -85,24 +85,24 @@ function migrate_example_update_7001() {
|
||||
function migrate_example_update_7002() {
|
||||
$ret = array();
|
||||
db_add_field('migrate_example_beer_node', 'image_alt', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image ALT',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image ALT',
|
||||
)
|
||||
);
|
||||
db_add_field('migrate_example_beer_node', 'image_title', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image title',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image title',
|
||||
)
|
||||
);
|
||||
db_add_field('migrate_example_beer_node', 'image_description', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image description',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image description',
|
||||
)
|
||||
);
|
||||
db_update('migrate_example_beer_node')
|
||||
@@ -207,10 +207,10 @@ function migrate_example_update_7006() {
|
||||
function migrate_example_update_7007() {
|
||||
$ret = array();
|
||||
db_add_field('migrate_example_wine_account', 'positions', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Positions held',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Positions held',
|
||||
)
|
||||
);
|
||||
$query = db_update('migrate_example_wine_account')
|
||||
|
@@ -11,9 +11,8 @@ name = "Migrate example - Oracle"
|
||||
package = "Migration"
|
||||
project = "migrate_example_oracle"
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-07-01
|
||||
version = "7.x-2.8"
|
||||
; Information added by Drupal.org packaging script on 2018-06-10
|
||||
version = "7.x-2.11"
|
||||
core = "7.x"
|
||||
project = "migrate"
|
||||
datestamp = "1435760949"
|
||||
|
||||
datestamp = "1528674486"
|
||||
|
@@ -123,7 +123,7 @@ function migrate_example_oracle_requirements($phase) {
|
||||
}
|
||||
|
||||
$sample_setting =
|
||||
'<pre>
|
||||
'<pre>
|
||||
$conf[\'oracle_db\'] = array(
|
||||
\'username\' => \'Oracle_username\',
|
||||
\'password\' => \'Oracle_password\',
|
||||
@@ -134,7 +134,7 @@ $conf[\'oracle_db\'] = array(
|
||||
$requirements['oracle_db'] = array('title' => $t('Oracle configuration'));
|
||||
global $conf;
|
||||
if (empty($conf['oracle_db']) || empty($conf['oracle_db']['username']) ||
|
||||
empty($conf['oracle_db']['password']) || empty($conf['oracle_db']['connection_string'])) {
|
||||
empty($conf['oracle_db']['password']) || empty($conf['oracle_db']['connection_string'])) {
|
||||
$requirements['oracle_db']['description'] = $t('You must define $conf[\'oracle_db\']
|
||||
(in your site\'s settings.php file) to point to the Oracle database where
|
||||
you want test data to be stored: ' . $sample_setting);
|
||||
@@ -150,8 +150,10 @@ $conf[\'oracle_db\'] = array(
|
||||
$e = oci_error();
|
||||
$requirements['oracle_connect']['description'] = $t('Could not connect to configured
|
||||
Oracle database at !conn_string. Oracle error message: !message',
|
||||
array('!conn_string' => $conf['oracle_db']['connection_string'],
|
||||
'!message' => $e['message']));
|
||||
array(
|
||||
'!conn_string' => $conf['oracle_db']['connection_string'],
|
||||
'!message' => $e['message'],
|
||||
));
|
||||
$requirements['oracle_connect']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
@@ -159,35 +161,35 @@ $conf[\'oracle_db\'] = array(
|
||||
// Check for necessary privileges
|
||||
$requirements['oracle_privs'] = array('title' => $t('Necessary Oracle privileges are assigned'));
|
||||
$statement = oci_parse($connection, 'SELECT * FROM SESSION_PRIVS');
|
||||
if (!$statement) {
|
||||
$e = oci_error($connection);
|
||||
$requirements['oracle_connect']['description'] = $e['message'];
|
||||
$requirements['oracle_connect']['severity'] = REQUIREMENT_ERROR;
|
||||
if (!$statement) {
|
||||
$e = oci_error($connection);
|
||||
$requirements['oracle_connect']['description'] = $e['message'];
|
||||
$requirements['oracle_connect']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
$result = oci_execute($statement);
|
||||
if (!$result) {
|
||||
$e = oci_error($statement);
|
||||
$requirements['oracle_connect']['description'] = $e['message'];
|
||||
$requirements['oracle_connect']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
$ok = FALSE;
|
||||
while ($row = oci_fetch_object($statement)) {
|
||||
if ($row->PRIVILEGE == 'CREATE TABLE') {
|
||||
$ok = TRUE;
|
||||
break;
|
||||
}
|
||||
$result = oci_execute($statement);
|
||||
if (!$result) {
|
||||
$e = oci_error($statement);
|
||||
$requirements['oracle_connect']['description'] = $e['message'];
|
||||
$requirements['oracle_connect']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
$ok = FALSE;
|
||||
while ($row = oci_fetch_object($statement)) {
|
||||
if ($row->PRIVILEGE == 'CREATE TABLE') {
|
||||
$ok = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$ok) {
|
||||
$requirements['oracle_privs']['description'] = $t('The specified
|
||||
if (!$ok) {
|
||||
$requirements['oracle_privs']['description'] = $t('The specified
|
||||
username !username does not have the CREATE TABLE privilege. This privilege
|
||||
is necessary to create test tables in the Oracle database.',
|
||||
array('!username' => $conf['oracle_db']['username']));
|
||||
$requirements['oracle_privs']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
array('!username' => $conf['oracle_db']['username']));
|
||||
$requirements['oracle_privs']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'update':
|
||||
break;
|
||||
|
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Examples and test fodder for migration from Oracle sources. To use this example
|
||||
* (and to run the corresponding tests) you must define a connection to an Oracle database
|
||||
* in your settings.php. E.g.,
|
||||
* Examples and test fodder for migration from Oracle sources. To use this
|
||||
* example
|
||||
* (and to run the corresponding tests) you must define a connection to an
|
||||
* Oracle database in your settings.php. E.g.,
|
||||
*
|
||||
* $conf['oracle_db'] = array(
|
||||
* 'username' => 'DRUPAL',
|
||||
@@ -11,17 +12,18 @@
|
||||
* 'connection_string' => '//oracledb/orcl',
|
||||
* );
|
||||
*
|
||||
* The username must have the CREATE TABLE privilege, so test data can be stored for the
|
||||
* example to import.
|
||||
* The username must have the CREATE TABLE privilege, so test data can be
|
||||
* stored for the example to import.
|
||||
*
|
||||
* See http://us.php.net/manual/en/function.oci-connect.php for more information on
|
||||
* connection_string.
|
||||
* See http://us.php.net/manual/en/function.oci-connect.php for more
|
||||
* information on connection_string.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Migration class to test importing from Oracle into nodes.
|
||||
*/
|
||||
class MigrateExampleOracleNode extends Migration {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->description = t('Example migration from Oracle into nodes.');
|
||||
@@ -35,7 +37,7 @@ class MigrateExampleOracleNode extends Migration {
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Content ID',
|
||||
)
|
||||
),
|
||||
),
|
||||
MigrateDestinationNode::getKeySchema()
|
||||
);
|
||||
@@ -67,23 +69,31 @@ class MigrateExampleOracleNode extends Migration {
|
||||
// Basic fields
|
||||
$this->addFieldMapping('title', 'TITLE');
|
||||
$this->addFieldMapping('uid')
|
||||
->defaultValue(1);
|
||||
->defaultValue(1);
|
||||
$this->addFieldMapping('body', 'BODY');
|
||||
$this->addFieldMapping('field_mainimage', 'MAINIMAGE')
|
||||
->description('An image blob in the DB')
|
||||
->arguments(array(
|
||||
'file_function' => 'file_blob',
|
||||
// Alternatively, specify a column here for dynamic file name.
|
||||
'source_path' => 'druplicon.png',
|
||||
->description('An image blob in the DB')
|
||||
->arguments(array(
|
||||
'file_function' => 'file_blob',
|
||||
// Alternatively, specify a column here for dynamic file name.
|
||||
'source_path' => 'druplicon.png',
|
||||
|
||||
));
|
||||
));
|
||||
$this->addFieldMapping('created', 'CREATED');
|
||||
$this->addFieldMapping('changed', 'UPDATED');
|
||||
|
||||
|
||||
// Unmapped destination fields
|
||||
$this->addUnmigratedDestinations(array('is_new', 'status', 'promote',
|
||||
'revision', 'language', 'sticky', 'revision_uid', 'path'));
|
||||
$this->addUnmigratedDestinations(array(
|
||||
'is_new',
|
||||
'status',
|
||||
'promote',
|
||||
'revision',
|
||||
'language',
|
||||
'sticky',
|
||||
'revision_uid',
|
||||
'path',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +105,7 @@ function migrate_example_oracle_migrate_api() {
|
||||
'api' => 2,
|
||||
'migrations' => array(
|
||||
'MigrateExampleOracle' => array('class_name' => 'MigrateExampleOracleNode'),
|
||||
)
|
||||
),
|
||||
);
|
||||
return $api;
|
||||
}
|
||||
|
@@ -20,20 +20,36 @@ function migrate_example_oracle_generate($length) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of data rows for testing Oracle import. Note that 4000 is a magic
|
||||
* number for Oracle LOB datatypes, so we testing lengths above and below that limit.
|
||||
* Return an array of data rows for testing Oracle import. Note that 4000 is a
|
||||
* magic number for Oracle LOB datatypes, so we testing lengths above and below
|
||||
* that limit.
|
||||
*/
|
||||
function migrate_example_oracle_sample_data() {
|
||||
$image = file_get_contents('misc/druplicon.png');
|
||||
return array(
|
||||
array('oid' => 3, 'title' => 'Sample title', 'body' => 'Sample body',
|
||||
'mainimage' => $image, 'created' => '2011/05/01 01:02:03',
|
||||
'updated' => '2011/06/30 04:05:06'),
|
||||
array('oid' => 5, 'title' => 'Another title', 'body' => migrate_example_oracle_generate(3900),
|
||||
'mainimage' => $image, 'created' => '2011/08/12 07:08:09',
|
||||
'updated' => '2011/12/25 10:11:12'),
|
||||
array('oid' => 7, 'title' => 'Yet another title', 'body' => migrate_example_oracle_generate(4500),
|
||||
'mainimage' => $image, 'created' => '2012/01/01 13:14:15',
|
||||
'updated' => '2012/03/14 16:17:18'),
|
||||
array(
|
||||
'oid' => 3,
|
||||
'title' => 'Sample title',
|
||||
'body' => 'Sample body',
|
||||
'mainimage' => $image,
|
||||
'created' => '2011/05/01 01:02:03',
|
||||
'updated' => '2011/06/30 04:05:06',
|
||||
),
|
||||
array(
|
||||
'oid' => 5,
|
||||
'title' => 'Another title',
|
||||
'body' => migrate_example_oracle_generate(3900),
|
||||
'mainimage' => $image,
|
||||
'created' => '2011/08/12 07:08:09',
|
||||
'updated' => '2011/12/25 10:11:12',
|
||||
),
|
||||
array(
|
||||
'oid' => 7,
|
||||
'title' => 'Yet another title',
|
||||
'body' => migrate_example_oracle_generate(4500),
|
||||
'mainimage' => $image,
|
||||
'created' => '2012/01/01 13:14:15',
|
||||
'updated' => '2012/03/14 16:17:18',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -72,13 +72,13 @@ function migrate_example_wine_schema_wine() {
|
||||
return array(
|
||||
'description' => 'Wines of the world',
|
||||
'fields' => array(
|
||||
'wineid' => array(
|
||||
'wineid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Wine ID',
|
||||
),
|
||||
'name' => array(
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
@@ -140,7 +140,7 @@ function migrate_example_wine_schema_updates() {
|
||||
return array(
|
||||
'description' => 'Updated wine ratings',
|
||||
'fields' => array(
|
||||
'wineid' => array(
|
||||
'wineid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -161,13 +161,13 @@ function migrate_example_wine_schema_producer() {
|
||||
return array(
|
||||
'description' => 'Wine producers of the world',
|
||||
'fields' => array(
|
||||
'producerid' => array(
|
||||
'producerid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Producer ID',
|
||||
),
|
||||
'name' => array(
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
@@ -211,7 +211,7 @@ function migrate_example_wine_schema_categories() {
|
||||
'not null' => TRUE,
|
||||
'description' => 'Type of category: variety, region, best_with',
|
||||
),
|
||||
'name' => array(
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
@@ -242,12 +242,12 @@ function migrate_example_wine_schema_vintages() {
|
||||
return array(
|
||||
'description' => 'Wine vintages',
|
||||
'fields' => array(
|
||||
'wineid' => array(
|
||||
'wineid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Wine ID',
|
||||
),
|
||||
'vintage' => array(
|
||||
'vintage' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -282,12 +282,12 @@ function migrate_example_wine_schema_category_wine() {
|
||||
return array(
|
||||
'description' => 'Wine category assignments',
|
||||
'fields' => array(
|
||||
'wineid' => array(
|
||||
'wineid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Wine ID',
|
||||
),
|
||||
'categoryid' => array(
|
||||
'categoryid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -302,12 +302,12 @@ function migrate_example_wine_schema_category_producer() {
|
||||
return array(
|
||||
'description' => 'Producer category assignments',
|
||||
'fields' => array(
|
||||
'producerid' => array(
|
||||
'producerid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Producer ID',
|
||||
),
|
||||
'categoryid' => array(
|
||||
'categoryid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -322,13 +322,13 @@ function migrate_example_wine_schema_comment() {
|
||||
return array(
|
||||
'description' => 'Wine comments',
|
||||
'fields' => array(
|
||||
'commentid' => array(
|
||||
'commentid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Comment ID',
|
||||
),
|
||||
'wineid' => array(
|
||||
'wineid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -403,7 +403,7 @@ function migrate_example_wine_schema_comment_updates() {
|
||||
return array(
|
||||
'description' => 'Wine comment updates',
|
||||
'fields' => array(
|
||||
'commentid' => array(
|
||||
'commentid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -424,12 +424,12 @@ function migrate_example_wine_schema_account() {
|
||||
return array(
|
||||
'description' => 'Wine accounts.',
|
||||
'fields' => array(
|
||||
'accountid' => array(
|
||||
'accountid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Account ID',
|
||||
),
|
||||
'status' => array(
|
||||
'status' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Blocked_Allowed',
|
||||
@@ -488,7 +488,7 @@ function migrate_example_wine_schema_account() {
|
||||
'not null' => TRUE,
|
||||
'description' => 'Signature for comments',
|
||||
),
|
||||
'imageid' => array(
|
||||
'imageid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
@@ -509,7 +509,7 @@ function migrate_example_wine_schema_account_updates() {
|
||||
return array(
|
||||
'description' => 'Wine account updates',
|
||||
'fields' => array(
|
||||
'accountid' => array(
|
||||
'accountid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Account ID',
|
||||
@@ -529,7 +529,7 @@ function migrate_example_wine_schema_blobs() {
|
||||
return array(
|
||||
'description' => 'Wine blobs to be migrated to file entities',
|
||||
'fields' => array(
|
||||
'imageid' => array(
|
||||
'imageid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -549,31 +549,31 @@ function migrate_example_wine_schema_files() {
|
||||
return array(
|
||||
'description' => 'Wine and account files',
|
||||
'fields' => array(
|
||||
'imageid' => array(
|
||||
'imageid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Image ID',
|
||||
),
|
||||
'url' => array(
|
||||
'url' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Image URL',
|
||||
),
|
||||
'image_alt' => array(
|
||||
'image_alt' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image alt',
|
||||
),
|
||||
'image_title' => array(
|
||||
'image_title' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image title',
|
||||
),
|
||||
'wineid' => array(
|
||||
'wineid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
@@ -588,19 +588,19 @@ function migrate_example_wine_schema_table_source() {
|
||||
return array(
|
||||
'description' => 'Source data to go into a custom Drupal table',
|
||||
'fields' => array(
|
||||
'fooid' => array(
|
||||
'fooid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Primary key',
|
||||
),
|
||||
'field1' => array(
|
||||
'field1' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'First field',
|
||||
),
|
||||
'field2' => array(
|
||||
'field2' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -615,19 +615,19 @@ function migrate_example_wine_schema_table_dest() {
|
||||
return array(
|
||||
'description' => 'Custom Drupal table to receive source data directly',
|
||||
'fields' => array(
|
||||
'recordid' => array(
|
||||
'recordid' => array(
|
||||
'type' => 'serial',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Primary key',
|
||||
),
|
||||
'drupal_text' => array(
|
||||
'drupal_text' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'First field',
|
||||
),
|
||||
'drupal_int' => array(
|
||||
'drupal_int' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
@@ -944,9 +944,12 @@ function migrate_example_wine_fields() {
|
||||
|
||||
function migrate_example_wine_content_type_delete() {
|
||||
$bundle = 'migrate_example_wine';
|
||||
$field_names = array('migrate_example_wine_varieties',
|
||||
'migrate_example_wine_regions', 'migrate_example_wine_best_with',
|
||||
'field_migrate_example_image');
|
||||
$field_names = array(
|
||||
'migrate_example_wine_varieties',
|
||||
'migrate_example_wine_regions',
|
||||
'migrate_example_wine_best_with',
|
||||
'field_migrate_example_image',
|
||||
);
|
||||
foreach ($field_names as $field_name) {
|
||||
$instance = field_info_instance('node', $field_name, $bundle);
|
||||
field_delete_instance($instance);
|
||||
@@ -964,15 +967,45 @@ function migrate_example_wine_content_type_delete() {
|
||||
}
|
||||
|
||||
function migrate_example_wine_data_wine() {
|
||||
$fields = array('wineid', 'name', 'body', 'excerpt', 'accountid',
|
||||
'posted', 'last_changed', 'variety', 'region', 'rating');
|
||||
$fields = array(
|
||||
'wineid',
|
||||
'name',
|
||||
'body',
|
||||
'excerpt',
|
||||
'accountid',
|
||||
'posted',
|
||||
'last_changed',
|
||||
'variety',
|
||||
'region',
|
||||
'rating',
|
||||
);
|
||||
$query = db_insert('migrate_example_wine')
|
||||
->fields($fields);
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'Montes Classic Cabernet Sauvignon', 'Intense ruby-red color', 'Great!', 9,
|
||||
strtotime('2010-01-02 03:04:05'), strtotime('2010-03-04 05:06:07'), 25, 17, 95),
|
||||
array(2, 'Archeo Ruggero di Tasso Nero d\'Avola', 'Lots of berry character', 'Pair with red sauced dishes', 3,
|
||||
strtotime('2010-09-03 18:23:58'), strtotime('2010-09-03 18:23:58'), 26, 2, 85),
|
||||
array(
|
||||
1,
|
||||
'Montes Classic Cabernet Sauvignon',
|
||||
'Intense ruby-red color',
|
||||
'Great!',
|
||||
9,
|
||||
strtotime('2010-01-02 03:04:05'),
|
||||
strtotime('2010-03-04 05:06:07'),
|
||||
25,
|
||||
17,
|
||||
95,
|
||||
),
|
||||
array(
|
||||
2,
|
||||
'Archeo Ruggero di Tasso Nero d\'Avola',
|
||||
'Lots of berry character',
|
||||
'Pair with red sauced dishes',
|
||||
3,
|
||||
strtotime('2010-09-03 18:23:58'),
|
||||
strtotime('2010-09-03 18:23:58'),
|
||||
26,
|
||||
2,
|
||||
85,
|
||||
),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
@@ -983,7 +1016,7 @@ function migrate_example_wine_data_wine() {
|
||||
function migrate_example_wine_data_updates() {
|
||||
$fields = array('wineid', 'rating');
|
||||
$query = db_insert('migrate_example_wine_updates')
|
||||
->fields($fields);
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 93),
|
||||
array(2, NULL),
|
||||
@@ -997,7 +1030,7 @@ function migrate_example_wine_data_updates() {
|
||||
function migrate_example_wine_data_producer() {
|
||||
$fields = array('producerid', 'name', 'body', 'excerpt', 'accountid');
|
||||
$query = db_insert('migrate_example_wine_producer')
|
||||
->fields($fields);
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'Montes', 'Fine Chilean winery', 'Great!', 9),
|
||||
array(2, 'Archeo', 'Sicilia!', NULL, 3),
|
||||
@@ -1009,20 +1042,69 @@ function migrate_example_wine_data_producer() {
|
||||
}
|
||||
|
||||
function migrate_example_wine_data_account() {
|
||||
$fields = array('accountid', 'status', 'posted', 'last_access', 'last_login',
|
||||
'name', 'sex', 'password', 'mail', 'original_mail', 'sig', 'imageid', 'positions');
|
||||
$fields = array(
|
||||
'accountid',
|
||||
'status',
|
||||
'posted',
|
||||
'last_access',
|
||||
'last_login',
|
||||
'name',
|
||||
'sex',
|
||||
'password',
|
||||
'mail',
|
||||
'original_mail',
|
||||
'sig',
|
||||
'imageid',
|
||||
'positions',
|
||||
);
|
||||
$query = db_insert('migrate_example_wine_account')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 1, '2010-03-30 10:31:05', '2010-04-30 18:25:24', '2010-04-30 14:01:02',
|
||||
'darren', 'M', 'dpass', 'ddarren@example.com', 'darren@example.com',
|
||||
'All about the Australians', NULL, '5'),
|
||||
array(3, 0, '2007-03-15 10:31:05', '2007-06-10 04:11:38', '2007-06-10 04:11:38',
|
||||
'emily', 'F', 'insecure', 'emily@example.com', 'emily@example.com',
|
||||
'Sommelier to the stars', NULL, '18'),
|
||||
array(9, 1, '2004-02-29 10:31:05', '2004-02-29 10:31:05', '2004-02-29 10:31:05',
|
||||
'fonzie', NULL, 'bike', 'thefonz@example.com', 'arthur@example.com',
|
||||
'Aaay!', 1, '5,18'),
|
||||
array(
|
||||
1,
|
||||
1,
|
||||
'2010-03-30 10:31:05',
|
||||
'2010-04-30 18:25:24',
|
||||
'2010-04-30 14:01:02',
|
||||
'darren',
|
||||
'M',
|
||||
'dpass',
|
||||
'ddarren@example.com',
|
||||
'darren@example.com',
|
||||
'All about the Australians',
|
||||
NULL,
|
||||
'5',
|
||||
),
|
||||
array(
|
||||
3,
|
||||
0,
|
||||
'2007-03-15 10:31:05',
|
||||
'2007-06-10 04:11:38',
|
||||
'2007-06-10 04:11:38',
|
||||
'emily',
|
||||
'F',
|
||||
'insecure',
|
||||
'emily@example.com',
|
||||
'emily@example.com',
|
||||
'Sommelier to the stars',
|
||||
NULL,
|
||||
'18',
|
||||
),
|
||||
array(
|
||||
9,
|
||||
1,
|
||||
'2004-02-29 10:31:05',
|
||||
'2004-02-29 10:31:05',
|
||||
'2004-02-29 10:31:05',
|
||||
'fonzie',
|
||||
NULL,
|
||||
'bike',
|
||||
'thefonz@example.com',
|
||||
'arthur@example.com',
|
||||
'Aaay!',
|
||||
1,
|
||||
'5,18',
|
||||
),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
@@ -1033,7 +1115,7 @@ function migrate_example_wine_data_account() {
|
||||
function migrate_example_wine_data_account_updates() {
|
||||
$fields = array('accountid', 'sex');
|
||||
$query = db_insert('migrate_example_wine_account_updates')
|
||||
->fields($fields);
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, NULL),
|
||||
array(3, 'M'),
|
||||
@@ -1046,26 +1128,93 @@ function migrate_example_wine_data_account_updates() {
|
||||
}
|
||||
|
||||
function migrate_example_wine_data_comment() {
|
||||
$fields = array('commentid', 'wineid', 'comment_parent', 'subject', 'body',
|
||||
'name', 'mail', 'accountid', 'commenthost', 'userpage', 'posted', 'lastchanged');
|
||||
$fields = array(
|
||||
'commentid',
|
||||
'wineid',
|
||||
'comment_parent',
|
||||
'subject',
|
||||
'body',
|
||||
'name',
|
||||
'mail',
|
||||
'accountid',
|
||||
'commenthost',
|
||||
'userpage',
|
||||
'posted',
|
||||
'lastchanged',
|
||||
);
|
||||
$query = db_insert('migrate_example_wine_comment')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 1, NULL, 'im first', 'Tasty', 'grace', 'grace@example.com', 0,
|
||||
'123.456.78.9', 'http:://grace.example.com/',
|
||||
strtotime('2010-01-02 03:04:05'), strtotime('2010-04-05 06:07:08')),
|
||||
array(2, 1, NULL, 'im second', 'Delicious', 'horace', 'horace@example.com', 0,
|
||||
'example.com', NULL,
|
||||
strtotime('2010-02-02 03:04:05'), strtotime('2010-05-05 06:07:08')),
|
||||
array(3, 1, NULL, 'im parent', 'Don\'t care for it', 'irene', 'irene@example.com', 0,
|
||||
'254.0.2.5', 'http:://www.example.com/irene',
|
||||
strtotime('2010-03-02 03:04:05'), strtotime('2010-03-02 03:04:05')),
|
||||
array(4, 1, 3, 'im child', 'But it\'s so good!', 'emily', NULL, 3,
|
||||
'58.29.126.1', 'http:://www.wine.com/',
|
||||
strtotime('2010-01-02 03:04:05'), strtotime('2010-01-02 03:04:05')),
|
||||
array(5, 1, 4, 'im grandchild', 'Right on, Emily!', 'thefonz@example.com', NULL, 9,
|
||||
'123.456.78.9', NULL,
|
||||
strtotime('2010-06-02 03:04:05'), strtotime('2010-06-02 03:04:05')),
|
||||
array(
|
||||
1,
|
||||
1,
|
||||
NULL,
|
||||
'im first',
|
||||
'Tasty',
|
||||
'grace',
|
||||
'grace@example.com',
|
||||
0,
|
||||
'123.456.78.9',
|
||||
'http:://grace.example.com/',
|
||||
strtotime('2010-01-02 03:04:05'),
|
||||
strtotime('2010-04-05 06:07:08'),
|
||||
),
|
||||
array(
|
||||
2,
|
||||
1,
|
||||
NULL,
|
||||
'im second',
|
||||
'Delicious',
|
||||
'horace',
|
||||
'horace@example.com',
|
||||
0,
|
||||
'example.com',
|
||||
NULL,
|
||||
strtotime('2010-02-02 03:04:05'),
|
||||
strtotime('2010-05-05 06:07:08'),
|
||||
),
|
||||
array(
|
||||
3,
|
||||
1,
|
||||
NULL,
|
||||
'im parent',
|
||||
'Don\'t care for it',
|
||||
'irene',
|
||||
'irene@example.com',
|
||||
0,
|
||||
'254.0.2.5',
|
||||
'http:://www.example.com/irene',
|
||||
strtotime('2010-03-02 03:04:05'),
|
||||
strtotime('2010-03-02 03:04:05'),
|
||||
),
|
||||
array(
|
||||
4,
|
||||
1,
|
||||
3,
|
||||
'im child',
|
||||
'But it\'s so good!',
|
||||
'emily',
|
||||
NULL,
|
||||
3,
|
||||
'58.29.126.1',
|
||||
'http:://www.wine.com/',
|
||||
strtotime('2010-01-02 03:04:05'),
|
||||
strtotime('2010-01-02 03:04:05'),
|
||||
),
|
||||
array(
|
||||
5,
|
||||
1,
|
||||
4,
|
||||
'im grandchild',
|
||||
'Right on, Emily!',
|
||||
'thefonz@example.com',
|
||||
NULL,
|
||||
9,
|
||||
'123.456.78.9',
|
||||
NULL,
|
||||
strtotime('2010-06-02 03:04:05'),
|
||||
strtotime('2010-06-02 03:04:05'),
|
||||
),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
@@ -1076,7 +1225,7 @@ function migrate_example_wine_data_comment() {
|
||||
function migrate_example_wine_data_comment_updates() {
|
||||
$fields = array('commentid', 'subject');
|
||||
$query = db_insert('migrate_example_wine_comment_updates')
|
||||
->fields($fields);
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'I am first'),
|
||||
array(2, 'I am second'),
|
||||
@@ -1091,12 +1240,33 @@ function migrate_example_wine_data_comment_updates() {
|
||||
}
|
||||
|
||||
function migrate_example_wine_data_categories() {
|
||||
$fields = array('categoryid', 'type', 'name', 'category_parent', 'details', 'ordering');
|
||||
$fields = array(
|
||||
'categoryid',
|
||||
'type',
|
||||
'name',
|
||||
'category_parent',
|
||||
'details',
|
||||
'ordering',
|
||||
);
|
||||
$query = db_insert('migrate_example_wine_categories')
|
||||
->fields($fields);
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'variety', 'White wine', NULL, 'White wines are generally simpler and sweeter than red', 3),
|
||||
array(3, 'variety', 'Red wine', NULL, 'Red wines are generally more complex and "dry" than white', 1),
|
||||
array(
|
||||
1,
|
||||
'variety',
|
||||
'White wine',
|
||||
NULL,
|
||||
'White wines are generally simpler and sweeter than red',
|
||||
3,
|
||||
),
|
||||
array(
|
||||
3,
|
||||
'variety',
|
||||
'Red wine',
|
||||
NULL,
|
||||
'Red wines are generally more complex and "dry" than white',
|
||||
1,
|
||||
),
|
||||
array(8, 'variety', 'Riesling', 1, 'Associated with Germany', 2),
|
||||
array(9, 'variety', 'Chardonnay', 1, 'One of the most popular whites', 1),
|
||||
array(13, 'variety', 'Merlot', 3, 'Very drinkable', 4),
|
||||
@@ -1128,7 +1298,7 @@ function migrate_example_wine_data_categories() {
|
||||
function migrate_example_wine_data_vintages() {
|
||||
$fields = array('wineid', 'vintage');
|
||||
$query = db_insert('migrate_example_wine_vintages')
|
||||
->fields($fields);
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 2006),
|
||||
array(1, 2007),
|
||||
@@ -1143,7 +1313,7 @@ function migrate_example_wine_data_vintages() {
|
||||
function migrate_example_wine_data_variety_updates() {
|
||||
$fields = array('categoryid', 'details');
|
||||
$query = db_insert('migrate_example_wine_variety_updates')
|
||||
->fields($fields);
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'White wines are simpler and sweeter than red'),
|
||||
array(3, 'Red wines are generally more complex and dry than white'),
|
||||
@@ -1194,9 +1364,27 @@ function migrate_example_wine_data_files() {
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'http://placekitten.com/200/200', NULL, NULL, NULL),
|
||||
array(2, 'http://cyrve.com/files/penguin.jpeg', 'Penguin alt', 'Penguin title', 1),
|
||||
array(3, 'http://cyrve.com/files/rioja.jpeg', 'Rioja alt', 'Rioja title', 2),
|
||||
array(4, 'http://cyrve.com/files/boutisse_0.jpeg', 'Boutisse alt', 'Boutisse title', 2),
|
||||
array(
|
||||
2,
|
||||
'http://cyrve.com/files/penguin.jpeg',
|
||||
'Penguin alt',
|
||||
'Penguin title',
|
||||
1,
|
||||
),
|
||||
array(
|
||||
3,
|
||||
'http://cyrve.com/files/rioja.jpeg',
|
||||
'Rioja alt',
|
||||
'Rioja title',
|
||||
2,
|
||||
),
|
||||
array(
|
||||
4,
|
||||
'http://cyrve.com/files/boutisse_0.jpeg',
|
||||
'Boutisse alt',
|
||||
'Boutisse title',
|
||||
2,
|
||||
),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
|
@@ -24,9 +24,8 @@ name = "migrate_example_baseball"
|
||||
package = "Migration"
|
||||
php = "5.2.4"
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-07-01
|
||||
version = "7.x-2.8"
|
||||
; Information added by Drupal.org packaging script on 2018-06-10
|
||||
version = "7.x-2.11"
|
||||
core = "7.x"
|
||||
project = "migrate"
|
||||
datestamp = "1435760949"
|
||||
|
||||
datestamp = "1528674486"
|
||||
|
@@ -8,7 +8,7 @@
|
||||
function migrate_example_baseball_enable() {
|
||||
$path = dirname(__FILE__) . '/data';
|
||||
migrate_example_baseball_get_files($path);
|
||||
for ($i=0; $i<=9; $i++) {
|
||||
for ($i = 0; $i <= 9; $i++) {
|
||||
$file = 'GL200' . $i . '.TXT';
|
||||
Migration::registerMigration('GameBaseball',
|
||||
pathinfo($file, PATHINFO_FILENAME),
|
||||
@@ -26,7 +26,7 @@ function migrate_example_baseball_get_files($path) {
|
||||
if (!file_exists("$path/GL2000.TXT") && !file_exists("$path/gl2000.txt")) {
|
||||
file_prepare_directory($path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
|
||||
$result = copy('http://www.retrosheet.org/gamelogs/gl2000_09.zip',
|
||||
$path . '/gl2000_09.zip');
|
||||
$path . '/gl2000_09.zip');
|
||||
if ($result) {
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($path . '/gl2000_09.zip');
|
||||
@@ -39,11 +39,22 @@ function migrate_example_baseball_get_files($path) {
|
||||
|
||||
function migrate_example_baseball_uninstall() {
|
||||
$bundle = 'migrate_example_baseball';
|
||||
$field_names = array('field_park', 'field_home_team', 'field_home_game_number',
|
||||
'field_home_score', 'field_visiting_score', 'field_outs', 'field_attendance',
|
||||
'field_duration', 'field_home_batters', 'field_visiting_batters',
|
||||
'field_home_pitcher', 'field_visiting_pitcher', 'field_visiting_team',
|
||||
'field_start_date');
|
||||
$field_names = array(
|
||||
'field_park',
|
||||
'field_home_team',
|
||||
'field_home_game_number',
|
||||
'field_home_score',
|
||||
'field_visiting_score',
|
||||
'field_outs',
|
||||
'field_attendance',
|
||||
'field_duration',
|
||||
'field_home_batters',
|
||||
'field_visiting_batters',
|
||||
'field_home_pitcher',
|
||||
'field_visiting_pitcher',
|
||||
'field_visiting_team',
|
||||
'field_start_date',
|
||||
);
|
||||
foreach ($field_names as $field_name) {
|
||||
$instance = field_info_instance('node', $field_name, $bundle);
|
||||
field_delete_instance($instance);
|
||||
|
@@ -26,30 +26,34 @@ function migrate_example_baseball_migrate_api() {
|
||||
* A migration that is reused for each source CSV file.
|
||||
*/
|
||||
class GameBaseball extends Migration {
|
||||
|
||||
public function __construct($arguments) {
|
||||
parent::__construct($arguments);
|
||||
$this->description = t('Import box scores from CSV file.');
|
||||
|
||||
// Create a map object for tracking the relationships between source rows
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array(
|
||||
'start_date' => array('type' => 'varchar',
|
||||
'length' => 8,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Start date',
|
||||
),
|
||||
'home_team' => array('type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Home team',
|
||||
),
|
||||
'home_game_number' => array('type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Home team game number',
|
||||
),
|
||||
array(
|
||||
'start_date' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 8,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Start date',
|
||||
),
|
||||
MigrateDestinationNode::getKeySchema()
|
||||
);
|
||||
'home_team' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Home team',
|
||||
),
|
||||
'home_game_number' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Home team game number',
|
||||
),
|
||||
),
|
||||
MigrateDestinationNode::getKeySchema()
|
||||
);
|
||||
|
||||
// Create a MigrateSource object, which manages retrieving the input data.
|
||||
$this->source = new MigrateSourceCSV($arguments['source_file'], $this->csvcolumns(), array(), $this->fields());
|
||||
@@ -57,7 +61,7 @@ class GameBaseball extends Migration {
|
||||
$this->destination = new MigrateDestinationNode('migrate_example_baseball');
|
||||
|
||||
$this->addFieldMapping('title', 'title')
|
||||
->description('See prepareRow().');
|
||||
->description('See prepareRow().');
|
||||
$this->addFieldMapping('field_start_date', 'start_date');
|
||||
$this->addFieldMapping('field_park', 'park_id');
|
||||
$this->addFieldMapping('field_visiting_team', 'visiting_team');
|
||||
@@ -68,20 +72,20 @@ class GameBaseball extends Migration {
|
||||
$this->addFieldMapping('field_outs', 'outs');
|
||||
$this->addFieldMapping('field_attendance', 'attendance');
|
||||
$this->addFieldMapping('field_duration', 'duration')
|
||||
->defaultValue(NULL);
|
||||
->defaultValue(NULL);
|
||||
$this->addFieldMapping('field_home_pitcher', 'home_pitcher');
|
||||
$this->addFieldMapping('field_visiting_pitcher', 'visiting_pitcher');
|
||||
$this->addFieldMapping('field_home_batters', 'home_batters')
|
||||
->separator(',')
|
||||
->description('See prepareRow().');
|
||||
->separator(',')
|
||||
->description('See prepareRow().');
|
||||
$this->addFieldMapping('field_visiting_batters', 'visiting_batters')
|
||||
->separator(',')
|
||||
->description('See prepareRow().');
|
||||
for ($i=1; $i <= 9; $i++ ) {
|
||||
->separator(',')
|
||||
->description('See prepareRow().');
|
||||
for ($i = 1; $i <= 9; $i++) {
|
||||
$this->addFieldMapping(NULL, "visiting_batter_$i")
|
||||
->description('Not needed since we use the multi-value field: visiting_batters.');
|
||||
->description('Not needed since we use the multi-value field: visiting_batters.');
|
||||
$this->addFieldMapping(NULL, "home_batter_$i")
|
||||
->description('Not needed since we use the multi-value field: home_batters.');
|
||||
->description('Not needed since we use the multi-value field: home_batters.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,9 +101,12 @@ class GameBaseball extends Migration {
|
||||
$columns[16] = array('park_id', 'Ballpark ID');
|
||||
$columns[17] = array('attendance', 'Attendance');
|
||||
$columns[18] = array('duration', 'Duration in minutes');
|
||||
for ($i=1; $i <= 9; $i++ ) {
|
||||
$columns[103+3*$i] = array("visiting_batter_$i", "Visiting batter $i");
|
||||
$columns[130+3*$i] = array("home_batter_$i", "Home batter $i");
|
||||
for ($i = 1; $i <= 9; $i++) {
|
||||
$columns[103 + 3 * $i] = array(
|
||||
"visiting_batter_$i",
|
||||
"Visiting batter $i",
|
||||
);
|
||||
$columns[130 + 3 * $i] = array("home_batter_$i", "Home batter $i");
|
||||
}
|
||||
$columns[102] = array('visiting_pitcher', 'Visiting starting pitcher');
|
||||
$columns[104] = array('home_pitcher', 'Home starting pitcher');
|
||||
@@ -108,11 +115,11 @@ class GameBaseball extends Migration {
|
||||
|
||||
public function prepareRow($row) {
|
||||
// Collect all the batters into one multi-value field.
|
||||
for ($i=1; $i <= 9; $i++ ) {
|
||||
for ($i = 1; $i <= 9; $i++) {
|
||||
$key = "visiting_batter_$i";
|
||||
$visiting_batters[] = $row->$key;
|
||||
$visiting_batters[] = $row->{$key};
|
||||
$key = "home_batter_$i";
|
||||
$home_batters[] = $row->$key;
|
||||
$home_batters[] = $row->{$key};
|
||||
}
|
||||
$row->visiting_batters = implode(',', $visiting_batters);
|
||||
$row->home_batters = implode(',', $home_batters);
|
||||
@@ -124,7 +131,7 @@ class GameBaseball extends Migration {
|
||||
*/
|
||||
protected function generateMachineName($class_name = NULL) {
|
||||
return drupal_strtolower(pathinfo($this->arguments['source_file'],
|
||||
PATHINFO_FILENAME));
|
||||
PATHINFO_FILENAME));
|
||||
}
|
||||
|
||||
public function fields() {
|
||||
|
@@ -1,18 +1,15 @@
|
||||
|
||||
table.migrate-dashboard tr.migrate-running {
|
||||
background-color: #CFC;
|
||||
background-color: #cfc;
|
||||
}
|
||||
|
||||
.migrate-running {
|
||||
background-color: #CFC;
|
||||
background-color: #cfc;
|
||||
}
|
||||
|
||||
.migrate-option-separator {
|
||||
margin-bottom:0.2em;
|
||||
margin-bottom: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
#migrate-migration-info td.migrate-error {
|
||||
background: #ffc9c9;
|
||||
}
|
||||
|
@@ -6,9 +6,8 @@ core = 7.x
|
||||
dependencies[] = migrate
|
||||
files[] = migrate_ui.wizard.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-07-01
|
||||
version = "7.x-2.8"
|
||||
; Information added by Drupal.org packaging script on 2018-06-10
|
||||
version = "7.x-2.11"
|
||||
core = "7.x"
|
||||
project = "migrate"
|
||||
datestamp = "1435760949"
|
||||
|
||||
datestamp = "1528674486"
|
||||
|
@@ -35,10 +35,10 @@ function migrate_ui_update_7201() {
|
||||
*/
|
||||
function migrate_ui_set_weight() {
|
||||
$node_weight = db_select('system', 's')
|
||||
->fields('s', array('weight'))
|
||||
->condition('name', 'node')
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('s', array('weight'))
|
||||
->condition('name', 'node')
|
||||
->execute()
|
||||
->fetchField();
|
||||
db_update('system')
|
||||
->fields(array('weight' => $node_weight + 1))
|
||||
->condition('name', 'migrate_ui')
|
||||
@@ -62,10 +62,10 @@ function migrate_ui_update_7202() {
|
||||
}
|
||||
variable_set('migrate_import_method', $import_method);
|
||||
variable_set('migrate_drush_mail',
|
||||
variable_get('wordpress_migrate_notification', 0));
|
||||
variable_get('wordpress_migrate_notification', 0));
|
||||
variable_set('migrate_drush_mail_subject',
|
||||
variable_get('wordpress_migrate_notification_subject', ''));
|
||||
variable_get('wordpress_migrate_notification_subject', ''));
|
||||
variable_set('migrate_drush_mail_body',
|
||||
variable_get('wordpress_migrate_notification_body', ''));
|
||||
variable_get('wordpress_migrate_notification_body', ''));
|
||||
}
|
||||
}
|
||||
|
@@ -123,10 +123,10 @@ function migrate_ui_migrate_migration_title($migration_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
* Implements hook_theme()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function migrate_ui_theme() {
|
||||
return array(
|
||||
'migrate_ui_field_mapping_form' => array(
|
||||
|
@@ -25,15 +25,15 @@ function migrate_ui_migrate_dashboard($form, &$form_state) {
|
||||
);
|
||||
|
||||
$result = db_select('migrate_group', 'mg')
|
||||
->fields('mg', array('name', 'title', 'arguments'))
|
||||
->execute();
|
||||
->fields('mg', array('name', 'title', 'arguments'))
|
||||
->execute();
|
||||
$rows = array();
|
||||
foreach ($result as $group_row) {
|
||||
$row = array();
|
||||
$migration_result = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('machine_name', 'status', 'arguments'))
|
||||
->condition('group_name', $group_row->name)
|
||||
->execute();
|
||||
->fields('ms', array('machine_name', 'status', 'arguments'))
|
||||
->condition('group_name', $group_row->name)
|
||||
->execute();
|
||||
if (!$migration_result) {
|
||||
continue;
|
||||
}
|
||||
@@ -201,17 +201,8 @@ function migrate_ui_migrate_group($form, &$form_state, $group_name) {
|
||||
|
||||
$row['status'] = $status;
|
||||
$machine_name = $migration->getMachineName();
|
||||
$name_length = strlen($machine_name);
|
||||
$group_length = strlen($group_name);
|
||||
if ($name_length != $group_length &&
|
||||
!strncasecmp($group_name, $machine_name, $group_length)) {
|
||||
$display_name = substr($machine_name, $group_length);
|
||||
}
|
||||
else {
|
||||
$display_name = $machine_name;
|
||||
}
|
||||
$row['machinename'] =
|
||||
l($display_name, "admin/content/migrate/groups/$group_name/$machine_name");
|
||||
l($machine_name, "admin/content/migrate/groups/$group_name/$machine_name");
|
||||
$row['importrows'] = (int) $total;
|
||||
$row['imported'] = (int) $imported;
|
||||
$row['unprocessed'] = (int) $unprocessed;
|
||||
@@ -287,7 +278,7 @@ function _migrate_ui_migrate_operations() {
|
||||
'import_immediate' => t('Import'),
|
||||
'rollback_immediate' => t('Rollback'),
|
||||
);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
$options += array(
|
||||
@@ -460,10 +451,16 @@ function migrate_ui_migrate_submit($form, &$form_state) {
|
||||
if ($update && method_exists($migration, 'prepareUpdate')) {
|
||||
$migration->prepareUpdate();
|
||||
}
|
||||
$operations[] = array('migrate_ui_batch', array('import', $machine_name, $limit, $force));
|
||||
$operations[] = array(
|
||||
'migrate_ui_batch',
|
||||
array('import', $machine_name, $limit, $force),
|
||||
);
|
||||
break;
|
||||
case 'rollback_immediate':
|
||||
$operations[] = array('migrate_ui_batch', array('rollback', $machine_name, $limit, $force));
|
||||
$operations[] = array(
|
||||
'migrate_ui_batch',
|
||||
array('rollback', $machine_name, $limit, $force),
|
||||
);
|
||||
break;
|
||||
case 'import_background':
|
||||
case 'rollback_background':
|
||||
@@ -543,7 +540,7 @@ function migrate_ui_migrate_submit($form, &$form_state) {
|
||||
drupal_set_message('Your operation is running in the background. You will receive an email message when it is complete.');
|
||||
}
|
||||
else {
|
||||
drupal_set_message('Your operation is running in the background. You may '.
|
||||
drupal_set_message('Your operation is running in the background. You may ' .
|
||||
'refresh the dashboard page to check on its progress.');
|
||||
}
|
||||
}
|
||||
@@ -590,10 +587,16 @@ function migrate_ui_batch($operation, $machine_name, $limit, $force = FALSE, &$c
|
||||
// Perform the requested operation
|
||||
switch ($operation) {
|
||||
case 'import':
|
||||
$result = $migration->processImport(array('limit' => $limit, 'force' => $force));
|
||||
$result = $migration->processImport(array(
|
||||
'limit' => $limit,
|
||||
'force' => $force,
|
||||
));
|
||||
break;
|
||||
case 'rollback':
|
||||
$result = $migration->processRollback(array('limit' => $limit, 'force' => $force));
|
||||
$result = $migration->processRollback(array(
|
||||
'limit' => $limit,
|
||||
'force' => $force,
|
||||
));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -608,10 +611,10 @@ function migrate_ui_batch($operation, $machine_name, $limit, $force = FALSE, &$c
|
||||
switch ($operation) {
|
||||
case 'import':
|
||||
$to_update = $migration->updateCount();
|
||||
$context['finished'] = ($processed-$to_update)/$total;
|
||||
$context['finished'] = ($processed - $to_update) / $total;
|
||||
break;
|
||||
case 'rollback':
|
||||
$context['finished'] = ($total - $migration->importedCount())/$total;
|
||||
$context['finished'] = ($total - $migration->importedCount()) / $total;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -623,8 +626,8 @@ function migrate_ui_batch($operation, $machine_name, $limit, $force = FALSE, &$c
|
||||
array(
|
||||
'!name' => $machine_name,
|
||||
'!depends' => implode(", ", $migration->incompleteDependencies()),
|
||||
))
|
||||
);
|
||||
)),
|
||||
);
|
||||
$context['finished'] = 1;
|
||||
break;
|
||||
case MigrationBase::RESULT_STOPPED:
|
||||
@@ -770,7 +773,7 @@ function migrate_migration_info($form, $form_state, $group_name, $migration_name
|
||||
$dependencies = $migration->getHardDependencies();
|
||||
if (count($dependencies) > 0) {
|
||||
$form['overview']['dependencies'] = array(
|
||||
'#title' => t('Dependencies') ,
|
||||
'#title' => t('Dependencies'),
|
||||
'#markup' => filter_xss_admin(implode(', ', $dependencies)),
|
||||
'#type' => 'item',
|
||||
);
|
||||
@@ -903,7 +906,13 @@ function migrate_migration_info($form, $form_state, $group_name, $migration_name
|
||||
'#empty' => t('No fields'),
|
||||
);
|
||||
|
||||
$header = array(t('Destination'), t('Source'), t('Default'), t('Description'), t('Priority'));
|
||||
$header = array(
|
||||
t('Destination'),
|
||||
t('Source'),
|
||||
t('Default'),
|
||||
t('Description'),
|
||||
t('Priority'),
|
||||
);
|
||||
|
||||
// First group the mappings
|
||||
$descriptions = array();
|
||||
@@ -917,17 +926,18 @@ function migrate_migration_info($form, $form_state, $group_name, $migration_name
|
||||
if (!is_null($source_field) && !isset($source_fields[$source_field])) {
|
||||
drupal_set_message(t('"!source" was used as source field in the
|
||||
"!destination" mapping but is not in list of source fields', array(
|
||||
'!source' => filter_xss_admin($source_field),
|
||||
'!destination' => filter_xss_admin($destination_field),
|
||||
)),
|
||||
'warning');
|
||||
'!source' => filter_xss_admin($source_field),
|
||||
'!destination' => filter_xss_admin($destination_field),
|
||||
)),
|
||||
'warning');
|
||||
}
|
||||
if (!is_null($destination_field) && !isset($destination_fields[$destination_field])) {
|
||||
drupal_set_message(t('"!destination" was used as destination field in
|
||||
"!source" mapping but is not in list of destination fields', array(
|
||||
'!source' => filter_xss_admin($source_field),
|
||||
'!destination' => filter_xss_admin($destination_field))),
|
||||
'warning');
|
||||
'!source' => filter_xss_admin($source_field),
|
||||
'!destination' => filter_xss_admin($destination_field),
|
||||
)),
|
||||
'warning');
|
||||
}
|
||||
$descriptions[$mapping->getIssueGroup()][] = $mapping;
|
||||
}
|
||||
@@ -954,7 +964,7 @@ function migrate_migration_info($form, $form_state, $group_name, $migration_name
|
||||
$issue_number = $mapping->getIssueNumber();
|
||||
if (!is_null($issue_pattern) && !is_null($issue_number)) {
|
||||
$priority .= ' (' . l(t('#') . $issue_number, str_replace(':id:', $issue_number,
|
||||
$issue_pattern)) . ')';
|
||||
$issue_pattern)) . ')';
|
||||
}
|
||||
if ($issue_priority != MigrateFieldMapping::ISSUE_PRIORITY_OK) {
|
||||
$classes[] = 'migrate-error';
|
||||
@@ -972,10 +982,16 @@ function migrate_migration_info($form, $form_state, $group_name, $migration_name
|
||||
$source_field = "<em>$source_field</em>";
|
||||
}
|
||||
$row = array(
|
||||
array('data' => filter_xss_admin($destination_field), 'class' => $classes),
|
||||
array(
|
||||
'data' => filter_xss_admin($destination_field),
|
||||
'class' => $classes,
|
||||
),
|
||||
array('data' => filter_xss_admin($source_field), 'class' => $classes),
|
||||
array('data' => filter_xss_admin($default), 'class' => $classes),
|
||||
array('data' => filter_xss_admin($mapping->getDescription()), 'class' => $classes),
|
||||
array(
|
||||
'data' => filter_xss_admin($mapping->getDescription()),
|
||||
'class' => $classes,
|
||||
),
|
||||
array('data' => filter_xss_admin($priority), 'class' => $classes),
|
||||
);
|
||||
$rows[] = $row;
|
||||
@@ -1091,14 +1107,14 @@ function migrate_ui_edit_mappings($form, $form_state, $group_name,
|
||||
|
||||
// Check for a click of the DNM box...
|
||||
if (isset($form_state['values']) &&
|
||||
$form_state['values']['source_fields'][$name] == 1) {
|
||||
$form_state['values']['source_fields'][$name] == 1) {
|
||||
$dnm_value = 1;
|
||||
}
|
||||
else {
|
||||
// ... or a source-only mapping with the DNM issue group.
|
||||
foreach ($field_mappings as $mapping) {
|
||||
if ($mapping->getSourceField() == $name &&
|
||||
$mapping->getIssueGroup() == t('DNM')) {
|
||||
$mapping->getIssueGroup() == t('DNM')) {
|
||||
$dnm_value = 1;
|
||||
}
|
||||
}
|
||||
@@ -1119,7 +1135,8 @@ function migrate_ui_edit_mappings($form, $form_state, $group_name,
|
||||
|
||||
if (isset($field_mappings['is_new'])) {
|
||||
$default_is_new = $field_mappings['is_new']->getDefaultValue();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$default_is_new = 0;
|
||||
}
|
||||
foreach ($dest_fields as $name => $description) {
|
||||
@@ -1146,7 +1163,7 @@ function migrate_ui_edit_mappings($form, $form_state, $group_name,
|
||||
// If the DNM box has been clicked, make sure we clear the mapping and
|
||||
// default value fields.
|
||||
if (isset($form_state['values']) &&
|
||||
$form_state['values']['field_mappings'][$name]['issue_group'] == 1) {
|
||||
$form_state['values']['field_mappings'][$name]['issue_group'] == 1) {
|
||||
$dnm_value = 1;
|
||||
}
|
||||
else {
|
||||
@@ -1185,7 +1202,7 @@ function migrate_ui_edit_mappings($form, $form_state, $group_name,
|
||||
$form['field_mappings'][$name]['mapping'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t($label,
|
||||
array('!description' => $description, '!field_name' => $name)),
|
||||
array('!description' => $description, '!field_name' => $name)),
|
||||
'#options' => $options,
|
||||
'#default_value' => $default_mapping,
|
||||
);
|
||||
@@ -1245,7 +1262,7 @@ function migrate_ui_edit_mappings($form, $form_state, $group_name,
|
||||
// Remove any migrations depending on us, directly or indirectly. First, get
|
||||
// a list of such migrations.
|
||||
$descendent_migrations = _migrate_ui_get_descendents($migration_name,
|
||||
$all_dependencies);
|
||||
$all_dependencies);
|
||||
$source_migration_options = array_diff_key($source_migration_options,
|
||||
$descendent_migrations);
|
||||
foreach ($source_migration_options as $machine_name) {
|
||||
@@ -1294,7 +1311,7 @@ function _migrate_ui_get_descendents($migration_name, array $all_dependencies) {
|
||||
if (in_array($migration_name, $dependencies)) {
|
||||
$descendents[$machine_name] = $machine_name;
|
||||
$descendents += _migrate_ui_get_descendents($machine_name,
|
||||
$all_dependencies);
|
||||
$all_dependencies);
|
||||
}
|
||||
}
|
||||
return $descendents;
|
||||
@@ -1310,10 +1327,10 @@ function _migrate_ui_get_descendents($migration_name, array $all_dependencies) {
|
||||
function migrate_ui_edit_mappings_submit(&$form, &$form_state) {
|
||||
$machine_name = $form_state['values']['machine_name'];
|
||||
$row = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('arguments', 'class_name', 'group_name'))
|
||||
->condition('machine_name', $machine_name)
|
||||
->execute()
|
||||
->fetchObject();
|
||||
->fields('ms', array('arguments', 'class_name', 'group_name'))
|
||||
->condition('machine_name', $machine_name)
|
||||
->execute()
|
||||
->fetchObject();
|
||||
$class_name = $row->class_name;
|
||||
$group_name = $row->group_name;
|
||||
$arguments = unserialize($row->arguments);
|
||||
@@ -1359,17 +1376,17 @@ function migrate_ui_edit_mappings_submit(&$form, &$form_state) {
|
||||
$info['source_migration'] = NULL;
|
||||
}
|
||||
if ($info['issue_group'] == 0 && $coded_mappings[$destination_field]->getIssueGroup() != t('DNM') ||
|
||||
$info['issue_group'] == 1 && $coded_mappings[$destination_field]->getIssueGroup() == t('DNM')) {
|
||||
$info['issue_group'] == 1 && $coded_mappings[$destination_field]->getIssueGroup() == t('DNM')) {
|
||||
$dnm_matches = TRUE;
|
||||
}
|
||||
else {
|
||||
$dnm_matches = FALSE;
|
||||
}
|
||||
if ($info['mapping'] == $coded_source_field &&
|
||||
$info['default_value'] == $coded_default_value &&
|
||||
$info['source_migration'] == $coded_source_migration &&
|
||||
(!$xml || ($xml && ($info['xpath'] == $coded_xpath))) &&
|
||||
$dnm_matches) {
|
||||
$info['default_value'] == $coded_default_value &&
|
||||
$info['source_migration'] == $coded_source_migration &&
|
||||
(!$xml || ($xml && ($info['xpath'] == $coded_xpath))) &&
|
||||
$dnm_matches) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1401,17 +1418,17 @@ function migrate_ui_edit_mappings_submit(&$form, &$form_state) {
|
||||
// losing important bits.
|
||||
$mapping = NULL;
|
||||
if (isset($existing_mappings[$destination_field]) &&
|
||||
$issue_group_values[$destination_field] != 0) {
|
||||
$issue_group_values[$destination_field] != 0) {
|
||||
/** @var MigrateFieldMapping $old_mapping */
|
||||
$old_mapping = $existing_mappings[$destination_field];
|
||||
if ($source_field == $old_mapping->getSourceField() &&
|
||||
$default_values[$destination_field] == $old_mapping->getDefaultValue() &&
|
||||
$source_migrations[$destination_field] == $old_mapping->getSourceMigration() &&
|
||||
(!$xml || ($xml && ($xpaths[$destination_field] == $old_mapping->getXpath())))) {
|
||||
$default_values[$destination_field] == $old_mapping->getDefaultValue() &&
|
||||
$source_migrations[$destination_field] == $old_mapping->getSourceMigration() &&
|
||||
(!$xml || ($xml && ($xpaths[$destination_field] == $old_mapping->getXpath())))) {
|
||||
// First, if this mapping matches a previously-stored mapping, we want to
|
||||
// preserve it as it was originally stored.
|
||||
if ($old_mapping->getMappingSource() ==
|
||||
MigrateFieldMapping::MAPPING_SOURCE_DB) {
|
||||
MigrateFieldMapping::MAPPING_SOURCE_DB) {
|
||||
$mapping = $old_mapping;
|
||||
}
|
||||
// If it matches a coded mapping, then we don't want to save it at all.
|
||||
@@ -1439,7 +1456,7 @@ function migrate_ui_edit_mappings_submit(&$form, &$form_state) {
|
||||
}
|
||||
|
||||
if ($source_migrations[$destination_field] &&
|
||||
$source_migrations[$destination_field] != '-1') {
|
||||
$source_migrations[$destination_field] != '-1') {
|
||||
$mapping->sourceMigration($source_migrations[$destination_field]);
|
||||
}
|
||||
|
||||
@@ -1452,7 +1469,7 @@ function migrate_ui_edit_mappings_submit(&$form, &$form_state) {
|
||||
$code_ignored = FALSE;
|
||||
foreach ($coded_mappings as $destination_field => $mapping) {
|
||||
if (is_numeric($destination_field) &&
|
||||
$mapping->getSourceField() == $source_field) {
|
||||
$mapping->getSourceField() == $source_field) {
|
||||
$code_ignored = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1548,8 +1565,13 @@ function theme_migrate_ui_field_mapping_form($variables) {
|
||||
$form = $variables['field_mappings'];
|
||||
$elements = element_children($form);
|
||||
if (!empty($elements)) {
|
||||
$header = array(t('DNM'), t('Destination field'), t('Source field'),
|
||||
t('Default value'), t('Source migration'));
|
||||
$header = array(
|
||||
t('DNM'),
|
||||
t('Destination field'),
|
||||
t('Source field'),
|
||||
t('Default value'),
|
||||
t('Source migration'),
|
||||
);
|
||||
if (!empty($form['#is_xml_migration'])) {
|
||||
$header[] = t('Xpath');
|
||||
}
|
||||
@@ -1596,7 +1618,11 @@ function theme_migrate_ui_field_mapping_dependencies($variables) {
|
||||
$row[] = drupal_render($form[$mapping_key]);
|
||||
$rows[] = $row;
|
||||
}
|
||||
$output .= theme('table', array('rows' => $rows, 'header' => $header, 'empty' => t('No other migrations were found.')));
|
||||
$output .= theme('table', array(
|
||||
'rows' => $rows,
|
||||
'header' => $header,
|
||||
'empty' => t('No other migrations were found.'),
|
||||
));
|
||||
|
||||
$output .= drupal_render_children($form);
|
||||
return $output;
|
||||
@@ -1607,7 +1633,7 @@ function theme_migrate_ui_field_mapping_dependencies($variables) {
|
||||
*/
|
||||
function migrate_ui_messages($group_name, $migration_name) {
|
||||
drupal_set_title(t('Import messages for !migration',
|
||||
array('!migration' => $migration_name)));
|
||||
array('!migration' => $migration_name)));
|
||||
|
||||
$build = $rows = array();
|
||||
|
||||
@@ -1624,7 +1650,7 @@ function migrate_ui_messages($group_name, $migration_name) {
|
||||
// Add a table header for each source key in the migration's map.
|
||||
foreach ($source_key as $key => $map_info) {
|
||||
$header[] = array(
|
||||
'data' => filter_xss_admin($map_info['description']),
|
||||
'data' => isset($map_info['description']) ? filter_xss_admin($map_info['description']) : t('Source ID'),
|
||||
'field' => $source_key_map[$key],
|
||||
'sort' => 'asc',
|
||||
);
|
||||
@@ -1635,13 +1661,13 @@ function migrate_ui_messages($group_name, $migration_name) {
|
||||
|
||||
// TODO: need a general MigrateMap API
|
||||
$messages = $migration->getMap()->getConnection()
|
||||
->select($migration->getMap()->getMessageTable(), 'msg')
|
||||
->extend('PagerDefault')
|
||||
->extend('TableSort')
|
||||
->orderByHeader($header)
|
||||
->limit(500)
|
||||
->fields('msg')
|
||||
->execute();
|
||||
->select($migration->getMap()->getMessageTable(), 'msg')
|
||||
->extend('PagerDefault')
|
||||
->extend('TableSort')
|
||||
->orderByHeader($header)
|
||||
->limit(500)
|
||||
->fields('msg')
|
||||
->execute();
|
||||
|
||||
foreach ($messages as $message) {
|
||||
$classes[] = $message->level <= MigrationBase::MESSAGE_WARNING ? 'migrate-error' : '';
|
||||
@@ -1732,17 +1758,17 @@ function migrate_ui_configure_form($form, &$form_state) {
|
||||
|
||||
$migrations = array();
|
||||
$result = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('class_name', 'machine_name'))
|
||||
->execute();
|
||||
->fields('ms', array('class_name', 'machine_name'))
|
||||
->execute();
|
||||
$migration_list = '';
|
||||
foreach ($result as $row) {
|
||||
if (!class_exists($row->class_name)) {
|
||||
$migrations[] = $row->machine_name;
|
||||
$migration_list .= '<li>' . t('!migration (class !class)',
|
||||
array(
|
||||
'!migration' => filter_xss_admin($row->machine_name),
|
||||
'!class' => filter_xss_admin($row->class_name),
|
||||
)) . "</li>\n";
|
||||
array(
|
||||
'!migration' => filter_xss_admin($row->machine_name),
|
||||
'!class' => filter_xss_admin($row->class_name),
|
||||
)) . "</li>\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1906,18 +1932,18 @@ function migrate_ui_configure_form($form, &$form_state) {
|
||||
);
|
||||
|
||||
$disabled = unserialize(variable_get('migrate_disabled_handlers',
|
||||
serialize(array())));
|
||||
serialize(array())));
|
||||
$class_list = _migrate_class_list('MigrateDestinationHandler');
|
||||
$rows = array();
|
||||
$default_values = array();
|
||||
foreach ($class_list as $class_name => $handler) {
|
||||
$row = array();
|
||||
$module = db_select('registry', 'r')
|
||||
->fields('r', array('module'))
|
||||
->condition('name', $class_name)
|
||||
->condition('type', 'class')
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('r', array('module'))
|
||||
->condition('name', $class_name)
|
||||
->condition('type', 'class')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$row['module'] = check_plain($module);
|
||||
$row['class'] = check_plain($class_name);
|
||||
$row['types'] = filter_xss_admin(implode(', ', $handler->getTypesHandled()));
|
||||
@@ -1950,11 +1976,11 @@ function migrate_ui_configure_form($form, &$form_state) {
|
||||
foreach ($class_list as $class_name => $handler) {
|
||||
$row = array();
|
||||
$module = db_select('registry', 'r')
|
||||
->fields('r', array('module'))
|
||||
->condition('name', $class_name)
|
||||
->condition('type', 'class')
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('r', array('module'))
|
||||
->condition('name', $class_name)
|
||||
->condition('type', 'class')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$row['module'] = check_plain($module);
|
||||
$row['class'] = check_plain($class_name);
|
||||
$row['types'] = filter_xss_admin(implode(', ', $handler->getTypesHandled()));
|
||||
@@ -1992,8 +2018,8 @@ function migrate_ui_configure_register_submit($form, &$form_state) {
|
||||
*/
|
||||
function migrate_ui_configure_deregister_submit($form, &$form_state) {
|
||||
$result = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('class_name', 'machine_name'))
|
||||
->execute();
|
||||
->fields('ms', array('class_name', 'machine_name'))
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
if (!class_exists($row->class_name)) {
|
||||
migrate_ui_deregister_migration($row->machine_name);
|
||||
@@ -2007,7 +2033,7 @@ function migrate_ui_configure_deregister_submit($form, &$form_state) {
|
||||
*/
|
||||
function migrate_ui_configure_settings_submit($form, &$form_state) {
|
||||
variable_set('migrate_deprecation_warnings',
|
||||
$form_state['values']['deprecation_warnings']);
|
||||
$form_state['values']['deprecation_warnings']);
|
||||
drupal_set_message(t('Migration settings saved.'));
|
||||
}
|
||||
|
||||
|
@@ -93,7 +93,8 @@ function migrate_ui_wizard_next_submit($form, &$form_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler for the Save settings button. Register the migrations that were
|
||||
* Submit handler for the Save settings button. Register the migrations that
|
||||
* were
|
||||
* (implicitly) defined along the way and redirect to the Migrate dashboard.
|
||||
*/
|
||||
function migrate_ui_wizard_submit($form, &$form_state) {
|
||||
@@ -101,7 +102,7 @@ function migrate_ui_wizard_submit($form, &$form_state) {
|
||||
$wizard = $form_state['wizard'];
|
||||
$wizard->formSaveSettings();
|
||||
$form_state['redirect'] = 'admin/content/migrate/groups/' .
|
||||
$wizard->getGroupName();
|
||||
$wizard->getGroupName();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +116,7 @@ function migrate_ui_wizard_migrate_submit($form, &$form_state) {
|
||||
$wizard->formSaveSettings();
|
||||
$wizard->formPerformImport();
|
||||
$form_state['redirect'] = 'admin/content/migrate/groups/' .
|
||||
$wizard->getGroupName();
|
||||
$wizard->getGroupName();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,6 +125,7 @@ function migrate_ui_wizard_migrate_submit($form, &$form_state) {
|
||||
* WordPress, etc.).
|
||||
*/
|
||||
abstract class MigrateUIWizard {
|
||||
|
||||
/**
|
||||
* We maintain a doubly-linked list of wizard steps, both to support
|
||||
* previous/next, and to easily insert steps dynamically.
|
||||
@@ -185,6 +187,7 @@ abstract class MigrateUIWizard {
|
||||
* @var string
|
||||
*/
|
||||
protected $groupName = 'default';
|
||||
|
||||
public function getGroupName() {
|
||||
return $this->groupName;
|
||||
}
|
||||
@@ -217,6 +220,7 @@ abstract class MigrateUIWizard {
|
||||
* @var array
|
||||
*/
|
||||
protected $extenders = array();
|
||||
|
||||
public function getExtender($extender_class) {
|
||||
if (isset($this->extenders[$extender_class])) {
|
||||
return $this->extenders[$extender_class];
|
||||
@@ -234,7 +238,8 @@ abstract class MigrateUIWizard {
|
||||
*/
|
||||
abstract public function getSourceName();
|
||||
|
||||
public function __construct() {}
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a wizard extender.
|
||||
@@ -373,13 +378,14 @@ abstract class MigrateUIWizard {
|
||||
$form['title'] = array(
|
||||
'#prefix' => '<h2>',
|
||||
'#markup' => t('Step @step: @step_name',
|
||||
array(
|
||||
'@step' => $this->stepNumber,
|
||||
'@step_name' => $this->currentStep->getName())),
|
||||
array(
|
||||
'@step' => $this->stepNumber,
|
||||
'@step_name' => $this->currentStep->getName(),
|
||||
)),
|
||||
'#suffix' => '</h2>',
|
||||
);
|
||||
|
||||
$form += call_user_func($form_method, $form_state);
|
||||
$form += call_user_func_array($form_method, array(&$form_state));
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
|
||||
@@ -441,7 +447,7 @@ abstract class MigrateUIWizard {
|
||||
}
|
||||
|
||||
if (is_callable($validate_method)) {
|
||||
call_user_func($validate_method, $form_state);
|
||||
call_user_func_array($validate_method, array(&$form_state));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,11 +465,11 @@ abstract class MigrateUIWizard {
|
||||
// called.
|
||||
if (is_subclass_of($info['class_name'], 'Migration')) {
|
||||
Migration::registerMigration($info['class_name'], $machine_name,
|
||||
$info['arguments']);
|
||||
$info['arguments']);
|
||||
}
|
||||
else {
|
||||
MigrationBase::registerMigration($info['class_name'], $machine_name,
|
||||
$info['arguments']);
|
||||
$info['arguments']);
|
||||
}
|
||||
};
|
||||
menu_rebuild();
|
||||
@@ -479,7 +485,10 @@ abstract class MigrateUIWizard {
|
||||
foreach ($migrations as $migration) {
|
||||
$group_name = $migration->getGroup()->getName();
|
||||
if ($group_name == $this->groupName) {
|
||||
$operations[] = array('migrate_ui_batch', array('import', $migration->getMachineName(), NULL, 0));
|
||||
$operations[] = array(
|
||||
'migrate_ui_batch',
|
||||
array('import', $migration->getMachineName(), NULL, 0),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,6 +553,7 @@ abstract class MigrateUIWizard {
|
||||
* Class representing one step of a wizard.
|
||||
*/
|
||||
class MigrateUIStep {
|
||||
|
||||
/**
|
||||
* A translatable string briefly describing this step, to be used in the page
|
||||
* title for the step form.
|
||||
@@ -551,6 +561,7 @@ class MigrateUIStep {
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
@@ -561,6 +572,7 @@ class MigrateUIStep {
|
||||
* @var string
|
||||
*/
|
||||
protected $formMethod;
|
||||
|
||||
public function getFormMethod() {
|
||||
return $this->formMethod;
|
||||
}
|
||||
@@ -572,9 +584,11 @@ class MigrateUIStep {
|
||||
* @var array
|
||||
*/
|
||||
protected $formValues;
|
||||
|
||||
public function getFormValues() {
|
||||
return $this->formValues;
|
||||
}
|
||||
|
||||
public function setFormValues($form_values) {
|
||||
$this->formValues = $form_values;
|
||||
}
|
||||
@@ -587,6 +601,7 @@ class MigrateUIStep {
|
||||
* @var mixed
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
public function getContext() {
|
||||
return $this->context;
|
||||
}
|
||||
@@ -627,6 +642,7 @@ class MigrateUIStep {
|
||||
*
|
||||
*/
|
||||
abstract class MigrateUIWizardExtender {
|
||||
|
||||
/**
|
||||
* Reference to the wizard object that this extender applies to.
|
||||
*/
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Destination class implementing migration into {block_custom}.
|
||||
*/
|
||||
class MigrateDestinationCustomBlock extends MigrateDestination {
|
||||
|
||||
static public function getKeySchema() {
|
||||
return array(
|
||||
'bid' => array(
|
||||
@@ -19,6 +20,7 @@ class MigrateDestinationCustomBlock extends MigrateDestination {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
@@ -33,6 +35,7 @@ class MigrateDestinationCustomBlock extends MigrateDestination {
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
@@ -51,9 +54,11 @@ class MigrateDestinationCustomBlock extends MigrateDestination {
|
||||
* Import a single row.
|
||||
*
|
||||
* @param $block
|
||||
* Custom block object to build. Prefilled with any fields mapped in the Migration.
|
||||
* Custom block object to build. Prefilled with any fields mapped in the
|
||||
* Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields of the object that was saved if
|
||||
* successful. FALSE on failure.
|
||||
@@ -75,8 +80,8 @@ class MigrateDestinationCustomBlock extends MigrateDestination {
|
||||
}
|
||||
$block_to_update = (object) $old_block;
|
||||
foreach ($old_block as $key => $value) {
|
||||
if (!isset($block->$key)) {
|
||||
$block->$key = $old_block[$key];
|
||||
if (!isset($block->{$key})) {
|
||||
$block->{$key} = $old_block[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,8 +235,17 @@ class MigrateDestinationCustomBlock extends MigrateDestination {
|
||||
|
||||
public function deleteMultipleCustomBlocks(array $bids) {
|
||||
db_delete('block_custom')->condition('bid', $bids, 'IN')->execute();
|
||||
db_delete('block')->condition('module', 'block')->condition('delta', $bids, 'IN')->execute();
|
||||
db_delete('block_role')->condition('module', 'block')->condition('delta', $bids, 'IN')->execute();
|
||||
db_delete('block_node_type')->condition('module', 'block')->condition('delta', $bids, 'IN')->execute();
|
||||
db_delete('block')
|
||||
->condition('module', 'block')
|
||||
->condition('delta', $bids, 'IN')
|
||||
->execute();
|
||||
db_delete('block_role')
|
||||
->condition('module', 'block')
|
||||
->condition('delta', $bids, 'IN')
|
||||
->execute();
|
||||
db_delete('block_node_type')
|
||||
->condition('module', 'block')
|
||||
->condition('delta', $bids, 'IN')
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
* Destination class implementing migration into comments.
|
||||
*/
|
||||
class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
|
||||
static public function getKeySchema() {
|
||||
return array(
|
||||
'cid' => array(
|
||||
@@ -24,6 +25,7 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
|
||||
/**
|
||||
* Save the original setting of comment_maintain_node_statistics
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $maintainNodeStatistics;
|
||||
@@ -58,6 +60,7 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
@@ -66,33 +69,33 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
$fields = array();
|
||||
// First the core (comment table) properties
|
||||
$fields['cid'] = t('<a href="@doc">Existing comment ID</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#cid'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#cid'));
|
||||
$fields['nid'] = t('<a href="@doc">Node (by Drupal ID)</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#nid'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#nid'));
|
||||
$fields['uid'] = t('<a href="@doc">User (by Drupal ID)</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#uid'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#uid'));
|
||||
$fields['pid'] = t('<a href="@doc">Parent (by Drupal ID)</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#pid'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#pid'));
|
||||
$fields['subject'] = t('<a href="@doc">Subject</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#subject'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#subject'));
|
||||
$fields['created'] = t('<a href="@doc">Created timestamp</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#created'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#created'));
|
||||
$fields['changed'] = t('<a href="@doc">Modified timestamp</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#changed'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#changed'));
|
||||
$fields['status'] = t('<a href="@doc">Status</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#status'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#status'));
|
||||
$fields['hostname'] = t('<a href="@doc">Hostname/IP address</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#hostname'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#hostname'));
|
||||
$fields['name'] = t('<a href="@doc">User name (not username)</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#name'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#name'));
|
||||
$fields['mail'] = t('<a href="@doc">Email address</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#mail'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#mail'));
|
||||
$fields['homepage'] = t('<a href="@doc">Homepage</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#homepage'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#homepage'));
|
||||
$fields['language'] = t('<a href="@doc">Language</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#language'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#language'));
|
||||
$fields['thread'] = t('<a href="@doc">Thread</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349714#thread'));
|
||||
array('@doc' => 'http://drupal.org/node/1349714#thread'));
|
||||
|
||||
// Then add in anything provided by handlers
|
||||
$fields += migrate_handler_invoke_all('Entity', 'fields', $this->entityType, $this->bundle, $migration);
|
||||
@@ -120,12 +123,14 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
* Import a single comment.
|
||||
*
|
||||
* @param $comment
|
||||
* Comment object to build. Prefilled with any fields mapped in the Migration.
|
||||
* Comment object to build. Prefilled with any fields mapped in the
|
||||
* Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields (cid only in this case) of the comment that was saved if
|
||||
* successful. FALSE on failure.
|
||||
* Array of key fields (cid only in this case) of the comment that was saved
|
||||
* if successful. FALSE on failure.
|
||||
*/
|
||||
public function import(stdClass $comment, stdClass $row) {
|
||||
$migration = Migration::currentMigration();
|
||||
@@ -134,7 +139,10 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
if (isset($comment->cid)) {
|
||||
if ($comment->cid != $row->migrate_map_destid1) {
|
||||
throw new MigrateException(t("Incoming cid !cid and map destination nid !destid1 don't match",
|
||||
array('!cid' => $comment->cid, '!destid1' => $row->migrate_map_destid1)));
|
||||
array(
|
||||
'!cid' => $comment->cid,
|
||||
'!destid1' => $row->migrate_map_destid1,
|
||||
)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -174,7 +182,7 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
}
|
||||
$this->prepare($comment, $row);
|
||||
foreach ($rawcomment as $field => $value) {
|
||||
$old_comment->$field = $comment->$field;
|
||||
$old_comment->{$field} = $comment->{$field};
|
||||
}
|
||||
$comment = $old_comment;
|
||||
}
|
||||
@@ -190,8 +198,8 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
'pid' => 0,
|
||||
);
|
||||
foreach ($defaults as $field => $value) {
|
||||
if (!isset($comment->$field)) {
|
||||
$comment->$field = $value;
|
||||
if (!isset($comment->{$field})) {
|
||||
$comment->{$field} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,8 +281,8 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
|
||||
/**
|
||||
* Updating node statistics on every comment imported or rolled back is
|
||||
* expensive. We disable node statistics while performing imports and rollbacks,
|
||||
* then re-enable and compute them in bulk when done.
|
||||
* expensive. We disable node statistics while performing imports and
|
||||
* rollbacks, then re-enable and compute them in bulk when done.
|
||||
*/
|
||||
protected function disableStatistics() {
|
||||
// If maintaining node statistics is enabled, temporarily disable it
|
||||
@@ -316,7 +324,7 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
GROUP BY c.nid
|
||||
) AS c2 ON c.nid = c2.nid AND c.created=c2.created
|
||||
)";
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
$sql = "
|
||||
@@ -333,8 +341,7 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
}
|
||||
try {
|
||||
db_query($sql, array(':published' => COMMENT_PUBLISHED));
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// Our edge case has been hit. A Postgres migration has likely just
|
||||
// lost data. Let the user know.
|
||||
Migration::displayMessage(t('Failed to update node comment statistics: !message',
|
||||
@@ -360,6 +367,7 @@ class MigrateDestinationComment extends MigrateDestinationEntity {
|
||||
}
|
||||
|
||||
class MigrateCommentNodeHandler extends MigrateDestinationHandler {
|
||||
|
||||
public function __construct() {
|
||||
$this->registerTypes(array('node'));
|
||||
}
|
||||
|
@@ -10,12 +10,14 @@
|
||||
* Field API-related functions.
|
||||
*/
|
||||
abstract class MigrateDestinationEntity extends MigrateDestination {
|
||||
|
||||
/**
|
||||
* The entity type (node, user, taxonomy_term, etc.) of the destination.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
public function getEntityType() {
|
||||
return $this->entityType;
|
||||
}
|
||||
@@ -26,6 +28,7 @@ abstract class MigrateDestinationEntity extends MigrateDestination {
|
||||
* @var string
|
||||
*/
|
||||
protected $bundle;
|
||||
|
||||
public function getBundle() {
|
||||
return $this->bundle;
|
||||
}
|
||||
@@ -36,6 +39,7 @@ abstract class MigrateDestinationEntity extends MigrateDestination {
|
||||
* @var string
|
||||
*/
|
||||
protected $language;
|
||||
|
||||
public function getLanguage() {
|
||||
return $this->language;
|
||||
}
|
||||
@@ -46,6 +50,7 @@ abstract class MigrateDestinationEntity extends MigrateDestination {
|
||||
* @var int
|
||||
*/
|
||||
protected $textFormat;
|
||||
|
||||
public function getTextFormat() {
|
||||
return $this->textFormat;
|
||||
}
|
||||
@@ -125,12 +130,12 @@ abstract class MigrateDestinationEntity extends MigrateDestination {
|
||||
// Add source keys for debugging and identification of migrated data by hooks.
|
||||
/* TODO: Restore
|
||||
foreach ($migration->sourceKeyMap() as $field_name => $key_name) {
|
||||
$keys[$key_name] = $source_row->$field_name;
|
||||
$keys[$key_name] = $source_row->{$field_name};
|
||||
}
|
||||
*/
|
||||
$migration = Migration::currentMigration();
|
||||
$entity->migrate = array(
|
||||
// 'source_keys' => $keys,
|
||||
// 'source_keys' => $keys,
|
||||
'machineName' => $migration->getMachineName(),
|
||||
);
|
||||
|
||||
@@ -168,8 +173,7 @@ abstract class MigrateDestinationEntity extends MigrateDestination {
|
||||
if (method_exists($migration, 'complete')) {
|
||||
try {
|
||||
$migration->complete($entity, $source_row);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// If we catch any errors here, save the messages without letting
|
||||
// the exception prevent the saving of the entity being recorded.
|
||||
$migration->saveMessage($e->getMessage());
|
||||
@@ -190,17 +194,14 @@ abstract class MigrateDestinationEntity extends MigrateDestination {
|
||||
static public function fieldAttachValidate($entity_type, $entity) {
|
||||
try {
|
||||
field_attach_validate($entity_type, $entity);
|
||||
}
|
||||
catch (FieldValidationException $e) {
|
||||
} catch (FieldValidationException $e) {
|
||||
$migration = Migration::currentMigration();
|
||||
foreach ($e->errors as $field_name => $field_errors) {
|
||||
foreach ($field_errors as $langcode => $errors) {
|
||||
foreach ($errors as $delta => $error_list) {
|
||||
foreach ($error_list as $index => $error) {
|
||||
$message = $error['message'];
|
||||
$migration->saveMessage(t('Field validation error for !field_name: !message',
|
||||
array('!field_name' => $field_name, '!message' => $message)));
|
||||
}
|
||||
foreach ($e->errors as $field_name => $error_list) {
|
||||
if (is_array($error_list)) {
|
||||
foreach ($error_list as $index => $error) {
|
||||
$message = $error['message'];
|
||||
$migration->saveMessage(t('Field validation error for !field_name: !message',
|
||||
array('!field_name' => $field_name, '!message' => $message)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
class MigrateFieldsEntityHandler extends MigrateDestinationHandler {
|
||||
|
||||
public function __construct() {
|
||||
$this->registerTypes(array('entity'));
|
||||
}
|
||||
@@ -33,10 +34,10 @@ class MigrateFieldsEntityHandler extends MigrateDestinationHandler {
|
||||
$fields_found = FALSE;
|
||||
foreach ($class_list as $class_name => $handler) {
|
||||
if (!in_array($class_name, $disabled) && $handler->handlesType($type)
|
||||
&& method_exists($handler, 'fields')) {
|
||||
&& method_exists($handler, 'fields')) {
|
||||
migrate_instrument_start($class_name . '->fields');
|
||||
$subfields = call_user_func(array($handler, 'fields'), $type,
|
||||
$instance, $migration);
|
||||
$instance, $migration);
|
||||
migrate_instrument_stop($class_name . '->fields');
|
||||
foreach ($subfields as $subfield_name => $subfield_label) {
|
||||
$fields[$machine_name . ':' . $subfield_name] = $subfield_label;
|
||||
@@ -49,7 +50,7 @@ class MigrateFieldsEntityHandler extends MigrateDestinationHandler {
|
||||
migrate_instrument_start('MigrateDefaultFieldHandler->fields');
|
||||
$subfields = call_user_func(
|
||||
array(new MigrateDefaultFieldHandler, 'fields'), $type, $instance,
|
||||
$migration);
|
||||
$migration);
|
||||
migrate_instrument_stop('MigrateDefaultFieldHandler->fields');
|
||||
foreach ($subfields as $subfield_name => $subfield_label) {
|
||||
$fields[$machine_name . ':' . $subfield_name] = $subfield_label;
|
||||
@@ -71,12 +72,12 @@ class MigrateFieldsEntityHandler extends MigrateDestinationHandler {
|
||||
foreach ($instances as $machine_name => $instance) {
|
||||
if (property_exists($entity, $machine_name)) {
|
||||
// Normalize to an array
|
||||
if (!is_array($entity->$machine_name)) {
|
||||
$entity->$machine_name = array($entity->$machine_name);
|
||||
if (!is_array($entity->{$machine_name})) {
|
||||
$entity->{$machine_name} = array($entity->{$machine_name});
|
||||
}
|
||||
$field_info = field_info_field($machine_name);
|
||||
$entity->$machine_name = migrate_field_handler_invoke_all($entity, $field_info,
|
||||
$instance, $entity->$machine_name);
|
||||
$entity->{$machine_name} = migrate_field_handler_invoke_all($entity, $field_info,
|
||||
$instance, $entity->{$machine_name});
|
||||
}
|
||||
}
|
||||
migrate_instrument_stop('MigrateDestinationEntity->prepareFields');
|
||||
@@ -93,12 +94,12 @@ class MigrateFieldsEntityHandler extends MigrateDestinationHandler {
|
||||
foreach ($instances as $machine_name => $instance) {
|
||||
if (property_exists($entity, $machine_name)) {
|
||||
// Normalize to an array
|
||||
if (!is_array($entity->$machine_name)) {
|
||||
$entity->$machine_name = array($entity->$machine_name);
|
||||
if (!is_array($entity->{$machine_name})) {
|
||||
$entity->{$machine_name} = array($entity->{$machine_name});
|
||||
}
|
||||
$field_info = field_info_field($machine_name);
|
||||
migrate_field_handler_invoke_all($entity, $field_info,
|
||||
$instance, $entity->$machine_name, 'complete');
|
||||
$instance, $entity->{$machine_name}, 'complete');
|
||||
}
|
||||
}
|
||||
migrate_instrument_stop('MigrateDestinationEntity->completeFields');
|
||||
@@ -106,6 +107,7 @@ class MigrateFieldsEntityHandler extends MigrateDestinationHandler {
|
||||
}
|
||||
|
||||
abstract class MigrateFieldHandler extends MigrateHandler {
|
||||
|
||||
// Derived classes are expected to implement one or both of the prepare/complete
|
||||
// handlers.
|
||||
|
||||
@@ -118,12 +120,14 @@ abstract class MigrateFieldHandler extends MigrateHandler {
|
||||
* @param $entity
|
||||
* @param $field_info
|
||||
* @param $arguments
|
||||
*
|
||||
* @return string language code
|
||||
*/
|
||||
function getFieldLanguage($entity, $field_info, array $arguments) {
|
||||
$migration = Migration::currentMigration();
|
||||
switch (TRUE) {
|
||||
case !field_is_translatable($migration->getDestination()->getEntityType(), $field_info):
|
||||
case !field_is_translatable($migration->getDestination()
|
||||
->getEntityType(), $field_info):
|
||||
return LANGUAGE_NONE;
|
||||
case isset($arguments['language']):
|
||||
return $arguments['language'];
|
||||
@@ -140,7 +144,9 @@ abstract class MigrateFieldHandler extends MigrateHandler {
|
||||
* A fallback field handler to do basic copying of field data.
|
||||
*/
|
||||
class MigrateDefaultFieldHandler extends MigrateFieldHandler {
|
||||
public function __construct() {}
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements MigrateFieldHandler::fields().
|
||||
@@ -230,6 +236,7 @@ class MigrateDefaultFieldHandler extends MigrateFieldHandler {
|
||||
*
|
||||
* To use this class just extend it and pass key where the field's value should
|
||||
* be stored to the constructor, then register the type(s):
|
||||
*
|
||||
* @code
|
||||
* class MigrateLinkFieldHandler extends MigrateSimpleFieldHandler {
|
||||
* public function __construct() {
|
||||
@@ -240,6 +247,7 @@ class MigrateDefaultFieldHandler extends MigrateFieldHandler {
|
||||
* @endcode
|
||||
*/
|
||||
abstract class MigrateSimpleFieldHandler extends MigrateFieldHandler {
|
||||
|
||||
protected $fieldValueKey = 'value';
|
||||
|
||||
protected $skipEmpty = FALSE;
|
||||
@@ -294,6 +302,7 @@ abstract class MigrateSimpleFieldHandler extends MigrateFieldHandler {
|
||||
* Returns TRUE only for values which are not NULL.
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function notNull($value) {
|
||||
@@ -302,6 +311,7 @@ abstract class MigrateSimpleFieldHandler extends MigrateFieldHandler {
|
||||
}
|
||||
|
||||
class MigrateTextFieldHandler extends MigrateFieldHandler {
|
||||
|
||||
public function __construct() {
|
||||
$this->registerTypes(array('text', 'text_long', 'text_with_summary'));
|
||||
}
|
||||
@@ -330,6 +340,7 @@ class MigrateTextFieldHandler extends MigrateFieldHandler {
|
||||
* @param Migration $migration
|
||||
* The migration context for the parent field. We can look at the mappings
|
||||
* and determine which subfields are relevant.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields($type, $instance, $migration = NULL) {
|
||||
@@ -345,7 +356,7 @@ class MigrateTextFieldHandler extends MigrateFieldHandler {
|
||||
$field = field_info_field($instance['field_name']);
|
||||
if (field_is_translatable($instance['entity_type'], $field)) {
|
||||
$fields['language'] = t('Subfield: <a href="@doc">Language for the field</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1224042#language'));
|
||||
array('@doc' => 'http://drupal.org/node/1224042#language'));
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
@@ -382,7 +393,7 @@ class MigrateTextFieldHandler extends MigrateFieldHandler {
|
||||
if (is_array($arguments['format'])) {
|
||||
$format = $arguments['format'][$delta];
|
||||
}
|
||||
else{
|
||||
else {
|
||||
$format = $arguments['format'];
|
||||
}
|
||||
}
|
||||
@@ -393,6 +404,11 @@ class MigrateTextFieldHandler extends MigrateFieldHandler {
|
||||
$format = NULL;
|
||||
}
|
||||
$item['format'] = $item['value_format'] = $format;
|
||||
// If the value is an array, which it might be if the destination entity
|
||||
// was loaded via entity_load(), ensure we're handling a string.
|
||||
if (is_array($value) && !empty($value[0]) && array_key_exists('value', $value[0])) {
|
||||
$value = $value[0]['value'];
|
||||
}
|
||||
// Make sure the value will fit
|
||||
if ($max_length) {
|
||||
$item['value'] = drupal_substr($value, 0, $max_length);
|
||||
@@ -401,8 +417,11 @@ class MigrateTextFieldHandler extends MigrateFieldHandler {
|
||||
if ($value_length > $max_length) {
|
||||
$migration->saveMessage(
|
||||
t('Value for field !field exceeds max length of !max_length, actual length is !length',
|
||||
array('!field' => $instance['field_name'], '!max_length' => $max_length,
|
||||
'!length' => $value_length)),
|
||||
array(
|
||||
'!field' => $instance['field_name'],
|
||||
'!max_length' => $max_length,
|
||||
'!length' => $value_length,
|
||||
)),
|
||||
Migration::MESSAGE_INFORMATIONAL);
|
||||
}
|
||||
}
|
||||
@@ -426,17 +445,28 @@ class MigrateTextFieldHandler extends MigrateFieldHandler {
|
||||
}
|
||||
|
||||
class MigrateValueFieldHandler extends MigrateSimpleFieldHandler {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(array(
|
||||
'value_key' => 'value',
|
||||
'skip_empty' => FALSE,
|
||||
));
|
||||
$this->registerTypes(array('value', 'list', 'list_boolean', 'list_integer',
|
||||
'list_float', 'list_text', 'number_integer', 'number_decimal', 'number_float'));
|
||||
$this->registerTypes(array(
|
||||
'value',
|
||||
'list',
|
||||
'list_boolean',
|
||||
'list_integer',
|
||||
'list_float',
|
||||
'list_text',
|
||||
'number_integer',
|
||||
'number_decimal',
|
||||
'number_float',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
class MigrateTaxonomyTermReferenceFieldHandler extends MigrateFieldHandler {
|
||||
|
||||
public function __construct() {
|
||||
$this->registerTypes(array('taxonomy_term_reference'));
|
||||
}
|
||||
@@ -451,6 +481,7 @@ class MigrateTaxonomyTermReferenceFieldHandler extends MigrateFieldHandler {
|
||||
* @param Migration $migration
|
||||
* The migration context for the parent field. We can look at the mappings
|
||||
* and determine which subfields are relevant.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields($type, $instance, $migration = NULL) {
|
||||
@@ -575,6 +606,7 @@ class MigrateTaxonomyTermReferenceFieldHandler extends MigrateFieldHandler {
|
||||
* dealing with the file entity to an embedded MigrateFileInterface instance.
|
||||
*/
|
||||
abstract class MigrateFileFieldBaseHandler extends MigrateFieldHandler {
|
||||
|
||||
/**
|
||||
* Implementation of MigrateFieldHandler::fields().
|
||||
*
|
||||
@@ -585,6 +617,7 @@ abstract class MigrateFileFieldBaseHandler extends MigrateFieldHandler {
|
||||
* @param Migration $migration
|
||||
* The migration context for the parent field. We can look at the mappings
|
||||
* and determine which subfields are relevant.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields($type, $instance, $migration = NULL) {
|
||||
@@ -673,8 +706,12 @@ abstract class MigrateFileFieldBaseHandler extends MigrateFieldHandler {
|
||||
}
|
||||
else {
|
||||
$migration->saveMessage(
|
||||
t('No data for subfield %key at row %delta for field %field',
|
||||
array('%key' => $key, '%delta' => $delta, '%field' => $field_info['field_name'])),
|
||||
t('No data for subfield %key at row %delta for field %field',
|
||||
array(
|
||||
'%key' => $key,
|
||||
'%delta' => $delta,
|
||||
'%field' => $field_info['field_name'],
|
||||
)),
|
||||
Migration::MESSAGE_WARNING);
|
||||
}
|
||||
}
|
||||
@@ -710,6 +747,7 @@ abstract class MigrateFileFieldBaseHandler extends MigrateFieldHandler {
|
||||
* Field API info on the general field.
|
||||
* @param $instance
|
||||
* Field API info on the field instance for this entity type.
|
||||
*
|
||||
* @return string
|
||||
* Directory relative to the Drupal public files directory.
|
||||
*/
|
||||
@@ -743,6 +781,7 @@ abstract class MigrateFileFieldBaseHandler extends MigrateFieldHandler {
|
||||
* Handle for file fields.
|
||||
*/
|
||||
class MigrateFileFieldHandler extends MigrateFileFieldBaseHandler {
|
||||
|
||||
public function __construct() {
|
||||
$this->registerTypes(array('file'));
|
||||
}
|
||||
@@ -758,6 +797,7 @@ class MigrateFileFieldHandler extends MigrateFileFieldBaseHandler {
|
||||
* @param Migration $migration
|
||||
* The migration context for the parent field. We can look at the mappings
|
||||
* and determine which subfields are relevant.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields($type, $instance, $migration = NULL) {
|
||||
@@ -806,6 +846,7 @@ class MigrateFileFieldHandler extends MigrateFileFieldBaseHandler {
|
||||
* Handle for image fields;
|
||||
*/
|
||||
class MigrateImageFieldHandler extends MigrateFileFieldBaseHandler {
|
||||
|
||||
public function __construct() {
|
||||
$this->registerTypes(array('image'));
|
||||
}
|
||||
@@ -821,6 +862,7 @@ class MigrateImageFieldHandler extends MigrateFileFieldBaseHandler {
|
||||
* @param Migration $migration
|
||||
* The migration context for the parent field. We can look at the mappings
|
||||
* and determine which subfields are relevant.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields($type, $instance, $migration = NULL) {
|
||||
@@ -859,6 +901,7 @@ class MigrateImageFieldHandler extends MigrateFileFieldBaseHandler {
|
||||
}
|
||||
|
||||
class MigrateNodeReferenceFieldHandler extends MigrateSimpleFieldHandler {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(array(
|
||||
'value_key' => 'nid',
|
||||
@@ -873,6 +916,7 @@ class MigrateNodeReferenceFieldHandler extends MigrateSimpleFieldHandler {
|
||||
}
|
||||
|
||||
class MigrateUserReferenceFieldHandler extends MigrateSimpleFieldHandler {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(array(
|
||||
'value_key' => 'uid',
|
||||
|
@@ -12,6 +12,7 @@
|
||||
* a Drupal file entity (creating the entity if necessary).
|
||||
*/
|
||||
interface MigrateFileInterface {
|
||||
|
||||
/**
|
||||
* Return a list of subfields and options specific to this implementation,
|
||||
* keyed by name.
|
||||
@@ -35,6 +36,7 @@ interface MigrateFileInterface {
|
||||
}
|
||||
|
||||
abstract class MigrateFileBase implements MigrateFileInterface {
|
||||
|
||||
/**
|
||||
* Extension of the core FILE_EXISTS_* constants, offering an alternative to
|
||||
* reuse the existing file if present as-is (core only offers the options of
|
||||
@@ -99,6 +101,7 @@ abstract class MigrateFileBase implements MigrateFileInterface {
|
||||
* Path to the Drupal copy of the file.
|
||||
* @param $owner
|
||||
* Uid of the file owner.
|
||||
*
|
||||
* @return stdClass
|
||||
* A file object ready to be saved.
|
||||
*/
|
||||
@@ -130,7 +133,7 @@ abstract class MigrateFileBase implements MigrateFileInterface {
|
||||
// If we are replacing or reusing an existing filesystem entry,
|
||||
// also re-use its database record.
|
||||
if ($this->fileReplace == FILE_EXISTS_REPLACE ||
|
||||
$this->fileReplace == self::FILE_EXISTS_REUSE) {
|
||||
$this->fileReplace == self::FILE_EXISTS_REUSE) {
|
||||
$existing_files = file_load_multiple(array(), array('uri' => $destination));
|
||||
if (count($existing_files)) {
|
||||
$existing = reset($existing_files);
|
||||
@@ -171,6 +174,7 @@ abstract class MigrateFileBase implements MigrateFileInterface {
|
||||
* to copy or otherwise use it.
|
||||
*/
|
||||
class MigrateFileUriAsIs extends MigrateFileBase {
|
||||
|
||||
public function processFile($value, $owner) {
|
||||
$file = file_save($this->createFileEntity($value, $owner));
|
||||
return $file;
|
||||
@@ -181,6 +185,7 @@ class MigrateFileUriAsIs extends MigrateFileBase {
|
||||
* Handle the degenerate case where we already have a file ID.
|
||||
*/
|
||||
class MigrateFileFid extends MigrateFileBase {
|
||||
|
||||
/**
|
||||
* Implementation of MigrateFileInterface::processFile().
|
||||
*
|
||||
@@ -188,6 +193,7 @@ class MigrateFileFid extends MigrateFileBase {
|
||||
* An existing file entity ID (fid).
|
||||
* @param $owner
|
||||
* User ID (uid) to be the owner of the file. Ignored in this case.
|
||||
*
|
||||
* @return int
|
||||
* The file entity corresponding to the fid that was passed in.
|
||||
*/
|
||||
@@ -201,6 +207,7 @@ class MigrateFileFid extends MigrateFileBase {
|
||||
* Base class for creating core file entities.
|
||||
*/
|
||||
abstract class MigrateFile extends MigrateFileBase {
|
||||
|
||||
/**
|
||||
* The destination directory within Drupal.
|
||||
*
|
||||
@@ -232,13 +239,13 @@ abstract class MigrateFile extends MigrateFileBase {
|
||||
*/
|
||||
static public function fields() {
|
||||
return parent::fields() + array(
|
||||
'destination_dir' => t('Subfield: <a href="@doc">Path within Drupal files directory to store file</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1540106#destination_dir')),
|
||||
'destination_file' => t('Subfield: <a href="@doc">Path within destination_dir to store the file.</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1540106#destination_file')),
|
||||
'file_replace' => t('Option: <a href="@doc">Value of $replace in that file function. Defaults to FILE_EXISTS_RENAME.</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1540106#file_replace')),
|
||||
);
|
||||
'destination_dir' => t('Subfield: <a href="@doc">Path within Drupal files directory to store file</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1540106#destination_dir')),
|
||||
'destination_file' => t('Subfield: <a href="@doc">Path within destination_dir to store the file.</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1540106#destination_file')),
|
||||
'file_replace' => t('Option: <a href="@doc">Value of $replace in that file function. Defaults to FILE_EXISTS_RENAME.</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1540106#file_replace')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,6 +253,7 @@ abstract class MigrateFile extends MigrateFileBase {
|
||||
*
|
||||
* @param $destination
|
||||
* Destination path within Drupal.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the file is successfully saved, FALSE otherwise.
|
||||
*/
|
||||
@@ -258,6 +266,7 @@ abstract class MigrateFile extends MigrateFileBase {
|
||||
* The URI or local filespec of a file to be imported.
|
||||
* @param $owner
|
||||
* User ID (uid) to be the owner of the file.
|
||||
*
|
||||
* @return object
|
||||
* The file entity being created or referenced.
|
||||
*/
|
||||
@@ -286,9 +295,9 @@ abstract class MigrateFile extends MigrateFileBase {
|
||||
// Prepare the destination directory.
|
||||
$destdir = drupal_dirname($destination);
|
||||
if (!file_prepare_directory($destdir,
|
||||
FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
|
||||
FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
|
||||
$migration->saveMessage(t('Could not create destination directory for !dest',
|
||||
array('!dest' => $destination)));
|
||||
array('!dest' => $destination)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -330,6 +339,7 @@ abstract class MigrateFile extends MigrateFileBase {
|
||||
* to be imported to Drupal.
|
||||
*/
|
||||
class MigrateFileUri extends MigrateFile {
|
||||
|
||||
/**
|
||||
* The source directory for the file, relative to which the value (source
|
||||
* file) will be taken.
|
||||
@@ -390,13 +400,21 @@ class MigrateFileUri extends MigrateFile {
|
||||
$this->sourcePath = self::urlencode($this->sourcePath);
|
||||
}
|
||||
try {
|
||||
copy($this->sourcePath, $destination);
|
||||
return TRUE;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$copied = copy($this->sourcePath, $destination);
|
||||
if ($copied == FALSE) {
|
||||
$migration = Migration::currentMigration();
|
||||
$migration->saveMessage(t('The specified file %file could not be copied to %destination',
|
||||
array('%file' => $this->sourcePath, '%destination' => $destination)));
|
||||
}
|
||||
return $copied;
|
||||
} catch (Exception $e) {
|
||||
$migration = Migration::currentMigration();
|
||||
$migration->saveMessage(t('The specified file %file could not be copied to %destination: "%exception_msg"',
|
||||
array('%file' => $this->sourcePath, '%destination' => $destination, '%exception_msg' => $e->getMessage())));
|
||||
array(
|
||||
'%file' => $this->sourcePath,
|
||||
'%destination' => $destination,
|
||||
'%exception_msg' => $e->getMessage(),
|
||||
)));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -431,6 +449,7 @@ class MigrateFileUri extends MigrateFile {
|
||||
* The URI or local filespec of a file to be imported.
|
||||
* @param $owner
|
||||
* User ID (uid) to be the owner of the file.
|
||||
*
|
||||
* @return object
|
||||
* The file entity being created or referenced.
|
||||
*/
|
||||
@@ -460,6 +479,7 @@ class MigrateFileUri extends MigrateFile {
|
||||
* such as image data) to be stored as a real file in Drupal.
|
||||
*/
|
||||
class MigrateFileBlob extends MigrateFile {
|
||||
|
||||
/**
|
||||
* The file contents we will be writing to a real file.
|
||||
*
|
||||
@@ -472,6 +492,7 @@ class MigrateFileBlob extends MigrateFile {
|
||||
*
|
||||
* @param $destination
|
||||
* Drupal destination path.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the file contents were successfully written, FALSE otherwise.
|
||||
*/
|
||||
@@ -482,7 +503,7 @@ class MigrateFileBlob extends MigrateFile {
|
||||
else {
|
||||
$migration = Migration::currentMigration();
|
||||
$migration->saveMessage(t('Failed to write blob data to %destination',
|
||||
array('%destination' => $destination)));
|
||||
array('%destination' => $destination)));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -494,6 +515,7 @@ class MigrateFileBlob extends MigrateFile {
|
||||
* The file contents to be saved as a file.
|
||||
* @param $owner
|
||||
* User ID (uid) to be the owner of the file.
|
||||
*
|
||||
* @return object
|
||||
* File entity being created or referenced.
|
||||
*/
|
||||
@@ -508,12 +530,14 @@ class MigrateFileBlob extends MigrateFile {
|
||||
* Destination class implementing migration into the files table.
|
||||
*/
|
||||
class MigrateDestinationFile extends MigrateDestinationEntity {
|
||||
|
||||
/**
|
||||
* File class (MigrateFileUri etc.) doing the dirty wrk.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fileClass;
|
||||
|
||||
public function setFileClass($file_class) {
|
||||
$this->fileClass = $file_class;
|
||||
}
|
||||
@@ -554,10 +578,12 @@ class MigrateDestinationFile extends MigrateDestinationEntity {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of fields available to be mapped for the entity type (bundle)
|
||||
* Returns a list of fields available to be mapped for the entity type
|
||||
* (bundle)
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
@@ -635,6 +661,7 @@ class MigrateDestinationFile extends MigrateDestinationEntity {
|
||||
* File object to build. Prefilled with any fields mapped in the Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields (fid only in this case) of the file that was saved if
|
||||
* successful. FALSE on failure.
|
||||
@@ -646,7 +673,10 @@ class MigrateDestinationFile extends MigrateDestinationEntity {
|
||||
if (isset($file->fid)) {
|
||||
if ($file->fid != $row->migrate_map_destid1) {
|
||||
throw new MigrateException(t("Incoming fid !fid and map destination fid !destid1 don't match",
|
||||
array('!fid' => $file->fid, '!destid1' => $row->migrate_map_destid1)));
|
||||
array(
|
||||
'!fid' => $file->fid,
|
||||
'!destid1' => $row->migrate_map_destid1,
|
||||
)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -700,7 +730,7 @@ class MigrateDestinationFile extends MigrateDestinationEntity {
|
||||
$file->preserve_files = FALSE;
|
||||
|
||||
$file_class = $this->fileClass;
|
||||
$source = new $file_class((array)$file, $file);
|
||||
$source = new $file_class((array) $file, $file);
|
||||
$file = $source->processFile($file->value, $file->uid);
|
||||
|
||||
if (is_object($file) && isset($file->fid)) {
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Destination class implementing migration into {menu_custom}.
|
||||
*/
|
||||
class MigrateDestinationMenu extends MigrateDestination {
|
||||
|
||||
static public function getKeySchema() {
|
||||
return array(
|
||||
'menu_name' => array(
|
||||
@@ -35,6 +36,7 @@ class MigrateDestinationMenu extends MigrateDestination {
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
@@ -55,6 +57,7 @@ class MigrateDestinationMenu extends MigrateDestination {
|
||||
* Menu object to build. Prefilled with any fields mapped in the Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields of the object that was saved if
|
||||
* successful. FALSE on failure.
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Destination class implementing migration into {menu_links}.
|
||||
*/
|
||||
class MigrateDestinationMenuLinks extends MigrateDestination {
|
||||
|
||||
static public function getKeySchema() {
|
||||
return array(
|
||||
'mlid' => array(
|
||||
@@ -19,6 +20,7 @@ class MigrateDestinationMenuLinks extends MigrateDestination {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
@@ -33,6 +35,7 @@ class MigrateDestinationMenuLinks extends MigrateDestination {
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
@@ -72,9 +75,11 @@ class MigrateDestinationMenuLinks extends MigrateDestination {
|
||||
* Import a single row.
|
||||
*
|
||||
* @param $menu_link
|
||||
* Menu link object to build. Prefilled with any fields mapped in the Migration.
|
||||
* Menu link object to build. Prefilled with any fields mapped in the
|
||||
* Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields of the object that was saved if
|
||||
* successful. FALSE on failure.
|
||||
@@ -95,9 +100,9 @@ class MigrateDestinationMenuLinks extends MigrateDestination {
|
||||
throw new MigrateException(t('System-of-record is DESTINATION, and the provided mlid could not be found'));
|
||||
}
|
||||
$menu_link_to_update = (object) $old_menu_link;
|
||||
foreach($old_menu_link as $key => $value) {
|
||||
if (!isset($menu_link->$key)) {
|
||||
$menu_link->$key = $old_menu_link[$key];
|
||||
foreach ($old_menu_link as $key => $value) {
|
||||
if (!isset($menu_link->{$key})) {
|
||||
$menu_link->{$key} = $old_menu_link[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
* Destination class implementing migration into nodes.
|
||||
*/
|
||||
class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
|
||||
protected $bypassDestIdCheck = FALSE;
|
||||
|
||||
static public function getKeySchema() {
|
||||
@@ -53,6 +54,7 @@ class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
@@ -61,39 +63,39 @@ class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
$fields = array();
|
||||
// First the core (node table) properties
|
||||
$fields['nid'] = t('Node: <a href="@doc">Existing node ID</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#nid'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#nid'));
|
||||
$node_type = node_type_load($this->bundle);
|
||||
if ($node_type->has_title) {
|
||||
$fields['title'] = t('Node: <a href="@doc">',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#title'))
|
||||
. $node_type->title_label . '</a>';
|
||||
array('@doc' => 'http://drupal.org/node/1349696#title'))
|
||||
. $node_type->title_label . '</a>';
|
||||
}
|
||||
$fields['uid'] = t('<a href="@doc">Authored by (uid)</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#uid'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#uid'));
|
||||
$fields['created'] = t('<a href="@doc">Created timestamp</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#created'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#created'));
|
||||
$fields['changed'] = t('<a href="@doc">Modified timestamp</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#changed'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#changed'));
|
||||
$fields['status'] = t('<a href="@doc">Published</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#status'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#status'));
|
||||
$fields['promote'] = t('<a href="@doc">Promoted to front page</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#promote'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#promote'));
|
||||
$fields['sticky'] = t('<a href="@doc">Sticky at top of lists</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#sticky'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#sticky'));
|
||||
$fields['revision'] = t('<a href="@doc">Create new revision</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#revision'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#revision'));
|
||||
$fields['log'] = t('<a href="@doc">Revision Log message</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#log'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#log'));
|
||||
$fields['language'] = t('<a href="@doc">Language (fr, en, ...)</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#language'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#language'));
|
||||
$fields['tnid'] = t('<a href="@doc">The translation set id for this node</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#tnid'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#tnid'));
|
||||
$fields['translate'] = t('<a href="@doc">A boolean indicating whether this translation page needs to be updated</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#translate'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#translate'));
|
||||
$fields['revision_uid'] = t('<a href="@doc">Modified (uid)</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#revision_uid'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#revision_uid'));
|
||||
$fields['is_new'] = t('Option: <a href="@doc">Indicates a new node with the specified nid should be created</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349696#is_new'));
|
||||
array('@doc' => 'http://drupal.org/node/1349696#is_new'));
|
||||
|
||||
// Then add in anything provided by handlers
|
||||
$fields += migrate_handler_invoke_all('Entity', 'fields', $this->entityType, $this->bundle, $migration);
|
||||
@@ -123,6 +125,7 @@ class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
* Node object to build. Prefilled with any fields mapped in the Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields (nid only in this case) of the node that was saved if
|
||||
* successful. FALSE on failure.
|
||||
@@ -136,7 +139,10 @@ class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
if (isset($node->nid)) {
|
||||
if ($node->nid != $row->migrate_map_destid1) {
|
||||
throw new MigrateException(t("Incoming nid !nid and map destination nid !destid1 don't match",
|
||||
array('!nid' => $node->nid, '!destid1' => $row->migrate_map_destid1)));
|
||||
array(
|
||||
'!nid' => $node->nid,
|
||||
'!destid1' => $row->migrate_map_destid1,
|
||||
)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -144,13 +150,13 @@ class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
}
|
||||
// Get the existing vid, tnid so updates don't generate notices
|
||||
$values = db_select('node', 'n')
|
||||
->fields('n', array('vid', 'tnid'))
|
||||
->condition('nid', $node->nid)
|
||||
->execute()
|
||||
->fetchAssoc();
|
||||
->fields('n', array('vid', 'tnid'))
|
||||
->condition('nid', $node->nid)
|
||||
->execute()
|
||||
->fetchAssoc();
|
||||
if (empty($values)) {
|
||||
throw new MigrateException(t("Incoming node ID !nid no longer exists",
|
||||
array('!nid' => $node->nid)));
|
||||
array('!nid' => $node->nid)));
|
||||
}
|
||||
$node->vid = $values['vid'];
|
||||
if (empty($node->tnid)) {
|
||||
@@ -164,7 +170,7 @@ class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
$old_node = node_load($node->nid);
|
||||
if (empty($old_node)) {
|
||||
throw new MigrateException(t('System-of-record is DESTINATION, but node !nid does not exist',
|
||||
array('!nid' => $node->nid)));
|
||||
array('!nid' => $node->nid)));
|
||||
}
|
||||
if (!isset($node->created)) {
|
||||
$node->created = $old_node->created;
|
||||
@@ -241,11 +247,11 @@ class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
foreach ($old_node as $field => $value) {
|
||||
// An explicit NULL in the source data means to wipe to old value (i.e.,
|
||||
// don't copy it over from $old_node)
|
||||
if (property_exists($node, $field) && $node->$field === NULL) {
|
||||
if (property_exists($node, $field) && $node->{$field} === NULL) {
|
||||
// Ignore this field
|
||||
}
|
||||
elseif (!isset($node->$field)) {
|
||||
$node->$field = $old_node->$field;
|
||||
elseif (!isset($node->{$field})) {
|
||||
$node->{$field} = $old_node->{$field};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -289,7 +295,7 @@ class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
|
||||
// Potentially fix uid and timestamp in node_revisions.
|
||||
$query = db_update('node_revision')
|
||||
->condition('vid', $node->vid);
|
||||
->condition('vid', $node->vid);
|
||||
if (isset($changed)) {
|
||||
$fields['timestamp'] = $changed;
|
||||
}
|
||||
@@ -319,7 +325,8 @@ class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
/**
|
||||
* Allows you to import revisions.
|
||||
*
|
||||
* Adapted from http://www.darrenmothersele.com/blog/2012/07/16/migrating-node-revisions-drupal-7/
|
||||
* Adapted from
|
||||
* http://www.darrenmothersele.com/blog/2012/07/16/migrating-node-revisions-drupal-7/
|
||||
*
|
||||
* Class MigrateDestinationNodeRevision
|
||||
*
|
||||
@@ -327,6 +334,7 @@ class MigrateDestinationNode extends MigrateDestinationEntity {
|
||||
* @author cthos
|
||||
*/
|
||||
class MigrateDestinationNodeRevision extends MigrateDestinationNode {
|
||||
|
||||
/**
|
||||
* Basic initialization.
|
||||
*
|
||||
@@ -398,9 +406,16 @@ class MigrateDestinationNodeRevision extends MigrateDestinationNode {
|
||||
}
|
||||
$this->completeRollback($vids);
|
||||
foreach ($nids as $nid) {
|
||||
$vid = db_select('node_revision', 'nr')->fields('nr', array('vid'))->condition('nid', $nid, '=')->execute()->fetchField();
|
||||
$vid = db_select('node_revision', 'nr')
|
||||
->fields('nr', array('vid'))
|
||||
->condition('nid', $nid, '=')
|
||||
->execute()
|
||||
->fetchField();
|
||||
if (!empty($vid)) {
|
||||
db_update('node')->fields(array('vid' => $vid))->condition('nid', $nid, '=')->execute();
|
||||
db_update('node')
|
||||
->fields(array('vid' => $vid))
|
||||
->condition('nid', $nid, '=')
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
migrate_instrument_stop('revision_delete_multiple');
|
||||
|
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
class MigratePathEntityHandler extends MigrateDestinationHandler {
|
||||
|
||||
public function __construct() {
|
||||
$this->registerTypes(array('entity'));
|
||||
}
|
||||
|
@@ -21,7 +21,8 @@
|
||||
* public function prepareRow($row);
|
||||
* $choices = Database::getConnection('default', 'legacy')
|
||||
* ->select('src_poll_choice', 'c')
|
||||
* ->fields('c', array('choice_label', 'choice_order', 'choice_total'))
|
||||
* ->fields('c', array('choice_label', 'choice_order',
|
||||
* 'choice_total'))
|
||||
* ->condition('c.choiceid', $row->src_contentid);
|
||||
* ->execute();
|
||||
* $row->src_choices = array();
|
||||
@@ -38,7 +39,8 @@
|
||||
* ->select('src_poll_vote', 'v')
|
||||
* ->fields('v', array('choice_uid', 'hostname', 'timestamp'))
|
||||
* ->condition('v.choiceid', $row->src_contentid);
|
||||
* $votes = $query->innerJoin('src_poll_choice', 'c', 'v.choice_id=c.choice_id')
|
||||
* $votes = $query->innerJoin('src_poll_choice', 'c',
|
||||
* 'v.choice_id=c.choice_id')
|
||||
* ->fields('c', array('choice_label'))
|
||||
* ->execute();
|
||||
* $row->src_votes = array();
|
||||
@@ -56,6 +58,7 @@
|
||||
*/
|
||||
|
||||
class MigratePollEntityHandler extends MigrateDestinationHandler {
|
||||
|
||||
public function __construct() {
|
||||
$this->registerTypes(array('node'));
|
||||
}
|
||||
@@ -92,7 +95,10 @@ class MigratePollEntityHandler extends MigrateDestinationHandler {
|
||||
foreach ($row->choice as $choice) {
|
||||
// Have no mapping tracking for chid, so assume choice text is unique.
|
||||
db_update('poll_choice')
|
||||
->fields(array('chvotes' => $choice['chvotes'], 'weight' => $choice['weight']))
|
||||
->fields(array(
|
||||
'chvotes' => $choice['chvotes'],
|
||||
'weight' => $choice['weight'],
|
||||
))
|
||||
->condition('nid', $entity->nid)
|
||||
->condition('chtext', $choice['chtext'])
|
||||
->execute();
|
||||
@@ -102,10 +108,10 @@ class MigratePollEntityHandler extends MigrateDestinationHandler {
|
||||
foreach ($row->votes as $vote) {
|
||||
if (!isset($vote['chid'])) {
|
||||
$result = db_select('poll_choice', 'pc')
|
||||
->fields('pc', array('chid'))
|
||||
->condition('pc.nid', $entity->nid)
|
||||
->condition('pc.chtext', $vote['chtext'])
|
||||
->execute();
|
||||
->fields('pc', array('chid'))
|
||||
->condition('pc.nid', $entity->nid)
|
||||
->condition('pc.chtext', $vote['chtext'])
|
||||
->execute();
|
||||
$chid = $result->fetchField();
|
||||
}
|
||||
else {
|
||||
|
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
class MigrateStatisticsEntityHandler extends MigrateDestinationHandler {
|
||||
|
||||
public function __construct() {
|
||||
$this->registerTypes(array('node'));
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@
|
||||
* the Schema API.
|
||||
*/
|
||||
class MigrateDestinationTable extends MigrateDestination {
|
||||
|
||||
/**
|
||||
* The schema of the current table.
|
||||
*
|
||||
@@ -81,6 +82,7 @@ class MigrateDestinationTable extends MigrateDestination {
|
||||
* Object object to build. Prefilled with any fields mapped in the Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields of the object that was saved if
|
||||
* successful. FALSE on failure.
|
||||
@@ -122,7 +124,7 @@ class MigrateDestinationTable extends MigrateDestination {
|
||||
}
|
||||
|
||||
$select = db_select($this->tableName)
|
||||
->fields($this->tableName);
|
||||
->fields($this->tableName);
|
||||
foreach ($this->schema['primary key'] as $key) {
|
||||
$select->condition($key, $entity->{$key});
|
||||
}
|
||||
@@ -131,7 +133,7 @@ class MigrateDestinationTable extends MigrateDestination {
|
||||
throw new MigrateException(t('System-of-record is DESTINATION, but the destination entity does not exist'));
|
||||
}
|
||||
foreach ($entity as $field => $value) {
|
||||
$old_entity->$field = $entity->$field;
|
||||
$old_entity->{$field} = $entity->{$field};
|
||||
}
|
||||
$entity = $old_entity;
|
||||
}
|
||||
@@ -159,6 +161,7 @@ class MigrateDestinationTable extends MigrateDestination {
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Destination class implementing migration into a single table.
|
||||
*/
|
||||
class MigrateDestinationTableCopy extends MigrateDestination {
|
||||
|
||||
public function __construct($tableName, $keySchema) {
|
||||
parent::__construct();
|
||||
$this->tableName = $tableName;
|
||||
@@ -41,6 +42,7 @@ class MigrateDestinationTableCopy extends MigrateDestination {
|
||||
* Object object to build. Prefilled with any fields mapped in the Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields of the object that was saved if
|
||||
* successful. FALSE on failure.
|
||||
@@ -53,15 +55,17 @@ class MigrateDestinationTableCopy extends MigrateDestination {
|
||||
// table.
|
||||
foreach ($fields as $field => $data) {
|
||||
if (strpos($field, 'migrate_map_') === 0) {
|
||||
unset($fields->$field);
|
||||
unset($fields->{$field});
|
||||
}
|
||||
}
|
||||
$keys = array_keys($this->keySchema);
|
||||
$values = array();
|
||||
$values = array();
|
||||
foreach ($keys as $key) {
|
||||
$values[] = $row->$key;
|
||||
$values[] = $row->{$key};
|
||||
}
|
||||
$query = db_merge($this->tableName)->key($keys, $values)->fields((array)$fields);
|
||||
$query = db_merge($this->tableName)
|
||||
->key($keys, $values)
|
||||
->fields((array) $fields);
|
||||
try {
|
||||
$status = $query->execute();
|
||||
if ($status == MergeQuery::STATUS_INSERT) {
|
||||
@@ -71,12 +75,10 @@ class MigrateDestinationTableCopy extends MigrateDestination {
|
||||
$this->numUpdated++;
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
} catch (MigrateException $e) {
|
||||
$migration->saveMessage($e->getMessage(), $e->getLevel());
|
||||
Migration::displayMessage($e->getMessage());
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$migration->handleException($e);
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@
|
||||
* Destination class implementing migration into terms.
|
||||
*/
|
||||
class MigrateDestinationTerm extends MigrateDestinationEntity {
|
||||
|
||||
/**
|
||||
* Boolean indicating whether to permit duplicate terms to be created.
|
||||
*
|
||||
@@ -59,10 +60,12 @@ class MigrateDestinationTerm extends MigrateDestinationEntity {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of fields available to be mapped for this vocabulary (bundle)
|
||||
* Returns a list of fields available to be mapped for this vocabulary
|
||||
* (bundle)
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
@@ -71,20 +74,20 @@ class MigrateDestinationTerm extends MigrateDestinationEntity {
|
||||
$fields = array();
|
||||
// First the core (taxonomy_term_data table) properties
|
||||
$fields['tid'] = t('<a href="@doc">Existing term ID</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349702#tid'));
|
||||
array('@doc' => 'http://drupal.org/node/1349702#tid'));
|
||||
$fields['name'] = t('<a href="@doc">Name</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349702#name'));
|
||||
array('@doc' => 'http://drupal.org/node/1349702#name'));
|
||||
$fields['description'] = t('<a href="@doc">Description</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349702#description'));
|
||||
array('@doc' => 'http://drupal.org/node/1349702#description'));
|
||||
$fields['parent'] = t('<a href="@doc">Parent (by Drupal term ID)</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349702#parent'));
|
||||
array('@doc' => 'http://drupal.org/node/1349702#parent'));
|
||||
// TODO: Remove parent_name, implement via arguments
|
||||
$fields['parent_name'] = t('<a href="@doc">Parent (by name)</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349702#parent_name'));
|
||||
array('@doc' => 'http://drupal.org/node/1349702#parent_name'));
|
||||
$fields['format'] = t('<a href="@doc">Format</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349702#format'));
|
||||
array('@doc' => 'http://drupal.org/node/1349702#format'));
|
||||
$fields['weight'] = t('<a href="@doc">Weight</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349702#weight'));
|
||||
array('@doc' => 'http://drupal.org/node/1349702#weight'));
|
||||
|
||||
// Then add in anything provided by handlers
|
||||
$fields += migrate_handler_invoke_all('entity', 'fields', $this->entityType, $this->bundle, $migration);
|
||||
@@ -131,6 +134,7 @@ class MigrateDestinationTerm extends MigrateDestinationEntity {
|
||||
* Term object to build. Prefilled with any fields mapped in the Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields (tid only in this case) of the term that was saved if
|
||||
* successful. FALSE on failure.
|
||||
@@ -142,7 +146,10 @@ class MigrateDestinationTerm extends MigrateDestinationEntity {
|
||||
if (isset($term->tid)) {
|
||||
if ($term->tid != $row->migrate_map_destid1) {
|
||||
throw new MigrateException(t("Incoming tid !tid and map destination nid !destid1 don't match",
|
||||
array('!tid' => $term->tid, '!destid1' => $row->migrate_map_destid1)));
|
||||
array(
|
||||
'!tid' => $term->tid,
|
||||
'!destid1' => $row->migrate_map_destid1,
|
||||
)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -167,7 +174,7 @@ class MigrateDestinationTerm extends MigrateDestinationEntity {
|
||||
array('!tid' => $term->tid)));
|
||||
}
|
||||
foreach ($rawterm as $field => $value) {
|
||||
$old_term->$field = $term->$field;
|
||||
$old_term->{$field} = $term->{$field};
|
||||
}
|
||||
$term = $old_term;
|
||||
}
|
||||
@@ -230,8 +237,8 @@ class MigrateDestinationTerm extends MigrateDestinationEntity {
|
||||
|
||||
if (!$this->allowDuplicateTerms && $existing_term = $this->findMatchingTerm($term)) {
|
||||
foreach ($existing_term as $field => $value) {
|
||||
if (!isset($term->$field)) {
|
||||
$term->$field = $existing_term->$field;
|
||||
if (!isset($term->{$field})) {
|
||||
$term->{$field} = $existing_term->{$field};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,8 +250,8 @@ class MigrateDestinationTerm extends MigrateDestinationEntity {
|
||||
if ($existing_term) {
|
||||
// Incoming data overrides existing data, so only copy non-existent fields
|
||||
foreach ($existing_term as $field => $value) {
|
||||
if (!isset($term->$field)) {
|
||||
$term->$field = $existing_term->$field;
|
||||
if (!isset($term->{$field})) {
|
||||
$term->{$field} = $existing_term->{$field};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@
|
||||
* Destination class implementing migration into users.
|
||||
*/
|
||||
class MigrateDestinationUser extends MigrateDestinationEntity {
|
||||
|
||||
/**
|
||||
* Indicates whether incoming passwords are md5-encrypted - if so, we will
|
||||
* rehash them similarly to the D6->D7 upgrade path.
|
||||
@@ -68,6 +69,7 @@ class MigrateDestinationUser extends MigrateDestinationEntity {
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
@@ -76,43 +78,43 @@ class MigrateDestinationUser extends MigrateDestinationEntity {
|
||||
$fields = array();
|
||||
// First the core (users table) properties
|
||||
$fields['uid'] = t('<a href="@doc">Existing user ID</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#uid'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#uid'));
|
||||
$fields['mail'] = t('<a href="@doc">Email address</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#mail'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#mail'));
|
||||
$fields['name'] = t('<a href="@doc">Username</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#name'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#name'));
|
||||
$fields['pass'] = t('<a href="@doc">Password</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#pass'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#pass'));
|
||||
$fields['status'] = t('<a href="@doc">Status</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#status'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#status'));
|
||||
$fields['created'] = t('<a href="@doc">Registered timestamp</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#created'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#created'));
|
||||
$fields['access'] = t('<a href="@doc">Last access timestamp</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#access'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#access'));
|
||||
$fields['login'] = t('<a href="@doc">Last login timestamp</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#login'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#login'));
|
||||
$fields['roles'] = t('<a href="@doc">Role IDs</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#roles'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#roles'));
|
||||
$fields['role_names'] = t('<a href="@doc">Role Names</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#role_names'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#role_names'));
|
||||
$fields['picture'] = t('<a href="@doc">Picture</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#picture'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#picture'));
|
||||
$fields['signature'] = t('<a href="@doc">Signature</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#signature'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#signature'));
|
||||
$fields['signature_format'] = t('<a href="@doc">Signature format</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#signature_format'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#signature_format'));
|
||||
$fields['timezone'] = t('<a href="@doc">Timezone</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#timezone'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#timezone'));
|
||||
$fields['language'] = t('<a href="@doc">Language</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#language'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#language'));
|
||||
$fields['theme'] = t('<a href="@doc">Default theme</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#theme'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#theme'));
|
||||
$fields['init'] = t('<a href="@doc">Init</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#init'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#init'));
|
||||
$fields['data'] = t('<a href="@doc">Data</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#init'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#init'));
|
||||
$fields['is_new'] = t('Option: <a href="@doc">Indicates a new user with the specified uid should be created</a>',
|
||||
array('@doc' => 'http://drupal.org/node/1349632#is_new'));
|
||||
array('@doc' => 'http://drupal.org/node/1349632#is_new'));
|
||||
|
||||
// Then add in anything provided by handlers
|
||||
$fields += migrate_handler_invoke_all('Entity', 'fields', $this->entityType, $this->bundle, $migration);
|
||||
@@ -139,9 +141,11 @@ class MigrateDestinationUser extends MigrateDestinationEntity {
|
||||
* Import a single user.
|
||||
*
|
||||
* @param $account
|
||||
* Account object to build. Prefilled with any fields mapped in the Migration.
|
||||
* Account object to build. Prefilled with any fields mapped in the
|
||||
* Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields (uid only in this case) of the user that was saved if
|
||||
* successful. FALSE on failure.
|
||||
@@ -155,7 +159,10 @@ class MigrateDestinationUser extends MigrateDestinationEntity {
|
||||
if (isset($account->uid)) {
|
||||
if ($account->uid != $row->migrate_map_destid1) {
|
||||
throw new MigrateException(t("Incoming uid !uid and map destination uid !destid1 don't match",
|
||||
array('!uid' => $account->uid, '!destid1' => $row->migrate_map_destid1)));
|
||||
array(
|
||||
'!uid' => $account->uid,
|
||||
'!destid1' => $row->migrate_map_destid1,
|
||||
)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -195,7 +202,7 @@ class MigrateDestinationUser extends MigrateDestinationEntity {
|
||||
}
|
||||
$account->roles = drupal_map_assoc($account->roles);
|
||||
}
|
||||
if (empty($account->roles) && empty($old_account->roles)) {
|
||||
if (empty($account->roles) && empty($old_account->roles)) {
|
||||
$account->roles = array();
|
||||
}
|
||||
|
||||
@@ -234,7 +241,7 @@ class MigrateDestinationUser extends MigrateDestinationEntity {
|
||||
MigrateDestinationEntity::fieldAttachValidate('user', $account);
|
||||
|
||||
migrate_instrument_start('user_save');
|
||||
$newaccount = user_save($old_account, (array)$account);
|
||||
$newaccount = user_save($old_account, (array) $account);
|
||||
migrate_instrument_stop('user_save');
|
||||
if ($newaccount) {
|
||||
if ($this->md5Passwords && !empty($account->pass)) {
|
||||
@@ -285,6 +292,7 @@ class MigrateDestinationUser extends MigrateDestinationEntity {
|
||||
}
|
||||
|
||||
class MigrateDestinationRole extends MigrateDestinationTable {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct('role');
|
||||
}
|
||||
@@ -309,7 +317,7 @@ class MigrateDestinationRole extends MigrateDestinationTable {
|
||||
public function rollback(array $id) {
|
||||
migrate_instrument_start('role rollback');
|
||||
$rid = reset($id);
|
||||
user_role_delete((int)$rid);
|
||||
user_role_delete((int) $rid);
|
||||
migrate_instrument_stop('role rollback');
|
||||
}
|
||||
|
||||
@@ -320,6 +328,7 @@ class MigrateDestinationRole extends MigrateDestinationTable {
|
||||
* Object object to build. Prefilled with any fields mapped in the Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields of the object that was saved if
|
||||
* successful. FALSE on failure.
|
||||
@@ -333,7 +342,10 @@ class MigrateDestinationRole extends MigrateDestinationTable {
|
||||
if (isset($entity->rid)) {
|
||||
if ($entity->rid != $row->migrate_map_destid1) {
|
||||
throw new MigrateException(t("Incoming id !id and map destination id !destid don't match",
|
||||
array('!id' => $entity->rid, '!destid' => $row->migrate_map_destid1)));
|
||||
array(
|
||||
'!id' => $entity->rid,
|
||||
'!destid' => $row->migrate_map_destid1,
|
||||
)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -350,7 +362,7 @@ class MigrateDestinationRole extends MigrateDestinationTable {
|
||||
$old_entity = user_role_load($entity->rid);
|
||||
|
||||
foreach ($entity as $field => $value) {
|
||||
$old_entity->$field = $entity->$field;
|
||||
$old_entity->{$field} = $entity->{$field};
|
||||
}
|
||||
$entity = $old_entity;
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@ class MigrateDestinationVariable extends MigrateDestination {
|
||||
*
|
||||
* @param Migration $migration
|
||||
* Optionally, the migration containing this destination.
|
||||
*
|
||||
* @return array
|
||||
* Keys: machine names of the fields (to be passed to addFieldMapping)
|
||||
* Values: Human-friendly descriptions of the fields.
|
||||
@@ -52,9 +53,11 @@ class MigrateDestinationVariable extends MigrateDestination {
|
||||
* Import a single row.
|
||||
*
|
||||
* @param $variable
|
||||
* Variable object to build. Prefilled with any fields mapped in the Migration.
|
||||
* Variable object to build. Prefilled with any fields mapped in the
|
||||
* Migration.
|
||||
* @param $row
|
||||
* Raw source data object - passed through to prepare/complete handlers.
|
||||
*
|
||||
* @return array
|
||||
* Array of key fields of the object that was saved if
|
||||
* successful. FALSE on failure.
|
||||
|
@@ -5,6 +5,213 @@
|
||||
* Define a MigrateSource for importing from comma separated values files.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of MigrateList, for retrieving a list of IDs to be migrated
|
||||
* from a CSV file.
|
||||
*/
|
||||
class MigrateListCSV extends MigrateList {
|
||||
|
||||
/**
|
||||
* The path to the CSV file containing a list of IDs to be processed.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* File handle for the CSV file being iterated.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $csvHandle = NULL;
|
||||
|
||||
/**
|
||||
* The column which contains the ID.
|
||||
*
|
||||
* If numeric, this is the index of the column from 0; if non-numeric, this
|
||||
* is the column name as given by the header row.
|
||||
*/
|
||||
protected $idColumn;
|
||||
|
||||
/**
|
||||
* The number of rows in the CSV file before the data starts.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $headerRows = 0;
|
||||
|
||||
/**
|
||||
* The array keys taken from the first row.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $headers = array();
|
||||
|
||||
/**
|
||||
* Parameters for the fgetcsv() call.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fgetcsv = array();
|
||||
|
||||
/**
|
||||
* Constructor for MigrateListCSV.
|
||||
*
|
||||
* @param $list_path
|
||||
* The path to the CSV file that holds the list of IDs.
|
||||
* @param $id_column
|
||||
* The column in the file that holds the IDs. A numeric index for the column,
|
||||
* from 0.
|
||||
* @param $options = array()
|
||||
* An array of further options for the CSV file.
|
||||
*/
|
||||
public function __construct($list_path, $id_column, $options = array()) {
|
||||
parent::__construct();
|
||||
$this->file = $list_path;
|
||||
$this->idColumn = $id_column;
|
||||
$this->options = $options;
|
||||
|
||||
// fgetcsv specific options
|
||||
foreach (array(
|
||||
'length' => NULL,
|
||||
'delimiter' => ',',
|
||||
'enclosure' => '"',
|
||||
'escape' => '\\',
|
||||
) as $key => $default) {
|
||||
$this->fgetcsv[$key] = isset($options[$key]) ? $options[$key] : $default;
|
||||
}
|
||||
|
||||
if (!empty($options['header_rows'])) {
|
||||
$this->headerRows = $options['header_rows'];
|
||||
}
|
||||
else {
|
||||
$this->headerRows = 0;
|
||||
}
|
||||
|
||||
if (!is_numeric($id_column)) {
|
||||
//we need to store the headers.
|
||||
$this->csvHandle = fopen($this->file, 'r');
|
||||
if (!$this->validResource()) {
|
||||
return;
|
||||
}
|
||||
$this->headers = $this->getNextLine();
|
||||
fclose($this->csvHandle);
|
||||
$this->csvHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representing the source file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of IDs from the CSV file.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getIdList() {
|
||||
$ids = array();
|
||||
|
||||
$this->csvHandle = fopen($this->file, 'r');
|
||||
if (!$this->validResource()) {
|
||||
return $ids;
|
||||
}
|
||||
|
||||
// Skip the headers if any,
|
||||
for ($i = 0; $i < $this->headerRows; $i++) {
|
||||
$this->getNextLine();
|
||||
}
|
||||
|
||||
while ($row = $this->getNextLine()) {
|
||||
$ids[] = $row[$this->idColumn];
|
||||
}
|
||||
|
||||
fclose($this->csvHandle);
|
||||
$this->csvHandle = NULL;
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a count of all available IDs from the source listing.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function computeCount() {
|
||||
// If the data may have embedded newlines, the file line count won't reflect
|
||||
// the number of CSV records (one record will span multiple lines). We need
|
||||
// to scan with fgetcsv to get the true count.
|
||||
if (!empty($this->options['embedded_newlines'])) {
|
||||
$this->csvHandle = fopen($this->file, 'r');
|
||||
$count = 0;
|
||||
if (!$this->validResource()) {
|
||||
return $count;
|
||||
}
|
||||
// Skip all but the last header
|
||||
for ($i = 0; $i < $this->headerRows; $i++) {
|
||||
fgets($this->csvHandle);
|
||||
}
|
||||
while ($this->getNextLine()) {
|
||||
$count++;
|
||||
}
|
||||
fclose($this->csvHandle);
|
||||
$this->csvHandle = NULL;
|
||||
}
|
||||
else {
|
||||
|
||||
$file = new SplFileObject($this->file, 'r');
|
||||
$file->seek(PHP_INT_MAX);
|
||||
$count = $file->key() + 1;
|
||||
$file->rewind();
|
||||
$count -= $this->headerRows;
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next line of the CSV file.
|
||||
* Returns an array of the next line, keyed by headers if required
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getNextLine() {
|
||||
// escape parameter was added in PHP 5.3.
|
||||
if (version_compare(phpversion(), '5.3', '<')) {
|
||||
$row = fgetcsv($this->csvHandle, $this->fgetcsv['length'],
|
||||
$this->fgetcsv['delimiter'], $this->fgetcsv['enclosure']);
|
||||
}
|
||||
else {
|
||||
$row = fgetcsv($this->csvHandle, $this->fgetcsv['length'],
|
||||
$this->fgetcsv['delimiter'], $this->fgetcsv['enclosure'],
|
||||
$this->fgetcsv['escape']);
|
||||
}
|
||||
// Key the array with the headers
|
||||
if (!empty($this->headers) && $row) {
|
||||
$row = array_combine($this->headers, $row);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if resource loaded correctly.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validResource() {
|
||||
if (!$this->csvHandle) {
|
||||
Migration::displayMessage(t('Could not open CSV file !url',
|
||||
array('!url' => $this->file)));
|
||||
}
|
||||
return (bool) $this->csvHandle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of MigrateSource, to handle imports from CSV files.
|
||||
*
|
||||
@@ -12,6 +219,7 @@
|
||||
* UTF BOM (Byte Order Marker) so they are interpreted correctly.
|
||||
*/
|
||||
class MigrateSourceCSV extends MigrateSource {
|
||||
|
||||
/**
|
||||
* List of available source fields.
|
||||
*
|
||||
@@ -47,6 +255,13 @@ class MigrateSourceCSV extends MigrateSource {
|
||||
*/
|
||||
protected $rowNumber;
|
||||
|
||||
/**
|
||||
* The path to the source file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* Simple initialization.
|
||||
*
|
||||
@@ -73,7 +288,12 @@ class MigrateSourceCSV extends MigrateSource {
|
||||
$this->options = $options;
|
||||
$this->fields = $fields;
|
||||
// fgetcsv specific options
|
||||
foreach (array('length' => NULL, 'delimiter' => ',', 'enclosure' => '"', 'escape' => '\\') as $key => $default) {
|
||||
foreach (array(
|
||||
'length' => NULL,
|
||||
'delimiter' => ',',
|
||||
'enclosure' => '"',
|
||||
'escape' => '\\',
|
||||
) as $key => $default) {
|
||||
$this->fgetcsv[$key] = isset($options[$key]) ? $options[$key] : $default;
|
||||
}
|
||||
// One can either pass in an explicit list of column names to use, or if we have
|
||||
@@ -81,6 +301,9 @@ class MigrateSourceCSV extends MigrateSource {
|
||||
if ($this->headerRows && empty($csvcolumns)) {
|
||||
$this->csvcolumns = array();
|
||||
$this->csvHandle = fopen($this->file, 'r');
|
||||
if (!$this->validResource()) {
|
||||
return;
|
||||
}
|
||||
// Skip all but the last header
|
||||
for ($i = 0; $i < $this->headerRows - 1; $i++) {
|
||||
$this->getNextLine();
|
||||
@@ -139,11 +362,14 @@ class MigrateSourceCSV extends MigrateSource {
|
||||
// to scan with fgetcsv to get the true count.
|
||||
if (!empty($this->options['embedded_newlines'])) {
|
||||
$this->csvHandle = fopen($this->file, 'r');
|
||||
$count = 0;
|
||||
if (!$this->validResource()) {
|
||||
return $count;
|
||||
}
|
||||
// Skip all but the last header
|
||||
for ($i = 0; $i < $this->headerRows; $i++) {
|
||||
fgets($this->csvHandle);
|
||||
}
|
||||
$count = 0;
|
||||
while ($this->getNextLine()) {
|
||||
$count++;
|
||||
}
|
||||
@@ -171,6 +397,9 @@ class MigrateSourceCSV extends MigrateSource {
|
||||
}
|
||||
// Load up the first row, skipping the header(s) if necessary
|
||||
$this->csvHandle = fopen($this->file, 'r');
|
||||
if (!$this->validResource()) {
|
||||
return;
|
||||
}
|
||||
for ($i = 0; $i < $this->headerRows; $i++) {
|
||||
$this->getNextLine();
|
||||
}
|
||||
@@ -196,7 +425,7 @@ class MigrateSourceCSV extends MigrateSource {
|
||||
unset($row[$int]);
|
||||
}
|
||||
$row['csvrownum'] = $this->rowNumber++;
|
||||
return (object)$row;
|
||||
return (object) $row;
|
||||
}
|
||||
else {
|
||||
fclose($this->csvHandle);
|
||||
@@ -218,4 +447,18 @@ class MigrateSourceCSV extends MigrateSource {
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if resource loaded correctly.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validResource() {
|
||||
if (!$this->csvHandle) {
|
||||
Migration::displayMessage(t('Could not open CSV file !url',
|
||||
array('!url' => $this->file)));
|
||||
}
|
||||
return (bool) $this->csvHandle;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Implementation of MigrateSource, to handle imports from remote DB2 servers.
|
||||
*/
|
||||
class MigrateSourceDB2 extends MigrateSource {
|
||||
|
||||
/**
|
||||
* Array containing information for connecting to DB2:
|
||||
* database - Database to connect to
|
||||
@@ -25,6 +26,7 @@ class MigrateSourceDB2 extends MigrateSource {
|
||||
* @var resource
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
public function getConnection() {
|
||||
return $this->connection;
|
||||
}
|
||||
@@ -54,7 +56,7 @@ class MigrateSourceDB2 extends MigrateSource {
|
||||
* Simple initialization.
|
||||
*/
|
||||
public function __construct(array $configuration, $query, $count_query,
|
||||
array $fields, array $options = array()) {
|
||||
array $fields, array $options = array()) {
|
||||
parent::__construct($options);
|
||||
$this->query = $query;
|
||||
$this->countQuery = $count_query;
|
||||
|
@@ -23,15 +23,71 @@ define('MIGRATE_CHUNK_SEPARATOR', '-?MIGRATECHUNK?-');
|
||||
* count, and then retrieve each chunk by it's ID.
|
||||
*/
|
||||
abstract class MigrateContentParser {
|
||||
|
||||
/**
|
||||
* Tells the MigrateListFiles implementation to always use chunk IDs when
|
||||
* constructing item IDs.
|
||||
*/
|
||||
public $alwaysUseChunkIDs = FALSE;
|
||||
|
||||
/**
|
||||
* The content of the current file to parse.
|
||||
*/
|
||||
protected $content;
|
||||
|
||||
public function setContent($content) {
|
||||
/**
|
||||
* The ID of the current file being parsed.
|
||||
*/
|
||||
protected $item_id;
|
||||
|
||||
/**
|
||||
* Set the content and file ID for the current file to parse.
|
||||
*
|
||||
* @param $content
|
||||
* The content of the current file to parse.
|
||||
* @param $item_id = NULL
|
||||
* The ID of the file. The chunk IDs are appended to this to form the IDs
|
||||
* that are returned by the MigrateList implementation.
|
||||
*/
|
||||
public function setContent($content, $item_id = NULL) {
|
||||
$this->content = $content;
|
||||
$this->item_id = $item_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of IDs for all the chunks found in the current file.
|
||||
*
|
||||
* Unless $alwaysUseChunkIDs is set to TRUE, this is only called if
|
||||
* getChunkCount() returned a count greater than 1.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* An array of IDs.
|
||||
*/
|
||||
abstract public function getChunkIDs();
|
||||
|
||||
/**
|
||||
* Get a single chunk from the current file.
|
||||
*
|
||||
* @param $id
|
||||
* The ID for the chunk. This is one of the IDs returned by getChunkIDs().
|
||||
*
|
||||
* @return
|
||||
* The content of the chunk.
|
||||
*/
|
||||
abstract public function getChunk($id);
|
||||
|
||||
/**
|
||||
* Return the count of chunks in the current file.
|
||||
*
|
||||
* If this returns 1, then getChunkIDs() is not called and the file is treated
|
||||
* as a single chunk. To override this, set $alwaysUseChunkIDs to TRUE.
|
||||
*
|
||||
* @return int
|
||||
* The number of chunks in the current file.
|
||||
*/
|
||||
abstract public function getChunkCount();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,12 +96,15 @@ abstract class MigrateContentParser {
|
||||
* primarily for when your HTML files map one-to-one to nodes.
|
||||
*/
|
||||
class MigrateSimpleContentParser extends MigrateContentParser {
|
||||
|
||||
public function getChunkIDs() {
|
||||
return array('1');
|
||||
}
|
||||
|
||||
public function getChunk($id) {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function getChunkCount() {
|
||||
return 1;
|
||||
}
|
||||
@@ -54,14 +113,22 @@ class MigrateSimpleContentParser extends MigrateContentParser {
|
||||
/**
|
||||
* Implementation of MigrateList, for retrieving a list of IDs to be migrated
|
||||
* from a directory listing. Each item is a file, it's ID is the path.
|
||||
*
|
||||
* If individual files contain more than one source, use a MigrateContentParser
|
||||
* to parse the file and split it into chunks.
|
||||
*/
|
||||
class MigrateListFiles extends MigrateList {
|
||||
|
||||
protected $listDirs;
|
||||
|
||||
protected $baseDir;
|
||||
|
||||
protected $fileMask;
|
||||
|
||||
protected $directoryOptions;
|
||||
|
||||
protected $parser;
|
||||
|
||||
protected $getContents;
|
||||
|
||||
/**
|
||||
@@ -77,22 +144,25 @@ class MigrateListFiles extends MigrateList {
|
||||
* );
|
||||
* @param $base_dir
|
||||
* The base dir is the part of the path that will be excluded when making
|
||||
* an ID for each file. To continue the example from above, you want base_dir
|
||||
* to be = '/var/html_source', so that the files will have IDs in the format
|
||||
* an ID for each file. To continue the example from above, you want
|
||||
* base_dir to be = '/var/html_source', so that the files will have IDs in
|
||||
* the format
|
||||
* '/en/news/news_2011_03_4.html'.
|
||||
* @param $file_mask
|
||||
* Passed on and used to filter for certain types of files. Use a regular
|
||||
* expression, for example '/(.*\.htm$|.*\.html$)/i' to match all .htm and
|
||||
* .html files, case insensitive.
|
||||
* (optional) Passed on and used to filter for certain types of files. Use
|
||||
* a
|
||||
* regular expression, for example '/(.*\.htm$|.*\.html$)/i' to match all
|
||||
* .htm and .html files, case insensitive. Defaults to matching all files.
|
||||
* @param $options
|
||||
* Options that will be passed on to file_scan_directory(). See docs of that
|
||||
* Options that will be passed on to file_scan_directory(). See docs of
|
||||
* that
|
||||
* core Drupal function for more information.
|
||||
* @param MigrateContentParser $parser
|
||||
* Content parser class to use.
|
||||
* @param $get_contents
|
||||
* Whether to load the contents of files.
|
||||
*/
|
||||
public function __construct($list_dirs, $base_dir, $file_mask = NULL, $options = array(), MigrateContentParser $parser = NULL, $get_contents = TRUE) {
|
||||
public function __construct($list_dirs, $base_dir, $file_mask = '//', $options = array(), MigrateContentParser $parser = NULL, $get_contents = TRUE) {
|
||||
if (!$parser) {
|
||||
$parser = new MigrateSimpleContentParser();
|
||||
}
|
||||
@@ -142,20 +212,21 @@ class MigrateListFiles extends MigrateList {
|
||||
protected function getIDsFromFiles(array $files) {
|
||||
$ids = array();
|
||||
foreach ($files as $file) {
|
||||
$file_base_id = str_replace($this->baseDir, '', (string) $file->uri);
|
||||
if ($this->getContents) {
|
||||
$contents = file_get_contents($file->uri);
|
||||
$this->parser->setContent($contents);
|
||||
if ($this->parser->getChunkCount() > 1) {
|
||||
$this->parser->setContent($contents, $file_base_id);
|
||||
if ($this->parser->alwaysUseChunkIDs || $this->parser->getChunkCount() > 1) {
|
||||
foreach ($this->parser->getChunkIDs() as $chunk_id) {
|
||||
$ids[] = str_replace($this->baseDir, '', (string) $file->uri) . MIGRATE_CHUNK_SEPARATOR . $chunk_id;
|
||||
$ids[] = $file_base_id . MIGRATE_CHUNK_SEPARATOR . $chunk_id;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$ids[] = str_replace($this->baseDir, '', (string) $file->uri);
|
||||
$ids[] = $file_base_id;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$ids[] = str_replace($this->baseDir, '', (string) $file->uri);
|
||||
$ids[] = $file_base_id;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -183,7 +254,9 @@ class MigrateListFiles extends MigrateList {
|
||||
class MigrateItemFile extends MigrateItem {
|
||||
|
||||
protected $baseDir;
|
||||
|
||||
protected $getContents;
|
||||
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
@@ -215,28 +288,30 @@ class MigrateItemFile extends MigrateItem {
|
||||
* The item object for migration.
|
||||
*/
|
||||
public function getItem($id) {
|
||||
$pieces = explode(MIGRATE_CHUNK_SEPARATOR ,$id);
|
||||
$pieces = explode(MIGRATE_CHUNK_SEPARATOR, $id);
|
||||
$item_uri = $this->baseDir . $pieces[0];
|
||||
$chunk = !empty($pieces[1]) ? $pieces[1] : '';
|
||||
|
||||
// Get the file data at the specified URI
|
||||
$data = $this->loadFile($item_uri);
|
||||
if (is_string($data)) {
|
||||
$this->parser->setContent($data);
|
||||
$this->parser->setContent($data, $pieces[0]);
|
||||
$return = new stdClass;
|
||||
$return->filedata = $this->parser->getChunk($chunk);
|
||||
return $return;
|
||||
}
|
||||
else if ($data === TRUE) {
|
||||
$return = new stdClass;
|
||||
return $return;
|
||||
}
|
||||
else {
|
||||
$migration = Migration::currentMigration();
|
||||
$message = t('Loading of !objecturi failed:', array('!objecturi' => $item_uri));
|
||||
$migration->getMap()->saveMessage(
|
||||
array($id), $message, MigrationBase::MESSAGE_ERROR);
|
||||
return NULL;
|
||||
if ($data === TRUE) {
|
||||
$return = new stdClass;
|
||||
return $return;
|
||||
}
|
||||
else {
|
||||
$migration = Migration::currentMigration();
|
||||
$message = t('Loading of !objecturi failed:', array('!objecturi' => $item_uri));
|
||||
$migration->getMap()->saveMessage(
|
||||
array($id), $message, MigrationBase::MESSAGE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,7 @@
|
||||
* from a JSON object.
|
||||
*/
|
||||
class MigrateListJSON extends MigrateList {
|
||||
|
||||
/**
|
||||
* A URL pointing to an JSON object containing a list of IDs to be processed.
|
||||
*
|
||||
@@ -35,7 +36,8 @@ class MigrateListJSON extends MigrateList {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the JSON at the given URL, and return an array of the IDs found within it.
|
||||
* Load the JSON at the given URL, and return an array of the IDs found
|
||||
* within it.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -51,12 +53,12 @@ class MigrateListJSON extends MigrateList {
|
||||
migrate_instrument_stop("Retrieve $this->listUrl");
|
||||
if ($json) {
|
||||
$data = drupal_json_decode($json);
|
||||
if ($data) {
|
||||
if ($data !== NULL) {
|
||||
return $this->getIDsFromJSON($data);
|
||||
}
|
||||
}
|
||||
Migration::displayMessage(t('Loading of !listurl failed:',
|
||||
array('!listurl' => $this->listUrl)));
|
||||
array('!listurl' => $this->listUrl)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -104,6 +106,7 @@ class MigrateListJSON extends MigrateList {
|
||||
* an ID provided by a MigrateList class.
|
||||
*/
|
||||
class MigrateItemJSON extends MigrateItem {
|
||||
|
||||
/**
|
||||
* A URL pointing to a JSON object containing the data for one item to be
|
||||
* migrated.
|
||||
@@ -136,7 +139,7 @@ class MigrateItemJSON extends MigrateItem {
|
||||
}
|
||||
else {
|
||||
$migration = Migration::currentMigration();
|
||||
$message = t('Loading of !objecturl failed:', array('!objecturl' => $item_url));
|
||||
$message = t('Loading of !objecturl failed:', array('!objecturl' => $item_url));
|
||||
$migration->getMap()->saveMessage(
|
||||
array($id), $message, MigrationBase::MESSAGE_ERROR);
|
||||
return NULL;
|
||||
@@ -178,6 +181,7 @@ class MigrateItemJSON extends MigrateItem {
|
||||
* To deal with different structures, extend this class and override next().
|
||||
*/
|
||||
class MigrateJSONReader implements Iterator {
|
||||
|
||||
/**
|
||||
* URL of the source JSON file.
|
||||
*
|
||||
@@ -242,7 +246,8 @@ class MigrateJSONReader implements Iterator {
|
||||
* The next non-whitespace character, or FALSE on end-of-file.
|
||||
*/
|
||||
protected function getNonBlank() {
|
||||
while (($c = fgetc($this->fileHandle)) !== FALSE && trim($c) == '') {}
|
||||
while (($c = fgetc($this->fileHandle)) !== FALSE && trim($c) == '') {
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
@@ -266,7 +271,7 @@ class MigrateJSONReader implements Iterator {
|
||||
$this->fileHandle = fopen($this->url, 'r');
|
||||
if (!$this->fileHandle) {
|
||||
Migration::displayMessage(t('Could not open JSON file !url',
|
||||
array('!url' => $this->url)));
|
||||
array('!url' => $this->url)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -278,7 +283,7 @@ class MigrateJSONReader implements Iterator {
|
||||
}
|
||||
if ($char != '[') {
|
||||
Migration::displayMessage(t('!url is not a JSON file containing an array of objects',
|
||||
array('!url' => $this->url)));
|
||||
array('!url' => $this->url)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -390,9 +395,11 @@ class MigrateJSONReader implements Iterator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of MigrateSource, to handle imports from stand-alone JSON files.
|
||||
* Implementation of MigrateSource, to handle imports from stand-alone JSON
|
||||
* files.
|
||||
*/
|
||||
class MigrateSourceJSON extends MigrateSource {
|
||||
|
||||
/**
|
||||
* The MigrateJSONReader object serving as a cursor over the JSON source file.
|
||||
*
|
||||
@@ -402,6 +409,7 @@ class MigrateSourceJSON extends MigrateSource {
|
||||
|
||||
/**
|
||||
* Name of the field within the JSON object holding the ID value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $idField;
|
||||
@@ -454,7 +462,7 @@ class MigrateSourceJSON extends MigrateSource {
|
||||
* MigrateJSONReader).
|
||||
*/
|
||||
public function __construct($urls, $id_field, array $fields = array(),
|
||||
array $options = array()) {
|
||||
array $options = array()) {
|
||||
parent::__construct($options);
|
||||
$this->idField = $id_field;
|
||||
if (empty($options['reader_class'])) {
|
||||
@@ -581,7 +589,7 @@ class MigrateSourceJSON extends MigrateSource {
|
||||
// Return value
|
||||
$status = FALSE;
|
||||
|
||||
while ($this->activeUrl === NULL || (count($this->sourceUrls)-1) > $this->activeUrl) {
|
||||
while ($this->activeUrl === NULL || (count($this->sourceUrls) - 1) > $this->activeUrl) {
|
||||
if (is_null($this->activeUrl)) {
|
||||
$this->activeUrl = 0;
|
||||
}
|
||||
|
@@ -15,7 +15,9 @@
|
||||
* obtain a list of IDs from an XML document).
|
||||
*/
|
||||
abstract class MigrateList {
|
||||
public function __construct() {}
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementors are expected to return a string representing where the listing
|
||||
@@ -34,7 +36,8 @@ abstract class MigrateList {
|
||||
abstract public function getIdList();
|
||||
|
||||
/**
|
||||
* Implementors are expected to return a count of IDs available to be migrated.
|
||||
* Implementors are expected to return a count of IDs available to be
|
||||
* migrated.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -46,7 +49,9 @@ abstract class MigrateList {
|
||||
* given migratable item given its ID as provided by the MigrateList class.
|
||||
*/
|
||||
abstract class MigrateItem {
|
||||
public function __construct() {}
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementors are expected to return an object representing a source item.
|
||||
@@ -74,6 +79,7 @@ abstract class MigrateItem {
|
||||
* IDs provided by a MigrateList and retrieving data from a MigrateItem.
|
||||
*/
|
||||
class MigrateSourceList extends MigrateSource {
|
||||
|
||||
/**
|
||||
* MigrateList object used to obtain ID lists.
|
||||
*
|
||||
@@ -105,8 +111,7 @@ class MigrateSourceList extends MigrateSource {
|
||||
/**
|
||||
* Simple initialization.
|
||||
*/
|
||||
public function __construct(MigrateList $list_class, MigrateItem $item_class, $fields = array(),
|
||||
$options = array()) {
|
||||
public function __construct(MigrateList $list_class, MigrateItem $item_class, $fields = array(), $options = array()) {
|
||||
parent::__construct($options);
|
||||
$this->listClass = $list_class;
|
||||
$this->itemClass = $item_class;
|
||||
@@ -122,6 +127,15 @@ class MigrateSourceList extends MigrateSource {
|
||||
return (string) $this->listClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return MigrateList object used to obtain ID lists.
|
||||
*
|
||||
* @return MigrateList
|
||||
*/
|
||||
public function listClass() {
|
||||
return $this->listClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of fields available to be mapped from the source query.
|
||||
* Since we can't reliably figure out what "fields" are in the source,
|
||||
@@ -195,8 +209,9 @@ class MigrateSourceList extends MigrateSource {
|
||||
foreach (array_keys($this->activeMap->getSourceKey()) as $key_name) {
|
||||
// Grab the first id and advance the array cursor. Then save the ID
|
||||
// using the map source key - it will be used for mapping.
|
||||
list(, $id) = each($ids);
|
||||
$row->$key_name = $id;
|
||||
$id = current($ids);
|
||||
next($ids);
|
||||
$row->{$key_name} = $id;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Implementation of MigrateSource, to handle imports from MongoDB connections.
|
||||
*/
|
||||
class MigrateSourceMongoDB extends MigrateSource {
|
||||
|
||||
/**
|
||||
* The mongodb collection object.
|
||||
*
|
||||
@@ -41,8 +42,8 @@ class MigrateSourceMongoDB extends MigrateSource {
|
||||
* Simple initialization.
|
||||
*/
|
||||
public function __construct(MongoCollection $collection, array $query,
|
||||
array $fields = array(), array $sort = array('_id' => 1),
|
||||
array $options = array()) {
|
||||
array $fields = array(), array $sort = array('_id' => 1),
|
||||
array $options = array()) {
|
||||
parent::__construct($options);
|
||||
|
||||
$this->collection = $collection;
|
||||
@@ -106,8 +107,8 @@ class MigrateSourceMongoDB extends MigrateSource {
|
||||
migrate_instrument_start('MigrateSourceMongoDB execute');
|
||||
try {
|
||||
$this->cursor = $this->collection
|
||||
->find($this->query)
|
||||
->sort($this->sort);
|
||||
->find($this->query)
|
||||
->sort($this->sort);
|
||||
$this->cursor->timeout(-1);
|
||||
} catch (MongoCursorException $e) {
|
||||
Migration::displayMessage($e->getMessage(), 'error');
|
||||
@@ -123,20 +124,20 @@ class MigrateSourceMongoDB extends MigrateSource {
|
||||
public function __toString() {
|
||||
if (is_null($this->cursor)) {
|
||||
$this->cursor = $this->collection
|
||||
->find($this->query)
|
||||
->sort($this->sort);
|
||||
->find($this->query)
|
||||
->sort($this->sort);
|
||||
$this->cursor->timeout(-1);
|
||||
}
|
||||
|
||||
$query_info = $this->cursor->info();
|
||||
|
||||
$query = 'query: ' . drupal_json_encode($query_info['query']['$query']);
|
||||
$sort = 'order by: ' . drupal_json_encode($query_info['query']['$orderby']);
|
||||
$query = 'query: ' . drupal_json_encode($query_info['query']['$query']);
|
||||
$sort = 'order by: ' . drupal_json_encode($query_info['query']['$orderby']);
|
||||
$fields = 'fields: ' . drupal_json_encode($query_info['fields']);
|
||||
|
||||
return $query . PHP_EOL .
|
||||
$sort . PHP_EOL .
|
||||
$fields . PHP_EOL;
|
||||
$sort . PHP_EOL .
|
||||
$fields . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,13 +148,14 @@ class MigrateSourceMongoDB extends MigrateSource {
|
||||
* Document key value.
|
||||
* @param array $keys
|
||||
* List of keys.
|
||||
*
|
||||
* @return type
|
||||
*/
|
||||
public function getMongoId($document_id, $keys) {
|
||||
if ($keys[0]['name'] != '_id') {
|
||||
switch ($keys[0]['type']) {
|
||||
case 'int':
|
||||
return (int)$document_id;
|
||||
return (int) $document_id;
|
||||
break;
|
||||
default:
|
||||
return $document_id;
|
||||
|
@@ -6,9 +6,11 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of MigrateSource, to handle imports from remote MS SQL Server db servers.
|
||||
* Implementation of MigrateSource, to handle imports from remote MS SQL Server
|
||||
* db servers.
|
||||
*/
|
||||
class MigrateSourceMSSQL extends MigrateSource {
|
||||
|
||||
/**
|
||||
* Array containing information for connecting to SQL Server:
|
||||
* servername - Hostname of the SQL Server
|
||||
@@ -62,7 +64,7 @@ class MigrateSourceMSSQL extends MigrateSource {
|
||||
* Simple initialization.
|
||||
*/
|
||||
public function __construct(array $configuration, $query, $count_query,
|
||||
array $fields, array $options = array()) {
|
||||
array $fields, array $options = array()) {
|
||||
parent::__construct($options);
|
||||
$this->query = $query;
|
||||
$this->countQuery = $count_query;
|
||||
|
@@ -14,7 +14,9 @@
|
||||
* to obtain the data for a given migratable item given its ID.
|
||||
*/
|
||||
abstract class MigrateItems {
|
||||
public function __construct() {}
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementors are expected to return a string representing where the listing
|
||||
@@ -33,7 +35,8 @@ abstract class MigrateItems {
|
||||
abstract public function getIdList();
|
||||
|
||||
/**
|
||||
* Implementors are expected to return a count of IDs available to be migrated.
|
||||
* Implementors are expected to return a count of IDs available to be
|
||||
* migrated.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -70,6 +73,7 @@ abstract class MigrateItems {
|
||||
* IDs provided by a MigrateItems and retrieving data from a MigrateItems.
|
||||
*/
|
||||
class MigrateSourceMultiItems extends MigrateSource {
|
||||
|
||||
/**
|
||||
* MigrateItems object used to obtain the list of IDs and source for
|
||||
* all objects.
|
||||
@@ -137,7 +141,7 @@ class MigrateSourceMultiItems extends MigrateSource {
|
||||
* @return int
|
||||
*/
|
||||
public function computeCount() {
|
||||
// @API: Support old count method for now.
|
||||
// @API: Support old count method for now.
|
||||
if (method_exists($this->itemsClass, 'computeCount')) {
|
||||
return $this->itemsClass->computeCount();
|
||||
}
|
||||
@@ -156,8 +160,8 @@ class MigrateSourceMultiItems extends MigrateSource {
|
||||
if ($this->idList) {
|
||||
$this->idsToProcess = $this->idList;
|
||||
}
|
||||
else {
|
||||
$this->idsToProcess = $this->itemsClass->getIdList();
|
||||
elseif (!$this->idsToProcess = $this->itemsClass->getIdList()) {
|
||||
$this->idsToProcess = array();
|
||||
}
|
||||
$this->idIterator = ($this->idsToProcess instanceof Iterator) ?
|
||||
$this->idsToProcess : new ArrayIterator($this->idsToProcess);
|
||||
@@ -186,7 +190,7 @@ class MigrateSourceMultiItems extends MigrateSource {
|
||||
// Save the ID using the map source key - it will be used for mapping
|
||||
$sourceKey = $this->activeMap->getSourceKey();
|
||||
$key_name = key($sourceKey);
|
||||
$row->$key_name = $id;
|
||||
$row->{$key_name} = $id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -6,14 +6,17 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of MigrateSource, to handle imports from remote Oracle servers.
|
||||
* Implementation of MigrateSource, to handle imports from remote Oracle
|
||||
* servers.
|
||||
*/
|
||||
class MigrateSourceOracle extends MigrateSource {
|
||||
|
||||
/**
|
||||
* Array containing information for connecting to Oracle:
|
||||
* username - Username to connect as
|
||||
* password - Password for logging in
|
||||
* connection_string - See http://us.php.net/manual/en/function.oci-connect.php.
|
||||
* connection_string - See
|
||||
* http://us.php.net/manual/en/function.oci-connect.php.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@@ -25,6 +28,7 @@ class MigrateSourceOracle extends MigrateSource {
|
||||
* @var resource
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
public function getConnection() {
|
||||
return $this->connection;
|
||||
}
|
||||
@@ -63,7 +67,7 @@ class MigrateSourceOracle extends MigrateSource {
|
||||
* Simple initialization.
|
||||
*/
|
||||
public function __construct(array $configuration, $query, $count_query,
|
||||
array $fields, array $options = array()) {
|
||||
array $fields, array $options = array()) {
|
||||
parent::__construct($options);
|
||||
$this->query = $query;
|
||||
$this->countQuery = $count_query;
|
||||
@@ -206,13 +210,13 @@ class MigrateSourceOracle extends MigrateSource {
|
||||
* Implementation of MigrateSource::getNextRow().
|
||||
*
|
||||
* Returns the next row of the result set as an object, making sure NULLs are
|
||||
* represented as PHP NULLs and that LOBs are returned directly without special
|
||||
* handling.
|
||||
* represented as PHP NULLs and that LOBs are returned directly without
|
||||
* special handling.
|
||||
*/
|
||||
public function getNextRow() {
|
||||
$row = oci_fetch_array($this->result, OCI_ASSOC | OCI_RETURN_NULLS | OCI_RETURN_LOBS);
|
||||
if (!empty($row)) {
|
||||
return (object)$row;
|
||||
return (object) $row;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
|
@@ -17,6 +17,7 @@
|
||||
* Implements MigrateSource, to handle imports from XLS files.
|
||||
*/
|
||||
class MigrateSourceSpreadsheet extends MigrateSource {
|
||||
|
||||
/**
|
||||
* PHPExcel object for storing the workbook data.
|
||||
*
|
||||
@@ -62,7 +63,8 @@ class MigrateSourceSpreadsheet extends MigrateSource {
|
||||
/**
|
||||
* The current row number in the XLS file.
|
||||
*
|
||||
* @var integer+ */
|
||||
* @var integer+
|
||||
*/
|
||||
protected $rowNumber;
|
||||
|
||||
/**
|
||||
@@ -70,6 +72,13 @@ class MigrateSourceSpreadsheet extends MigrateSource {
|
||||
*/
|
||||
protected $columns;
|
||||
|
||||
/**
|
||||
* The first row from where the table starts. It's a "zero based" value.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headerRows = 0;
|
||||
|
||||
/**
|
||||
* Simple initialization.
|
||||
*
|
||||
@@ -78,13 +87,18 @@ class MigrateSourceSpreadsheet extends MigrateSource {
|
||||
* @param string $sheet_name
|
||||
* The name of the sheet to be processed.
|
||||
* @param array $options
|
||||
* Options applied to this source.
|
||||
* Options applied to this source. If the source data begins on different
|
||||
* row than the first row, pass this "zero based" value as 'header_rows' in
|
||||
* options, along with other options inherited from MigrateSource.
|
||||
*/
|
||||
public function __construct($path, $sheet_name, $columns = array(), array $options = array()) {
|
||||
parent::__construct($options);
|
||||
$this->file = $path;
|
||||
$this->sheetName = $sheet_name;
|
||||
$this->columns = $columns;
|
||||
if (!empty($options['header_rows'])) {
|
||||
$this->headerRows = $options['header_rows'];
|
||||
}
|
||||
|
||||
// Load the workbook.
|
||||
if ($this->load()) {
|
||||
@@ -94,7 +108,8 @@ class MigrateSourceSpreadsheet extends MigrateSource {
|
||||
|
||||
// Map field names to their column index.
|
||||
for ($col = 0; $col < $this->cols; ++$col) {
|
||||
$this->fields[$col] = trim($this->worksheet->getCellByColumnAndRow($col, 1)->getValue());
|
||||
$this->fields[$col] = trim($this->worksheet->getCellByColumnAndRow($col, $this->headerRows + 1)
|
||||
->getValue());
|
||||
}
|
||||
|
||||
$this->unload();
|
||||
@@ -143,8 +158,7 @@ class MigrateSourceSpreadsheet extends MigrateSource {
|
||||
// Load the source file.
|
||||
$this->workbook = $reader->load($this->file);
|
||||
$this->worksheet = $this->workbook->getSheet();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
Migration::displayMessage(t('Error loading file: %message', array('%message' => $e->getMessage())));
|
||||
return FALSE;
|
||||
}
|
||||
@@ -190,8 +204,8 @@ class MigrateSourceSpreadsheet extends MigrateSource {
|
||||
* Returns a count of all available source records.
|
||||
*/
|
||||
public function computeCount() {
|
||||
// Subtract 1 for the header.
|
||||
return $this->rows - 1;
|
||||
// Subtract the non-data rows (rows before header and the header).
|
||||
return $this->rows - $this->headerRows - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,7 +219,7 @@ class MigrateSourceSpreadsheet extends MigrateSource {
|
||||
$this->load();
|
||||
}
|
||||
|
||||
$this->rowNumber = 1;
|
||||
$this->rowNumber = $this->headerRows + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,8 +235,9 @@ class MigrateSourceSpreadsheet extends MigrateSource {
|
||||
$row_values = array();
|
||||
for ($col = 0; $col < $this->cols; ++$col) {
|
||||
if (in_array($this->fields[$col], $this->columns) || empty($this->columns)) {
|
||||
$row_values[$this->fields[$col]] = trim($this->worksheet->getCellByColumnAndRow($col, $this->rowNumber)->getValue());
|
||||
}
|
||||
$row_values[$this->fields[$col]] = trim($this->worksheet->getCellByColumnAndRow($col, $this->rowNumber)
|
||||
->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return (object) $row_values;
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Implementation of MigrateSource, to handle imports from Drupal connections.
|
||||
*/
|
||||
class MigrateSourceSQL extends MigrateSource {
|
||||
|
||||
/**
|
||||
* The SQL query objects from which to obtain data, and counts of data
|
||||
*
|
||||
@@ -72,6 +73,7 @@ class MigrateSourceSQL extends MigrateSource {
|
||||
* @var boolean
|
||||
*/
|
||||
protected $mapJoinable = FALSE;
|
||||
|
||||
// Dynamically set whether the map is joinable - not really for production use,
|
||||
// this is primarily to support simpletests
|
||||
public function setMapJoinable($map_joinable) {
|
||||
@@ -97,7 +99,8 @@ class MigrateSourceSQL extends MigrateSource {
|
||||
* Return an options array for PDO sources.
|
||||
*
|
||||
* @param boolean $map_joinable
|
||||
* Indicates whether the map table can be joined directly to the source query.
|
||||
* Indicates whether the map table can be joined directly to the source
|
||||
* query.
|
||||
* @param boolean $cache_counts
|
||||
* Indicates whether to cache counts of source records.
|
||||
*/
|
||||
@@ -121,7 +124,7 @@ class MigrateSourceSQL extends MigrateSource {
|
||||
* Options applied to this source.
|
||||
*/
|
||||
public function __construct(SelectQueryInterface $query, array $fields = array(),
|
||||
SelectQueryInterface $count_query = NULL, array $options = array()) {
|
||||
SelectQueryInterface $count_query = NULL, array $options = array()) {
|
||||
parent::__construct($options);
|
||||
$this->originalQuery = $query;
|
||||
$this->query = clone $query;
|
||||
@@ -153,30 +156,30 @@ class MigrateSourceSQL extends MigrateSource {
|
||||
// directly to the query, but this won't work unless/until
|
||||
// http://drupal.org/node/802514 is committed, assume joinable for now
|
||||
$this->mapJoinable = TRUE;
|
||||
/* // To be able to join the map directly, it must be a PDO map on the same
|
||||
// connection, or a compatible connection
|
||||
$map = $migration->getMap();
|
||||
if (is_a($map, 'MigrateSQLMap')) {
|
||||
$map_options = $map->getConnection()->getConnectionOptions();
|
||||
$query_options = $this->query->connection()->getConnectionOptions();
|
||||
/* // To be able to join the map directly, it must be a PDO map on the same
|
||||
// connection, or a compatible connection
|
||||
$map = $migration->getMap();
|
||||
if (is_a($map, 'MigrateSQLMap')) {
|
||||
$map_options = $map->getConnection()->getConnectionOptions();
|
||||
$query_options = $this->query->connection()->getConnectionOptions();
|
||||
|
||||
// Identical options means it will work
|
||||
if ($map_options == $query_options) {
|
||||
$this->mapJoinable = TRUE;
|
||||
}
|
||||
else {
|
||||
// Otherwise, the one scenario we know will work is if it's MySQL and
|
||||
// the credentials match (SQLite too?)
|
||||
if ($map_options['driver'] == 'mysql' && $query_options['driver'] == 'mysql') {
|
||||
if ($map_options['host'] == $query_options['host'] &&
|
||||
$map_options['port'] == $query_options['port'] &&
|
||||
$map_options['username'] == $query_options['username'] &&
|
||||
$map_options['password'] == $query_options['password']) {
|
||||
$this->mapJoinable = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
// Identical options means it will work
|
||||
if ($map_options == $query_options) {
|
||||
$this->mapJoinable = TRUE;
|
||||
}
|
||||
else {
|
||||
// Otherwise, the one scenario we know will work is if it's MySQL and
|
||||
// the credentials match (SQLite too?)
|
||||
if ($map_options['driver'] == 'mysql' && $query_options['driver'] == 'mysql') {
|
||||
if ($map_options['host'] == $query_options['host'] &&
|
||||
$map_options['port'] == $query_options['port'] &&
|
||||
$map_options['username'] == $query_options['username'] &&
|
||||
$map_options['password'] == $query_options['password']) {
|
||||
$this->mapJoinable = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,26 +223,26 @@ class MigrateSourceSQL extends MigrateSource {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle queries without explicit field lists
|
||||
* TODO: Waiting on http://drupal.org/node/814312
|
||||
$info = Database::getConnectionInfo($query->getConnection());
|
||||
$database = $info['default']['database'];
|
||||
foreach ($this->query->getTables() as $table) {
|
||||
if (isset($table['all_fields']) && $table['all_fields']) {
|
||||
/*
|
||||
* Handle queries without explicit field lists
|
||||
* TODO: Waiting on http://drupal.org/node/814312
|
||||
$info = Database::getConnectionInfo($query->getConnection());
|
||||
$database = $info['default']['database'];
|
||||
foreach ($this->query->getTables() as $table) {
|
||||
if (isset($table['all_fields']) && $table['all_fields']) {
|
||||
|
||||
$database = 'plants';
|
||||
$table = $table['table'];
|
||||
$sql = 'SELECT column_name
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema=:database AND table_name = :table
|
||||
ORDER BY ordinal_position';
|
||||
$result = dbtng_query($sql, array(':database' => $database, ':table' => $table));
|
||||
foreach ($result as $row) {
|
||||
$fields[$row->column_name] = $table . '.' . $row->column_name;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
$database = 'plants';
|
||||
$table = $table['table'];
|
||||
$sql = 'SELECT column_name
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema=:database AND table_name = :table
|
||||
ORDER BY ordinal_position';
|
||||
$result = dbtng_query($sql, array(':database' => $database, ':table' => $table));
|
||||
foreach ($result as $row) {
|
||||
$fields[$row->column_name] = $table . '.' . $row->column_name;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
$expressionFields = $this->query->getExpressions();
|
||||
foreach ($expressionFields as $field_name => $field_info) {
|
||||
$fields[$field_name] = $field_info['alias'];
|
||||
@@ -355,7 +358,7 @@ class MigrateSourceSQL extends MigrateSource {
|
||||
}
|
||||
|
||||
$alias = $this->query->leftJoin($this->activeMap->getQualifiedMapTable(),
|
||||
'map', $map_join);
|
||||
'map', $map_join);
|
||||
$conditions->isNull($alias . '.sourceid1');
|
||||
$conditions->condition($alias . '.needs_update', MigrateMap::STATUS_NEEDS_UPDATE);
|
||||
$condition_added = TRUE;
|
||||
|
@@ -6,15 +6,18 @@
|
||||
*/
|
||||
|
||||
class MigrateSQLMap extends MigrateMap {
|
||||
|
||||
/**
|
||||
* Names of tables created for tracking the migration.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $mapTable, $messageTable;
|
||||
|
||||
public function getMapTable() {
|
||||
return $this->mapTable;
|
||||
}
|
||||
|
||||
public function getMessageTable() {
|
||||
return $this->messageTable;
|
||||
}
|
||||
@@ -36,7 +39,13 @@ class MigrateSQLMap extends MigrateMap {
|
||||
return $this->mapTable;
|
||||
}
|
||||
else {
|
||||
return $options['database'] . '.' . $this->mapTable;
|
||||
$dbname = $options['database'];
|
||||
|
||||
if (!empty($options['driver']) && $options['driver'] == 'mysql') {
|
||||
// Backtick the db name on mysql to ensure dbs with hyphens work.
|
||||
$dbname = "`{$dbname}`";
|
||||
}
|
||||
return $dbname . '.' . $this->mapTable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,15 +58,18 @@ class MigrateSQLMap extends MigrateMap {
|
||||
public function getSourceKey() {
|
||||
return $this->sourceKey;
|
||||
}
|
||||
|
||||
public function getDestinationKey() {
|
||||
return $this->destinationKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drupal connection object on which to create the map/message tables
|
||||
*
|
||||
* @var DatabaseConnection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
public function getConnection() {
|
||||
return $this->connection;
|
||||
}
|
||||
@@ -84,7 +96,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
* @param array $destination_key
|
||||
* The database schema for the destination key.
|
||||
* @param string $connection_key
|
||||
* Optional - The connection used to create the mapping tables. By default
|
||||
* Optional - The connection used to create the mapping tables. By default
|
||||
* this is the destination (Drupal). If it's not possible to make joins
|
||||
* between the destination database and your source database you can specify
|
||||
* a different connection to create the mapping tables on.
|
||||
@@ -92,7 +104,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
* Optional - Options applied to this source.
|
||||
*/
|
||||
public function __construct($machine_name, array $source_key,
|
||||
array $destination_key, $connection_key = 'default', $options = array()) {
|
||||
array $destination_key, $connection_key = 'default', $options = array()) {
|
||||
if (isset($options['track_last_imported'])) {
|
||||
$this->trackLastImported = TRUE;
|
||||
}
|
||||
@@ -107,7 +119,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
$this->connection = Database::getConnection('default', $connection_key);
|
||||
|
||||
// Default generated table names, limited to 63 characters
|
||||
$prefixLength = strlen($this->connection->tablePrefix()) ;
|
||||
$prefixLength = strlen($this->connection->tablePrefix());
|
||||
$this->mapTable = 'migrate_map_' . drupal_strtolower($machine_name);
|
||||
$this->mapTable = drupal_substr($this->mapTable, 0, 63 - $prefixLength);
|
||||
$this->messageTable = 'migrate_message_' . drupal_strtolower($machine_name);
|
||||
@@ -143,6 +155,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
foreach ($this->sourceKey as $field_schema) {
|
||||
$mapkey = 'sourceid' . $count++;
|
||||
$source_key_schema[$mapkey] = $field_schema;
|
||||
$source_key_schema[$mapkey]['not null'] = TRUE;
|
||||
$pks[] = $mapkey;
|
||||
}
|
||||
|
||||
@@ -154,6 +167,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
foreach ($this->destinationKey as $field_schema) {
|
||||
// Allow dest key fields to be NULL (for IGNORED/FAILED cases)
|
||||
$field_schema['not null'] = FALSE;
|
||||
$field_schema['default'] = NULL;
|
||||
$mapkey = 'destid' . $count++;
|
||||
$fields[$mapkey] = $field_schema;
|
||||
}
|
||||
@@ -224,18 +238,19 @@ class MigrateSQLMap extends MigrateMap {
|
||||
else {
|
||||
// Add any missing columns to the map table
|
||||
if (!$this->connection->schema()->fieldExists($this->mapTable,
|
||||
'rollback_action')) {
|
||||
'rollback_action')) {
|
||||
$this->connection->schema()->addField($this->mapTable,
|
||||
'rollback_action', array(
|
||||
'type' => 'int',
|
||||
'size' => 'tiny',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => 'Flag indicating what to do for this item on rollback',
|
||||
));
|
||||
'rollback_action', array(
|
||||
'type' => 'int',
|
||||
'size' => 'tiny',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => 'Flag indicating what to do for this item on rollback',
|
||||
));
|
||||
}
|
||||
if (!$this->connection->schema()->fieldExists($this->mapTable, 'hash')) {
|
||||
if (!$this->connection->schema()
|
||||
->fieldExists($this->mapTable, 'hash')) {
|
||||
$this->connection->schema()->addField($this->mapTable, 'hash', array(
|
||||
'type' => 'varchar',
|
||||
'length' => '32',
|
||||
@@ -256,7 +271,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
public function getRowBySource(array $source_id) {
|
||||
migrate_instrument_start('mapRowBySource');
|
||||
$query = $this->connection->select($this->mapTable, 'map')
|
||||
->fields('map');
|
||||
->fields('map');
|
||||
foreach ($this->sourceKeyMap as $key_name) {
|
||||
$query = $query->condition("map.$key_name", array_shift($source_id), '=');
|
||||
}
|
||||
@@ -273,7 +288,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
public function getRowByDestination(array $destination_id) {
|
||||
migrate_instrument_start('getRowByDestination');
|
||||
$query = $this->connection->select($this->mapTable, 'map')
|
||||
->fields('map');
|
||||
->fields('map');
|
||||
foreach ($this->destinationKeyMap as $key_name) {
|
||||
$query = $query->condition("map.$key_name", array_shift($destination_id), '=');
|
||||
}
|
||||
@@ -287,16 +302,17 @@ class MigrateSQLMap extends MigrateMap {
|
||||
*
|
||||
* @param int $count
|
||||
* Maximum rows to return; defaults to 10,000
|
||||
*
|
||||
* @return array
|
||||
* Array of map row objects with needs_update==1.
|
||||
*/
|
||||
public function getRowsNeedingUpdate($count) {
|
||||
$rows = array();
|
||||
$result = $this->connection->select($this->mapTable, 'map')
|
||||
->fields('map')
|
||||
->condition('needs_update', MigrateMap::STATUS_NEEDS_UPDATE)
|
||||
->range(0, $count)
|
||||
->execute();
|
||||
->fields('map')
|
||||
->condition('needs_update', MigrateMap::STATUS_NEEDS_UPDATE)
|
||||
->range(0, $count)
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
$rows[] = $row;
|
||||
}
|
||||
@@ -304,11 +320,12 @@ class MigrateSQLMap extends MigrateMap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a (possibly multi-field) destination key, return the (possibly multi-field)
|
||||
* source key mapped to it.
|
||||
* Given a (possibly multi-field) destination key, return the (possibly
|
||||
* multi-field) source key mapped to it.
|
||||
*
|
||||
* @param array $destination_id
|
||||
* Array of destination key values.
|
||||
*
|
||||
* @return array
|
||||
* Array of source key values, or NULL on failure.
|
||||
*/
|
||||
@@ -325,7 +342,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
}
|
||||
|
||||
$query = $this->connection->select($this->mapTable, 'map')
|
||||
->fields('map', $this->sourceKeyMap);
|
||||
->fields('map', $this->sourceKeyMap);
|
||||
foreach ($this->destinationKeyMap as $key_name) {
|
||||
$query = $query->condition("map.$key_name", array_shift($destination_id), '=');
|
||||
}
|
||||
@@ -342,11 +359,12 @@ class MigrateSQLMap extends MigrateMap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a (possibly multi-field) source key, return the (possibly multi-field)
|
||||
* destination key it is mapped to.
|
||||
* Given a (possibly multi-field) source key, return the (possibly
|
||||
* multi-field) destination key it is mapped to.
|
||||
*
|
||||
* @param array $source_id
|
||||
* Array of source key values.
|
||||
*
|
||||
* @return array
|
||||
* Array of destination key values, or NULL on failure.
|
||||
*/
|
||||
@@ -363,7 +381,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
}
|
||||
|
||||
$query = $this->connection->select($this->mapTable, 'map')
|
||||
->fields('map', $this->destinationKeyMap);
|
||||
->fields('map', $this->destinationKeyMap);
|
||||
foreach ($this->sourceKeyMap as $key_name) {
|
||||
$query = $query->condition("map.$key_name", array_shift($source_id), '=');
|
||||
}
|
||||
@@ -378,6 +396,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
migrate_instrument_stop('lookupDestinationID');
|
||||
return $destination_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called upon import of one record, we record a mapping from the source key
|
||||
* to the destination key. Also may be called, setting the third parameter to
|
||||
@@ -397,26 +416,26 @@ class MigrateSQLMap extends MigrateMap {
|
||||
* If hashing is enabled, the hash of the raw source row.
|
||||
*/
|
||||
public function saveIDMapping(stdClass $source_row, array $dest_ids,
|
||||
$needs_update = MigrateMap::STATUS_IMPORTED,
|
||||
$rollback_action = MigrateMap::ROLLBACK_DELETE, $hash = NULL) {
|
||||
$needs_update = MigrateMap::STATUS_IMPORTED,
|
||||
$rollback_action = MigrateMap::ROLLBACK_DELETE, $hash = NULL) {
|
||||
migrate_instrument_start('saveIDMapping');
|
||||
// Construct the source key
|
||||
$keys = array();
|
||||
foreach ($this->sourceKeyMap as $field_name => $key_name) {
|
||||
// A NULL key value will fail.
|
||||
if (is_null($source_row->$field_name)) {
|
||||
if (is_null($source_row->{$field_name})) {
|
||||
Migration::displayMessage(t(
|
||||
'Could not save to map table due to NULL value for key field !field',
|
||||
array('!field' => $field_name)));
|
||||
migrate_instrument_stop('saveIDMapping');
|
||||
return;
|
||||
}
|
||||
$keys[$key_name] = $source_row->$field_name;
|
||||
$keys[$key_name] = $source_row->{$field_name};
|
||||
}
|
||||
|
||||
$fields = array(
|
||||
'needs_update' => (int)$needs_update,
|
||||
'rollback_action' => (int)$rollback_action,
|
||||
'needs_update' => (int) $needs_update,
|
||||
'rollback_action' => (int) $rollback_action,
|
||||
'hash' => $hash,
|
||||
);
|
||||
$count = 1;
|
||||
@@ -476,8 +495,8 @@ class MigrateSQLMap extends MigrateMap {
|
||||
*/
|
||||
public function prepareUpdate() {
|
||||
$this->connection->update($this->mapTable)
|
||||
->fields(array('needs_update' => MigrateMap::STATUS_NEEDS_UPDATE))
|
||||
->execute();
|
||||
->fields(array('needs_update' => MigrateMap::STATUS_NEEDS_UPDATE))
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -501,7 +520,10 @@ class MigrateSQLMap extends MigrateMap {
|
||||
public function importedCount() {
|
||||
$query = $this->connection->select($this->mapTable);
|
||||
$query->addExpression('COUNT(*)', 'count');
|
||||
$query->condition('needs_update', array(MigrateMap::STATUS_IMPORTED, MigrateMap::STATUS_NEEDS_UPDATE), 'IN');
|
||||
$query->condition('needs_update', array(
|
||||
MigrateMap::STATUS_IMPORTED,
|
||||
MigrateMap::STATUS_NEEDS_UPDATE,
|
||||
), 'IN');
|
||||
$count = $query->execute()->fetchField();
|
||||
return $count;
|
||||
}
|
||||
@@ -547,7 +569,8 @@ class MigrateSQLMap extends MigrateMap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the map entry and any message table entries for the specified source row.
|
||||
* Delete the map entry and any message table entries for the specified
|
||||
* source row.
|
||||
*
|
||||
* @param array $source_key
|
||||
*/
|
||||
@@ -572,7 +595,8 @@ class MigrateSQLMap extends MigrateMap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the map entry and any message table entries for the specified destination row.
|
||||
* Delete the map entry and any message table entries for the specified
|
||||
* destination row.
|
||||
*
|
||||
* @param array $destination_key
|
||||
*/
|
||||
@@ -601,7 +625,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
*/
|
||||
public function setUpdate(array $source_key) {
|
||||
$query = $this->connection->update($this->mapTable)
|
||||
->fields(array('needs_update' => MigrateMap::STATUS_NEEDS_UPDATE));
|
||||
->fields(array('needs_update' => MigrateMap::STATUS_NEEDS_UPDATE));
|
||||
$count = 1;
|
||||
foreach ($source_key as $key_value) {
|
||||
$query->condition('sourceid' . $count++, $key_value);
|
||||
@@ -649,7 +673,7 @@ class MigrateSQLMap extends MigrateMap {
|
||||
*/
|
||||
public function clearMessages() {
|
||||
$this->connection->truncate($this->messageTable)
|
||||
->execute();
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -661,15 +685,18 @@ class MigrateSQLMap extends MigrateMap {
|
||||
}
|
||||
|
||||
protected $result = NULL;
|
||||
|
||||
protected $currentRow = NULL;
|
||||
|
||||
protected $currentKey = array();
|
||||
|
||||
public function getCurrentKey() {
|
||||
return $this->currentKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of Iterator::rewind() - called before beginning a foreach loop.
|
||||
* TODO: Support idlist, itemlimit
|
||||
* Implementation of Iterator::rewind() - called before beginning a foreach
|
||||
* loop. TODO: Support idlist, itemlimit
|
||||
*/
|
||||
public function rewind() {
|
||||
$this->currentRow = NULL;
|
||||
@@ -701,17 +728,18 @@ class MigrateSQLMap extends MigrateMap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of Iterator::key - called when entering a loop iteration, returning
|
||||
* the key of the current row. It must be a scalar - we will serialize
|
||||
* to fulfill the requirement, but using getCurrentKey() is preferable.
|
||||
* Implementation of Iterator::key - called when entering a loop iteration,
|
||||
* returning the key of the current row. It must be a scalar - we will
|
||||
* serialize to fulfill the requirement, but using getCurrentKey() is
|
||||
* preferable.
|
||||
*/
|
||||
public function key() {
|
||||
return serialize($this->currentKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of Iterator::next() - called at the bottom of the loop implicitly,
|
||||
* as well as explicitly from rewind().
|
||||
* Implementation of Iterator::next() - called at the bottom of the loop
|
||||
* implicitly, as well as explicitly from rewind().
|
||||
*/
|
||||
public function next() {
|
||||
$this->currentRow = $this->result->fetchObject();
|
||||
@@ -721,16 +749,16 @@ class MigrateSQLMap extends MigrateMap {
|
||||
}
|
||||
else {
|
||||
foreach ($this->sourceKeyMap as $map_field) {
|
||||
$this->currentKey[$map_field] = $this->currentRow->$map_field;
|
||||
$this->currentKey[$map_field] = $this->currentRow->{$map_field};
|
||||
// Leave only destination fields
|
||||
unset($this->currentRow->$map_field);
|
||||
unset($this->currentRow->{$map_field});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of Iterator::valid() - called at the top of the loop, returning
|
||||
* TRUE to process the loop and FALSE to terminate it
|
||||
* Implementation of Iterator::valid() - called at the top of the loop,
|
||||
* returning TRUE to process the loop and FALSE to terminate it
|
||||
*/
|
||||
public function valid() {
|
||||
// TODO: Check numProcessed against itemlimit
|
||||
|
@@ -20,11 +20,13 @@
|
||||
/* ========================================================================== */
|
||||
/* List Method */
|
||||
/* ========================================================================== */
|
||||
|
||||
/**
|
||||
* Implementation of MigrateList, for retrieving a list of IDs to be migrated
|
||||
* from an XML document.
|
||||
*/
|
||||
class MigrateListXML extends MigrateList {
|
||||
|
||||
/**
|
||||
* A URL pointing to an XML document containing a list of IDs to be processed.
|
||||
*
|
||||
@@ -157,6 +159,7 @@ class MigrateListXML extends MigrateList {
|
||||
* an ID provided by a MigrateList class.
|
||||
*/
|
||||
class MigrateItemXML extends MigrateItem {
|
||||
|
||||
/**
|
||||
* A URL pointing to an XML document containing the data for one item to be
|
||||
* migrated.
|
||||
@@ -282,6 +285,7 @@ class MigrateItemXML extends MigrateItem {
|
||||
* Adds xpath info to field mappings for XML sources
|
||||
*/
|
||||
class MigrateXMLFieldMapping extends MigrateFieldMapping {
|
||||
|
||||
/**
|
||||
* The xpath used to retrieve the data for this field from the XML.
|
||||
*
|
||||
@@ -315,6 +319,7 @@ class MigrateXMLFieldMapping extends MigrateFieldMapping {
|
||||
* Migrations using XML sources should extend this class instead of Migration.
|
||||
*/
|
||||
abstract class XMLMigration extends Migration {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
@@ -370,7 +375,7 @@ abstract class XMLMigration extends Migration {
|
||||
// Derived class may override applyXpath().
|
||||
$source_value = $this->applyXpath($this->sourceValues, $xpath);
|
||||
if (!is_null($source_value)) {
|
||||
$this->sourceValues->$source = $source_value;
|
||||
$this->sourceValues->{$source} = $source_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -414,11 +419,13 @@ abstract class XMLMigration extends Migration {
|
||||
/* ========================================================================== */
|
||||
/* MultiItems Method */
|
||||
/* ========================================================================== */
|
||||
|
||||
/**
|
||||
* Implementation of MigrateItems, for providing a list of IDs and for
|
||||
* retrieving a parsed XML document given an ID from this list.
|
||||
*/
|
||||
class MigrateItemsXML extends MigrateItems {
|
||||
|
||||
/**
|
||||
* An array with all urls to available xml files.
|
||||
*
|
||||
@@ -813,7 +820,7 @@ class MigrateItemsXML extends MigrateItems {
|
||||
$this->getIdList();
|
||||
}
|
||||
foreach ($this->idsMap as $url => $ids) {
|
||||
if (in_array($id, $ids)) {
|
||||
if (in_array($id, $ids, TRUE)) {
|
||||
$this->currentItems = NULL;
|
||||
$this->currentUrl = $url;
|
||||
$items = $this->getAllItems();
|
||||
@@ -972,7 +979,7 @@ class MigrateXMLReader implements Iterator {
|
||||
if ($attribute_query) {
|
||||
// Matches [@attribute="value"] (with either single- or double-quotes).
|
||||
preg_match_all('|^\[@([^=]+)=[\'"](.*)[\'"]\]$|', $attribute_query,
|
||||
$matches);
|
||||
$matches);
|
||||
$this->attributeName = $matches[1][0];
|
||||
$this->attributeValue = $matches[2][0];
|
||||
}
|
||||
@@ -1002,7 +1009,7 @@ class MigrateXMLReader implements Iterator {
|
||||
}
|
||||
else {
|
||||
Migration::displayMessage(t('Could not open XML file !url',
|
||||
array('!url' => $this->url)));
|
||||
array('!url' => $this->url)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1028,7 +1035,7 @@ class MigrateXMLReader implements Iterator {
|
||||
// attribute, check that as well before accepting this element.
|
||||
if (empty($this->attributeName) ||
|
||||
($this->reader->getAttribute($this->attributeName) ==
|
||||
$this->attributeValue)
|
||||
$this->attributeValue)
|
||||
) {
|
||||
// We've found a matching element - get a SimpleXML object
|
||||
// representing it.We must associate the DOMNode with a
|
||||
@@ -1249,8 +1256,8 @@ class MigrateSourceXML extends MigrateSource {
|
||||
// a lot of urls, may need to hash.
|
||||
$urls = implode(', ', $this->sourceUrls);
|
||||
return 'urls = ' . $urls .
|
||||
' | item xpath = ' . $this->elementQuery .
|
||||
' | item ID xpath = ' . $this->idQuery;
|
||||
' | item xpath = ' . $this->elementQuery .
|
||||
' | item ID xpath = ' . $this->idQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1283,7 +1290,7 @@ class MigrateSourceXML extends MigrateSource {
|
||||
$count = 0;
|
||||
foreach ($this->sourceUrls as $url) {
|
||||
$reader = new $this->readerClass($url, $this->elementQuery,
|
||||
$this->idQuery);
|
||||
$this->idQuery);
|
||||
foreach ($reader as $element) {
|
||||
$count++;
|
||||
}
|
||||
@@ -1326,7 +1333,7 @@ class MigrateSourceXML extends MigrateSource {
|
||||
// Test the reader for a valid row.
|
||||
if (isset($this->reader) && $this->reader->valid()) {
|
||||
$row = new stdClass();
|
||||
$row->$key_name = $this->reader->key();
|
||||
$row->{$key_name} = $this->reader->key();
|
||||
$row->xml = $this->reader->current();
|
||||
$this->registerNamespaces($row->xml);
|
||||
}
|
||||
@@ -1334,7 +1341,7 @@ class MigrateSourceXML extends MigrateSource {
|
||||
// The current source is at the end, try to load the next source.
|
||||
if ($this->getNextSource()) {
|
||||
$row = new stdClass();
|
||||
$row->$key_name = $this->reader->key();
|
||||
$row->{$key_name} = $this->reader->key();
|
||||
$row->xml = $this->reader->current();
|
||||
$this->registerNamespaces($row->xml);
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Test node migration.
|
||||
*/
|
||||
class MigrateImportOptionsTest extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Import options',
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Test comment migration.
|
||||
*/
|
||||
class MigrateCommentUnitTest extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Comment migration',
|
||||
@@ -62,18 +63,29 @@ class MigrateCommentUnitTest extends DrupalWebTestCase {
|
||||
$this->assertEqual($result, Migration::RESULT_COMPLETED,
|
||||
t('Comment import returned RESULT_COMPLETED'));
|
||||
$result = db_select('migrate_message_winecomment', 'w')
|
||||
->fields('w', array('message'))
|
||||
->execute();
|
||||
->fields('w', array('message'))
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
$this->error($row->message);
|
||||
}
|
||||
|
||||
$result = db_select('migrate_example_wine_comment', 'wc')
|
||||
->fields('wc', array('commentid', 'comment_parent', 'name', 'mail',
|
||||
'accountid', 'body', 'wineid', 'subject', 'commenthost', 'userpage',
|
||||
'posted', 'lastchanged'))
|
||||
->orderBy('comment_parent')
|
||||
->execute();
|
||||
->fields('wc', array(
|
||||
'commentid',
|
||||
'comment_parent',
|
||||
'name',
|
||||
'mail',
|
||||
'accountid',
|
||||
'body',
|
||||
'wineid',
|
||||
'subject',
|
||||
'commenthost',
|
||||
'userpage',
|
||||
'posted',
|
||||
'lastchanged',
|
||||
))
|
||||
->orderBy('comment_parent')
|
||||
->execute();
|
||||
|
||||
$rawcomments = comment_load_multiple(FALSE);
|
||||
// Index by subject
|
||||
@@ -96,7 +108,8 @@ class MigrateCommentUnitTest extends DrupalWebTestCase {
|
||||
$this->assertEqual($comment->name, $row->name, t('Name matches'));
|
||||
$this->assertEqual($comment->status, COMMENT_PUBLISHED, t('Status matches'));
|
||||
$wine_migration = MigrationBase::getInstance('WineWine');
|
||||
$destid = $wine_migration->getMap()->lookupDestinationID(array($row->wineid));
|
||||
$destid = $wine_migration->getMap()
|
||||
->lookupDestinationID(array($row->wineid));
|
||||
$this->assertEqual($comment->nid, reset($destid), t('Nid matches'));
|
||||
$body = field_get_items('comment', $comment, 'comment_body');
|
||||
$this->assertEqual($body[0]['value'], $row->body, t('Body matches'));
|
||||
@@ -108,7 +121,8 @@ class MigrateCommentUnitTest extends DrupalWebTestCase {
|
||||
$comment = $comments['im child'];
|
||||
$row = $rows['im child'];
|
||||
$user_migration = MigrationBase::getInstance('WineUser');
|
||||
$destid = $user_migration->getMap()->lookupDestinationID(array($row->accountid));
|
||||
$destid = $user_migration->getMap()
|
||||
->lookupDestinationID(array($row->accountid));
|
||||
$this->assertEqual($comment->uid, reset($destid), t('Uid matches'));
|
||||
$this->assertEqual($comment->pid, $comments['im parent']->cid, t('Parent matches'));
|
||||
|
||||
@@ -123,16 +137,19 @@ class MigrateCommentUnitTest extends DrupalWebTestCase {
|
||||
foreach ($original_comments as $cid => $original_comment) {
|
||||
foreach ($original_comment as $field => $value) {
|
||||
if ($field == 'subject') {
|
||||
if ($value == $final_comments[$cid]->$field) {
|
||||
if ($value == $final_comments[$cid]->{$field}) {
|
||||
$this->error(t('Field !field should have changed but did not, value=!value',
|
||||
array('!field' => $field, '!value' => print_r($value, TRUE))));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($value != $final_comments[$cid]->$field) {
|
||||
if ($value != $final_comments[$cid]->{$field}) {
|
||||
$this->error(t('Field !field mismatch: original !value1, result !value2',
|
||||
array('!field' => $field, '!value1' => print_r($value, TRUE),
|
||||
'!value2' => print_r($final_comments[$cid]->$field, TRUE))));
|
||||
array(
|
||||
'!field' => $field,
|
||||
'!value1' => print_r($value, TRUE),
|
||||
'!value2' => print_r($final_comments[$cid]->{$field}, TRUE),
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,16 +162,16 @@ class MigrateCommentUnitTest extends DrupalWebTestCase {
|
||||
$rawcomments = comment_load_multiple(FALSE);
|
||||
$this->assertEqual(count($rawcomments), 0, t('All comments deleted'));
|
||||
$count = db_select('migrate_map_winecomment', 'map')
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Map cleared'));
|
||||
$count = db_select('migrate_message_winecomment', 'msg')
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Messages cleared'));
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Test node migration.
|
||||
*/
|
||||
class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Node migration',
|
||||
@@ -67,7 +68,13 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
}
|
||||
|
||||
$query = db_select('migrate_example_wine_producer', 'p')
|
||||
->fields('p', array('producerid', 'name', 'body', 'excerpt', 'accountid'));
|
||||
->fields('p', array(
|
||||
'producerid',
|
||||
'name',
|
||||
'body',
|
||||
'excerpt',
|
||||
'accountid',
|
||||
));
|
||||
// Region term is singletons, handled straighforwardly
|
||||
$query->leftJoin('migrate_example_wine_category_producer', 'reg',
|
||||
"p.producerid = reg.producerid");
|
||||
@@ -87,8 +94,17 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
$wine_nodes[$node->title] = $node;
|
||||
}
|
||||
$query = db_select('migrate_example_wine', 'w')
|
||||
->fields('w', array('wineid', 'name', 'body', 'excerpt', 'accountid',
|
||||
'posted', 'last_changed', 'variety', 'region'));
|
||||
->fields('w', array(
|
||||
'wineid',
|
||||
'name',
|
||||
'body',
|
||||
'excerpt',
|
||||
'accountid',
|
||||
'posted',
|
||||
'last_changed',
|
||||
'variety',
|
||||
'region',
|
||||
));
|
||||
$query->leftJoin('migrate_example_wine_category_wine', 'cwbw',
|
||||
"w.wineid = cwbw.wineid");
|
||||
$query->leftJoin('migrate_example_wine_categories', 'bw',
|
||||
@@ -111,7 +127,8 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
$wine_row = $wine_rows['Montes Classic Cabernet Sauvignon'];
|
||||
$user_migration = MigrationBase::getInstance('WineUser');
|
||||
|
||||
$mapped_uid = $user_migration->getMap()->lookupDestinationID(array($producer_row->accountid));
|
||||
$mapped_uid = $user_migration->getMap()
|
||||
->lookupDestinationID(array($producer_row->accountid));
|
||||
if (is_array($mapped_uid)) {
|
||||
$this->assertEqual($producer_node->uid, reset($mapped_uid),
|
||||
t('uid properly migrated'));
|
||||
@@ -134,7 +151,8 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
// taxonomy_term_reference - single and multiple
|
||||
$variety = field_get_items('node', $wine_node, 'migrate_example_wine_varieties');
|
||||
$variety_migration = MigrationBase::getInstance('WineVariety');
|
||||
$mapped_tid = $variety_migration->getMap()->lookupDestinationID(array($wine_row->variety));
|
||||
$mapped_tid = $variety_migration->getMap()
|
||||
->lookupDestinationID(array($wine_row->variety));
|
||||
if (is_array($mapped_tid)) {
|
||||
$this->assertEqual($variety[0]['tid'], reset($mapped_tid),
|
||||
t('Single taxonomy_term_reference properly migrated'));
|
||||
@@ -147,7 +165,8 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
$source_ids = explode(',', $wine_row->best_with);
|
||||
$mapped_tids = array();
|
||||
foreach ($source_ids as $source_id) {
|
||||
$tid = $best_with_migration->getMap()->lookupDestinationID(array($source_id));
|
||||
$tid = $best_with_migration->getMap()
|
||||
->lookupDestinationID(array($source_id));
|
||||
if ($tid) {
|
||||
$mapped_tids[reset($tid)] = reset($tid);
|
||||
}
|
||||
@@ -176,33 +195,66 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
foreach ($original_nodes as $nid => $original_node) {
|
||||
foreach ($original_node as $field => $value) {
|
||||
if ($field == 'field_migrate_example_wine_ratin' || $field == 'changed' || $field == 'revision_timestamp') {
|
||||
if ($value == $final_nodes[$nid]->$field) {
|
||||
if ($value == $final_nodes[$nid]->{$field}) {
|
||||
$this->error(t('Field !field should have changed but did not, value=!value',
|
||||
array('!field' => $field, '!value' => print_r($value, TRUE))));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($value != $final_nodes[$nid]->$field) {
|
||||
if ($value != $final_nodes[$nid]->{$field}) {
|
||||
$this->error(t('Field !field mismatch: original !value1, result !value2',
|
||||
array('!field' => $field, '!value1' => print_r($value, TRUE),
|
||||
'!value2' => print_r($final_nodes[$nid]->$field, TRUE))));
|
||||
array(
|
||||
'!field' => $field,
|
||||
'!value1' => print_r($value, TRUE),
|
||||
'!value2' => print_r($final_nodes[$nid]->{$field}, TRUE),
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test highwater marks - add new wines, modify an old one, and see what changes
|
||||
$fields = array('wineid', 'name', 'body', 'excerpt', 'accountid',
|
||||
'posted', 'last_changed', 'variety', 'region', 'rating');
|
||||
$fields = array(
|
||||
'wineid',
|
||||
'name',
|
||||
'body',
|
||||
'excerpt',
|
||||
'accountid',
|
||||
'posted',
|
||||
'last_changed',
|
||||
'variety',
|
||||
'region',
|
||||
'rating',
|
||||
);
|
||||
$query = db_insert('migrate_example_wine')
|
||||
->fields($fields);
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
// Timestamps 1284008523, 1284120550
|
||||
array(3, 'Schloss Muhlenhof Dornfelder', 'Juicy black & red berry fruits', 'Pretty good', 9,
|
||||
strtotime('2010-09-09 01:02:03'), strtotime('2010-09-10 08:09:10'), 25, 17, 95),
|
||||
array(
|
||||
3,
|
||||
'Schloss Muhlenhof Dornfelder',
|
||||
'Juicy black & red berry fruits',
|
||||
'Pretty good',
|
||||
9,
|
||||
strtotime('2010-09-09 01:02:03'),
|
||||
strtotime('2010-09-10 08:09:10'),
|
||||
25,
|
||||
17,
|
||||
95,
|
||||
),
|
||||
// Timestamps 1286122209, 1286122209
|
||||
array(4, 'Gachot-Monot Bourgogne Rge 06', 'Funky', 'Pair with white sauced dishes', 3,
|
||||
strtotime('2010-10-03 12:10:09'), strtotime('2010-10-03 12:10:09'), 26, 2, 85),
|
||||
array(
|
||||
4,
|
||||
'Gachot-Monot Bourgogne Rge 06',
|
||||
'Funky',
|
||||
'Pair with white sauced dishes',
|
||||
3,
|
||||
strtotime('2010-10-03 12:10:09'),
|
||||
strtotime('2010-10-03 12:10:09'),
|
||||
26,
|
||||
2,
|
||||
85,
|
||||
),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
@@ -211,9 +263,9 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
|
||||
db_update('migrate_example_wine')
|
||||
->fields(array(
|
||||
'body' => 'Not so much berry character',
|
||||
// Timestamp 1285058521
|
||||
'last_changed' => strtotime('2010-10-21 04:42:01'),
|
||||
'body' => 'Not so much berry character',
|
||||
// Timestamp 1285058521
|
||||
'last_changed' => strtotime('2010-10-21 04:42:01'),
|
||||
))
|
||||
->condition('wineid', 2)
|
||||
->execute();
|
||||
@@ -241,22 +293,24 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
$rawnodes = node_load_multiple(FALSE, array('type' => 'migrate_example_wine'), TRUE);
|
||||
$this->assertEqual(count($rawnodes), 0, t('All nodes deleted'));
|
||||
$count = db_select('migrate_map_winewine', 'map')
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Map cleared'));
|
||||
$count = db_select('migrate_message_winewine', 'msg')
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Messages cleared'));
|
||||
|
||||
// Now test highwater with unjoined map table
|
||||
$migration->getSource()->setMapJoinable(FALSE);
|
||||
$result = $migration->processImport(array('limit' =>
|
||||
array('value' => 2, 'unit' => 'items')));
|
||||
$result = $migration->processImport(array(
|
||||
'limit' =>
|
||||
array('value' => 2, 'unit' => 'items'),
|
||||
));
|
||||
db_update('migrate_example_wine')
|
||||
->fields(array(
|
||||
'body' => 'Very berry',
|
||||
@@ -282,8 +336,10 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
// Test itemlimit (joined map table)
|
||||
$result = $migration->processRollback(array('force' => TRUE));
|
||||
$migration->getSource()->setMapJoinable(TRUE);
|
||||
$result = $migration->processImport(array('limit' =>
|
||||
array('value' => 1, 'unit' => 'item')));
|
||||
$result = $migration->processImport(array(
|
||||
'limit' =>
|
||||
array('value' => 1, 'unit' => 'item'),
|
||||
));
|
||||
$this->assertEqual($result, Migration::RESULT_COMPLETED,
|
||||
t('Wine node import with itemlimit returned RESULT_COMPLETED'));
|
||||
$rawnodes = node_load_multiple(FALSE, array('type' => 'migrate_example_wine'), TRUE);
|
||||
@@ -303,8 +359,10 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
// Test itemlimit (unjoined map table)
|
||||
$result = $migration->processRollback(array('force' => TRUE));
|
||||
$migration->getSource()->setMapJoinable(FALSE);
|
||||
$result = $migration->processImport(array('limit' =>
|
||||
array('value' => 1, 'unit' => 'item')));
|
||||
$result = $migration->processImport(array(
|
||||
'limit' =>
|
||||
array('value' => 1, 'unit' => 'item'),
|
||||
));
|
||||
$this->assertEqual($result, Migration::RESULT_COMPLETED,
|
||||
t('Wine node import with itemlimit returned RESULT_COMPLETED'));
|
||||
$rawnodes = node_load_multiple(FALSE, array('type' => 'migrate_example_wine'), TRUE);
|
||||
@@ -359,10 +417,10 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
->execute();
|
||||
$result = $migration->processImport();
|
||||
$newHighwater = db_select('migrate_status', 'ms')
|
||||
->fields('ms', array('highwater'))
|
||||
->condition('machine_name', 'WineWine')
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('ms', array('highwater'))
|
||||
->condition('machine_name', 'WineWine')
|
||||
->execute()
|
||||
->fetchField();
|
||||
if (!$this->assertEqual($newHighwater, 1000000000, t('Correct highwater mark set'))) {
|
||||
$this->error(t('Unexpected highwater mark !highwater', array('!highwater' => $newHighwater)));
|
||||
}
|
||||
@@ -387,10 +445,23 @@ class MigrateNodeUnitTest extends DrupalWebTestCase {
|
||||
$this->assertEqual($result, Migration::RESULT_COMPLETED,
|
||||
t('Beer node update import returned RESULT_COMPLETED'));
|
||||
$result = db_select('migrate_message_beernode', 'msg')
|
||||
->fields('msg', array('message'))
|
||||
->execute();
|
||||
->fields('msg', array('message'))
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
$this->error($row->message);
|
||||
}
|
||||
|
||||
// Test proper disableMailSystem()/restoreMailSystem() behavior.
|
||||
// @see https://www.drupal.org/node/2499861
|
||||
// This is not necessarily node-related, but it was shoved in the node test.
|
||||
$migration->saveMailSystem();
|
||||
$migration->disableMailSystem();
|
||||
$ms = variable_get('mail_system', NULL);
|
||||
$this->assertTrue(is_array($ms) && in_array('MigrateMailIgnore', $ms),
|
||||
t('Migration has disabled mail system'));
|
||||
$migration->restoreMailSystem();
|
||||
$ms = variable_get('mail_system', NULL);
|
||||
$this->assertFalse(is_array($ms) && in_array('MigrateMailIgnore', $ms),
|
||||
t('Migration::restoreMailSystem restored mail system'));
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Test table migration.
|
||||
*/
|
||||
class MigrateTableUnitTest extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Table migration',
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Test taxonomy migration.
|
||||
*/
|
||||
class MigrateTaxonomyUnitTest extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Taxonomy migration',
|
||||
@@ -36,10 +37,16 @@ class MigrateTaxonomyUnitTest extends DrupalWebTestCase {
|
||||
$terms[$term->name] = $term;
|
||||
}
|
||||
$query = db_select('migrate_example_wine_categories', 'wc')
|
||||
->fields('wc', array('categoryid', 'name', 'details', 'category_parent', 'ordering'))
|
||||
->condition('wc.type', 'variety');
|
||||
->fields('wc', array(
|
||||
'categoryid',
|
||||
'name',
|
||||
'details',
|
||||
'category_parent',
|
||||
'ordering',
|
||||
))
|
||||
->condition('wc.type', 'variety');
|
||||
$query->leftJoin('migrate_example_wine_categories', 'wcpar',
|
||||
'wc.category_parent=wcpar.categoryid');
|
||||
'wc.category_parent=wcpar.categoryid');
|
||||
$query->addField('wcpar', 'name', 'parent_name');
|
||||
$result = $query->execute();
|
||||
|
||||
@@ -79,16 +86,19 @@ class MigrateTaxonomyUnitTest extends DrupalWebTestCase {
|
||||
foreach ($original_terms as $tid => $original_term) {
|
||||
foreach ($original_term as $field => $value) {
|
||||
if ($field == 'description') {
|
||||
if ($value == $final_terms[$tid]->$field) {
|
||||
if ($value == $final_terms[$tid]->{$field}) {
|
||||
$this->error(t('Field !field should have changed but did not, value=!value',
|
||||
array('!field' => $field, '!value' => print_r($value, TRUE))));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($value != $final_terms[$tid]->$field) {
|
||||
if ($value != $final_terms[$tid]->{$field}) {
|
||||
$this->error(t('Field !field mismatch: original !value1, result !value2',
|
||||
array('!field' => $field, '!value1' => print_r($value, TRUE),
|
||||
'!value2' => print_r($final_terms[$tid]->$field, TRUE))));
|
||||
array(
|
||||
'!field' => $field,
|
||||
'!value1' => print_r($value, TRUE),
|
||||
'!value2' => print_r($final_terms[$tid]->{$field}, TRUE),
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,16 +111,16 @@ class MigrateTaxonomyUnitTest extends DrupalWebTestCase {
|
||||
$rawterms = taxonomy_term_load_multiple(array(), array('vid' => $vocab->vid));
|
||||
$this->assertEqual(count($rawterms), 0, t('All terms deleted'));
|
||||
$count = db_select('migrate_map_winevariety', 'map')
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Map cleared'));
|
||||
$count = db_select('migrate_message_winevariety', 'msg')
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Messages cleared'));
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Test user migration.
|
||||
*/
|
||||
class MigrateUserUnitTest extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'User migration',
|
||||
@@ -38,9 +39,9 @@ class MigrateUserUnitTest extends DrupalWebTestCase {
|
||||
t('Role import returned RESULT_COMPLETED'));
|
||||
// Confirm both roles were successfully imported
|
||||
$result = db_select('role', 'r')
|
||||
->fields('r', array('rid', 'name'))
|
||||
->condition('name', array('Taster', 'Vintner'), 'IN')
|
||||
->execute();
|
||||
->fields('r', array('rid', 'name'))
|
||||
->condition('name', array('Taster', 'Vintner'), 'IN')
|
||||
->execute();
|
||||
$roles = array();
|
||||
foreach ($result as $row) {
|
||||
$roles[$row->name] = $row->rid;
|
||||
@@ -59,14 +60,24 @@ class MigrateUserUnitTest extends DrupalWebTestCase {
|
||||
$this->assertEqual($result, Migration::RESULT_COMPLETED,
|
||||
t('User import returned RESULT_COMPLETED'));
|
||||
$result = db_select('migrate_example_wine_account', 'mea')
|
||||
->fields('mea', array('accountid', 'status', 'posted', 'name',
|
||||
'sex', 'password', 'mail', 'last_access', 'last_login',
|
||||
'sig', 'original_mail'))
|
||||
->execute();
|
||||
->fields('mea', array(
|
||||
'accountid',
|
||||
'status',
|
||||
'posted',
|
||||
'name',
|
||||
'sex',
|
||||
'password',
|
||||
'mail',
|
||||
'last_access',
|
||||
'last_login',
|
||||
'sig',
|
||||
'original_mail',
|
||||
))
|
||||
->execute();
|
||||
$uids = db_select('users', 'u')
|
||||
->fields('u', array('uid'))
|
||||
->execute()
|
||||
->fetchCol();
|
||||
->fields('u', array('uid'))
|
||||
->execute()
|
||||
->fetchCol();
|
||||
// Index by name
|
||||
$users = array();
|
||||
foreach ($uids as $uid) {
|
||||
@@ -114,10 +125,10 @@ class MigrateUserUnitTest extends DrupalWebTestCase {
|
||||
1, t('Female gender migrated'));
|
||||
$this->assert(!isset($users['fonzie']->field_migrate_example_gender[LANGUAGE_NONE][0]['value']),
|
||||
t('Missing gender left unmigrated'));
|
||||
/* For some reason, this fails on d.o but not in local environments
|
||||
$this->assert(is_object($users['fonzie']->picture) &&
|
||||
$users['fonzie']->picture->filename == '200',
|
||||
t('Picture migrated'));*/
|
||||
/* For some reason, this fails on d.o but not in local environments
|
||||
$this->assert(is_object($users['fonzie']->picture) &&
|
||||
$users['fonzie']->picture->filename == '200',
|
||||
t('Picture migrated'));*/
|
||||
$this->assertNotNull($users['fonzie']->roles[$roles['Taster']], t('Taster role'));
|
||||
$this->assertNotNull($users['fonzie']->roles[$roles['Vintner']], t('Vintner role'));
|
||||
|
||||
@@ -140,20 +151,26 @@ class MigrateUserUnitTest extends DrupalWebTestCase {
|
||||
foreach ($original_users as $uid => $original_user) {
|
||||
foreach ($original_user as $field => $value) {
|
||||
if ($field == 'field_migrate_example_gender') {
|
||||
if ($value == $final_users[$uid]->$field) {
|
||||
if ($value == $final_users[$uid]->{$field}) {
|
||||
$this->error(t('For user !name, field !field should have changed but did not, value=!value',
|
||||
array('!name' => $final_users[$uid]->name, '!field' => $field,
|
||||
'!value' => print_r($value, TRUE))));
|
||||
array(
|
||||
'!name' => $final_users[$uid]->name,
|
||||
'!field' => $field,
|
||||
'!value' => print_r($value, TRUE),
|
||||
)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($value != $final_users[$uid]->$field) {
|
||||
if ($value != $final_users[$uid]->{$field}) {
|
||||
// Core bug http://drupal.org/node/935592 causes picture mismatches, ignore until it's fixed
|
||||
if ($field != 'picture') {
|
||||
$this->error(t('For user !name, field !field mismatch: original !value1, result !value2',
|
||||
array('!name' => $final_users[$uid]->name, '!field' => $field,
|
||||
array(
|
||||
'!name' => $final_users[$uid]->name,
|
||||
'!field' => $field,
|
||||
'!value1' => print_r($value, TRUE),
|
||||
'!value2' => print_r($final_users[$uid]->$field, TRUE))));
|
||||
'!value2' => print_r($final_users[$uid]->{$field}, TRUE),
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,23 +182,23 @@ class MigrateUserUnitTest extends DrupalWebTestCase {
|
||||
$this->assertEqual($result, Migration::RESULT_COMPLETED,
|
||||
t('User rollback returned RESULT_COMPLETED'));
|
||||
$count = db_select('users', 'u')
|
||||
->fields('u', array('uid'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('u', array('uid'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
// 2 users left - anon and admin
|
||||
$this->assertEqual($count, 2, t('All imported users deleted'));
|
||||
$count = db_select('migrate_map_wineuser', 'map')
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Map cleared'));
|
||||
$count = db_select('migrate_message_wineuser', 'msg')
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Messages cleared'));
|
||||
|
||||
// Test deduping
|
||||
@@ -191,9 +208,9 @@ class MigrateUserUnitTest extends DrupalWebTestCase {
|
||||
$this->assertEqual($result, Migration::RESULT_COMPLETED,
|
||||
t('User import returned RESULT_COMPLETED'));
|
||||
$accounts = db_select('users', 'u')
|
||||
->fields('u', array('mail', 'name'))
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
->fields('u', array('mail', 'name'))
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
if (!$this->assertEqual($accounts['alice@example.com'], 'alice', t('alice found'))) {
|
||||
$this->error(t('Expected alice, found !name', array('!name' => $accounts['alice@example.com'])));
|
||||
}
|
||||
@@ -207,9 +224,9 @@ class MigrateUserUnitTest extends DrupalWebTestCase {
|
||||
$this->assertEqual($result, Migration::RESULT_COMPLETED,
|
||||
t('User import returned RESULT_COMPLETED'));
|
||||
$accounts = db_select('users', 'u')
|
||||
->fields('u', array('mail', 'name'))
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
->fields('u', array('mail', 'name'))
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
if (!$this->assertEqual($accounts['alice@example.com'], 'alice', t('alice found'))) {
|
||||
$this->error(t('Expected alice, found !name', array('!name' => $accounts['alice@example.com'])));
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
* when that is fixed.
|
||||
*/
|
||||
class MigrateOracleUnitTest extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Oracle migration',
|
||||
@@ -23,7 +24,7 @@ class MigrateOracleUnitTest extends DrupalWebTestCase {
|
||||
function setUp() {
|
||||
global $conf;
|
||||
if (empty($conf['oracle_db']) || empty($conf['oracle_db']['username']) ||
|
||||
empty($conf['oracle_db']['password']) || empty($conf['oracle_db']['connection_string'])) {
|
||||
empty($conf['oracle_db']['password']) || empty($conf['oracle_db']['connection_string'])) {
|
||||
parent::setUp();
|
||||
}
|
||||
else {
|
||||
@@ -87,16 +88,16 @@ class MigrateOracleUnitTest extends DrupalWebTestCase {
|
||||
$rawnodes = node_load_multiple(FALSE, array('type' => 'migrate_example_oracle'), TRUE);
|
||||
$this->assertEqual(count($rawnodes), 0, t('All nodes deleted'));
|
||||
$count = db_select('migrate_map_migrateexampleoracle', 'map')
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Map cleared'));
|
||||
$count = db_select('migrate_message_migrateexampleoracle', 'msg')
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Messages cleared'));
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* Test node migration.
|
||||
*/
|
||||
class MigrateXMLUnitTest extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'XML migration',
|
||||
@@ -139,16 +140,16 @@ class MigrateXMLUnitTest extends DrupalWebTestCase {
|
||||
$rawnodes = node_load_multiple(FALSE, array('type' => 'migrate_example_producer'), TRUE);
|
||||
$this->assertEqual(count($rawnodes), 0, t('All nodes deleted'));
|
||||
$count = db_select('migrate_map_wineproducerxml', 'map')
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('map', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Map cleared'));
|
||||
$count = db_select('migrate_message_wineproducerxml', 'msg')
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
->fields('msg', array('sourceid1'))
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, t('Messages cleared'));
|
||||
}
|
||||
}
|
||||
|
@@ -3,9 +3,9 @@
|
||||
/**
|
||||
* @file
|
||||
* Sample file for handling redirection from old to new URIs. Use an Apache
|
||||
* rewrite rule (or equivalent) to map legacy requests to this file. To use, copy
|
||||
* or symlink this file to the root of your drupal site. Customize
|
||||
* this file to your needs.
|
||||
* rewrite rule (or equivalent) to map legacy requests to this file. To use,
|
||||
* copy or symlink this file to the root of your drupal site. Customize this
|
||||
* file to your needs.
|
||||
*
|
||||
* CREATE TABLE `migrate_source_uri_map` (
|
||||
* `source_uri` varchar(255) NOT NULL DEFAULT '',
|
||||
@@ -41,7 +41,7 @@ function migrate_build_url($destid1, $migration_name) {
|
||||
}
|
||||
|
||||
// Build absolute url for 301 redirect.
|
||||
return $base_url . '/' . $destination_uri;
|
||||
return $base_url . '/' . $destination_uri;
|
||||
}
|
||||
|
||||
define('DRUPAL_ROOT', getcwd());
|
||||
|
Reference in New Issue
Block a user