You are here

public function CsvParser::parse in Feeds 8.3

Parses content returned by fetcher.

@todo This needs more documentation.

Parameters

\Drupal\feeds\FeedInterface $feed: The feed we are parsing for.

\Drupal\feeds\Result\FetcherResultInterface $fetcher_result: The result returned by the fetcher.

\Drupal\feeds\StateInterface $state: The state object.

Return value

\Drupal\feeds\Result\ParserResultInterface The parser result object.

Overrides ParserInterface::parse

File

src/Feeds/Parser/CsvParser.php, line 31

Class

CsvParser
Defines a CSV feed parser.

Namespace

Drupal\feeds\Feeds\Parser

Code

public function parse(FeedInterface $feed, FetcherResultInterface $fetcher_result, StateInterface $state) {

  // Get sources.
  $sources = [];
  foreach ($feed
    ->getType()
    ->getMappingSources() as $key => $info) {
    if (isset($info['value']) && trim(strval($info['value'])) !== '') {
      $sources[$info['value']] = $key;
    }
  }
  $feed_config = $feed
    ->getConfigurationFor($this);
  if (!filesize($fetcher_result
    ->getFilePath())) {
    throw new EmptyFeedException();
  }

  // Load and configure parser.
  $parser = CsvFileParser::createFromFilePath($fetcher_result
    ->getFilePath())
    ->setDelimiter($feed_config['delimiter'] === 'TAB' ? "\t" : $feed_config['delimiter'])
    ->setHasHeader(!$feed_config['no_headers'])
    ->setStartByte((int) $state->pointer);

  // Wrap parser in a limit iterator.
  $parser = new \LimitIterator($parser, 0, $this->configuration['line_limit']);
  $header = !$feed_config['no_headers'] ? $parser
    ->getHeader() : [];
  $result = new ParserResult();
  foreach ($parser as $row) {
    $item = new DynamicItem();
    foreach ($row as $delta => $cell) {
      $key = isset($header[$delta]) ? $header[$delta] : $delta;

      // Pick machine name of source, if one is found.
      if (isset($sources[$key])) {
        $key = $sources[$key];
      }
      $item
        ->set($key, $cell);
    }
    $result
      ->addItem($item);
  }

  // Report progress.
  $state->total = filesize($fetcher_result
    ->getFilePath());
  $state->pointer = $parser
    ->lastLinePos();
  $state
    ->progress($state->total, $state->pointer);

  // Set progress to complete if no more results are parsed. Can happen with
  // empty lines in CSV.
  if (!$result
    ->count()) {
    $state
      ->setCompleted();
  }
  return $result;
}