You are here

protected static function FeedImport::processFeedChunked in Feed Import 7

Imports and process a huge xml in chunks

Parameters

array $feed: Feed info array

Return value

array An array of objects

File

./feed_import.inc.php, line 910
Feed import class for parsing and processing content

Class

FeedImport
@file Feed import class for parsing and processing content

Code

protected static function processFeedChunked(array $feed) {

  // This will hold all generated entities
  $entities = array();

  // XML head
  $xml_head = '<?xml version="1.0" encoding="utf-8"?>';

  // Bytes read with fread
  $chunk_length = 8192;
  $xml_head = variable_get('feed_import_processFeedChunked_xml_head', $xml_head);
  $chunk_length = variable_get('feed_import_processFeedChunked_chunk_length', $chunk_length);
  if ($chunk_length <= 0) {
    $chunk_length = 8192;
  }

  // Open xml url
  try {
    $fp = fopen($feed['url'], 'rb');
  } catch (Exception $e) {
    return NULL;
  }

  // Preparing tags
  $tag = trim($feed['xpath']['#root'], '/');
  $tag = array(
    'open' => '<' . $tag,
    'close' => '</' . $tag . '>',
    'length' => drupal_strlen($tag),
  );
  $tag['closelength'] = drupal_strlen($tag['close']);

  // This holds xml content
  $content = '';

  // Used to avoid problems with tags having same name start
  $continue_from = 0;

  // Read all content in chunks
  while (!feof($fp)) {
    $content .= fread($fp, $chunk_length);

    // If there isn't content read again
    if (!$content) {
      continue;
    }
    while (TRUE) {
      $openpos = strpos($content, $tag['open'], $continue_from);
      $openposclose = $openpos + $tag['length'] + 1;

      // Check for open tag
      if ($openpos === FALSE || !isset($content[$openposclose]) || $content[$openposclose] != ' ' && $content[$openposclose] != '>') {
        $continue_from = $openpos + 1;
        break;
      }
      $continue_from = 0;
      $closepos = strpos($content, $tag['close'], $openposclose);
      if ($closepos === FALSE) {
        break;
      }

      // We have data
      $closepos += $tag['closelength'];

      // Create xml string
      $item = $xml_head . substr($content, $openpos, $closepos - $openpos);

      // New content
      $content = substr($content, $closepos - 1);

      // Create xml object
      try {
        $item = simplexml_load_string($item, self::$simpleXMLElement, LIBXML_NOCDATA);
      } catch (Exception $e) {
        continue;
      }

      // Parse item
      $item = $item
        ->xpath($feed['xpath']['#root']);
      $item = reset($item);
      if (empty($item)) {
        continue;
      }

      // Create entity
      $item = self::createEntity($feed, $item);

      // Put in entities array
      $entities[] = $item;

      // No need anymore
      unset($item);
    }
  }

  // Close file
  // If fp is not a resurce then catch warning
  // Minimum chances for this to happen
  try {
    fclose($fp);
  } catch (Exception $e) {
  }
  unset($feed);

  // Return created items
  return $entities;
}