You are here

public function views_xml_backend_plugin_query_xml::parse in Views XML Backend 7

Same name and namespace in other branches
  1. 6 views_xml_backend_plugin_query_xml.inc \views_xml_backend_plugin_query_xml::parse()
1 call to views_xml_backend_plugin_query_xml::parse()
views_xml_backend_plugin_query_xml::execute in ./views_xml_backend_plugin_query_xml.inc
Executes the query and fills the associated view object with according values.

File

./views_xml_backend_plugin_query_xml.inc, line 191
Contains views_xml_backend_plugin_query_xml.

Class

views_xml_backend_plugin_query_xml
@file Contains views_xml_backend_plugin_query_xml.

Code

public function parse(&$view, $data) {

  // The appropriate error messages will be displayed automatically.
  if (!($doc = $this
    ->get_dom_document($data->contents))) {
    return;
  }
  $xpath = new DOMXPath($doc);

  // Create a simplexml object so that we can use
  // SimpleXMLElement::getNamespaces().
  // Does anyone know a better way to do this?
  $simple = simplexml_import_dom($doc);
  if (!$simple) {
    return;
  }
  $namespaces = $simple
    ->getNamespaces(TRUE);

  // Register namespaces. Allow for overriding the default namespace.
  foreach ($namespaces as $prefix => $namespace) {
    if ($prefix === '') {
      if (empty($this->options['default_namespace'])) {
        $prefix = 'default';
      }
      else {
        $prefix = $this->options['default_namespace'];
      }
    }
    $xpath
      ->registerNamespace($prefix, $namespace);
  }
  try {
    if ($this->pager
      ->use_count_query() || !empty($view->get_total_rows)) {

      // $this->pager->execute_count_query($count_query);
      // Hackish execute_count_query implementation.
      $this->pager->total_items = $xpath
        ->evaluate($view->build_info['count_query']);
      if (!empty($this->pager->options['offset'])) {
        $this->pager->total_items -= $this->pager->options['offset'];
      }
      $this->pager
        ->update_page_info();
    }

    // Let the pager modify the query to add limits.
    $this->pager
      ->pre_execute($view->build_info['query']);

    // Used to keep track of query misses when previewing.
    $in_preview = !empty($view->live_preview);

    // Get the rows.
    $rows = $xpath
      ->query($view->build_info['query']);
    $result = array();
    $duds = array();
    foreach ($rows as $row) {
      $item = new stdClass();

      // Query each field per row.
      foreach ($this->fields as $field) {
        $field_key = $field['field'];
        if (!$field_key) {
          continue;
        }
        $node_list = $xpath
          ->evaluate($field_key, $row);

        // It can happen that a field is not present, but the path is valid.
        // In that case, the evaluate function returns an empty list.
        if ($node_list && $node_list->length > 0) {

          // Allow multiple values in a field.
          if (!empty($field['multiple'])) {
            $item->{$field_key} = array();
            foreach ($node_list as $node) {
              $item->{$field_key}[] = $node->nodeValue;
            }
          }
          else {
            $item->{$field_key} = $node_list
              ->item(0)->nodeValue;
          }
        }
        else {

          // Make sure all of the fields are set. Allows us to do less error
          // checking later on.
          $item->{$field_key} = NULL;

          // Track empty results during preview for later assistance.
          if ($in_preview) {
            if (!isset($duds[$field_key])) {
              $duds[$field_key] = 0;
            }
            $duds[$field_key]++;
          }
        }
      }
      $result[] = $item;
    }

    // Give some feedback if we are previewing and a field is not returning
    // any values.
    if ($in_preview) {
      $count = count($result);
      foreach ($duds as $field_key => $empty_count) {
        if ($count == $empty_count) {
          drupal_set_message(t('Field %field never returned a valid result.', array(
            '%field' => $field_key,
          )), 'warning');
        }
      }
    }
    if (!empty($this->orderby)) {

      // Array reverse, because the most specific are first.
      foreach (array_reverse($this->orderby) as $orderby) {
        if ($orderby == 'rand') {
          shuffle($result);
        }
        else {
          $orderby
            ->sort($result);
        }
      }
    }
    if (!empty($this->limit) || !empty($this->offset)) {
      $result = array_slice($result, $this->offset, $this->limit, TRUE);
    }
    $view->result = $result;
    $view->total_rows = count($result);
    $this->pager
      ->post_execute($view->result);
  } catch (Exception $e) {
    $view->result = array();
    if (!empty($view->live_preview)) {
      drupal_set_message(time());
      drupal_set_message($e
        ->getMessage(), 'error');
    }
    else {
      debug($e
        ->getMessage(), 'Views XML Backend');
    }
  }
}