You are here

views_xml.module in Views Datasource 5

Same filename and directory in other branches
  1. 6 views_xml.module
  2. 7 views_xml.module

views_xml.module - provides Views plugin for rendering node content as XML.

File

views_xml.module
View source
<?php

/**
 * @file
 * views_xml.module - provides Views plugin for rendering node content as XML.
 */

/**
 *  Implementation of hook_views_style_plugins
 */
function views_xml_views_style_plugins() {
  return array(
    'views_xml_raw' => array(
      'name' => t('Views XML: Raw XML data document'),
      'theme' => 'views_xml_raw',
      'needs_table_header' => TRUE,
      'needs_fields' => TRUE,
      'even_empty' => TRUE,
    ),
    'views_xml_opml' => array(
      'name' => t('Views XML: OPML XML data document'),
      'theme' => 'views_xml_opml',
      'needs_table_header' => TRUE,
      'needs_fields' => TRUE,
      'even_empty' => TRUE,
    ),
    'views_xml_atom' => array(
      'name' => t('Views XML: Atom XML data document'),
      'theme' => 'views_xml_atom',
      'needs_table_header' => TRUE,
      'needs_fields' => TRUE,
      'even_empty' => TRUE,
    ),
  );
}

/*
 * Implementation of hook_views_arguments to add the XML
 * and OPML argument selectors.
 * @returns array of view arguments
 */
function views_xml_views_arguments() {
  $arguments = array(
    'xml_raw' => array(
      'name' => t('Views XML: raw XML data document selector'),
      'handler' => 'views_xml_views_handler',
      'option' => 'string',
      'help' => t('This argument specifies a Raw XML data document selector; it will only provide a method for rendering the current view as raw XML.'),
    ),
    'xml_opml' => array(
      'name' => t('Views XML: OPML XML data document selector'),
      'handler' => 'views_xml_views_handler',
      'option' => 'string',
      'help' => t('This argument specifies a OPML XML data document selector; it will only provide a method for rendering the current view as OPML.'),
    ),
    'xml_atom' => array(
      'name' => t('Views XML: Atom XML data document selector'),
      'handler' => 'views_xml_views_handler',
      'option' => 'string',
      'help' => t('This argument specifies an Atom XML data document selector; it will only provide a method for rendering the current view in the Atom XML format.'),
    ),
  );
  return $arguments;
}

/**
 * handler for our own raw-XML or OPML or structured-XML argument handler
 */
function views_xml_views_handler($op, &$query, $argtype, $arg = '') {
  if ($op == 'filter') {
    views_xml_views_argument('argument', $GLOBALS['current_view'], $arg);
  }
}

/**
 * argument hook that will display the XML document or display export icons.
 */
function views_xml_views_argument($op, &$view, $arg) {
  if ($op == 'argument' && ($arg == 'xml_raw' || $arg == 'xml_opml' || $arg == 'xml_atom')) {
    $view->page_type = 'views_' . $arg;
  }
  else {
    if ($op == 'post_view' && $view->build_type != 'block') {
      $args = views_post_view_make_args($view, $arg, $arg);
      $url = views_get_url($view, $args);
      $title = views_get_title($view, 'page', $args);
      $links = array();
      if ($arg == 'xml_opml') {
        if ($image = theme('image', drupal_get_path('module', 'views_xml') . '/opml32x32.png', t('OPML'), t('Show @title as OPML.', array(
          '@title' => $title,
        )))) {
          $links[] = l($image, $url, array(
            'class' => 'xml-icon',
          ), $url_filter, NULL, FALSE, TRUE);
          return implode('&nbsp;&nbsp;', $links);
        }
      }
      elseif ($arg == 'xml_raw') {
        if ($image = theme('image', drupal_get_path('module', 'views_xml') . '/xml32x36.png', t('Raw XML'), t('Show @title as raw XML', array(
          '@title' => $title,
        )))) {
          $links[] = l($image, $url, array(
            'class' => 'xml-icon',
          ), $url_filter, NULL, FALSE, TRUE);
          return implode('&nbsp;&nbsp;', $links);
        }
      }
      elseif ($arg == 'xml_atom') {
        if ($image = theme('image', drupal_get_path('module', 'views_xml') . '/atom80x15.png', t('Atom'), t('Show @title as Atom feed', array(
          '@title' => $title,
        )))) {
          $links[] = l($image, $url, array(
            'class' => 'xml-icon',
          ), $url_filter, NULL, FALSE, TRUE);
          return implode('&nbsp;&nbsp;', $links);
        }
      }
    }
  }
}

