Implementing your own source class - say you're migrating from a database system not supported by Migrate, or from some unusual file format - is not that difficult. You simply need to derive a class from MigrateSource, and implement a few simple methods (well, how simple they are depends on your source...).

Here's a very simple source class that generates ten sample source rows. For more sophisticated examples, review the source classes implemented by Migrate itself in plugins/sources.

class SimpleMigrateSource extends MigrateSource {
  protected $currentId;
  protected $numRows;

  // Your constructor will initialize any parameters to your migration. It's
  // important to pass through the options, so general options such as
  // cache_counts will work.
  public function __construct($num_rows = 10, array $options = array()) {
    parent::__construct($options);
    $this->numRows = $num_rows;
  }

  /**
   * Return a string representing the source, for display in the UI.
   */
  public function __toString() {
    return t('Generate %num sample rows', array('%num' => $this->numRows));
  }

  /**
   * Returns a list of fields available to be mapped from the source,
   * keyed by field name.
   */
  public function fields() {
    return array(
  		'id' => t('ID'),
  		'title' => t('Title'),
  		'body' => t('Body'),
    );
  }
  
  /**
   * Return the number of available source records.
   */
  public function computeCount() {
    return $this->numRows;
  }

  /**
   * Do whatever needs to be done to start a fresh traversal of the source data.
   *
   * This is always called at the start of an import, so tasks such as opening 
   * file handles, running queries, and so on should be performed here.
   */
  public function performRewind() {
    $this->currentId = 1;
  }

  /**
   * Fetch the next row of data, returning it as an object. Return FALSE
   * when there is no more data available.
   */
  public function getNextRow() {
    if ($this->currentId <= $this->numRows) {
      $row = new stdClass;
      $row->id = $this->currentId;
      $row->title = 'Sample title ' . $row->id;
      $row->body = 'Sample body';
      $this->currentId++;
      return $row;
    }
    else {
      return NULL;
    }
  }
}

Comments

gaas’s picture

MigrateSource subclasses should not override rewind() and next() directly. They should instead create performRewind() and getNextRow() methods. If you don't do that all the bookkeeping that migrate does is lost.

mikeryan’s picture

OK, rewritten to use the current MigrateSource API.