3

I want to migrate taxonomy terms from a legacy database to my drupal 7 installation. This is working almost as desired. What I do is basicly define a mapping as described in any migration example, e.g.:

$this->addFieldMapping('name', 'legacy_name');

But when I try to migrate dates I totally fail. This does not work:

$this->addFieldMapping('field_date', 'valid_from');

After some digging I found out I had to enable the Date Migration module, allright. But still, this does not work at all. I discovered some date migration example code and found out I have to reformat the date field in the prepareRow() function. But that feature is very much undocumented. The linked example doesn't work at all.

My current code looks like that:

abstract class MyBasicMigration extends Migration {
  public function __construct() {
    parent::__construct();
  }
}

class MyMigration extends MyBasicMigration {
  public function __construct() {
    parent::__construct();

    #[...]

    $this->destination = new MigrateDestinationTerm('mystuff');
    # this works:
    $this->addFieldMapping('name', 'legacy_name'); 
    # this does not:
    $this->addFieldMapping('field_date', 'valid_from'); 
  }

  public function prepareRow($current_row) {
    # checks for malformed date strings in DB and converts to datetime type
    if (($current_row->valid_from = strtotime($current_row->valid_from)) === false) {
      $current_row->valid_from = strtotime('1970-02-01');
    }
    if (($current_row->valid_to = strtotime($current_row->valid_to)) === false) {
      $current_row->valid_to = strtotime('2037-12-31');
    }
    # converts the date to YYYY-mm-dd format
    $format = 'Y-m-d';
    $current_row->valid_from = date($format, $current_row->valid_from);
    $current_row->valid_to = date($format, $current_row->valid_to);
    # creates a date field for the valid_from/to migration mapping
    $current_row->valid_from = array(
      'value' => (string) $current_row->valid_from,
      'value2' => (string) $current_row->valid_to,
      'timezone' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
      'timezone_db' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
      'date_type' => 'datetime',
    );
    $current_row->valid_from = drupal_json_encode($current_row->valid_from);
    # debug result output
    watchdog("PW_TEST", $current_row->valid_from, $variables = NULL, WATCHDOG_DEBUG, $link = NULL);
  }

The date format in database is a string formated like this 2013-12-31.

The prepareRow() function seems to work at all and the watchdog() output looks very good:

{"value":"1970-02-01","value2":"2013-12-31","timezone":{"timezone":"Europe\/Berlin","timezone_db":"UTC","rrule":null,"language":null},"timezone_db":{"timezone":"Europe\/Berlin","timezone_db":"UTC","rrule":null,"language":null},"date_type":"datetime"}

As you can see the returned JSON string includes the correct dates. But at some point now the migration mapping fails at the fields valid_from and valid_to.

If I do a print_r() on a migrated taxonomy term, I get something like that:

[field_date] => Array
    (
        [und] => Array
            (
                [0] => Array
                    (
                        [value] => 
                        [value2] => 
                        [timezone] => Europe/Berlin
                        [timezone_db] => Europe/Berlin
                        [date_type] => datetime
                    )
            )
    )

The JSON object got mapped correctly, date_type and timezone just displays properly. But where the hell are my dates gone? Any ideas?

I've been working on this all day now and I can not see any issues with my code. Thanks for any hints!

4

This is plain awfull and totally undocumented. But I found out:

# creates a date field for the valid_from/to migration mapping
$current_row->valid_from = array(
  'from' => (string) $current_row->valid_from,
  'to' => (string) $current_row->valid_to,
  //'timezone' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
  //'timezone_db' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
  //'date_type' => 'datetime',
);

Two issues with the code above are solved:

  1. The array containing the dates has to contain the fiels from and to. Otherwise it does not understand the date range. I've seen this in the date migration example but never thought the field names are important for the mapping. (I rather used the target names value and value2.)
  2. The array should not contain information about timezone and date types. The DateMigrateFieldHandler::prepare() will do that for you.

The working code above yields:

[field_date] => Array
    (
        [und] => Array
            (
                [0] => Array
                    (
                        [value] => 1970-02-01 00:00:00
                        [value2] => 2013-12-31 00:00:00
                        [timezone] => Europe/Berlin
                        [timezone_db] => Europe/Berlin
                        [date_type] => datetime
                    )
            )
    )

Fixed. :)

2

This is still poorly documented, yet I keep stumbling on this issue...

The solution given is almost correct, however, the final array must be passed through the drupal_json_encode() function to work:

# creates a date field for the valid_from/to migration mapping
$current_row->valid_from = drupal_json_encode(
  array(
    'from' => (string) $current_row->valid_from,
    'to' => (string) $current_row->valid_to,
    //'timezone' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
    //'timezone_db' => DateMigrateFieldHandler::arguments('Europe/Berlin'),
    //'date_type' => 'datetime',
 ));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.