/*
 * describes how to theme a raw XML view
 */
function theme_views_xml_raw($view, $nodes, $type) {
  views_xml_raw_render($view->vid, $nodes, $type);
}

/*
 * describes how to theme an OPML view
 */
function theme_views_xml_opml($view, $nodes, $type) {
  views_xml_opml_render($view->vid, $nodes, $type);
}

/*
 * describes how to theme an Atom view
 */
function theme_views_xml_atom($view, $nodes, $type) {
  views_xml_atom_render($view->vid, $nodes, $type);
}

/**
 * post view to display the render icons
 */
function views_xml_views_post_view($view, $items, $output) {
  $links = '';
  foreach ($view->argument as $id => $argument) {
    if ($argument['type'] == 'xml_raw' || $argument['type'] == 'xml_opml' || $argument['type'] == 'xml_atom') {
      $links .= views_xml_views_argument('post_view', $view, $argument['type'], '');
    }
  }
  return $links;
}
function views_xml_raw_render($vid, $nodes, $type) {
  $view = views_load_view($vid);
  $result = views_build_view('items', $view);
  $fields = _views_get_fields();
  $xml .= '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
  $xml .= '<!-- generator="Drupal Views_Datasource.Module" -->' . "\n";
  $xml .= '<nodes>' . "\n";
  foreach ($nodes as $node) {
    $xml .= '  <node>' . "\n";
    foreach ($view->field as $field) {
      if ($fields[$field['id']]['visible'] !== false) {
        $label = preg_replace('/\\W/', '', views_xml_strip_illegal_chars($field['label'] ? $field['label'] : $fields[$field['fullname']]['name']));
        $value = views_xml_strip_illegal_chars(views_xml_is_date(views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view)));
        if (is_null($value) || $value === '') {
          continue;
        }
        $label = str_replace("Profile", '', $label);

        //strip out Profile: from profile fields

        //        if (preg_match('/\d/', $value)) {
        //          if (strtotime($value))
        //            $value = date(DATE_ISO8601, strtotime($value));
        //        }
        $xml .= "    <{$label}><![CDATA[{$value}]]></{$label}>\n";
      }
    }
    $xml .= '  </node>' . "\n";
  }
  $xml .= '</nodes>' . "\n";
  drupal_set_header('Content-Type: text/xml');
  print $xml;
  module_invoke_all('exit');
  exit;
}
function views_xml_opml_render($vid, $nodes, $type) {
  global $user;
  global $base_path;
  $view = views_load_view($vid);
  $result = views_build_view('items', $view);
  $fields = _views_get_fields();
  $xml .= '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
  $xml .= '<!-- generator="Drupal Views_Datasource.Module" -->' . "\n";
  $xml .= '<opml version="1.0">' . "\n";
  $xml .= '<head>' . "\n";
  $xml .= '  <title>' . variable_get('site_name', 'drupal') . '-' . $view->name . '</title>' . "\n";
  $xml .= '  <ownerName>' . $user->name . '</ownerName>' . "\n";
  $xml .= '  <ownerEmail>' . $user->mail . '</ownerEmail>' . "\n";
  $xml .= '  <dateCreated>' . date(DATE_ISO8601, time()) . '</dateCreated>' . "\n";
  $xml .= '</head>' . "\n";
  $xml .= '<body>' . "\n";
  foreach ($nodes as $node) {
    $xml .= '  <outline ';
    $field_count = 0;
    foreach ($view->field as $field) {
      if ($fields[$field['id']]['visible'] !== false) {
        $label = preg_replace('/\\W/', '', views_xml_strip_illegal_chars($field['label'] ? $field['label'] : $fields[$field['fullname']]['name']));
        $value = views_xml_strip_illegal_chars(views_xml_is_date(views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view)));
        if (is_null($value) || $value === '') {
          continue;
        }
        if (strtolower($label) == 'text' || strtolower($label) == 'nodebody') {
          $label = "text";
        }
        if (strtolower($label) == 'type' || strtolower($label) == 'nodetype') {
          $label = "type";
        }
        if (strtolower($label) == 'id' || strtolower($label) == 'nid' || strtolower($label) == 'nodeid') {

          //if a nid is given construct the url attribute
          $url = 'http://' . $_SERVER['HTTP_HOST'] . $base_path . 'index.php?q=node/' . $value;
        }
        if (strtolower($label) == 'published' || strtolower($label) == 'node_created' || strtolower($label) == 'nodecreatedtime') {
          if ($node->node_created) {
            $label = 'created';
            $value = date(DATE_RFC822, $node->node_created);
          }
        }
        $xml .= $label . '="' . preg_replace('/[^A-Za-z0-9 :\\/\\-_\\.\\?\\=]/', '', $value) . '" ';
      }
    }
    if ($url) {
      $xml .= ' ' . 'url="' . $url . '"';
    }
    $xml .= "  />" . "\n";
  }
  $xml .= '</body>' . "\n";
  $xml .= '</opml>' . "\n";
  drupal_set_header('Content-Type: text/xml');

  //drupal_set_header('Content-Disposition: attachment; filename="view-'. $view->name .'.csv"');
  print $xml;
  module_invoke_all('exit');
  exit;
}
function views_xml_atom_render($vid, $nodes, $type) {
  global $user;
  global $base_path;
  $view = views_load_view($vid);
  $result = views_build_view('items', $view);
  $fields = _views_get_fields();
  $xml .= '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
  $xml .= '<!-- generator="Drupal Views_Datasource.Module" -->' . "\n";
  $xml .= '<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">' . "\n";
  $xml .= '  <title>' . $view->name . '</title>' . "\n";
  $xml .= '  <link rel="alternate" type="text/html" href="' . ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . base_path() . '"/>' . "\n";
  $xml .= '  <link rel ="self" type="application/atom+xml" href="' . ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . '/' . $view->real_url . '"/>' . "\n";
  $xml .= '  <id>' . ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . '/' . $view->real_url . '</id>' . "\n";

  //use path as id
  $xml .= '  <updated>###feed_updated###</updated>' . "\n";

  //will set later
  $xml .= '  <generator>Views Datasource module</generator>' . "\n";
  $feed_last_updated = 0;
  foreach ($nodes as $node) {
    if ($node->nid) {
      $entry['nid'] = $node->nid;
    }
    if ($node->title) {
      $entry['title'] = $node->title;
    }
    if ($node->node_created) {
      $entry['published'] = $node->node_created;
    }
    if ($node->node_changed) {
      $entry['updated'] = $node->node_changed;
    }
    if ($node->users_name) {
      $entry['author'] = $node->users_name;
    }
    if ($node->users_email) {
      $entry['email'] = $node->users_mail;
    }
    foreach ($view->field as $field) {
      if ($fields[$field['id']]['visible'] === false) {
        continue;
      }
      $label = preg_replace('/\\W/', '', views_xml_strip_illegal_chars($field['label'] ? $field['label'] : $fields[$field['fullname']]['name']));
      $value = views_xml_strip_illegal_chars(views_xml_is_date(views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view)));
      $label = str_replace("Profile", '', $label);

      //strip out Profile: from profile fields
      if (is_null($value) || $value === '') {
        continue;
      }
      if (!isset($entry['nid']) && (strtolower($label) == 'nid' || strtolower($label) == 'node_nid' || strtolower($label) == 'nodeid')) {
        $entry['nid'] = $value;
      }
      if (!isset($entry['updated']) && (strtolower($label) == 'updated' || strtolower($label) == 'updated date' || strtolower($label) == 'nodeupdatedtime')) {
        if (is_int($value)) {

          //timestamp
          $entry['updated'] = intval($value);
        }
        else {
          if (getdate($value)) {

            //string date
            $entry['updated'] = strtotime($value);
          }
          else {
            $entry['updated'] = $value;
          }
        }
      }
      if (!isset($entry['title']) && strtolower($label) == 'title' || strtolower($label) == 'nodetitle') {
        $entry['title'] = $value;
      }
      if (strtolower($label) == 'link') {
        $entry['link'] = $value;
      }
      if (!isset($entry['published']) && (strtolower($label) == 'published' || strtolower($label) == 'nodecreatedtime')) {
        if (intval($value)) {

          //timestamp
          $entry['published'] = intval($value);
        }
        else {
          if (getdate($value)) {

            //string date
            $entry['published'] = strtotime($value);
          }
        }
      }
      if (!isset($entry['author']) && (strtolower($label) == 'author' || strtolower($label) == 'nodeauthorname')) {
        $entry['author'] = $value;
      }
      if (!isset($entry['email']) && strtolower($label) == 'email' || strtolower($label) == 'users_mail') {
        $entry['email'] = $value;
      }
      if (strtolower($label) == 'content' || strtolower($label) == 'nodebody') {
        $entry['content'] = $value;
      }
      if (strtolower($label) == 'summary' || strtolower($label) == 'nodeteaser' || strtolower($label) == 'node_revisions_teaser') {
        $entry['summary'] = $value;
      }
      if (isset($entry['nid']) && isset($entry['updated']) && isset($entry['link']) && isset($entry['title']) && isset($entry['published'])) {
        if (parse_url($entry['link'])) {
          $link = $entry['link'];
        }
        else {
          drupal_set_message('The link URL is not valid.', 'error');
          return;
        }
      }
      elseif (isset($entry['nid']) && isset($entry['updated']) && isset($entry['title']) && isset($entry['published'])) {

        //make the entry path with base_path + nid {
        $entry['link'] = 'http://' . $_SERVER['HTTP_HOST'] . $base_path . 'index.php?q=node/' . $entry['nid'];
      }
      else {
        drupal_set_message('The fields "nid", "title", "published", and "updated" must exist.', 'error');
        return;
      }
    }
    $link = $entry['link'];
    $link_url = parse_url($link);
    $nid = $entry['nid'];
    $updated = $entry['updated'];
    if ($updated > $feed_last_updated) {
      $feed_last_updated = $updated;
    }

    //Overall feed updated is the most recent node updated timestamp
    $title = $entry['title'];
    $published = $entry['published'];
    $author = $entry['author'];
    $email = $entry['email'];
    $content = $entry['content'];
    $summary = $entry['summary'];

    //Create an id for the entry using tag URIs
    $id = 'tag:' . $link_url['host'] . ',' . date('Y-m-d', $updated) . ':' . $link_url['path'] . '?' . $link_url['query'];
    $xml .= '  <entry>' . "\n";
    $xml .= '    <id>' . $id . '</id>' . "\n";
    $xml .= '    <updated>' . date(DATE_ATOM, $updated) . '</updated>' . "\n";
    $xml .= '    <title type="text">' . $title . '</title>' . "\n";
    $xml .= '    <link rel="alternate" type="text/html" href="' . $link . '"/>' . "\n";
    $xml .= '    <published>' . date(DATE_ATOM, $published) . '</published>' . "\n";
    if ($author) {
      if ($email) {
        $xml .= '    <author><name>' . $author . '</name><email>' . $email . '</email></author>' . "\n";
      }
      else {
        $xml .= '    <author><name>' . $author . '</name></author>' . "\n";
      }
    }
    if ($content) {
      $xml .= '    <content type="html" xml:base="' . ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . base_path() . '"><![CDATA[' . $content . ']]></content>' . "\n";
    }
    if ($summary) {
      $xml .= '    <summary type="html" xml:base="' . ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . base_path() . '"><![CDATA[' . $summary . ']]></summary>' . "\n";
    }
    $xml .= '  </entry>' . "\n";
  }
  $xml .= '</feed>' . "\n";
  $xml = str_replace('###feed_updated###', date(DATE_ATOM, $feed_last_updated), $xml);
  drupal_set_header('Content-Type: application/atom+xml');
  print $xml;

  //var_dump($view);
  module_invoke_all('exit');
  exit;
}

