Skip to content

Instantly share code, notes, and snippets.

@chx
Created February 28, 2015 05:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chx/bff738ac8bb049e7c5e3 to your computer and use it in GitHub Desktop.
Save chx/bff738ac8bb049e7c5e3 to your computer and use it in GitHub Desktop.
Refactoring fun with benjy
public function next() {
$this->currentIds = NULL;
$this->currentRow = NULL;
$source_configuration = $this->migration->get('source');
while ($this->getIterator()->valid()) {
$row_data = $this->getIterator()->current() + $source_configuration;
$this->getIterator()->next();
$row = new Row($row_data, $this->migration->getSourcePlugin()->getIds(), $this->migration->get('destinationIds'));
// Populate the source key for this row.
$this->currentIds = $row->getSourceIdValues();
// Pick up the existing map row, if any, unless getNextRow() did it.
if (!$this->mapRowAdded && ($id_map = $this->idMap->getRowBySource($this->currentIds))) {
$row->setIdMap($id_map);
}
// First, determine if this row should be passed to prepareRow(), or
// skipped entirely. The rules are:
// 1. If there's an explicit idlist, that's all we care about (ignore
// high waters and map rows).
$prepared = FALSE;
if (!empty($this->idList)) {
if (in_array(reset($this->currentIds), $this->idList)) {
// In the list, fall through.
}
else {
// Not in the list, skip it.
continue;
}
}
// 2. If the row is not in the map (we have never tried to import it
// before), we always want to try it.
elseif (!$row->getIdMap()) {
// Fall through
}
// 3. If the row is marked as needing update, pass it.
elseif ($row->needsUpdate()) {
// Fall through.
}
// 4. At this point, we have a row which has previously been imported and
// not marked for update. If we're not using high water marks, then we
// will not take this row. Except, if we're looking for changes in the
// data, we need to go through prepareRow() before we can decide to
// skip it.
elseif (!empty($this->highWaterProperty['field'])) {
if ($this->trackChanges) {
if ($this->prepareRow($row) !== FALSE) {
if ($row->changed()) {
// This is a keeper
$this->currentRow = $row;
break;
}
else {
// No change, skip it.
continue;
}
}
else {
// prepareRow() told us to skip it.
continue;
}
}
else {
// No high water and not tracking changes, skip.
continue;
}
}
// 5. The initial high water mark, before anything is migrated, is ''. We
// want to make sure we don't mistakenly skip rows with a high water
// field value of 0, so explicitly handle '' here.
elseif ($this->originalHighWater === '') {
// Fall through
}
// 6. So, we are using high water marks. Take the row if its high water
// field value is greater than the saved mark, otherwise skip it.
else {
// Call prepareRow() here, in case the highWaterField needs preparation.
if ($this->prepareRow($row) !== FALSE) {
if ($row->getSourceProperty($this->highWaterProperty['name']) > $this->originalHighWater) {
$this->currentRow = $row;
break;
}
else {
// Skip.
continue;
}
}
$prepared = TRUE;
}
// Allow the Migration to prepare this row. prepareRow() can return
// boolean FALSE to ignore this row.
if (!$prepared) {
if ($this->prepareRow($row) !== FALSE) {
// Finally, we've got a keeper.
$this->currentRow = $row;
break;
}
else {
$this->currentRow = NULL;
}
}
}
if ($this->currentRow) {
$this->currentRow->freezeSource();
}
else {
$this->currentIds = NULL;
}
}
public function next() {
$this->currentSourceIds = NULL;
$this->currentRow = NULL;
$source_configuration = $this->migration->get('source');
// In order to find the next row we want to process, we ask the source
// plugin for the next possible row.
while (!isset($this->currentRow) && $this->getIterator()->valid()) {
$row_data = $this->getIterator()->current() + $source_configuration;
$this->getIterator()->next();
$row = new Row($row_data, $this->migration->getSourcePlugin()->getIds(), $this->migration->get('destinationIds'));
if ($this->prepareRow($row) === FALSE) {
continue;
}
// Populate the source key for this row.
$this->currentSourceIds = $row->getSourceIdValues();
// Pick up the existing map row, if any, unless getNextRow() did it.
if (!$this->mapRowAdded && ($id_map = $this->idMap->getRowBySource($this->currentSourceIds))) {
$row->setIdMap($id_map);
}
$id_in_the_list = $this->idList && in_array(reset($this->currentSourceIds), $this->idList);
// In case we have specified an ID list, but the ID given by the source is
// not in there, we skip the row.
if ($this->idList && !$id_in_the_list) {
continue;
}
// Check whether the row needs processing.
// 1. Explicitly specified IDs.
// 2. This row has not been imported yet.
// 3. Explicitly set to update.
// 4. The row is newer than the current highwater mark.
// 5. If no such property exists then try by checking the hash of the row.
if ($id_in_the_list || !$row->getIdMap() || $row->needsUpdate() || $this->aboveHighwater($row) || $this->rowChanged($row) ) {
$this->currentRow = $row->freezeSource();
}
}
}
/**
* Check if the incoming data is newer than what we've previously imported.
*
* @param \Drupal\migrate\Row $row
* The row we're importing.
*
* @return bool
* TRUE if the highwater value in the row is greater than our current value.
*/
protected function aboveHighwater(Row $row) {
return $this->highWaterProperty && $row->getSourceProperty($this->highWaterProperty['name']) > $this->originalHighWater;
}
/**
* Check if the row has changed.
*
* @param \Drupal\migrate\Row $row
* The row we're importing.
*
* @return bool
* TRUE if the row has changed otherwise FALSE.
*/
protected function rowChanged(Row $row) {
return $this->trackChanges && $row->changed();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment