You are here

class MigrateSourceSpreadsheet in Migrate 7.2

Implements MigrateSource, to handle imports from XLS files.

Hierarchy

Expanded class hierarchy of MigrateSourceSpreadsheet

File

plugins/sources/spreadsheet.inc, line 19
Define a MigrateSource for importing from spreadsheet files.

View source
class MigrateSourceSpreadsheet extends MigrateSource {

  /**
   * PHPExcel object for storing the workbook data.
   *
   * @var PHPExcel
   */
  protected $workbook;

  /**
   * PHPExcel object for storing the worksheet data.
   *
   * @var PHPExcel_Worksheet
   */
  protected $worksheet;

  /**
   * The name of the worksheet that will be processed.
   *
   * @var string
   */
  protected $sheetName;

  /**
   * Number of rows in the worksheet that is being processed.
   *
   * @var integer
   */
  protected $rows = 0;

  /**
   * Number of columns in the worksheet that is being processed.
   *
   * @var integer
   */
  protected $cols = 0;

  /**
   * List of available source fields.
   *
   * @var array
   */
  protected $fields = array();

  /**
   * The current row number in the XLS file.
   *
   * @var integer+
   */
  protected $rowNumber;

  /**
   * The columns to be read from Excel
   */
  protected $columns;

  /**
   * The first row from where the table starts. It's a "zero based" value.
   *
   * @var int
   */
  protected $headerRows = 0;

  /**
   * Simple initialization.
   *
   * @param string $path
   *   The path to the source file.
   * @param string $sheet_name
   *   The name of the sheet to be processed.
   * @param array $options
   *   Options applied to this source. If the source data begins on different
   *   row than the first row, pass this "zero based" value as 'header_rows' in
   *   options, along with other options inherited from MigrateSource.
   */
  public function __construct($path, $sheet_name, $columns = array(), array $options = array()) {
    parent::__construct($options);
    $this->file = $path;
    $this->sheetName = $sheet_name;
    $this->columns = $columns;
    if (!empty($options['header_rows'])) {
      $this->headerRows = $options['header_rows'];
    }

    // Load the workbook.
    if ($this
      ->load()) {

      // Get the dimensions of the worksheet.
      $this->rows = $this->worksheet
        ->getHighestDataRow();
      $this->cols = PHPExcel_Cell::columnIndexFromString($this->worksheet
        ->getHighestDataColumn());

      // Map field names to their column index.
      for ($col = 0; $col < $this->cols; ++$col) {
        $this->fields[$col] = trim($this->worksheet
          ->getCellByColumnAndRow($col, $this->headerRows + 1)
          ->getValue());
      }
      $this
        ->unload();
    }
  }

  /**
   * Loads the workbook.
   *
   * @return bool
   *   Returns true if the workbook was successfully loaded, otherwise false.
   */
  public function load() {

    // Check that the file exists.
    if (!file_exists($this->file)) {
      Migration::displayMessage(t('The file !filename does not exist.', array(
        '!filename' => $this->file,
      )));
      return FALSE;
    }

    // Check that required modules are enabled.
    if (!module_exists('libraries')) {
      Migration::displayMessage(t('The Libraries API module is not enabled.'));
      return FALSE;
    }
    if (!module_exists('phpexcel')) {
      Migration::displayMessage(t('The PHPExcel module is not enabled.'));
      return FALSE;
    }
    $library = libraries_load('PHPExcel');
    if (empty($library['loaded'])) {
      Migration::displayMessage(t('The PHPExcel library could not be found.'));
      return FALSE;
    }

    // Load the workbook.
    try {

      // Identify the type of the input file.
      $type = PHPExcel_IOFactory::identify($this->file);

      // Create a new Reader of the file type.
      $reader = PHPExcel_IOFactory::createReader($type);

      // Advise the Reader that we only want to load cell data.
      $reader
        ->setReadDataOnly(TRUE);

      // Advise the Reader of which worksheet we want to load.
      $reader
        ->setLoadSheetsOnly($this->sheetName);

      // Load the source file.
      $this->workbook = $reader
        ->load($this->file);
      $this->worksheet = $this->workbook
        ->getSheet();
    } catch (Exception $e) {
      Migration::displayMessage(t('Error loading file: %message', array(
        '%message' => $e
          ->getMessage(),
      )));
      return FALSE;
    }
    return TRUE;
  }

  /**
   * Unloads the workbook.
   */
  public function unload() {
    $this->workbook
      ->disconnectWorksheets();
    unset($this->workbook);
  }

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

  /**
   * Returns a list of fields available to be mapped from the source query.
   *
   * @return array
   *   Keys: machine names of the fields (to be passed to addFieldMapping).
   *   Values: Human-friendly descriptions of the fields.
   */
  public function fields() {
    $fields = array();
    foreach ($this->fields as $name) {
      $fields[$name] = $name;
    }
    return $fields;
  }

  /**
   * Returns a count of all available source records.
   */
  public function computeCount() {

    // Subtract the non-data rows (rows before header and the header).
    return $this->rows - $this->headerRows - 1;
  }

  /**
   * Implements MigrateSource::performRewind().
   *
   * @return void
   */
  public function performRewind() {

    // Initialize the workbook if it isn't already.
    if (!isset($this->workbook)) {
      $this
        ->load();
    }
    $this->rowNumber = $this->headerRows + 1;
  }