/**
 * Strips illegal Unicode characters and encodes entities in string
 *
 * @param string $input
 * @return string
 */
function views_xml_strip_illegal_chars($input) {

  //  $output = preg_replace('/[\x{80}-\x{A0}'. // Non-printable ISO-8859-1 + NBSP
  //        '\x{01}-\x{1F}'. //Non-printable ASCII characters
  //        '\x{AD}'. // Soft-hyphen
  //        '\x{2000}-\x{200F}'. // Various space characters
  //        '\x{2028}-\x{202F}'. // Bidirectional text overrides
  //        '\x{205F}-\x{206F}'. // Various text hinting characters
  //        '\x{FEFF}'. // Byte order mark
  //        '\x{FF01}-\x{FF60}'. // Full-width latin
  //        '\x{FFF9}-\x{FFFD}'. // Replacement characters
  //        '\x{0}]/u', // NULL byte
  //        '', $input);
  //  $output = preg_replace('/\x((10?|[2-F])FFF[EF]|FDD[0-9A-F]|[19][0-9A-F]|7F|8[0-46-9A-F]|0?[1-8BCEF])/', '', $input);
  //  $output = str_replace('"', '&quot;', $output); //encode quote
  //  $output = str_replace('&', '&amp;', $output); //encode ampersand
  //  $output = str_replace("'", '&pos;', $output); //encode apostrophe
  //  $output = str_replace('<', '&lt;', $output); //encode left-angled bracket
  //  $output = str_replace('>', '&gt;', $output); //encode right-angled bracket
  return check_plain(strip_tags($input));
}
function views_xml_is_date($input) {
  if (strpos($input, 'a:3:{s:5:"month"') !== 0) {
    return $input;
  }
  else {

    //serialized date array
    $date = unserialize($input);
    return date(DATE_ISO8601, mktime(0, 0, 0, $date['month'], $date['day'], $date['year']));
  }
}

