You are here

public function FeedsExcelParser::parse in Feeds Excel 7.2

Same name and namespace in other branches
  1. 6 ExcelParser.inc \FeedsExcelParser::parse()
  2. 7 ExcelParser.inc \FeedsExcelParser::parse()

File

./FeedsExcelParser.inc, line 74
Contains FeedsExcelParser.

Class

FeedsExcelParser
Provides feeds parser class for Excel files.

Code

public function parse(FeedsSource $source, FeedsFetcherResult $fetcher_result) {

  // Init vars.
  $this
    ->initFilePath($fetcher_result);
  $this
    ->initLibrary();
  $this
    ->initReader();

  // Init state. Use two pointers: global and by sheet.
  $state = $source
    ->state(FEEDS_PARSE);
  $state->total = !empty($state->total) ? $state->total : $this
    ->getTotal();
  $state->pointer = !empty($state->pointer) ? $state->pointer : array(
    'sheet_pointer' => 1,
    'processed_rows' => array(),
  );

  // Prepare to parsing.
  $items = array();
  $filter = new FeedsExcelParserIReadFilter($state->pointer['sheet_pointer'], $this->config['chunk_size']);
  $this->reader
    ->setReadFilter($filter);
  $excel = $this->reader
    ->load($this->file_path);

  // Setup parse type.
  switch ($this->config['sheets']['parse_type']) {
    case 'first':
      $sheets = array(
        $excel
          ->getSheet(),
      );
      break;
    case 'title':
      $sheets = array(
        $excel
          ->getSheetByName($this->config['sheets']['parse_value']),
      );
      break;
    case 'index':
      $sheets = array(
        $excel
          ->getSheet($this->config['sheets']['parse_value']),
      );
      break;
    default:
      $sheets = $excel
        ->getWorksheetIterator();
  }

  // Check for errors.
  if (is_array($sheets) && in_array(NULL, $sheets)) {
    throw new Exception(t('Wrong sheet !type: !value.', array(
      '!type' => $this->config['sheets']['parse_type'],
      '!value' => $this->config['sheets']['parse_value'],
    )));
  }

  // Parse values.
  foreach ($sheets as $sheet) {
    foreach ($sheet
      ->getRowIterator() as $row_index => $row) {

      // Generate row key.
      $row_key = implode('__', array(
        $sheet
          ->getTitle(),
        $row_index,
      ));

      // Iterate cells.
      foreach ($row
        ->getCellIterator() as $cell_index => $cell) {

        // Detect headers row.
        if (!$this->config['no_headers'] && $row_index === 1 && !is_null($header = $cell
          ->getCalculatedValue())) {
          $state->pointer['headers'][$cell_index] = $header;
          continue;
        }

        // Detect cell index and put values if not empty.
        $cell_key = !$this->config['no_headers'] && !empty($state->pointer['headers'][$cell_index]) ? $state->pointer['headers'][$cell_index] : $cell_index;
        $value = $this->config['calculate'] ? $cell
          ->getCalculatedValue() : $cell
          ->getValue();
        if (!is_null($value)) {
          $items[$row_key][$cell_key] = $value;
        }
      }

      // Add sheet title to values.
      if (isset($items[$row_key]) && !empty($this->config['sheets']['map_title'])) {
        $items[$row_key][$this->config['sheets']['map_title']] = $sheet
          ->getTitle();
      }

      // Increment row pointer.
      $state->pointer['sheet_pointer'] = $row_index + 1;

      // Save row as processed.
      $state->pointer['processed_rows'][$row_key] = $row_key;
    }
  }
  $state
    ->progress($state->total, count($state->pointer['processed_rows']));
  return new FeedsParserResult(array_values($items));
}