  /**
   * Implements MigrateSource::getNextRow().
   *
   * @return null|object
   */
  public function getNextRow() {
    migrate_instrument_start('MigrateSourceSpreadsheet::next');
    ++$this->rowNumber;
    if ($this->rowNumber <= $this->rows) {
      $row_values = array();
      for ($col = 0; $col < $this->cols; ++$col) {
        if (in_array($this->fields[$col], $this->columns) || empty($this->columns)) {
          $row_values[$this->fields[$col]] = trim($this->worksheet
            ->getCellByColumnAndRow($col, $this->rowNumber)
            ->getValue());
        }
      }
      return (object) $row_values;
    }
    else {

      // EOF, close the workbook.
      $this
        ->unload();
      migrate_instrument_stop('MigrateSourceSpreadsheet::next');
      return NULL;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
MigrateSource::$activeMap protected property The MigrateMap class for the current migration.
MigrateSource::$activeMigration protected property The Migration class currently invoking us, during rewind() and next().
MigrateSource::$cacheCounts protected property Whether this instance should cache the source count.
MigrateSource::$cacheKey protected property Key to use for caching counts.
MigrateSource::$currentKey protected property The primary key of the current row
MigrateSource::$currentRow protected property The current row from the quey
MigrateSource::$highwaterField protected property Information on the highwater mark for the current migration, if any.
MigrateSource::$idList protected property List of source IDs to process.
MigrateSource::$mapRowAdded protected property By default, next() will directly read the map row and add it to the data row. A source plugin implementation may do this itself (in particular, the SQL source can incorporate the map table into the query) - if so, it should set this TRUE so we…
MigrateSource::$multikeySeparator protected property Used in the case of multiple key sources that need to use idlist.
MigrateSource::$numIgnored protected property Number of rows intentionally ignored (prepareRow() returned FALSE)
MigrateSource::$numProcessed protected property Number of rows we've at least looked at. 1
MigrateSource::$originalHighwater protected property The highwater mark at the beginning of the import operation.
MigrateSource::$skipCount protected property Whether this instance should not attempt to count the source.
MigrateSource::$trackChanges protected property If TRUE, we will maintain hashed source rows to determine whether incoming data has changed.
MigrateSource::count public function Return a count of available source records, from the cache if appropriate. Returns -1 if the source is not countable.
MigrateSource::current public function Implementation of Iterator::current() - called when entering a loop iteration, returning the current row
MigrateSource::dataChanged protected function Determine whether this row has changed, and therefore whether it should be processed.
MigrateSource::getCurrentKey public function
MigrateSource::getIgnored public function
MigrateSource::getProcessed public function
MigrateSource::hash protected function Generate a hash of the source row. 3
MigrateSource::key public function Implementation of Iterator::key - called when entering a loop iteration, returning the key of the current row. It must be a scalar - we will serialize to fulfill the requirement, but using getCurrentKey() is preferable.
MigrateSource::next public function Implementation of Iterator::next() - subclasses of MigrateSource should implement getNextRow() to retrieve the next valid source rocord to process.
MigrateSource::prepareRow protected function Give the calling migration a shot at manipulating, and possibly rejecting, the source row.
MigrateSource::resetStats public function Reset numIgnored back to 0.
MigrateSource::rewind public function Implementation of Iterator::rewind() - subclasses of MigrateSource should implement performRewind() to do any class-specific setup for iterating source records.
MigrateSource::valid public function Implementation of Iterator::valid() - called at the top of the loop, returning TRUE to process the loop and FALSE to terminate it
MigrateSourceSpreadsheet::$cols protected property Number of columns in the worksheet that is being processed.
MigrateSourceSpreadsheet::$columns protected property The columns to be read from Excel
MigrateSourceSpreadsheet::$fields protected property List of available source fields.
MigrateSourceSpreadsheet::$headerRows protected property The first row from where the table starts. It's a "zero based" value.
MigrateSourceSpreadsheet::$rowNumber protected property The current row number in the XLS file.
MigrateSourceSpreadsheet::$rows protected property Number of rows in the worksheet that is being processed.
MigrateSourceSpreadsheet::$sheetName protected property The name of the worksheet that will be processed.
MigrateSourceSpreadsheet::$workbook protected property PHPExcel object for storing the workbook data.
MigrateSourceSpreadsheet::$worksheet protected property PHPExcel object for storing the worksheet data.
MigrateSourceSpreadsheet::computeCount public function Returns a count of all available source records.
MigrateSourceSpreadsheet::fields public function Returns a list of fields available to be mapped from the source query. Overrides MigrateSource::fields
MigrateSourceSpreadsheet::getNextRow public function Implements MigrateSource::getNextRow().
MigrateSourceSpreadsheet::load public function Loads the workbook.
MigrateSourceSpreadsheet::performRewind public function Implements MigrateSource::performRewind().
MigrateSourceSpreadsheet::unload public function Unloads the workbook.
MigrateSourceSpreadsheet::__construct public function Simple initialization. Overrides MigrateSource::__construct
MigrateSourceSpreadsheet::__toString public function Returns a string representing the source query.