/*
     print $field_name."\n";
     print $label."\n";
     print $value."\n";
     return;
//   $label = views_xml_strip_illegal_chars($field['fullname']);
//    if ($fields[$field['id']]['visible'] !== false) {
//      $label = views_xml_strip_illegal_chars($field['label'] ? $field['label'] : $fields[$field['fullname']]['name']);
//      $value = views_xml_strip_illegal_chars(views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view));
//      print($node->$field);
//      print $value;
//      $label = $fields[$field['fullname']]['name'];
//      var_dump($field);
//      var_dump($node);
     $field_name = $field['queryname'];
     //if ($field_name == 'node_nid') $field_name = 'nid';
     //print $label;
     $value = views_xml_strip_illegal_chars(views_xml_is_date($node->$field_name));
//    print ("$field_name:$value");
//    print $value;
//    return;
     $label =  views_xml_strip_illegal_chars($label);
*/

Functions

Namesort descending Description
theme_views_xml_atom
theme_views_xml_opml
theme_views_xml_raw
views_xml_atom_render
views_xml_is_date
views_xml_opml_render
views_xml_raw_render
views_xml_strip_illegal_chars Strips illegal Unicode characters and encodes entities in string
views_xml_views_argument argument hook that will display the XML document or display export icons.
views_xml_views_arguments
views_xml_views_handler handler for our own raw-XML or OPML or structured-XML argument handler
views_xml_views_post_view post view to display the render icons
views_xml_views_style_plugins Implementation of hook_views_style_plugins