idList; } /** * List of available source fields. * * @var array */ protected $fields = array(); /** * Keep the current source ID handy while iterating. * @var string */ protected $id; /** * Simple initialization. */ public function __construct(MigrateList $list_class, MigrateItem $item_class, $fields = array()) { parent::__construct(); $this->listClass = $list_class; $this->itemClass = $item_class; $this->fields = $fields; } /** * Return a string representing the source. * * @return string */ public function __toString() { return (string) $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, * it's up to the implementing Migration constructor to fill them in. * * @return array * Keys: machine names of the fields (to be passed to addFieldMapping) * Values: Human-friendly descriptions of the fields. */ public function fields() { return $this->fields; } /** * It's the list class that knows how many records are available, so ask it. * * @param boolean $refresh * * @return int */ public function count($refresh = FALSE) { return $this->listClass->count($refresh); } /** * Implementation of Iterator::rewind() - called before beginning a foreach loop. */ public function rewind() { $migration = Migration::currentMigration(); migrate_instrument_start('MigrateSourceList rewind'); $this->numProcessed = 0; $idlist = $migration->getOption('idlist'); if ($idlist) { $this->idList = explode(',', $idlist); } else { $this->idList = $this->listClass->getIdList(); } migrate_instrument_stop('MigrateSourceList rewind'); // Load up the first row $this->next(); } /** * Implementation of Iterator::next() - called at the bottom of the loop implicitly, * as well as explicitly from rewind(). */ public function next() { $migration = Migration::currentMigration(); migrate_instrument_start('MigrateSourceList next'); $this->currentRow = NULL; $this->currentKey = NULL; // Enforce the itemlimit $itemlimit = $migration->getOption('itemlimit'); // Get next item (next ID not already in the map, unless needs_update=1) while ($this->id = array_shift($this->idList)) { // Enforce the itemlimit if ($itemlimit && $this->numProcessed >= $itemlimit) { return; } // Check the map - if it's already mapped, and not marked for update, skip it $map_row = $migration->getMap()->getRowBySource(array($this->id)); if ($map_row && $map_row['needs_update'] == 0) { continue; } // TODO: Also check message table (non-informational entries here indicate failed items, we don't // want to run through them again) $this->currentRow = $this->itemClass->getItem($this->id); if ($this->currentRow) { $this->currentKey = array($this->id); // Save the ID using the map source key - it will be used for mapping $sourceKey = $migration->getMap()->getSourceKey(); $key_name = key($sourceKey); $this->currentRow->$key_name = $this->id; // Add map info to the row, if present if ($map_row) { foreach ($map_row as $field => $value) { $field = 'migrate_map_' . $field; $this->currentRow->$field = $value; } } // Allow the Migration to prepare this row. prepareRow() can return boolean // FALSE to stop processing this row. To add/modify fields on the // result, modify $row by reference. $return = TRUE; if (method_exists($migration, 'prepareRow')) { $return = $migration->prepareRow($this->currentRow); } if ($return !== FALSE) { // OK, got a valid one, break out and return $this->numProcessed++; break; } } else { $this->currentKey = NULL; } } migrate_instrument_stop('MigrateSourceList next'); } }