| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 | <?php/** * @file * Support for tables defined through the Schema API. *//** * Destination class implementing migration into a single table defined through * the Schema API. */class MigrateDestinationTable extends MigrateDestination {  /**   * The schema of the current table.   *   * @var array   */  protected $schema = NULL;  /**   * The name of the current table.   *   * @var string   */  protected $tableName = NULL;  public function __construct($table_name) {    $this->schema = drupal_get_schema($table_name);    $this->tableName = $table_name;  }  static public function getKeySchema($table_name = NULL) {    if (empty($table_name)) {      return array();    }    $schema = drupal_get_schema($table_name);    $keys = array();    foreach ($schema['primary key'] as $primary_key) {      // We can't have any form of serial fields here, since the mapping table      // already has it's own.      $schema['fields'][$primary_key]['auto_increment'] = FALSE;      if ($schema['fields'][$primary_key]['type'] == 'serial') {        $schema['fields'][$primary_key]['type'] = 'int';      }      $keys[$primary_key] = $schema['fields'][$primary_key];    }    return $keys;  }  public function __toString() {    $output = t('Table !name', array('!name' => $this->tableName));    return $output;  }  /**   * Delete a single row.   *   * @param $id   *  Primary key values.   */  public function rollback(array $id) {    migrate_instrument_start('table rollback');    $delete = db_delete($this->tableName);    $keys = array_keys(self::getKeySchema($this->tableName));    $i = 0;    foreach ($id as $value) {      $key = $keys[$i++];      $delete->condition($key, $value);    }    $delete->execute();    migrate_instrument_stop('table rollback');  }  /**   * Import a single row.   *   * @param $entity   *  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.   */  public function import(stdClass $entity, stdClass $row) {    if (empty($this->schema['primary key'])) {      throw new MigrateException(t("The destination table has no primary key defined."));    }    // Only filled when doing an update.    $primary_key = array();    $migration = Migration::currentMigration();    // Updating previously-migrated content?    if (isset($row->migrate_map_destid1)) {      $i = 1;      foreach ($this->schema['primary key'] as $key) {        $primary_key[] = $key;        $destination_id = $row->{'migrate_map_destid' . $i};        if (isset($entity->{$key})) {          if ($entity->{$key} != $destination_id) {            throw new MigrateException(t("Incoming id !id and map destination id !destid don't match",              array('!id' => $entity->{$key}, '!destid' => $destination_id)));          }        }        else {          $entity->{$key} = $destination_id;        }        $i++;      }    }    if ($migration->getSystemOfRecord() == Migration::DESTINATION) {      foreach ($this->schema['primary key'] as $key) {        $primary_key[] = $key;        if (!isset($entity->{$key})) {          throw new MigrateException(t('System-of-record is DESTINATION, but no destination id provided'));        }      }      $select = db_select($this->tableName)                ->fields($this->tableName);      foreach ($this->schema['primary key'] as $key) {        $select->condition($key, $entity->{$key});      }      $old_entity = $select->execute()->fetchObject();      if (empty($old_entity)) {        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;      }      $entity = $old_entity;    }    $this->prepare($entity, $row);    $status = drupal_write_record($this->tableName, $entity, $primary_key);    $this->complete($entity, $row);    if ($status) {      $id = array();      foreach ($this->schema['primary key'] as $key) {        $id[] = $entity->{$key};      }      // Increment the number of updated or inserted records by checking the      // result of drupal_write_record.      ($status == SAVED_NEW) ? $this->numCreated++ : $this->numUpdated++;      return $id;    }  }  /**   * Returns a list of fields available to be mapped.   *   * @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.   */  public function fields($migration = NULL) {    $fields = array();    foreach ($this->schema['fields'] as $column => $schema) {      $fields[$column] = t('Type: !type', array('!type' => $schema['type']));    }    return $fields;  }  /**   * Give handlers a shot at modifying the object before saving it.   *   * @param $entity   *  Entity object to build. Prefilled with any fields mapped in the Migration.   * @param $source_row   *  Raw source data object - passed through to prepare handlers.   */  public function prepare($entity, stdClass $source_row) {    $migration = Migration::currentMigration();    $entity->migrate = array(      'machineName' => $migration->getMachineName(),    );    // Call any prepare handler for this specific Migration.    if (method_exists($migration, 'prepare')) {      $migration->prepare($entity, $source_row);    }  }  /**   * Give handlers a shot at modifying the object (or taking additional action)   * after saving it.   *   * @param $object   *  Entity object to build. This is the complete object after saving.   * @param $source_row   *  Raw source data object - passed through to complete handlers.   */  public function complete($entity, stdClass $source_row) {    $migration = Migration::currentMigration();    // Call any complete handler for this specific Migration.    if (method_exists($migration, 'complete')) {      $migration->complete($entity, $source_row);    }  }}
 |