You are here

public function ParserBase::parse in Feeds XPath Parser 8

File

lib/Drupal/feeds_xpathparser/ParserBase.php, line 72
Contains \Drupal\feeds_xpathparser\ParserBase.

Class

ParserBase
Base class for the HTML and XML parsers.

Namespace

Drupal\feeds_xpathparser

Code

public function parse(FeedInterface $feed, FetcherResultInterface $fetcher_result) {
  $feed_config = $feed
    ->getConfigFor($this);
  $state = $feed
    ->state(FEEDS_PARSE);
  if (empty($feed_config)) {
    $feed_config = $this
      ->getConfig();
  }
  $this->doc = $this
    ->setup($feed_config, $fetcher_result);
  $parser_result = new FeedsParserResult();
  $mappings = $this
    ->getOwnMappings();
  $this->rawXML = array_keys(array_filter($feed_config['raw_xml']));

  // Set link.
  $fetcher_config = $feed
    ->getConfigFor($this->importer->fetcher);
  $parser_result->link = $fetcher_config['source'];
  $this->xpath = new DOMXPath($this->doc);
  $config = array();
  $config['debug'] = array_keys(array_filter($feed_config['debug']));
  $config['errors'] = $feed_config['errors'];
  $this->xpath
    ->setConfig($config);
  $context_query = '(' . $feed_config['context'] . ')';
  if (empty($state->total)) {
    $state->total = $this->xpath
      ->namespacedQuery('count(' . $context_query . ')', 'count', $this->doc);
  }
  $start = $state->pointer ? $state->pointer : 0;
  $limit = $start + $this->importer
    ->getLimit();
  $end = $limit > $state->total ? $state->total : $limit;
  $state->pointer = $end;
  $context_query .= "[position() > {$start} and position() <= {$end}]";
  $progress = $state->pointer ? $state->pointer : 0;
  $all_nodes = $this->xpath
    ->namespacedQuery($context_query, 'context');
  foreach ($all_nodes as $node) {

    // Invoke a hook to check whether the domnode should be skipped.
    if (in_array(TRUE, module_invoke_all('feeds_xpathparser_filter_domnode', $node, $this->doc, $feed), TRUE)) {
      continue;
    }
    $parsed_item = $variables = array();
    foreach ($feed_config['sources'] as $element_key => $query) {

      // Variable substitution.
      $query = strtr($query, $variables);

      // Parse the item.
      $result = $this
        ->parseSourceElement($query, $node, $element_key);
      if (isset($result)) {
        if (!is_array($result)) {
          $variables['$' . $mappings[$element_key]] = $result;
        }
        else {
          $variables['$' . $mappings[$element_key]] = '';
        }
        $parsed_item[$element_key] = $result;
      }
    }
    if (!empty($parsed_item)) {
      $parser_result->items[] = $parsed_item;
    }
  }
  $state
    ->progress($state->total, $progress);
  unset($this->doc);
  unset($this->xpath);
  return $parser_result;
}