You are here

class MigrateListCSV in Migrate 7.2

Implementation of MigrateList, for retrieving a list of IDs to be migrated from a CSV file.

Hierarchy

Expanded class hierarchy of MigrateListCSV

File

plugins/sources/csv.inc, line 12
Define a MigrateSource for importing from comma separated values files.

View source
class MigrateListCSV extends MigrateList {

  /**
   * The path to the CSV file containing a list of IDs to be processed.
   *
   * @var string
   */
  protected $file;

  /**
   * File handle for the CSV file being iterated.
   *
   * @var resource
   */
  protected $csvHandle = NULL;

  /**
   * The column which contains the ID.
   *
   * If numeric, this is the index of the column from 0; if non-numeric, this
   * is the column name as given by the header row.
   */
  protected $idColumn;

  /**
   * The number of rows in the CSV file before the data starts.
   *
   * @var integer
   */
  protected $headerRows = 0;

  /**
   * The array keys taken from the first row.
   *
   * @var array
   */
  protected $headers = array();

  /**
   * Parameters for the fgetcsv() call.
   *
   * @var array
   */
  protected $fgetcsv = array();

  /**
   * Constructor for MigrateListCSV.
   *
   * @param $list_path
   *  The path to the CSV file that holds the list of IDs.
   * @param $id_column
   *  The column in the file that holds the IDs. A numeric index for the column,
   *  from 0.
   * @param $options = array()
   *  An array of further options for the CSV file.
   */
  public function __construct($list_path, $id_column, $options = array()) {
    parent::__construct();
    $this->file = $list_path;
    $this->idColumn = $id_column;
    $this->options = $options;

    // fgetcsv specific options
    foreach (array(
      'length' => NULL,
      'delimiter' => ',',
      'enclosure' => '"',
      'escape' => '\\',
    ) as $key => $default) {
      $this->fgetcsv[$key] = isset($options[$key]) ? $options[$key] : $default;
    }
    if (!empty($options['header_rows'])) {
      $this->headerRows = $options['header_rows'];
    }
    else {
      $this->headerRows = 0;
    }
    if (!is_numeric($id_column)) {

      //we need to store the headers.
      $this->csvHandle = fopen($this->file, 'r');
      if (!$this
        ->validResource()) {
        return;
      }
      $this->headers = $this
        ->getNextLine();
      fclose($this->csvHandle);
      $this->csvHandle = NULL;
    }
  }

  /**
   * Return a string representing the source file.
   *
   * @return string
   */
  public function __toString() {
    return $this->file;
  }

  /**
   * Return an array of IDs from the CSV file.
   *
   * @return array
   */
  public function getIdList() {
    $ids = array();
    $this->csvHandle = fopen($this->file, 'r');
    if (!$this
      ->validResource()) {
      return $ids;
    }

    // Skip the headers if any,
    for ($i = 0; $i < $this->headerRows; $i++) {
      $this
        ->getNextLine();
    }
    while ($row = $this
      ->getNextLine()) {
      $ids[] = $row[$this->idColumn];
    }
    fclose($this->csvHandle);
    $this->csvHandle = NULL;
    return $ids;
  }

  /**
   * Return a count of all available IDs from the source listing.
   *
   * @return integer
   */
  public function computeCount() {

    // If the data may have embedded newlines, the file line count won't reflect
    // the number of CSV records (one record will span multiple lines). We need
    // to scan with fgetcsv to get the true count.
    if (!empty($this->options['embedded_newlines'])) {
      $this->csvHandle = fopen($this->file, 'r');
      $count = 0;
      if (!$this
        ->validResource()) {
        return $count;
      }

      // Skip header rows
      for ($i = 0; $i < $this->headerRows; $i++) {
        $this
          ->getNextLine();
      }
      while ($this
        ->getNextLine()) {
        $count++;
      }
      fclose($this->csvHandle);
      $this->csvHandle = NULL;
    }
    else {
      $file = new SplFileObject($this->file, 'r');
      $file
        ->seek(PHP_INT_MAX);
      $count = $file
        ->key() + 1;
      $file
        ->rewind();
      $count -= $this->headerRows;
    }
    return $count;
  }

  /**
   * Get the next line of the CSV file.
   * Returns an array of the next line, keyed by headers if required
   *
   * @return array
   */
  protected function getNextLine() {

    // escape parameter was added in PHP 5.3.
    if (version_compare(phpversion(), '5.3', '<')) {
      $row = fgetcsv($this->csvHandle, $this->fgetcsv['length'], $this->fgetcsv['delimiter'], $this->fgetcsv['enclosure']);
    }
    else {
      $row = fgetcsv($this->csvHandle, $this->fgetcsv['length'], $this->fgetcsv['delimiter'], $this->fgetcsv['enclosure'], $this->fgetcsv['escape']);
    }

    // Key the array with the headers
    if (!empty($this->headers) && $row) {
      $row = array_combine($this->headers, $row);
    }
    return $row;
  }

  /**
   * Check if resource loaded correctly.
   *
   * @return bool
   */
  public function validResource() {
    if (!$this->csvHandle) {
      Migration::displayMessage(t('Could not open CSV file !url', array(
        '!url' => $this->file,
      )));
    }
    return (bool) $this->csvHandle;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
MigrateListCSV::$csvHandle protected property File handle for the CSV file being iterated.
MigrateListCSV::$fgetcsv protected property Parameters for the fgetcsv() call.
MigrateListCSV::$file protected property The path to the CSV file containing a list of IDs to be processed.
MigrateListCSV::$headerRows protected property The number of rows in the CSV file before the data starts.
MigrateListCSV::$headers protected property The array keys taken from the first row.
MigrateListCSV::$idColumn protected property The column which contains the ID.
MigrateListCSV::computeCount public function Return a count of all available IDs from the source listing. Overrides MigrateList::computeCount
MigrateListCSV::getIdList public function Return an array of IDs from the CSV file. Overrides MigrateList::getIdList
MigrateListCSV::getNextLine protected function Get the next line of the CSV file. Returns an array of the next line, keyed by headers if required
MigrateListCSV::validResource public function Check if resource loaded correctly.
MigrateListCSV::__construct public function Constructor for MigrateListCSV. Overrides MigrateList::__construct
MigrateListCSV::__toString public function Return a string representing the source file. Overrides MigrateList::__toString